aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-11-22 03:02:09 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-12-03 02:34:09 -0500
commit78b76dbec8da6437e30519e6bbe4fb44d798addf (patch)
treeadf8c7b4d0b37593645dd2c8faa9d856c13c9145 /sound
parentf02b0de0f0925ea6dd1c5eee0a9e7748e38af4e6 (diff)
ASoC: wm8994: Simplify button detection code
Currently the WM8994 driver allows the WM8958 microphone detection code to be replaced in its entirety, providing a default implementation. This doesn't actually reflect the needs of users well. They generally wish to replace only the accessory identification parts of the algorithm (eg, using an external GPIO to provide the equivalent of the JACKDET support in the WM1811A). In preparation for supporting these users better refactor the existing code so that we have separate identification and button detection callbacks, selecting between them rather than using the mic_detecting flag in the existing callback. This also simplifies the code by introducing a more explicit state machine for the detecting and button states. In anticipation of future refactoring the callback is left in the signature for wm8958_mic_detect(), it will be removed at a later stage. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/wm8994.c87
-rw-r--r--sound/soc/codecs/wm8994.h2
2 files changed, 37 insertions, 52 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 4b4d58d3875e..4cd1b6cdb34f 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -91,8 +91,6 @@ static int wm8994_retune_mobile_base[] = {
91 WM8994_AIF2_EQ_GAINS_1, 91 WM8994_AIF2_EQ_GAINS_1,
92}; 92};
93 93
94static void wm8958_default_micdet(u16 status, void *data);
95
96static const struct wm8958_micd_rate micdet_rates[] = { 94static const struct wm8958_micd_rate micdet_rates[] = {
97 { 32768, true, 1, 4 }, 95 { 32768, true, 1, 4 },
98 { 32768, false, 1, 1 }, 96 { 32768, false, 1, 1 },
@@ -116,9 +114,6 @@ static void wm8958_micd_set_rate(struct snd_soc_codec *codec)
116 const struct wm8958_micd_rate *rates; 114 const struct wm8958_micd_rate *rates;
117 int num_rates; 115 int num_rates;
118 116
119 if (wm8994->jack_cb != wm8958_default_micdet)
120 return;
121
122 idle = !wm8994->jack_mic; 117 idle = !wm8994->jack_mic;
123 118
124 sysclk = snd_soc_read(codec, WM8994_CLOCKING_1); 119 sysclk = snd_soc_read(codec, WM8994_CLOCKING_1);
@@ -740,7 +735,7 @@ static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode)
740{ 735{
741 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 736 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
742 737
743 if (!wm8994->jackdet || !wm8994->jack_cb) 738 if (!wm8994->jackdet || !wm8994->micdet[0].jack)
744 return; 739 return;
745 740
746 if (wm8994->active_refcount) 741 if (wm8994->active_refcount)
@@ -3409,16 +3404,37 @@ static void wm1811_micd_stop(struct snd_soc_codec *codec)
3409 "MICBIAS2"); 3404 "MICBIAS2");
3410} 3405}
3411 3406
3412/* Default microphone detection handler for WM8958 - the user can 3407static void wm8958_button_det(struct snd_soc_codec *codec, u16 status)
3413 * override this if they wish.
3414 */
3415static void wm8958_default_micdet(u16 status, void *data)
3416{ 3408{
3417 struct snd_soc_codec *codec = data;
3418 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 3409 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3419 int report; 3410 int report;
3420 3411
3421 dev_dbg(codec->dev, "MICDET %x\n", status); 3412 report = 0;
3413 if (status & 0x4)
3414 report |= SND_JACK_BTN_0;
3415
3416 if (status & 0x8)
3417 report |= SND_JACK_BTN_1;
3418
3419 if (status & 0x10)
3420 report |= SND_JACK_BTN_2;
3421
3422 if (status & 0x20)
3423 report |= SND_JACK_BTN_3;
3424
3425 if (status & 0x40)
3426 report |= SND_JACK_BTN_4;
3427
3428 if (status & 0x80)
3429 report |= SND_JACK_BTN_5;
3430
3431 snd_soc_jack_report(wm8994->micdet[0].jack, report,
3432 wm8994->btn_mask);
3433}
3434
3435static void wm8958_mic_id(struct snd_soc_codec *codec, u16 status)
3436{
3437 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3422 3438
3423 /* Either nothing present or just starting detection */ 3439 /* Either nothing present or just starting detection */
3424 if (!(status & WM8958_MICD_STS)) { 3440 if (!(status & WM8958_MICD_STS)) {
@@ -3440,7 +3456,7 @@ static void wm8958_default_micdet(u16 status, void *data)
3440 /* If the measurement is showing a high impedence we've got a 3456 /* If the measurement is showing a high impedence we've got a
3441 * microphone. 3457 * microphone.
3442 */ 3458 */
3443 if (wm8994->mic_detecting && (status & 0x600)) { 3459 if (status & 0x600) {
3444 dev_dbg(codec->dev, "Detected microphone\n"); 3460 dev_dbg(codec->dev, "Detected microphone\n");
3445 3461
3446 wm8994->mic_detecting = false; 3462 wm8994->mic_detecting = false;
@@ -3453,7 +3469,7 @@ static void wm8958_default_micdet(u16 status, void *data)
3453 } 3469 }
3454 3470
3455 3471
3456 if (wm8994->mic_detecting && status & 0xfc) { 3472 if (status & 0xfc) {
3457 dev_dbg(codec->dev, "Detected headphone\n"); 3473 dev_dbg(codec->dev, "Detected headphone\n");
3458 wm8994->mic_detecting = false; 3474 wm8994->mic_detecting = false;
3459 3475
@@ -3465,31 +3481,6 @@ static void wm8958_default_micdet(u16 status, void *data)
3465 snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE, 3481 snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE,
3466 SND_JACK_HEADSET); 3482 SND_JACK_HEADSET);
3467 } 3483 }
3468
3469 /* Report short circuit as a button */
3470 if (wm8994->jack_mic) {
3471 report = 0;
3472 if (status & 0x4)
3473 report |= SND_JACK_BTN_0;
3474
3475 if (status & 0x8)
3476 report |= SND_JACK_BTN_1;
3477
3478 if (status & 0x10)
3479 report |= SND_JACK_BTN_2;
3480
3481 if (status & 0x20)
3482 report |= SND_JACK_BTN_3;
3483
3484 if (status & 0x40)
3485 report |= SND_JACK_BTN_4;
3486
3487 if (status & 0x80)
3488 report |= SND_JACK_BTN_5;
3489
3490 snd_soc_jack_report(wm8994->micdet[0].jack, report,
3491 wm8994->btn_mask);
3492 }
3493} 3484}
3494 3485
3495/* Deferred mic detection to allow for extra settling time */ 3486/* Deferred mic detection to allow for extra settling time */
@@ -3648,18 +3639,14 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3648 } 3639 }
3649 3640
3650 if (jack) { 3641 if (jack) {
3651 if (!cb) { 3642 /* No longer supported */
3652 dev_dbg(codec->dev, "Using default micdet callback\n"); 3643 if (cb)
3653 cb = wm8958_default_micdet; 3644 return -EINVAL;
3654 cb_data = codec;
3655 }
3656 3645
3657 snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS"); 3646 snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS");
3658 snd_soc_dapm_sync(&codec->dapm); 3647 snd_soc_dapm_sync(&codec->dapm);
3659 3648
3660 wm8994->micdet[0].jack = jack; 3649 wm8994->micdet[0].jack = jack;
3661 wm8994->jack_cb = cb;
3662 wm8994->jack_cb_data = cb_data;
3663 3650
3664 wm8994->mic_detecting = true; 3651 wm8994->mic_detecting = true;
3665 wm8994->jack_mic = false; 3652 wm8994->jack_mic = false;
@@ -3762,10 +3749,10 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3762 trace_snd_soc_jack_irq(dev_name(codec->dev)); 3749 trace_snd_soc_jack_irq(dev_name(codec->dev));
3763#endif 3750#endif
3764 3751
3765 if (wm8994->jack_cb) 3752 if (wm8994->mic_detecting)
3766 wm8994->jack_cb(reg, wm8994->jack_cb_data); 3753 wm8958_mic_id(codec, reg);
3767 else 3754 else
3768 dev_warn(codec->dev, "Accessory detection with no callback\n"); 3755 wm8958_button_det(codec, reg);
3769 3756
3770out: 3757out:
3771 pm_runtime_put(codec->dev); 3758 pm_runtime_put(codec->dev);
@@ -4296,7 +4283,7 @@ static int wm8994_resume(struct device *dev)
4296{ 4283{
4297 struct wm8994_priv *wm8994 = dev_get_drvdata(dev); 4284 struct wm8994_priv *wm8994 = dev_get_drvdata(dev);
4298 4285
4299 if (wm8994->jackdet && wm8994->jack_cb) 4286 if (wm8994->jackdet && wm8994->jackdet_mode)
4300 regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2, 4287 regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2,
4301 WM1811_JACKDET_MODE_MASK, 4288 WM1811_JACKDET_MODE_MASK,
4302 WM1811_JACKDET_MODE_AUDIO); 4289 WM1811_JACKDET_MODE_AUDIO);
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index f618d16e1a12..f5546f242ab1 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -137,8 +137,6 @@ struct wm8994_priv {
137 int jackdet_mode; 137 int jackdet_mode;
138 struct delayed_work jackdet_bootstrap; 138 struct delayed_work jackdet_bootstrap;
139 139
140 wm8958_micdet_cb jack_cb;
141 void *jack_cb_data;
142 int micdet_irq; 140 int micdet_irq;
143 141
144 int revision; 142 int revision;