ASoC: Check that WM8996 FLL started even if we don't have the IRQ
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Sun, 4 Sep 2011 16:35:47 +0000 (09:35 -0700)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Tue, 6 Sep 2011 01:14:04 +0000 (18:14 -0700)
We can directly read the FLL lock status on WM8996 so even if we don't
have an interrupt wired up we can still verify that the FLL started
successfully.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@ti.com>
sound/soc/codecs/wm8996.c

index e5e46075c3651fa0c680a9c094d0fcc48fda67f0..e386d25aba820dd22e083d3b2fec3d454d6b64ec 100644 (file)
@@ -2054,7 +2054,7 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
        struct i2c_client *i2c = to_i2c_client(codec->dev);
        struct _fll_div fll_div;
        unsigned long timeout;
-       int ret, reg;
+       int ret, reg, retry;
 
        /* Any change? */
        if (source == wm8996->fll_src && Fref == wm8996->fll_fref &&
@@ -2141,17 +2141,29 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
        else
                timeout = msecs_to_jiffies(2);
 
-       /* Allow substantially longer if we've actually got the IRQ */
+       /* Allow substantially longer if we've actually got the IRQ, poll
+        * at a slightly higher rate if we don't.
+        */
        if (i2c->irq)
-               timeout *= 1000;
+               timeout *= 10;
+       else
+               timeout /= 2;
 
-       ret = wait_for_completion_timeout(&wm8996->fll_lock, timeout);
+       for (retry = 0; retry < 10; retry++) {
+               ret = wait_for_completion_timeout(&wm8996->fll_lock,
+                                                 timeout);
+               if (ret != 0) {
+                       WARN_ON(!i2c->irq);
+                       break;
+               }
 
-       if (ret == 0 && i2c->irq) {
+               ret = snd_soc_read(codec, WM8996_INTERRUPT_RAW_STATUS_2);
+               if (ret & WM8996_FLL_LOCK_STS)
+                       break;
+       }
+       if (retry == 10) {
                dev_err(codec->dev, "Timed out waiting for FLL\n");
                ret = -ETIMEDOUT;
-       } else {
-               ret = 0;
        }
 
        dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);