ASoC: davinci-mcasp: Support for fck reparenting
authorPeter Ujfalusi <peter.ujfalusi@ti.com>
Thu, 14 Nov 2013 09:35:35 +0000 (11:35 +0200)
committerMark Brown <broonie@linaro.org>
Tue, 10 Dec 2013 11:22:25 +0000 (11:22 +0000)
Optional DT property to specify the desired parent clock for the McASP fck
clock.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
sound/soc/davinci/davinci-mcasp.c

index 990fa71ce804a0b70ce13991d14fec86c374e2f0..569b26c4a81ee25e1f141329f90903dcb28ab4e4 100644 (file)
@@ -37,7 +37,8 @@ Optional properties:
 - pinctrl-0: Should specify pin control group used for this controller.
 - pinctrl-names: Should contain only one value - "default", for more details
                 please refer to pinctrl-bindings.txt
-  
+- fck_parent : Should contain a valid clock name which will be used as parent
+              for the McASP fck
 
 Example:
 
index 8ec8795484886d191fd48a4b5ecd466ac24c94e6..b7858bfa0295357bc5d3ca6d1328932595167b9e 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/clk.h>
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
@@ -823,6 +824,46 @@ static const struct of_device_id mcasp_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, mcasp_dt_ids);
 
+static int mcasp_reparent_fck(struct platform_device *pdev)
+{
+       struct device_node *node = pdev->dev.of_node;
+       struct clk *gfclk, *parent_clk;
+       const char *parent_name;
+       int ret;
+
+       if (!node)
+               return 0;
+
+       parent_name = of_get_property(node, "fck_parent", NULL);
+       if (!parent_name)
+               return 0;
+
+       gfclk = clk_get(&pdev->dev, "fck");
+       if (IS_ERR(gfclk)) {
+               dev_err(&pdev->dev, "failed to get fck\n");
+               return PTR_ERR(gfclk);
+       }
+
+       parent_clk = clk_get(NULL, parent_name);
+       if (IS_ERR(parent_clk)) {
+               dev_err(&pdev->dev, "failed to get parent clock\n");
+               ret = PTR_ERR(parent_clk);
+               goto err1;
+       }
+
+       ret = clk_set_parent(gfclk, parent_clk);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to reparent fck\n");
+               goto err2;
+       }
+
+err2:
+       clk_put(parent_clk);
+err1:
+       clk_put(gfclk);
+       return ret;
+}
+
 static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
                                                struct platform_device *pdev)
 {
@@ -1052,6 +1093,9 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
        mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].filter_data = "rx";
 
        dev_set_drvdata(&pdev->dev, mcasp);
+
+       mcasp_reparent_fck(pdev);
+
        ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component,
                                         &davinci_mcasp_dai[pdata->op_mode], 1);