aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-08-25 08:44:51 +1000
committerDenis 'GNUtoo' Carikli <GNUtoo@no-log.org>2013-03-09 15:43:03 +0100
commitae7cef857a21f11dba4d2e1fa88206afd764d069 (patch)
treed8388af463daa1ca380dd65a2e600fe956e06397
parent9db3215c88e39b3c5a5aa5497603798b55831e2c (diff)
downloadkernel_goldelico_gta04-ae7cef857a21f11dba4d2e1fa88206afd764d069.zip
kernel_goldelico_gta04-ae7cef857a21f11dba4d2e1fa88206afd764d069.tar.gz
kernel_goldelico_gta04-ae7cef857a21f11dba4d2e1fa88206afd764d069.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.c58
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);