Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: fsl_micfil: Add support for PLL switch at runtime

i.MX8MQ/MN/MM/MP platforms typically have 2 AUDIO PLLs being
configured to handle 8kHz and 11kHz series audio rates.

The patch implements the functionality to select at runtime
the appropriate AUDIO PLL as function of audio file rate.

Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Link: https://lore.kernel.org/r/1656667961-1799-4-git-send-email-shengjiu.wang@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Shengjiu Wang and committed by
Mark Brown
93f54100 34dcdebe

+32
+1
sound/soc/fsl/Kconfig
··· 81 81 select REGMAP_MMIO 82 82 select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n 83 83 select SND_SOC_GENERIC_DMAENGINE_PCM 84 + select SND_SOC_FSL_UTILS 84 85 help 85 86 Say Y if you want to add Pulse Density Modulation microphone 86 87 interface (MICFIL) support for NXP.
+31
sound/soc/fsl/fsl_micfil.c
··· 24 24 #include <sound/core.h> 25 25 26 26 #include "fsl_micfil.h" 27 + #include "fsl_utils.h" 27 28 28 29 #define MICFIL_OSR_DEFAULT 16 29 30 ··· 43 42 const struct fsl_micfil_soc_data *soc; 44 43 struct clk *busclk; 45 44 struct clk *mclk; 45 + struct clk *pll8k_clk; 46 + struct clk *pll11k_clk; 46 47 struct snd_dmaengine_dai_dma_data dma_params_rx; 47 48 struct sdma_peripheral_config sdmacfg; 48 49 unsigned int dataline; ··· 267 264 return 0; 268 265 } 269 266 267 + static int fsl_micfil_reparent_rootclk(struct fsl_micfil *micfil, unsigned int sample_rate) 268 + { 269 + struct device *dev = &micfil->pdev->dev; 270 + u64 ratio = sample_rate; 271 + struct clk *clk; 272 + int ret; 273 + 274 + /* Get root clock */ 275 + clk = micfil->mclk; 276 + 277 + /* Disable clock first, for it was enabled by pm_runtime */ 278 + clk_disable_unprepare(clk); 279 + fsl_asoc_reparent_pll_clocks(dev, clk, micfil->pll8k_clk, 280 + micfil->pll11k_clk, ratio); 281 + ret = clk_prepare_enable(clk); 282 + if (ret) 283 + return ret; 284 + 285 + return 0; 286 + } 287 + 270 288 static int fsl_micfil_hw_params(struct snd_pcm_substream *substream, 271 289 struct snd_pcm_hw_params *params, 272 290 struct snd_soc_dai *dai) ··· 308 284 /* enable channels */ 309 285 ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1, 310 286 0xFF, ((1 << channels) - 1)); 287 + if (ret) 288 + return ret; 289 + 290 + ret = fsl_micfil_reparent_rootclk(micfil, rate); 311 291 if (ret) 312 292 return ret; 313 293 ··· 618 590 PTR_ERR(micfil->busclk)); 619 591 return PTR_ERR(micfil->busclk); 620 592 } 593 + 594 + fsl_asoc_get_pll_clocks(&pdev->dev, &micfil->pll8k_clk, 595 + &micfil->pll11k_clk); 621 596 622 597 /* init regmap */ 623 598 regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);