2017-12-18 19:55 GMT+08:00 Charles Keepax ckeepax@opensource.cirrus.com:
On Mon, Dec 18, 2017 at 07:32:41PM +0800, chen liu wrote:
2017-12-18 17:31 GMT+08:00 Charles Keepax <ckeepax@opensource.cirrus.com :
On Fri, Dec 15, 2017 at 09:07:15PM +0800, chen liu wrote:
2017-12-15 0:19 GMT+08:00 Charles Keepax <
ckeepax@opensource.cirrus.com
:
On Wed, Dec 13, 2017 at 08:37:30PM +0800, Chen.Liu wrote:
According to your detailed description above, I understand what you mean. For the 'wm8960_configure_pll' function,it deduces a reasonable PLL
output
clock frequency based on the 'freq_in' frequency,the sample rate,and the
bit
clock.
static int wm8960_configure_clocking(struct snd_soc_codec*codec) ... freq_out = wm8960_configure_pll(codec, freq_in, &i, &j, &k); if (freq_out < 0) { dev_err(codec->dev, "failed to configure clock via
PLL\n");
return freq_out; } wm8960_set_pll(codec, freq_in, freq_out);
...
In the 'wm8960_configure_clocking' function, it sets the PLL divider by calling the 'wm8960_set_pll' function after calling the 'wm8960_configure_pll'. However,there is no support for SYSCLK_DIV = 2 in the 'wm8960_set_pll' function.
Looking forward to your reply.
Indeed yes, as it looks like the intention was you would set the SYSCLKDIV manually if setting the PLL manually. But why not just call wm8960_set_pll will WM8960_SYSCLK_AUTO, and then your code will use the configure_pll stuff?
I would like to understand what about that approach isn't working for you as that seems like the easiest solution.
Hi Charles,
Thanks for your reply.
For your question,i will explain in detail below.
First at all,we can not call the 'wm8960_set_pll' function directly in the machine driver,but we can call the 'wm8960_set_dai_pll' function with 'WM8960_SYSCLK_AUTO' as a parameter.
example: sample rate = 44100HZ, MCLK = 24MHZ, channel = 2;
In the Machine driver, we call 'snd_soc_dai_set_pll(codec_dai, WM8960_SYSCLK_AUTO, 0, 24000000, 0);' function to automatically configure the clock frequency.
When we playback the audio file,the ALSA middle layer will call the 'wm8960_hw_params' function to configure the hardware parameters and the clock frequency.At the bottom of this function it will call the 'wm8960_configure_clocking' function to configure the clock frequency.
static int wm8960_configure_clocking(struct snd_soc_codec *codec) ... freq_in = wm8960->freq_in; //Should be 24MHZ ... if (wm8960->clk_id == WM8960_SYSCLK_AUTO) { /* disable the PLL and using MCLK to provide sysclk */ wm8960_set_pll(codec, 0, 0); freq_out = freq_in; //should be 24MHZ } else if (wm8960->sysclk) { freq_out = wm8960->sysclk; } else { dev_err(codec->dev, "No SYSCLK configured\n"); return -EINVAL; } ... if (wm8960->clk_id != WM8960_SYSCLK_PLL) { // If the freq_out is 24MHZ,ret will be less than zero. ret = wm8960_configure_sysclk(wm8960, freq_out, &i, &j, &k); if (ret >= 0) { goto configure_clock; } else if (wm8960->clk_id != WM8960_SYSCLK_AUTO) { dev_err(codec->dev, "failed to configure clock\n"); return -EINVAL; } } // Then this branch will be executed. // If the sample rate is 44100HZ, the value of freq_out will be 11.2896MHZ freq_out = wm8960_configure_pll(codec, freq_in, &i, &j, &k); if (freq_out < 0) { dev_err(codec->dev, "failed to configure clock via PLL\n"); return freq_out; } // The 'wm8960_set_pll' function will be executed,this function is very important. // But now, the freq_in is 24MHZ and the freq_out is 11.2896MHZ. wm8960_set_pll(codec, freq_in, freq_out); ...
Because the 'wm8960_configure_pll' function has been pre-scaled by 2 for freq_out, but the value of freq_out is not multiplied by 2 in the 'pll_factors' function, it prints the "WM8960 PLL: Unsupported N =" error message.
Looking forward to your reply.
Thanks, Chen.