diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-06-07 18:16:29 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-06-08 10:24:47 -0400 |
commit | 649a1a0ef28e5db99e838060f415a111566c63ea (patch) | |
tree | 9d12ae4bde566069c12c90b46508e075fe7c2fde /sound/soc/codecs/wm8962.c | |
parent | c7356da9e2ede4a89d000bde8a8a4408890943b9 (diff) |
ASoC: Report errors when we have a WM8962 IRQ and don't get FLL lock
We really should be getting the interrupt - if we don't get one it's very
likely that the configuration is incorrect and audio will fail. Also
increase the timeout substantially in this case for safety.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@ti.com>
Diffstat (limited to 'sound/soc/codecs/wm8962.c')
-rw-r--r-- | sound/soc/codecs/wm8962.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index b0cb4368d1b4..8493e336b3cd 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -2186,6 +2186,8 @@ static int sysclk_event(struct snd_soc_dapm_widget *w, | |||
2186 | struct snd_kcontrol *kcontrol, int event) | 2186 | struct snd_kcontrol *kcontrol, int event) |
2187 | { | 2187 | { |
2188 | struct snd_soc_codec *codec = w->codec; | 2188 | struct snd_soc_codec *codec = w->codec; |
2189 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | ||
2190 | unsigned long timeout; | ||
2189 | int src; | 2191 | int src; |
2190 | int fll; | 2192 | int fll; |
2191 | 2193 | ||
@@ -2205,9 +2207,19 @@ static int sysclk_event(struct snd_soc_dapm_widget *w, | |||
2205 | 2207 | ||
2206 | switch (event) { | 2208 | switch (event) { |
2207 | case SND_SOC_DAPM_PRE_PMU: | 2209 | case SND_SOC_DAPM_PRE_PMU: |
2208 | if (fll) | 2210 | if (fll) { |
2209 | snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, | 2211 | snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, |
2210 | WM8962_FLL_ENA, WM8962_FLL_ENA); | 2212 | WM8962_FLL_ENA, WM8962_FLL_ENA); |
2213 | if (wm8962->irq) { | ||
2214 | timeout = msecs_to_jiffies(5); | ||
2215 | timeout = wait_for_completion_timeout(&wm8962->fll_lock, | ||
2216 | timeout); | ||
2217 | |||
2218 | if (timeout == 0) | ||
2219 | dev_err(codec->dev, | ||
2220 | "Timed out starting FLL\n"); | ||
2221 | } | ||
2222 | } | ||
2211 | break; | 2223 | break; |
2212 | 2224 | ||
2213 | case SND_SOC_DAPM_POST_PMD: | 2225 | case SND_SOC_DAPM_POST_PMD: |
@@ -3263,16 +3275,31 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
3263 | 3275 | ||
3264 | dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); | 3276 | dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); |
3265 | 3277 | ||
3266 | /* This should be a massive overestimate */ | 3278 | ret = 0; |
3267 | timeout = msecs_to_jiffies(1); | 3279 | |
3280 | if (fll1 & WM8962_FLL_ENA) { | ||
3281 | /* This should be a massive overestimate but go even | ||
3282 | * higher if we'll error out | ||
3283 | */ | ||
3284 | if (wm8962->irq) | ||
3285 | timeout = msecs_to_jiffies(5); | ||
3286 | else | ||
3287 | timeout = msecs_to_jiffies(1); | ||
3288 | |||
3289 | timeout = wait_for_completion_timeout(&wm8962->fll_lock, | ||
3290 | timeout); | ||
3268 | 3291 | ||
3269 | wait_for_completion_timeout(&wm8962->fll_lock, timeout); | 3292 | if (timeout == 0 && wm8962->irq) { |
3293 | dev_err(codec->dev, "FLL lock timed out"); | ||
3294 | ret = -ETIMEDOUT; | ||
3295 | } | ||
3296 | } | ||
3270 | 3297 | ||
3271 | wm8962->fll_fref = Fref; | 3298 | wm8962->fll_fref = Fref; |
3272 | wm8962->fll_fout = Fout; | 3299 | wm8962->fll_fout = Fout; |
3273 | wm8962->fll_src = source; | 3300 | wm8962->fll_src = source; |
3274 | 3301 | ||
3275 | return 0; | 3302 | return ret; |
3276 | } | 3303 | } |
3277 | 3304 | ||
3278 | static int wm8962_mute(struct snd_soc_dai *dai, int mute) | 3305 | static int wm8962_mute(struct snd_soc_dai *dai, int mute) |