On 20 November 2019 15:24, Sebastian Reichel wrote: > This adds default clock/PLL configuration to the driver > for usage with generic drivers like simple-card for usage > with a fixed rate clock. > > Signed-off-by: Sebastian Reichel <sebastian.reichel@xxxxxxxxxxxxx> > --- > sound/soc/codecs/da7213.c | 75 > ++++++++++++++++++++++++++++++++++++--- > sound/soc/codecs/da7213.h | 2 ++ > 2 files changed, 73 insertions(+), 4 deletions(-) > > diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c > index 3e6ad996741b..ff1a936240be 100644 > --- a/sound/soc/codecs/da7213.c > +++ b/sound/soc/codecs/da7213.c > @@ -1156,6 +1156,7 @@ static int da7213_hw_params(struct > snd_pcm_substream *substream, > struct snd_soc_dai *dai) > { > struct snd_soc_component *component = dai->component; > + struct da7213_priv *da7213 = > snd_soc_component_get_drvdata(component); > u8 dai_ctrl = 0; > u8 fs; > > @@ -1181,33 +1182,43 @@ static int da7213_hw_params(struct > snd_pcm_substream *substream, > switch (params_rate(params)) { > case 8000: > fs = DA7213_SR_8000; > + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; > break; > case 11025: > fs = DA7213_SR_11025; > + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800; > break; > case 12000: > fs = DA7213_SR_12000; > + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; > break; > case 16000: > fs = DA7213_SR_16000; > + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; > break; > case 22050: > fs = DA7213_SR_22050; > + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800; > break; > case 32000: > fs = DA7213_SR_32000; > + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; > break; > case 44100: > fs = DA7213_SR_44100; > + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800; > break; > case 48000: > fs = DA7213_SR_48000; > + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; > break; > case 88200: > fs = DA7213_SR_88200; > + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800; > break; > case 96000: > fs = DA7213_SR_96000; > + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; > break; > default: > return -EINVAL; > @@ -1392,9 +1403,9 @@ static int da7213_set_component_sysclk(struct > snd_soc_component *component, > } > > /* Supported PLL input frequencies are 32KHz, 5MHz - 54MHz. */ > -static int da7213_set_component_pll(struct snd_soc_component *component, > - int pll_id, int source, > - unsigned int fref, unsigned int fout) > +static int _da7213_set_component_pll(struct snd_soc_component > *component, > + int pll_id, int source, > + unsigned int fref, unsigned int fout) > { > struct da7213_priv *da7213 = > snd_soc_component_get_drvdata(component); > > @@ -1503,6 +1514,16 @@ static int da7213_set_component_pll(struct > snd_soc_component *component, > return 0; > } > > +static int da7213_set_component_pll(struct snd_soc_component *component, > + int pll_id, int source, > + unsigned int fref, unsigned int fout) > +{ > + struct da7213_priv *da7213 = > snd_soc_component_get_drvdata(component); > + da7213->fixed_clk_auto_pll = false; > + > + return _da7213_set_component_pll(component, pll_id, source, fref, > fout); > +} > + > /* DAI operations */ > static const struct snd_soc_dai_ops da7213_dai_ops = { > .hw_params = da7213_hw_params, > @@ -1532,6 +1553,43 @@ static struct snd_soc_dai_driver da7213_dai = { > .symmetric_rates = 1, > }; > > +static int da7213_set_auto_pll(struct snd_soc_component *component, bool > enable) > +{ > + struct da7213_priv *da7213 = > snd_soc_component_get_drvdata(component); > + int mode; > + > + if (!da7213->fixed_clk_auto_pll) > + return 0; > + > + da7213->mclk_rate = clk_get_rate(da7213->mclk); > + > + if (enable) > + mode = DA7213_SYSCLK_PLL; > + else > + mode = DA7213_SYSCLK_MCLK; If we're the clock slave, and we're using an MCLK that's not a harmonic then SRM is required to synchronise the PLL to the incoming WCLK signal. I assume simple sound card should allow for both master and slave modes? If so we'll need to do something here to determine this as well. > + > + switch (da7213->out_rate) { > + case DA7213_PLL_FREQ_OUT_90316800: > + if (da7213->mclk_rate == 11289600 || > + da7213->mclk_rate == 22579200 || > + da7213->mclk_rate == 45158400) > + mode = DA7213_SYSCLK_MCLK; > + break; > + case DA7213_PLL_FREQ_OUT_98304000: > + if (da7213->mclk_rate == 12288000 || > + da7213->mclk_rate == 24576000 || > + da7213->mclk_rate == 49152000) > + mode = DA7213_SYSCLK_MCLK; > + > + break; > + default: > + return -1; > + } > + > + return _da7213_set_component_pll(component, 0, mode, > + da7213->mclk_rate, da7213->out_rate); > +} > + > static int da7213_set_bias_level(struct snd_soc_component *component, > enum snd_soc_bias_level level) > { > @@ -1551,6 +1609,8 @@ static int da7213_set_bias_level(struct > snd_soc_component *component, > "Failed to enable mclk\n"); > return ret; > } > + > + da7213_set_auto_pll(component, true); I've thought more about this and for the scenario where a machine driver controls the PLL through a DAPM widget associated with this codec (like some Intel boards do), then the PLL will be configured once here and then again when the relevant widget is called. I don't think that will matter but I will take a further look just in case this might cause some oddities. > } > } > break; > @@ -1562,8 +1622,10 @@ static int da7213_set_bias_level(struct > snd_soc_component *component, > DA7213_VMID_EN | DA7213_BIAS_EN); > } else { > /* Remove MCLK */ > - if (da7213->mclk) > + if (da7213->mclk) { > + da7213_set_auto_pll(component, false); > clk_disable_unprepare(da7213->mclk); > + } > } > break; > case SND_SOC_BIAS_OFF: > @@ -1829,6 +1891,11 @@ static int da7213_probe(struct snd_soc_component > *component) > return PTR_ERR(da7213->mclk); > else > da7213->mclk = NULL; > + } else { > + /* Do automatic PLL handling assuming fixed clock until > + * set_pll() has been called. This makes the codec usable > + * with the simple-audio-card driver. */ > + da7213->fixed_clk_auto_pll = true; > } > > return 0; > diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h > index 3890829dfb6e..97ccf0ddd2be 100644 > --- a/sound/soc/codecs/da7213.h > +++ b/sound/soc/codecs/da7213.h > @@ -535,10 +535,12 @@ struct da7213_priv { > struct regulator_bulk_data supplies[DA7213_NUM_SUPPLIES]; > struct clk *mclk; > unsigned int mclk_rate; > + unsigned int out_rate; > int clk_src; > bool master; > bool alc_calib_auto; > bool alc_en; > + bool fixed_clk_auto_pll; > struct da7213_platform_data *pdata; > }; > > -- > 2.24.0 _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx https://mailman.alsa-project.org/mailman/listinfo/alsa-devel