diff options
Diffstat (limited to 'sound/soc/fsl/fsl_sai.c')
-rw-r--r-- | sound/soc/fsl/fsl_sai.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index a0ddaf7e9f60..974ba0780b19 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -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) { |