diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-05-29 15:28:16 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-05-29 15:31:33 -0400 |
commit | 70bd3b298bbbd5a36c55af957bb3b5f727218918 (patch) | |
tree | 163f0ec0d44177c831b00aa0cc2d143240d95570 | |
parent | f7dbd399efff631203be9f09c07f128df18a3ee4 (diff) |
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 <broonie@opensource.wolfsonmicro.com>
-rw-r--r-- | sound/soc/codecs/wm8994.c | 40 | ||||
-rw-r--r-- | 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) | |||
3513 | wm8994->btn_mask); | 3513 | wm8994->btn_mask); |
3514 | } | 3514 | } |
3515 | 3515 | ||
3516 | static void wm8958_open_circuit_work(struct work_struct *work) | ||
3517 | { | ||
3518 | struct wm8994_priv *wm8994 = container_of(work, | ||
3519 | struct wm8994_priv, | ||
3520 | open_circuit_work.work); | ||
3521 | struct device *dev = wm8994->wm8994->dev; | ||
3522 | |||
3523 | wm1811_micd_stop(wm8994->hubs.codec); | ||
3524 | |||
3525 | mutex_lock(&wm8994->accdet_lock); | ||
3526 | |||
3527 | dev_dbg(dev, "Reporting open circuit\n"); | ||
3528 | |||
3529 | wm8994->jack_mic = false; | ||
3530 | wm8994->mic_detecting = true; | ||
3531 | |||
3532 | wm8958_micd_set_rate(wm8994->hubs.codec); | ||
3533 | |||
3534 | snd_soc_jack_report(wm8994->micdet[0].jack, 0, | ||
3535 | wm8994->btn_mask | | ||
3536 | SND_JACK_HEADSET); | ||
3537 | |||
3538 | mutex_unlock(&wm8994->accdet_lock); | ||
3539 | } | ||
3540 | |||
3516 | static void wm8958_mic_id(void *data, u16 status) | 3541 | static void wm8958_mic_id(void *data, u16 status) |
3517 | { | 3542 | { |
3518 | struct snd_soc_codec *codec = data; | 3543 | struct snd_soc_codec *codec = data; |
@@ -3522,16 +3547,9 @@ static void wm8958_mic_id(void *data, u16 status) | |||
3522 | if (!(status & WM8958_MICD_STS)) { | 3547 | if (!(status & WM8958_MICD_STS)) { |
3523 | /* If nothing present then clear our statuses */ | 3548 | /* If nothing present then clear our statuses */ |
3524 | dev_dbg(codec->dev, "Detected open circuit\n"); | 3549 | dev_dbg(codec->dev, "Detected open circuit\n"); |
3525 | wm8994->jack_mic = false; | ||
3526 | wm8994->mic_detecting = true; | ||
3527 | |||
3528 | wm1811_micd_stop(codec); | ||
3529 | 3550 | ||
3530 | wm8958_micd_set_rate(codec); | 3551 | schedule_delayed_work(&wm8994->open_circuit_work, |
3531 | 3552 | msecs_to_jiffies(2500)); | |
3532 | snd_soc_jack_report(wm8994->micdet[0].jack, 0, | ||
3533 | wm8994->btn_mask | | ||
3534 | SND_JACK_HEADSET); | ||
3535 | return; | 3553 | return; |
3536 | } | 3554 | } |
3537 | 3555 | ||
@@ -3812,6 +3830,8 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3812 | if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) | 3830 | if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) |
3813 | return IRQ_HANDLED; | 3831 | return IRQ_HANDLED; |
3814 | 3832 | ||
3833 | cancel_delayed_work_sync(&wm8994->open_circuit_work); | ||
3834 | |||
3815 | pm_runtime_get_sync(codec->dev); | 3835 | pm_runtime_get_sync(codec->dev); |
3816 | 3836 | ||
3817 | /* We may occasionally read a detection without an impedence | 3837 | /* We may occasionally read a detection without an impedence |
@@ -3911,6 +3931,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3911 | mutex_init(&wm8994->accdet_lock); | 3931 | mutex_init(&wm8994->accdet_lock); |
3912 | INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, | 3932 | INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, |
3913 | wm1811_jackdet_bootstrap); | 3933 | wm1811_jackdet_bootstrap); |
3934 | INIT_DELAYED_WORK(&wm8994->open_circuit_work, | ||
3935 | wm8958_open_circuit_work); | ||
3914 | 3936 | ||
3915 | switch (control->type) { | 3937 | switch (control->type) { |
3916 | case WM8994: | 3938 | 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 { | |||
134 | struct mutex accdet_lock; | 134 | struct mutex accdet_lock; |
135 | struct wm8994_micdet micdet[2]; | 135 | struct wm8994_micdet micdet[2]; |
136 | struct delayed_work mic_work; | 136 | struct delayed_work mic_work; |
137 | struct delayed_work open_circuit_work; | ||
137 | bool mic_detecting; | 138 | bool mic_detecting; |
138 | bool jack_mic; | 139 | bool jack_mic; |
139 | int btn_mask; | 140 | int btn_mask; |