From 70bd3b298bbbd5a36c55af957bb3b5f727218918 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 29 May 2013 20:28:16 +0100 Subject: [PATCH] ASoC: wm8994: Defer declaration of open circuit microphones Provide a bit of debounce to handle pathological cases with slow input better by allowing the microphone detection to run for a bit longer. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8994.c | 40 ++++++++++++++++++++++++++++++--------- sound/soc/codecs/wm8994.h | 1 + 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 0805d6ff9ff7..2c2a183da2b6 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3513,6 +3513,31 @@ static void wm8958_button_det(struct snd_soc_codec *codec, u16 status) wm8994->btn_mask); } +static void wm8958_open_circuit_work(struct work_struct *work) +{ + struct wm8994_priv *wm8994 = container_of(work, + struct wm8994_priv, + open_circuit_work.work); + struct device *dev = wm8994->wm8994->dev; + + wm1811_micd_stop(wm8994->hubs.codec); + + mutex_lock(&wm8994->accdet_lock); + + dev_dbg(dev, "Reporting open circuit\n"); + + wm8994->jack_mic = false; + wm8994->mic_detecting = true; + + wm8958_micd_set_rate(wm8994->hubs.codec); + + snd_soc_jack_report(wm8994->micdet[0].jack, 0, + wm8994->btn_mask | + SND_JACK_HEADSET); + + mutex_unlock(&wm8994->accdet_lock); +} + static void wm8958_mic_id(void *data, u16 status) { struct snd_soc_codec *codec = data; @@ -3522,16 +3547,9 @@ static void wm8958_mic_id(void *data, u16 status) if (!(status & WM8958_MICD_STS)) { /* If nothing present then clear our statuses */ dev_dbg(codec->dev, "Detected open circuit\n"); - wm8994->jack_mic = false; - wm8994->mic_detecting = true; - - wm1811_micd_stop(codec); - wm8958_micd_set_rate(codec); - - snd_soc_jack_report(wm8994->micdet[0].jack, 0, - wm8994->btn_mask | - SND_JACK_HEADSET); + schedule_delayed_work(&wm8994->open_circuit_work, + msecs_to_jiffies(2500)); return; } @@ -3812,6 +3830,8 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) return IRQ_HANDLED; + cancel_delayed_work_sync(&wm8994->open_circuit_work); + pm_runtime_get_sync(codec->dev); /* We may occasionally read a detection without an impedence @@ -3911,6 +3931,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) mutex_init(&wm8994->accdet_lock); INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, wm1811_jackdet_bootstrap); + INIT_DELAYED_WORK(&wm8994->open_circuit_work, + wm8958_open_circuit_work); switch (control->type) { case WM8994: diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index 55ddf4d57d9b..9d19a9185d35 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -134,6 +134,7 @@ struct wm8994_priv { struct mutex accdet_lock; struct wm8994_micdet micdet[2]; struct delayed_work mic_work; + struct delayed_work open_circuit_work; bool mic_detecting; bool jack_mic; int btn_mask; -- 2.39.5