Commit 21fa98f4 authored by Arnaud Ferraris's avatar Arnaud Ferraris Committed by Mark Brown

ASoC: sun8i-codec: Implement jack and accessory detection

Add support for the jack detection functionality in the A64 variant,
which uses a pair of IRQs; and microphone accessory (button) detection,
which uses an ADC with an IRQ trigger.

IRQs will only be triggered if the JACKDETEN, HMICBIASEN, and MICADCEN
bits are set appropriately in the analog codec component
(sun50i-codec-analog), but there is no direct software dependency
between the two components.

Setup ADC so that it samples with period of 16ms, disable smoothing
and enable MDATA threshold (should be below idle voltage/HMIC_DATA
value). Also enable HMIC_N, which makes sure we get HMIC_N samples
after HMIC_DATA crosses the threshold.

This allows us to perform steady state detection of HMIC_DATA, by
comparing current and previous ADC samples, to detect end of the
transient when the user de-presses the button. Otherwise ADC could
sample anywhere within the transient, and the driver may mis-issue
key-press events for other buttons attached to the resistor ladder.

[Ondrej: Almost complete rewrite of the patch, change to use set_jack
API. Better de-bounce, fix mic button handling, better interrupt
processing.]
Signed-off-by: default avatarArnaud Ferraris <arnaud.ferraris@collabora.com>
[Samuel: Decouple from analog codec, fixes]
Co-developed-by: default avatarSamuel Holland <samuel@sholland.org>
Signed-off-by: default avatarSamuel Holland <samuel@sholland.org>
Co-developed-by: default avatarOndrej Jirman <megi@xff.cz>
Signed-off-by: default avatarOndrej Jirman <megi@xff.cz>
Link: https://msgid.link/r/20240302140042.1990256-5-megi@xff.czSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent d5961e43
......@@ -115,6 +115,11 @@
#define SUN50I_ADDA_HS_MBIAS_CTRL 0x0e
#define SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN 7
#define SUN50I_ADDA_MDET_CTRL 0x1c
#define SUN50I_ADDA_MDET_CTRL_SELDETADC_FS 4
#define SUN50I_ADDA_MDET_CTRL_SELDETADC_DB 2
#define SUN50I_ADDA_MDET_CTRL_SELDETADC_BF 0
#define SUN50I_ADDA_JACK_MIC_CTRL 0x1d
#define SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN 7
#define SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN 6
......@@ -564,6 +569,13 @@ static int sun50i_codec_analog_probe(struct platform_device *pdev)
BIT(SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN),
enable << SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN);
/* Select sample interval of the ADC sample to 16ms */
regmap_update_bits(regmap, SUN50I_ADDA_MDET_CTRL,
0x7 << SUN50I_ADDA_MDET_CTRL_SELDETADC_FS |
0x3 << SUN50I_ADDA_MDET_CTRL_SELDETADC_BF,
0x3 << SUN50I_ADDA_MDET_CTRL_SELDETADC_FS |
0x3 << SUN50I_ADDA_MDET_CTRL_SELDETADC_BF);
return devm_snd_soc_register_component(&pdev->dev,
&sun50i_codec_analog_cmpnt_drv,
NULL, 0);
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment