ASoC: wm8994: Simplify button detection code
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Thu, 22 Nov 2012 08:02:09 +0000 (17:02 +0900)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Mon, 3 Dec 2012 07:34:09 +0000 (16:34 +0900)
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>
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm8994.h

index 4b4d58d3875ed528edd0438c341a6a0518a09c79..4cd1b6cdb34f7fbb3d809ebb5909515a10689c5d 100644 (file)
@@ -91,8 +91,6 @@ static int wm8994_retune_mobile_base[] = {
        WM8994_AIF2_EQ_GAINS_1,
 };
 
-static void wm8958_default_micdet(u16 status, void *data);
-
 static const struct wm8958_micd_rate micdet_rates[] = {
        { 32768,       true,  1, 4 },
        { 32768,       false, 1, 1 },
@@ -116,9 +114,6 @@ static void wm8958_micd_set_rate(struct snd_soc_codec *codec)
        const struct wm8958_micd_rate *rates;
        int num_rates;
 
-       if (wm8994->jack_cb != wm8958_default_micdet)
-               return;
-
        idle = !wm8994->jack_mic;
 
        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)
 {
        struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 
-       if (!wm8994->jackdet || !wm8994->jack_cb)
+       if (!wm8994->jackdet || !wm8994->micdet[0].jack)
                return;
 
        if (wm8994->active_refcount)
@@ -3409,16 +3404,37 @@ static void wm1811_micd_stop(struct snd_soc_codec *codec)
                                         "MICBIAS2");
 }
 
-/* Default microphone detection handler for WM8958 - the user can
- * override this if they wish.
- */
-static void wm8958_default_micdet(u16 status, void *data)
+static void wm8958_button_det(struct snd_soc_codec *codec, u16 status)
 {
-       struct snd_soc_codec *codec = data;
        struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
        int report;
 
-       dev_dbg(codec->dev, "MICDET %x\n", status);
+       report = 0;
+       if (status & 0x4)
+               report |= SND_JACK_BTN_0;
+
+       if (status & 0x8)
+               report |= SND_JACK_BTN_1;
+
+       if (status & 0x10)
+               report |= SND_JACK_BTN_2;
+
+       if (status & 0x20)
+               report |= SND_JACK_BTN_3;
+
+       if (status & 0x40)
+               report |= SND_JACK_BTN_4;
+
+       if (status & 0x80)
+               report |= SND_JACK_BTN_5;
+
+       snd_soc_jack_report(wm8994->micdet[0].jack, report,
+                           wm8994->btn_mask);
+}
+
+static void wm8958_mic_id(struct snd_soc_codec *codec, u16 status)
+{
+       struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 
        /* Either nothing present or just starting detection */
        if (!(status & WM8958_MICD_STS)) {
@@ -3440,7 +3456,7 @@ static void wm8958_default_micdet(u16 status, void *data)
        /* If the measurement is showing a high impedence we've got a
         * microphone.
         */
-       if (wm8994->mic_detecting && (status & 0x600)) {
+       if (status & 0x600) {
                dev_dbg(codec->dev, "Detected microphone\n");
 
                wm8994->mic_detecting = false;
@@ -3453,7 +3469,7 @@ static void wm8958_default_micdet(u16 status, void *data)
        }
 
 
-       if (wm8994->mic_detecting && status & 0xfc) {
+       if (status & 0xfc) {
                dev_dbg(codec->dev, "Detected headphone\n");
                wm8994->mic_detecting = false;
 
@@ -3465,31 +3481,6 @@ static void wm8958_default_micdet(u16 status, void *data)
                snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE,
                                    SND_JACK_HEADSET);
        }
-
-       /* Report short circuit as a button */
-       if (wm8994->jack_mic) {
-               report = 0;
-               if (status & 0x4)
-                       report |= SND_JACK_BTN_0;
-
-               if (status & 0x8)
-                       report |= SND_JACK_BTN_1;
-
-               if (status & 0x10)
-                       report |= SND_JACK_BTN_2;
-
-               if (status & 0x20)
-                       report |= SND_JACK_BTN_3;
-
-               if (status & 0x40)
-                       report |= SND_JACK_BTN_4;
-
-               if (status & 0x80)
-                       report |= SND_JACK_BTN_5;
-
-               snd_soc_jack_report(wm8994->micdet[0].jack, report,
-                                   wm8994->btn_mask);
-       }
 }
 
 /* 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,
        }
 
        if (jack) {
-               if (!cb) {
-                       dev_dbg(codec->dev, "Using default micdet callback\n");
-                       cb = wm8958_default_micdet;
-                       cb_data = codec;
-               }
+               /* No longer supported */
+               if (cb)
+                       return -EINVAL;
 
                snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS");
                snd_soc_dapm_sync(&codec->dapm);
 
                wm8994->micdet[0].jack = jack;
-               wm8994->jack_cb = cb;
-               wm8994->jack_cb_data = cb_data;
 
                wm8994->mic_detecting = true;
                wm8994->jack_mic = false;
@@ -3762,10 +3749,10 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
        trace_snd_soc_jack_irq(dev_name(codec->dev));
 #endif
 
-       if (wm8994->jack_cb)
-               wm8994->jack_cb(reg, wm8994->jack_cb_data);
+       if (wm8994->mic_detecting)
+               wm8958_mic_id(codec, reg);
        else
-               dev_warn(codec->dev, "Accessory detection with no callback\n");
+               wm8958_button_det(codec, reg);
 
 out:
        pm_runtime_put(codec->dev);
@@ -4296,7 +4283,7 @@ static int wm8994_resume(struct device *dev)
 {
        struct wm8994_priv *wm8994 = dev_get_drvdata(dev);
 
-       if (wm8994->jackdet && wm8994->jack_cb)
+       if (wm8994->jackdet && wm8994->jackdet_mode)
                regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2,
                                   WM1811_JACKDET_MODE_MASK,
                                   WM1811_JACKDET_MODE_AUDIO);
index f618d16e1a125f5f2e08925fc59fecb53cad7372..f5546f242ab15a24e548bebc212543e9c0ad8206 100644 (file)
@@ -137,8 +137,6 @@ struct wm8994_priv {
        int jackdet_mode;
        struct delayed_work jackdet_bootstrap;
 
-       wm8958_micdet_cb jack_cb;
-       void *jack_cb_data;
        int micdet_irq;
 
        int revision;