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 --- sound/soc/codecs/wm8996.c | 26 +++++++++++++++++++------- 1 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 169a865..cbd0206 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -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);