Message ID | 1656567554-32122-4-git-send-email-shengjiu.wang@nxp.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Add support of two Audio PLL source | expand |
On Thu, Jun 30, 2022 at 01:39:11PM +0800, Shengjiu Wang wrote: > +static int fsl_micfil_reparent_rootclk(struct fsl_micfil *micfil, unsigned int sample_rate) > +{ > + struct device *dev = &micfil->pdev->dev; > + u64 ratio = sample_rate; > + struct clk *clk; > + int ret; > + > + /* Reparent clock if required condition is true */ > + if (!micfil->pll8k_clk || !micfil->pll11k_clk) > + return 0; > + > + ratio = do_div(ratio, 8000) ? CLK_11K_FREQ : CLK_8K_FREQ; > + > + /* Get root clock */ > + clk = micfil->mclk; > + if (IS_ERR_OR_NULL(clk)) { > + dev_err(dev, "no mclk clock in devicetree\n"); > + return PTR_ERR(clk); > + } > + > + /* Disable clock first, for it was enabled by pm_runtime */ > + clk_disable_unprepare(clk); > + fsl_asoc_reparent_pll_clocks(dev, clk, micfil->pll8k_clk, > + micfil->pll11k_clk, ratio); > + ret = clk_prepare_enable(clk); > + if (ret) > + return ret; > + > + return 0; > +} Seems like more of this logic could be factored out into the reparent function if the target sample rate is passed in?
On Thu, Jun 30, 2022 at 6:37 PM Mark Brown <broonie@kernel.org> wrote: > On Thu, Jun 30, 2022 at 01:39:11PM +0800, Shengjiu Wang wrote: > > > +static int fsl_micfil_reparent_rootclk(struct fsl_micfil *micfil, > unsigned int sample_rate) > > +{ > > + struct device *dev = &micfil->pdev->dev; > > + u64 ratio = sample_rate; > > + struct clk *clk; > > + int ret; > > + > > + /* Reparent clock if required condition is true */ > > + if (!micfil->pll8k_clk || !micfil->pll11k_clk) > > + return 0; > > + > > + ratio = do_div(ratio, 8000) ? CLK_11K_FREQ : CLK_8K_FREQ; > > + > > + /* Get root clock */ > > + clk = micfil->mclk; > > + if (IS_ERR_OR_NULL(clk)) { > > + dev_err(dev, "no mclk clock in devicetree\n"); > > + return PTR_ERR(clk); > > + } > > + > > + /* Disable clock first, for it was enabled by pm_runtime */ > > + clk_disable_unprepare(clk); > > + fsl_asoc_reparent_pll_clocks(dev, clk, micfil->pll8k_clk, > > + micfil->pll11k_clk, ratio); > > + ret = clk_prepare_enable(clk); > > + if (ret) > > + return ret; > > + > > + return 0; > > +} > > Seems like more of this logic could be factored out into the reparent > function if the target sample rate is passed in? > Yes, let me update. Best regards Wang Shengjiu
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 910b8747b6bd..533937166b4a 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -81,6 +81,7 @@ config SND_SOC_FSL_MICFIL select REGMAP_MMIO select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n select SND_SOC_GENERIC_DMAENGINE_PCM + select SND_SOC_FSL_UTILS help Say Y if you want to add Pulse Density Modulation microphone interface (MICFIL) support for NXP. diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index 18ab80b68752..9b4baeb0f41d 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -24,6 +24,7 @@ #include <sound/core.h> #include "fsl_micfil.h" +#include "fsl_utils.h" #define MICFIL_OSR_DEFAULT 16 @@ -42,6 +43,8 @@ struct fsl_micfil { const struct fsl_micfil_soc_data *soc; struct clk *busclk; struct clk *mclk; + struct clk *pll8k_clk; + struct clk *pll11k_clk; struct snd_dmaengine_dai_dma_data dma_params_rx; struct sdma_peripheral_config sdmacfg; unsigned int dataline; @@ -283,6 +286,37 @@ static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd, return 0; } +static int fsl_micfil_reparent_rootclk(struct fsl_micfil *micfil, unsigned int sample_rate) +{ + struct device *dev = &micfil->pdev->dev; + u64 ratio = sample_rate; + struct clk *clk; + int ret; + + /* Reparent clock if required condition is true */ + if (!micfil->pll8k_clk || !micfil->pll11k_clk) + return 0; + + ratio = do_div(ratio, 8000) ? CLK_11K_FREQ : CLK_8K_FREQ; + + /* Get root clock */ + clk = micfil->mclk; + if (IS_ERR_OR_NULL(clk)) { + dev_err(dev, "no mclk clock in devicetree\n"); + return PTR_ERR(clk); + } + + /* Disable clock first, for it was enabled by pm_runtime */ + clk_disable_unprepare(clk); + fsl_asoc_reparent_pll_clocks(dev, clk, micfil->pll8k_clk, + micfil->pll11k_clk, ratio); + ret = clk_prepare_enable(clk); + if (ret) + return ret; + + return 0; +} + static int fsl_micfil_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -306,6 +340,10 @@ static int fsl_micfil_hw_params(struct snd_pcm_substream *substream, if (ret) return ret; + ret = fsl_micfil_reparent_rootclk(micfil, rate); + if (ret) + return ret; + ret = clk_set_rate(micfil->mclk, rate * clk_div * osr * 8); if (ret) return ret; @@ -610,6 +648,9 @@ static int fsl_micfil_probe(struct platform_device *pdev) return PTR_ERR(micfil->busclk); } + fsl_asoc_get_pll_clocks(&pdev->dev, &micfil->pll8k_clk, + &micfil->pll11k_clk); + /* init regmap */ regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(regs))