]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ASoC: fsl_micfil: Add support for PLL switch at runtime
authorShengjiu Wang <shengjiu.wang@nxp.com>
Fri, 1 Jul 2022 09:32:38 +0000 (17:32 +0800)
committerMark Brown <broonie@kernel.org>
Tue, 5 Jul 2022 12:00:39 +0000 (13:00 +0100)
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>
sound/soc/fsl/Kconfig
sound/soc/fsl/fsl_micfil.c

index 910b8747b6bdfd934498a6fe8e00ffcec7503594..533937166b4af03588c64aa58d2a263d3f70a35a 100644 (file)
@@ -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.
index be9781ad884938e383de6febca692f86b57ba40a..79ef4e269bc95a3ef248f9da4af8503b9ef70dd6 100644 (file)
@@ -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;
@@ -264,6 +267,27 @@ 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;
+
+       /* Get root clock */
+       clk = micfil->mclk;
+
+       /* 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)
@@ -287,6 +311,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;
@@ -591,6 +619,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))