[alsa-devel] [PATCH] ASoC: wm8962: Enable SYSCLK provisonally before fetching generated DSPCLK_DIV
DSPCLK_DIV can be only generated correctly after enabling SYSCLK. But if the current bias_level hasn't reached SND_SOC_BIAS_ON, DAPM won't enable SYSCLK, which would cause the calculation result from DSPCLK_DIV invalid since bit DSPCLK_DIV will be finally turned to its true value after DAPM enables SYSCLK while the driver won't calculate it again for the current instance. In this circumstance, a playback which needs non-zero DSPCLK_DIV would be distorted due to unexpected clock frequency resulted from an invalid DSPCLK_DIV value.
So this patch provisionally enables the SYSCLK to get a valid DSPCLK_DIV for calculation and then disables it afterward.
Signed-off-by: Nicolin Chen b42378@freescale.com --- sound/soc/codecs/wm8962.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 07da601..97db3b4 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -2439,7 +2439,20 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM8962_CLOCKING_4, WM8962_SYSCLK_RATE_MASK, clocking4);
+ /* DSPCLK_DIV can be only generated correctly after enabling SYSCLK. + * So we here provisionally enable it and then disable it afterward + * if current bias_level hasn't reached SND_SOC_BIAS_ON. + */ + if (codec->dapm.bias_level != SND_SOC_BIAS_ON) + snd_soc_update_bits(codec, WM8962_CLOCKING2, + WM8962_SYSCLK_ENA_MASK, WM8962_SYSCLK_ENA); + dspclk = snd_soc_read(codec, WM8962_CLOCKING1); + + if (codec->dapm.bias_level != SND_SOC_BIAS_ON) + snd_soc_update_bits(codec, WM8962_CLOCKING2, + WM8962_SYSCLK_ENA_MASK, 0); + if (dspclk < 0) { dev_err(codec->dev, "Failed to read DSPCLK: %d\n", dspclk); return;
On Wed, Dec 04, 2013 at 05:22:16PM +0800, Nicolin Chen wrote:
DSPCLK_DIV can be only generated correctly after enabling SYSCLK. But if the current bias_level hasn't reached SND_SOC_BIAS_ON, DAPM won't enable SYSCLK, which would cause the calculation result from DSPCLK_DIV invalid since bit DSPCLK_DIV will be finally turned to its true value after DAPM enables SYSCLK while the driver won't calculate it again for the current instance. In this circumstance, a playback which needs non-zero DSPCLK_DIV would be distorted due to unexpected clock frequency resulted from an invalid DSPCLK_DIV value.
So this patch provisionally enables the SYSCLK to get a valid DSPCLK_DIV for calculation and then disables it afterward.
Acked-by: Charles Keepax ckeepax@opensource.wolfsonmicro.com
It feels like there should be a neater way to handle this, but I can't really see what that might be right now. So I think this looks fine for now and hopefully I can find some time to look at it in more detail soon.
Thanks, Charles
On Thu, Dec 05, 2013 at 02:14:21PM +0000, Charles Keepax wrote:
On Wed, Dec 04, 2013 at 05:22:16PM +0800, Nicolin Chen wrote:
DSPCLK_DIV can be only generated correctly after enabling SYSCLK. But if the current bias_level hasn't reached SND_SOC_BIAS_ON, DAPM won't enable SYSCLK, which would cause the calculation result from DSPCLK_DIV invalid since bit DSPCLK_DIV will be finally turned to its true value after DAPM enables SYSCLK while the driver won't calculate it again for the current instance. In this circumstance, a playback which needs non-zero DSPCLK_DIV would be distorted due to unexpected clock frequency resulted from an invalid DSPCLK_DIV value.
So this patch provisionally enables the SYSCLK to get a valid DSPCLK_DIV for calculation and then disables it afterward.
Acked-by: Charles Keepax ckeepax@opensource.wolfsonmicro.com
It feels like there should be a neater way to handle this, but I can't really see what that might be right now. So I think this looks fine for now and hopefully I can find some time to look at it in more detail soon.
Thanks Charles,
And I was preparing a patch for SSI and met a similar problem, after a few reconsideration, I'm wondering if it's better to save the value of SYSCLK_ENA and apply it after getting DSPCLK_DIV.
By doing this we can no more reply on bias_level, which looks more safer.
Best regards, Nicolin Chen
On Wed, Dec 04, 2013 at 05:22:16PM +0800, Nicolin Chen wrote:
DSPCLK_DIV can be only generated correctly after enabling SYSCLK. But if the current bias_level hasn't reached SND_SOC_BIAS_ON, DAPM won't enable SYSCLK, which would cause the calculation result from DSPCLK_DIV invalid since bit DSPCLK_DIV will be finally turned to its true value after DAPM enables SYSCLK while the driver won't calculate it again for the current instance. In this circumstance, a playback which needs non-zero DSPCLK_DIV would be distorted due to unexpected clock frequency resulted from an invalid DSPCLK_DIV value.
Applied, thanks.
participants (3)
-
Charles Keepax
-
Mark Brown
-
Nicolin Chen