ASoC: pxa-ssp: add support for an external clock in devicetree
authorDaniel Mack <daniel@zonque.org>
Mon, 2 Jul 2018 15:11:00 +0000 (17:11 +0200)
committerMark Brown <broonie@kernel.org>
Thu, 5 Jul 2018 10:08:08 +0000 (11:08 +0100)
Allow setting a clock called 'extclk' in the device of the ssp-dai
device. If specified, this clock will be set to the mclk rate from the
DAI's .set_sysclk() callback. The DAI will also configure itself to
use that external clock.

Signed-off-by: Daniel Mack <daniel@zonque.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
Documentation/devicetree/bindings/sound/mrvl,pxa-ssp.txt
sound/soc/pxa/pxa-ssp.c

index 74c9ba6c2823d9d1dc0704bc7338f8b3414e2eca..93b982e9419fd9c6bdadd361c9266efb24f95422 100644 (file)
@@ -5,6 +5,14 @@ Required properties:
        compatible      Must be "mrvl,pxa-ssp-dai"
        port            A phandle reference to a PXA ssp upstream device
 
+Optional properties:
+
+       clock-names
+       clocks          Through "clock-names" and "clocks", external clocks
+                       can be configured. If a clock names "extclk" exists,
+                       it will be set to the mclk rate of the audio stream
+                       and be used as clock provider of the DAI.
+
 Example:
 
        /* upstream device */
index ff1e0bd8d407a4985c8c7968d24e097bd85340bb..69033e1a84e6ad52ef7c01b395af3a8f48a91c15 100644 (file)
@@ -41,6 +41,7 @@
  */
 struct ssp_priv {
        struct ssp_device *ssp;
+       struct clk *extclk;
        unsigned long ssp_clk;
        unsigned int sysclk;
        unsigned int dai_fmt;
@@ -205,6 +206,21 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
        u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
                ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
 
+       if (priv->extclk) {
+               int ret;
+
+               /*
+                * For DT based boards, if an extclk is given, use it
+                * here and configure PXA_SSP_CLK_EXT.
+                */
+
+               ret = clk_set_rate(priv->extclk, freq);
+               if (ret < 0)
+                       return ret;
+
+               clk_id = PXA_SSP_CLK_EXT;
+       }
+
        dev_dbg(&ssp->pdev->dev,
                "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %u\n",
                cpu_dai->id, clk_id, freq);
@@ -774,6 +790,15 @@ static int pxa_ssp_probe(struct snd_soc_dai *dai)
                        ret = -ENODEV;
                        goto err_priv;
                }
+
+               priv->extclk = devm_clk_get(dev, "extclk");
+               if (IS_ERR(priv->extclk)) {
+                       ret = PTR_ERR(priv->extclk);
+                       if (ret == -EPROBE_DEFER)
+                               return ret;
+
+                       priv->extclk = NULL;
+               }
        } else {
                priv->ssp = pxa_ssp_request(dai->id + 1, "SoC audio");
                if (priv->ssp == NULL) {