|
@@ -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);
|