aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-09-28 11:50:15 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-10-14 22:51:32 -0400
commitc0cc3f1665256b7cfdc1d581f997dcea1af71405 (patch)
tree53f064b7140e727147a9251baaf4dac25541edd6 /sound/soc
parentddffeb8c4d0331609ef2581d84de4d763607bd37 (diff)
ASoC: wm8994: Allow a delay between jack insertion and microphone detect
This can be used to provide some additional settling time to ensure that we don't start microphone detection while the microphone pin is connected to one of the headphone pins. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/wm8994.c74
1 files changed, 55 insertions, 19 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 2b2dadc54dac..07095a9ca9a6 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -3470,11 +3470,46 @@ static void wm8958_default_micdet(u16 status, void *data)
3470 } 3470 }
3471} 3471}
3472 3472
3473/* Deferred mic detection to allow for extra settling time */
3474static void wm1811_mic_work(struct work_struct *work)
3475{
3476 struct wm8994_priv *wm8994 = container_of(work, struct wm8994_priv,
3477 mic_work.work);
3478 struct snd_soc_codec *codec = wm8994->hubs.codec;
3479
3480 pm_runtime_get_sync(codec->dev);
3481
3482 /* If required for an external cap force MICBIAS on */
3483 if (wm8994->pdata->jd_ext_cap) {
3484 snd_soc_dapm_force_enable_pin(&codec->dapm,
3485 "MICBIAS2");
3486 snd_soc_dapm_sync(&codec->dapm);
3487 }
3488
3489 mutex_lock(&wm8994->accdet_lock);
3490
3491 dev_dbg(codec->dev, "Starting mic detection\n");
3492
3493 /*
3494 * Start off measument of microphone impedence to find out
3495 * what's actually there.
3496 */
3497 wm8994->mic_detecting = true;
3498 wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC);
3499
3500 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
3501 WM8958_MICD_ENA, WM8958_MICD_ENA);
3502
3503 mutex_unlock(&wm8994->accdet_lock);
3504
3505 pm_runtime_put(codec->dev);
3506}
3507
3473static irqreturn_t wm1811_jackdet_irq(int irq, void *data) 3508static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3474{ 3509{
3475 struct wm8994_priv *wm8994 = data; 3510 struct wm8994_priv *wm8994 = data;
3476 struct snd_soc_codec *codec = wm8994->hubs.codec; 3511 struct snd_soc_codec *codec = wm8994->hubs.codec;
3477 int reg; 3512 int reg, delay;
3478 bool present; 3513 bool present;
3479 3514
3480 pm_runtime_get_sync(codec->dev); 3515 pm_runtime_get_sync(codec->dev);
@@ -3505,18 +3540,14 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3505 snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, 3540 snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
3506 WM1811_JACKDET_DB, 0); 3541 WM1811_JACKDET_DB, 0);
3507 3542
3508 /* 3543 delay = wm8994->pdata->micdet_delay;
3509 * Start off measument of microphone impedence to find 3544 schedule_delayed_work(&wm8994->mic_work,
3510 * out what's actually there. 3545 msecs_to_jiffies(delay));
3511 */
3512 wm8994->mic_detecting = true;
3513 wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC);
3514
3515 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
3516 WM8958_MICD_ENA, WM8958_MICD_ENA);
3517 } else { 3546 } else {
3518 dev_dbg(codec->dev, "Jack not detected\n"); 3547 dev_dbg(codec->dev, "Jack not detected\n");
3519 3548
3549 cancel_delayed_work_sync(&wm8994->mic_work);
3550
3520 snd_soc_update_bits(codec, WM8958_MICBIAS2, 3551 snd_soc_update_bits(codec, WM8958_MICBIAS2,
3521 WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); 3552 WM8958_MICB2_DISCH, WM8958_MICB2_DISCH);
3522 3553
@@ -3533,14 +3564,9 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3533 3564
3534 mutex_unlock(&wm8994->accdet_lock); 3565 mutex_unlock(&wm8994->accdet_lock);
3535 3566
3536 /* If required for an external cap force MICBIAS on */ 3567 /* Turn off MICBIAS if it was on for an external cap */
3537 if (wm8994->pdata->jd_ext_cap) { 3568 if (wm8994->pdata->jd_ext_cap && !present)
3538 if (present) 3569 snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2");
3539 snd_soc_dapm_force_enable_pin(&codec->dapm,
3540 "MICBIAS2");
3541 else
3542 snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2");
3543 }
3544 3570
3545 if (present) 3571 if (present)
3546 snd_soc_jack_report(wm8994->micdet[0].jack, 3572 snd_soc_jack_report(wm8994->micdet[0].jack,
@@ -3763,10 +3789,20 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3763 snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); 3789 snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
3764 3790
3765 mutex_init(&wm8994->accdet_lock); 3791 mutex_init(&wm8994->accdet_lock);
3766 INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work);
3767 INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, 3792 INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap,
3768 wm1811_jackdet_bootstrap); 3793 wm1811_jackdet_bootstrap);
3769 3794
3795 switch (control->type) {
3796 case WM8994:
3797 INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work);
3798 break;
3799 case WM1811:
3800 INIT_DELAYED_WORK(&wm8994->mic_work, wm1811_mic_work);
3801 break;
3802 default:
3803 break;
3804 }
3805
3770 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) 3806 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
3771 init_completion(&wm8994->fll_locked[i]); 3807 init_completion(&wm8994->fll_locked[i]);
3772 3808