diff options
author | NeilBrown <neilb@suse.de> | 2012-08-25 08:44:51 +1000 |
---|---|---|
committer | Denis 'GNUtoo' Carikli <GNUtoo@no-log.org> | 2013-03-09 14:51:24 +0100 |
commit | 5e0dc2bcc0ae188e68dd8a3eaa399f653ae1482c (patch) | |
tree | bb0b7a365a6917306065763bf60f9c2b1c6a41c3 | |
parent | 16caa62c4112d5244430ec67ddae24d1d97c6765 (diff) | |
download | kernel_goldelico_gta04-5e0dc2bcc0ae188e68dd8a3eaa399f653ae1482c.zip kernel_goldelico_gta04-5e0dc2bcc0ae188e68dd8a3eaa399f653ae1482c.tar.gz kernel_goldelico_gta04-5e0dc2bcc0ae188e68dd8a3eaa399f653ae1482c.tar.bz2 |
GTA04 audio headset jack detect.
Enhance jack detection to differentiate with and without a microphone,
and to report a button-press when the microphone is shorted.
Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r-- | sound/soc/omap/gta04-audio.c | 58 |
1 files changed, 51 insertions, 7 deletions
diff --git a/sound/soc/omap/gta04-audio.c b/sound/soc/omap/gta04-audio.c index b5cbe37..f49877c 100644 --- a/sound/soc/omap/gta04-audio.c +++ b/sound/soc/omap/gta04-audio.c @@ -144,20 +144,63 @@ static struct { struct delayed_work jack_work; struct snd_soc_codec *codec; int open; + /* When any jack is present, we: + * - poll more quickly to catch button presses + * - assume a 'short' is 'button press', not 'headset has + * no mic + * 'present' stores SND_JACK_HEADPHONE and SND_JACK_MICROPHONE + * indication what we thing is present. + */ + int present; } jack; static void gta04_audio_jack_work(struct work_struct *work) { long val; + long delay = msecs_to_jiffies(500); + int jackbits; + + /* choose delay *before* checking presence so we still get + * one long delay on first insertion to help with debounce. + */ + if (jack.present) + delay = msecs_to_jiffies(50); val = twl4030_get_madc_conversion(7); - if (val < 100) - snd_soc_jack_report(&jack.hs_jack, 0, SND_JACK_HEADSET); - else - snd_soc_jack_report(&jack.hs_jack, SND_JACK_HEADSET, - SND_JACK_HEADSET); + /* On my device: + * open circuit = around 20 + * short circuit = around 800 + * microphone = around 830-840 !!! + */ + if (val < 100) { + /* open circuit */ + jackbits = 0; + jack.present = 0; + /* debounce */ + delay = msecs_to_jiffies(500); + } else if (val < 820) { + /* short */ + if (jack.present == 0) { + /* Inserted headset with no mic */ + jack.present = SND_JACK_HEADPHONE; + jackbits = jack.present; + } else if (jack.present & SND_JACK_MICROPHONE) { + /* mic shorter == button press */ + jackbits = SND_JACK_BTN_0 | jack.present; + } else { + /* headphones still present */ + jackbits = jack.present; + } + } else { + /* There is a microphone there */ + jack.present = SND_JACK_HEADSET; + jackbits = jack.present; + } + snd_soc_jack_report(&jack.hs_jack, jackbits, + SND_JACK_HEADSET | SND_JACK_BTN_0); + if (jack.open) - schedule_delayed_work(&jack.jack_work, msecs_to_jiffies(500)); + schedule_delayed_work(&jack.jack_work, delay); } static int gta04_audio_suspend(struct snd_soc_card *card) @@ -236,7 +279,8 @@ static int omap3gta04_init(struct snd_soc_pcm_runtime *runtime) * but we need to poll :-( */ ret = snd_soc_jack_new(codec, "Headset Jack", - SND_JACK_HEADSET, &jack.hs_jack); + SND_JACK_HEADSET | SND_JACK_BTN_0, + &jack.hs_jack); if (ret) return ret; INIT_DELAYED_WORK(&jack.jack_work, gta04_audio_jack_work); |