diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index bc12d097ef0dbbc5b383d04970eaba80792e1bae..15fcb1bb71486391e97b85baed1ad4d82169f13d 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3166,9 +3166,16 @@ static void wm8958_default_micdet(u16 status, void *data) /* If we have jackdet that will detect removal */ if (wm8994->jackdet) { + mutex_lock(&wm8994->accdet_lock); + snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0); + wm1811_jackdet_set_mode(codec, + WM1811_JACKDET_MODE_JACK); + + mutex_unlock(&wm8994->accdet_lock); + if (wm8994->pdata->jd_ext_cap) { mutex_lock(&codec->mutex); snd_soc_dapm_disable_pin(&codec->dapm, @@ -3176,9 +3183,6 @@ static void wm8958_default_micdet(u16 status, void *data) snd_soc_dapm_sync(&codec->dapm); mutex_unlock(&codec->mutex); } - - wm1811_jackdet_set_mode(codec, - WM1811_JACKDET_MODE_JACK); } } @@ -3213,6 +3217,7 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) struct wm8994_priv *wm8994 = data; struct snd_soc_codec *codec = wm8994->codec; int reg; + bool present; mutex_lock(&wm8994->accdet_lock); @@ -3225,11 +3230,10 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) dev_dbg(codec->dev, "JACKDET %x\n", reg); - if (reg & WM1811_JACKDET_LVL) { - dev_dbg(codec->dev, "Jack detected\n"); + present = reg & WM1811_JACKDET_LVL; - snd_soc_jack_report(wm8994->micdet[0].jack, - SND_JACK_MECHANICAL, SND_JACK_MECHANICAL); + if (present) { + dev_dbg(codec->dev, "Jack detected\n"); snd_soc_update_bits(codec, WM8958_MICBIAS2, WM8958_MICB2_DISCH, 0); @@ -3247,32 +3251,12 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, WM8958_MICD_ENA); - - /* If required for an external cap force MICBIAS on */ - if (wm8994->pdata->jd_ext_cap) { - mutex_lock(&codec->mutex); - snd_soc_dapm_force_enable_pin(&codec->dapm, - "MICBIAS2"); - snd_soc_dapm_sync(&codec->dapm); - mutex_unlock(&codec->mutex); - } } else { dev_dbg(codec->dev, "Jack not detected\n"); snd_soc_update_bits(codec, WM8958_MICBIAS2, WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); - if (wm8994->pdata->jd_ext_cap) { - mutex_lock(&codec->mutex); - snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); - snd_soc_dapm_sync(&codec->dapm); - mutex_unlock(&codec->mutex); - } - - snd_soc_jack_report(wm8994->micdet[0].jack, 0, - SND_JACK_MECHANICAL | SND_JACK_HEADSET | - wm8994->btn_mask); - /* Enable debounce while removed */ snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, WM1811_JACKDET_DB, WM1811_JACKDET_DB); @@ -3286,6 +3270,28 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) mutex_unlock(&wm8994->accdet_lock); + /* If required for an external cap force MICBIAS on */ + if (wm8994->pdata->jd_ext_cap) { + mutex_lock(&codec->mutex); + + if (present) + snd_soc_dapm_force_enable_pin(&codec->dapm, + "MICBIAS2"); + else + snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); + + snd_soc_dapm_sync(&codec->dapm); + mutex_unlock(&codec->mutex); + } + + if (present) + snd_soc_jack_report(wm8994->micdet[0].jack, + SND_JACK_MECHANICAL, SND_JACK_MECHANICAL); + else + snd_soc_jack_report(wm8994->micdet[0].jack, 0, + SND_JACK_MECHANICAL | SND_JACK_HEADSET | + wm8994->btn_mask); + return IRQ_HANDLED; } @@ -3389,17 +3395,13 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) struct snd_soc_codec *codec = wm8994->codec; int reg, count; - mutex_lock(&wm8994->accdet_lock); - /* * Jack detection may have detected a removal simulataneously * with an update of the MICDET status; if so it will have * stopped detection and we can ignore this interrupt. */ - if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) { - mutex_unlock(&wm8994->accdet_lock); + if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) return IRQ_HANDLED; - } /* We may occasionally read a detection without an impedence * range being provided - if that happens loop again. @@ -3408,7 +3410,6 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) do { reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); if (reg < 0) { - mutex_unlock(&wm8994->accdet_lock); dev_err(codec->dev, "Failed to read mic detect status: %d\n", reg); @@ -3439,8 +3440,6 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) dev_warn(codec->dev, "Accessory detection with no callback\n"); out: - mutex_unlock(&wm8994->accdet_lock); - return IRQ_HANDLED; }