diff options
author | Nicolin Chen <b42378@freescale.com> | 2013-04-08 19:38:34 +0800 |
---|---|---|
committer | Nicolin Chen <b42378@freescale.com> | 2013-04-10 14:29:37 +0800 |
commit | 5e0d6ea2c2d36f3cd2f90a8ae37c5a3f0152dac1 (patch) | |
tree | 1c7180203f8d028e586a2fb1cfb25004ffdb48dd | |
parent | 9e7dff89053577fa016a974ccad6fac372ba15a5 (diff) |
ENGR00257755-1 Revert "ASoC: wm8962: Don't automatically enable and disable"
This reverts commit e2bd4d2117e1c78cfd487fb10848f3361b358057.
With this patch, WM8962 couldn't work normally after SabreSD power-on.
So revert it and find a better solution.
Acked-by: Wang Shengjiu <b02247@freescale.com>
Signed-off-by: Nicolin Chen <b42378@freescale.com>
-rw-r--r-- | sound/soc/codecs/wm8962.c | 65 |
1 files changed, 59 insertions, 6 deletions
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 3ec5cc7e06c4..4d0c69ab4a5f 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -2337,6 +2337,61 @@ SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5, 4, 1, 0, inmix_tlv), }; +static int sysclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); + unsigned long timeout; + int src; + int fll; + + src = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_SRC_MASK; + + switch (src) { + case 0: /* MCLK */ + fll = 0; + break; + case 0x200: /* FLL */ + fll = 1; + break; + default: + dev_err(codec->dev, "Unknown SYSCLK source %x\n", src); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (fll) { + try_wait_for_completion(&wm8962->fll_lock); + + snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, + WM8962_FLL_ENA, WM8962_FLL_ENA); + + timeout = msecs_to_jiffies(5); + timeout = wait_for_completion_timeout(&wm8962->fll_lock, + timeout); + + if (wm8962->irq && timeout == 0) + dev_err(codec->dev, + "Timed out starting FLL\n"); + } + break; + + case SND_SOC_DAPM_POST_PMD: + if (fll) + snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, + WM8962_FLL_ENA, 0); + break; + + default: + BUG(); + return -EINVAL; + } + + return 0; +} + static int cp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -2622,7 +2677,8 @@ SND_SOC_DAPM_INPUT("DMICDAT"), SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0), -SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event, SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0), @@ -3362,7 +3418,7 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, struct _fll_div fll_div = {0}; unsigned long timeout; int ret; - int fll1 = 0; + int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1) & WM8962_FLL_ENA; /* Any change? */ if (source == wm8962->fll_src && Fref == wm8962->fll_fref && @@ -3385,9 +3441,6 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, if (ret != 0) return ret; - /* Parameters good, disable so we can reprogram */ - snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0); - switch (fll_id) { case WM8962_FLL_MCLK: case WM8962_FLL_BCLK: @@ -3428,7 +3481,7 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK | - WM8962_FLL_ENA, fll1 | WM8962_FLL_ENA); + WM8962_FLL_ENA, fll1); fll1 |= WM8962_FLL_ENA; |