ASoC: fsl_sai: Add clock controls for SAI
[deliverable/linux.git] / sound / soc / fsl / fsl_sai.c
index dde084273c6422ace0a607b6567f28141a7dbf8d..1c93282fbd2696a9475499ee7e4b0d51ddb0f615 100644 (file)
@@ -427,7 +427,15 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
                struct snd_soc_dai *cpu_dai)
 {
        struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
+       struct device *dev = &sai->pdev->dev;
        u32 reg;
+       int ret;
+
+       ret = clk_prepare_enable(sai->bus_clk);
+       if (ret) {
+               dev_err(dev, "failed to enable bus clock: %d\n", ret);
+               return ret;
+       }
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                reg = FSL_SAI_TCR3;
@@ -453,6 +461,8 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
 
        regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE,
                           ~FSL_SAI_CR3_TRCE);
+
+       clk_disable_unprepare(sai->bus_clk);
 }
 
 static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
@@ -585,7 +595,8 @@ static int fsl_sai_probe(struct platform_device *pdev)
        struct fsl_sai *sai;
        struct resource *res;
        void __iomem *base;
-       int irq, ret;
+       char tmp[8];
+       int irq, ret, i;
 
        sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
        if (!sai)
@@ -608,12 +619,35 @@ static int fsl_sai_probe(struct platform_device *pdev)
                return PTR_ERR(base);
 
        sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
-                       "sai", base, &fsl_sai_regmap_config);
+                       "bus", base, &fsl_sai_regmap_config);
+
+       /* Compatible with old DTB cases */
+       if (IS_ERR(sai->regmap))
+               sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
+                               "sai", base, &fsl_sai_regmap_config);
        if (IS_ERR(sai->regmap)) {
                dev_err(&pdev->dev, "regmap init failed\n");
                return PTR_ERR(sai->regmap);
        }
 
+       /* No error out for old DTB cases but only mark the clock NULL */
+       sai->bus_clk = devm_clk_get(&pdev->dev, "bus");
+       if (IS_ERR(sai->bus_clk)) {
+               dev_err(&pdev->dev, "failed to get bus clock: %ld\n",
+                               PTR_ERR(sai->bus_clk));
+               sai->bus_clk = NULL;
+       }
+
+       for (i = 0; i < FSL_SAI_MCLK_MAX; i++) {
+               sprintf(tmp, "mclk%d", i + 1);
+               sai->mclk_clk[i] = devm_clk_get(&pdev->dev, tmp);
+               if (IS_ERR(sai->mclk_clk[i])) {
+                       dev_err(&pdev->dev, "failed to get mclk%d clock: %ld\n",
+                                       i + 1, PTR_ERR(sai->mclk_clk[i]));
+                       sai->mclk_clk[i] = NULL;
+               }
+       }
+
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
                dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
This page took 0.026669 seconds and 5 git commands to generate.