aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-07-25 18:03:36 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-08-03 18:03:56 -0400
commit99af79dff5a609fe886d271bbc91e1a95eca3066 (patch)
tree204f77752d1f2a7939ad2ba58d9f8b32ff86d701
parent8cb8e83bfa7cb63ad4b3c3b79410766da397124b (diff)
ASoC: wm8994: Ensure we get a notification on startup for jackdet
Since jackdet only reports deltas it won't generate an interrupt on startup when a jack is not present. This doesn't make a difference to userspace but does mean we don't generate a notification via the internal notifier chains. Fix that by scheduling a work to poll the chip after the clock is enabled. Use an extremely large timeout since there's no urgency and we don't want to report a false negative. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/codecs/wm8994.c37
-rw-r--r--sound/soc/codecs/wm8994.h2
2 files changed, 38 insertions, 1 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 1237c11c8c35..7bb0c2c824cc 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -789,11 +789,27 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
789 struct snd_kcontrol *kcontrol, int event) 789 struct snd_kcontrol *kcontrol, int event)
790{ 790{
791 struct snd_soc_codec *codec = w->codec; 791 struct snd_soc_codec *codec = w->codec;
792 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
792 793
793 switch (event) { 794 switch (event) {
794 case SND_SOC_DAPM_PRE_PMU: 795 case SND_SOC_DAPM_PRE_PMU:
795 return configure_clock(codec); 796 return configure_clock(codec);
796 797
798 case SND_SOC_DAPM_POST_PMU:
799 /*
800 * JACKDET won't run until we start the clock and it
801 * only reports deltas, make sure we notify the state
802 * up the stack on startup. Use a *very* generous
803 * timeout for paranoia, there's no urgency and we
804 * don't want false reports.
805 */
806 if (wm8994->jackdet && !wm8994->clk_has_run) {
807 schedule_delayed_work(&wm8994->jackdet_bootstrap,
808 msecs_to_jiffies(1000));
809 wm8994->clk_has_run = true;
810 }
811 break;
812
797 case SND_SOC_DAPM_POST_PMD: 813 case SND_SOC_DAPM_POST_PMD:
798 configure_clock(codec); 814 configure_clock(codec);
799 break; 815 break;
@@ -1632,7 +1648,8 @@ SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, vmid_event,
1632 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 1648 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1633 1649
1634SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, 1650SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
1635 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1651 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1652 SND_SOC_DAPM_PRE_PMD),
1636 1653
1637SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, 3, 0, NULL, 0), 1654SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, 3, 0, NULL, 0),
1638SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM, 2, 0, NULL, 0), 1655SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM, 2, 0, NULL, 0),
@@ -3508,10 +3525,22 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3508 SND_JACK_MECHANICAL | SND_JACK_HEADSET | 3525 SND_JACK_MECHANICAL | SND_JACK_HEADSET |
3509 wm8994->btn_mask); 3526 wm8994->btn_mask);
3510 3527
3528 /* Since we only report deltas force an update, ensures we
3529 * avoid bootstrapping issues with the core. */
3530 snd_soc_jack_report(wm8994->micdet[0].jack, 0, 0);
3531
3511 pm_runtime_put(codec->dev); 3532 pm_runtime_put(codec->dev);
3512 return IRQ_HANDLED; 3533 return IRQ_HANDLED;
3513} 3534}
3514 3535
3536static void wm1811_jackdet_bootstrap(struct work_struct *work)
3537{
3538 struct wm8994_priv *wm8994 = container_of(work,
3539 struct wm8994_priv,
3540 jackdet_bootstrap.work);
3541 wm1811_jackdet_irq(0, wm8994);
3542}
3543
3515/** 3544/**
3516 * wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ 3545 * wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ
3517 * 3546 *
@@ -3582,6 +3611,10 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3582 * otherwise jump straight to microphone detection. 3611 * otherwise jump straight to microphone detection.
3583 */ 3612 */
3584 if (wm8994->jackdet) { 3613 if (wm8994->jackdet) {
3614 /* Disable debounce for the initial detect */
3615 snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
3616 WM1811_JACKDET_DB, 0);
3617
3585 snd_soc_update_bits(codec, WM8958_MICBIAS2, 3618 snd_soc_update_bits(codec, WM8958_MICBIAS2,
3586 WM8958_MICB2_DISCH, 3619 WM8958_MICB2_DISCH,
3587 WM8958_MICB2_DISCH); 3620 WM8958_MICB2_DISCH);
@@ -3706,6 +3739,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3706 3739
3707 mutex_init(&wm8994->accdet_lock); 3740 mutex_init(&wm8994->accdet_lock);
3708 INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work); 3741 INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work);
3742 INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap,
3743 wm1811_jackdet_bootstrap);
3709 3744
3710 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) 3745 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
3711 init_completion(&wm8994->fll_locked[i]); 3746 init_completion(&wm8994->fll_locked[i]);
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index e6d8209b8f29..f142ec198db3 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -81,6 +81,7 @@ struct wm8994_priv {
81 struct completion fll_locked[2]; 81 struct completion fll_locked[2];
82 bool fll_locked_irq; 82 bool fll_locked_irq;
83 bool fll_byp; 83 bool fll_byp;
84 bool clk_has_run;
84 85
85 int vmid_refcount; 86 int vmid_refcount;
86 int active_refcount; 87 int active_refcount;
@@ -134,6 +135,7 @@ struct wm8994_priv {
134 int btn_mask; 135 int btn_mask;
135 bool jackdet; 136 bool jackdet;
136 int jackdet_mode; 137 int jackdet_mode;
138 struct delayed_work jackdet_bootstrap;
137 139
138 wm8958_micdet_cb jack_cb; 140 wm8958_micdet_cb jack_cb;
139 void *jack_cb_data; 141 void *jack_cb_data;