]> git.karo-electronics.de Git - linux-beck.git/commitdiff
ASoC: wm8994: Allow debounce before MICDET identification
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Thu, 30 May 2013 12:42:29 +0000 (13:42 +0100)
committerMark Brown <broonie@linaro.org>
Sat, 1 Jun 2013 18:28:58 +0000 (19:28 +0100)
For systems which do not have a jack detection feature allow some debounce
to be specified before we perform accessory identification, improving
robustness without impacting button detection responsiveness.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
include/linux/mfd/wm8994/pdata.h
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm8994.h

index 68e77659488950f69df451b04b065eee72c9d144..b5046f6313a91936a54d937eb24f5728ee585567 100644 (file)
@@ -182,6 +182,11 @@ struct wm8994_pdata {
         */
        int micdet_delay;
 
+       /* Delay between microphone detect completing and reporting on
+        * insert (specified in ms)
+        */
+       int mic_id_delay;
+
        /* IRQ for microphone detection if brought out directly as a
         * signal.
         */
index 5d046b1c5a7e8d2ec86c3e678022b3583fdd07ca..0f58f003dc1a50fade5105688e42b248c568092c 100644 (file)
@@ -3660,6 +3660,8 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
 
        pm_runtime_get_sync(codec->dev);
 
+       cancel_delayed_work_sync(&wm8994->mic_complete_work);
+
        mutex_lock(&wm8994->accdet_lock);
 
        reg = snd_soc_read(codec, WM1811_JACKDET_CTRL);
@@ -3842,11 +3844,33 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
 }
 EXPORT_SYMBOL_GPL(wm8958_mic_detect);
 
+static void wm8958_mic_work(struct work_struct *work)
+{
+       struct wm8994_priv *wm8994 = container_of(work,
+                                                 struct wm8994_priv,
+                                                 mic_complete_work.work);
+       struct snd_soc_codec *codec = wm8994->hubs.codec;
+
+       dev_crit(codec->dev, "MIC WORK %x\n", wm8994->mic_status);
+
+       pm_runtime_get_sync(codec->dev);
+
+       mutex_lock(&wm8994->accdet_lock);
+
+       wm8994->mic_id_cb(wm8994->mic_id_cb_data, wm8994->mic_status);
+
+       mutex_unlock(&wm8994->accdet_lock);
+
+       pm_runtime_put(codec->dev);
+
+       dev_crit(codec->dev, "MIC WORK %x DONE\n", wm8994->mic_status);
+}
+
 static irqreturn_t wm8958_mic_irq(int irq, void *data)
 {
        struct wm8994_priv *wm8994 = data;
        struct snd_soc_codec *codec = wm8994->hubs.codec;
-       int reg, count, ret;
+       int reg, count, ret, id_delay;
 
        /*
         * Jack detection may have detected a removal simulataneously
@@ -3856,6 +3880,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
        if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA))
                return IRQ_HANDLED;
 
+       cancel_delayed_work_sync(&wm8994->mic_complete_work);
        cancel_delayed_work_sync(&wm8994->open_circuit_work);
 
        pm_runtime_get_sync(codec->dev);
@@ -3904,8 +3929,12 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
                }
        }
 
+       wm8994->mic_status = reg;
+       id_delay = wm8994->wm8994->pdata.mic_id_delay;
+
        if (wm8994->mic_detecting)
-               wm8994->mic_id_cb(wm8994->mic_id_cb_data, reg);
+               schedule_delayed_work(&wm8994->mic_complete_work,
+                                     msecs_to_jiffies(id_delay));
        else
                wm8958_button_det(codec, reg);
 
@@ -3971,6 +4000,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
                break;
        }
 
+       INIT_DELAYED_WORK(&wm8994->mic_complete_work, wm8958_mic_work);
+
        for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
                init_completion(&wm8994->fll_locked[i]);
 
index 9d19a9185d352406484959b3a1bb440c922ec5b1..6536f8d45ac6bb0c4a13409582e299020bf0245d 100644 (file)
@@ -135,6 +135,8 @@ struct wm8994_priv {
        struct wm8994_micdet micdet[2];
        struct delayed_work mic_work;
        struct delayed_work open_circuit_work;
+       struct delayed_work mic_complete_work;
+       u16 mic_status;
        bool mic_detecting;
        bool jack_mic;
        int btn_mask;