[alsa-devel] [PATCH v2] ASOC: wm8960: Add multiple MCLK frequency support

chen liu chen.liu.opensource at gmail.com
Tue Dec 19 07:19:48 CET 2017


2017-12-18 19:55 GMT+08:00 Charles Keepax <ckeepax at 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 at 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 at 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.


More information about the Alsa-devel mailing list