Unverified Commit 945c7683 authored by Mark Brown's avatar Mark Brown
Browse files

Add support of two Audio PLL source

Merge series from Shengjiu Wang <shengjiu.wang@nxp.com>:

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

The patches implement the functionality to select at runtime
the appropriate AUDIO PLL for root clock, if there is no
two PLL registered, then no action taken.
parents 65b6851d 6c06ad34
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -58,6 +58,8 @@ properties:
          slave of the Shared Peripheral Bus and when two or more bus masters
          (CPU, DMA or DSP) try to access it. This property is optional depending
          on the SoC design.
      - description: PLL clock source for 8kHz series rate, optional.
      - description: PLL clock source for 11khz series rate, optional.
    minItems: 9

  clock-names:
@@ -72,6 +74,8 @@ properties:
      - const: rxtx6
      - const: rxtx7
      - const: spba
      - const: pll8k
      - const: pll11k
    minItems: 9

  big-endian:
+3 −0
Original line number Diff line number Diff line
@@ -21,6 +21,9 @@ Required properties:
  - clock-names		: Must include the "bus" for register access and
			  "mclk1", "mclk2", "mclk3" for bit clock and frame
			  clock providing.
                          "pll8k", "pll11k" are optional, they are the clock
                          source for root clock, one is for 8kHz series rates
                          another one is for 11kHz series rates.
  - dmas		: Generic dma devicetree binding as described in
			  Documentation/devicetree/bindings/dma/dma.txt.

+3 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ config SND_SOC_FSL_SAI
	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 Synchronous Audio Interface (SAI)
	  support for the Freescale CPUs.
@@ -59,6 +60,7 @@ config SND_SOC_FSL_SPDIF
	select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
	select SND_SOC_IMX_PCM_FIQ if SND_IMX_SOC != n && (MXC_TZIC || MXC_AVIC)
	select BITREVERSE
	select SND_SOC_FSL_UTILS
	help
	  Say Y if you want to add Sony/Philips Digital Interface (SPDIF)
	  support for the Freescale CPUs.
@@ -80,6 +82,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.
+31 −0
Original line number Diff line number Diff line
@@ -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))
+38 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>

#include "fsl_sai.h"
#include "fsl_utils.h"
#include "imx-pcm.h"

#define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\
@@ -220,14 +221,48 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
	return 0;
}

static int fsl_sai_set_mclk_rate(struct snd_soc_dai *dai, int clk_id, unsigned int freq)
{
	struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
	int ret;

	fsl_asoc_reparent_pll_clocks(dai->dev, sai->mclk_clk[clk_id],
				     sai->pll8k_clk, sai->pll11k_clk, freq);

	ret = clk_set_rate(sai->mclk_clk[clk_id], freq);
	if (ret < 0)
		dev_err(dai->dev, "failed to set clock rate (%u): %d\n", freq, ret);

	return ret;
}

static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
		int clk_id, unsigned int freq, int dir)
{
	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
	int ret;

	if (dir == SND_SOC_CLOCK_IN)
		return 0;

	if (freq > 0 && clk_id != FSL_SAI_CLK_BUS) {
		if (clk_id < 0 || clk_id >= FSL_SAI_MCLK_MAX) {
			dev_err(cpu_dai->dev, "Unknown clock id: %d\n", clk_id);
			return -EINVAL;
		}

		if (IS_ERR_OR_NULL(sai->mclk_clk[clk_id])) {
			dev_err(cpu_dai->dev, "Unassigned clock: %d\n", clk_id);
			return -EINVAL;
		}

		if (sai->mclk_streams == 0) {
			ret = fsl_sai_set_mclk_rate(cpu_dai, clk_id, freq);
			if (ret < 0)
				return ret;
		}
	}

	ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, true);
	if (ret) {
		dev_err(cpu_dai->dev, "Cannot set tx sysclk: %d\n", ret);
@@ -1281,6 +1316,9 @@ static int fsl_sai_probe(struct platform_device *pdev)
	else
		sai->mclk_clk[0] = sai->bus_clk;

	fsl_asoc_get_pll_clocks(&pdev->dev, &sai->pll8k_clk,
				&sai->pll11k_clk);

	/* read dataline mask for rx and tx*/
	ret = fsl_sai_read_dlcfg(sai);
	if (ret < 0) {
Loading