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 --- .../bindings/sound/mrvl,pxa-ssp.txt | 8 ++++++ sound/soc/pxa/pxa-ssp.c | 25 +++++++++++++++++++ 2 files changed, 33 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/mrvl,pxa-ssp.txt b/Documentation/devicetree/bindings/sound/mrvl,pxa-ssp.txt index efd3fb1f68d2..feef39b4a4fd 100644 --- a/Documentation/devicetree/bindings/sound/mrvl,pxa-ssp.txt +++ b/Documentation/devicetree/bindings/sound/mrvl,pxa-ssp.txt @@ -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 */ diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index f8339bb01251..c43fe3b9c79c 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -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); @@ -773,6 +789,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) {