aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@freescale.com>2015-11-24 04:19:33 -0500
committerMark Brown <broonie@kernel.org>2015-11-25 07:14:22 -0500
commit0bc5680af8c436d292797d58991b83bca570d079 (patch)
tree05b8df8b94f2dbe025ab8ff404d888d8b3d99c10
parent8005c49d9aea74d382f474ce11afbbc7d7130bec (diff)
ASoC: fsl_spdif: spba clk is needed by spdif device
SPDIF need to enable the spba clock, when sdma is using share peripheral script. In this case, there is two spba master port is used, if don't enable the clock, the spba bus will have arbitration issue, which may cause read/write wrong data from/to SPDIF registers. Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com> Acked-by: Nicolin Chen <nicoleotsuka@gmail.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,spdif.txt5
-rw-r--r--sound/soc/fsl/fsl_spdif.c19
2 files changed, 24 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/sound/fsl,spdif.txt b/Documentation/devicetree/bindings/sound/fsl,spdif.txt
index b5ee32ee3706..4ca39ddc0417 100644
--- a/Documentation/devicetree/bindings/sound/fsl,spdif.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,spdif.txt
@@ -27,6 +27,11 @@ Required properties:
27 Transceiver Clock Diagram" of SoC reference manual. 27 Transceiver Clock Diagram" of SoC reference manual.
28 It can also be referred to TxClk_Source bit of 28 It can also be referred to TxClk_Source bit of
29 register SPDIF_STC. 29 register SPDIF_STC.
30 "spba" The spba clock is required when SPDIF is placed as a
31 bus slave of the Shared Peripheral Bus and when two
32 or more bus masters (CPU, DMA or DSP) try to access
33 it. This property is optional depending on the SoC
34 design.
30 35
31 - big-endian : If this property is absent, the native endian mode 36 - big-endian : If this property is absent, the native endian mode
32 will be in use as default, or the big endian mode 37 will be in use as default, or the big endian mode
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 3d59bb6719f2..fa36e6753799 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -88,6 +88,7 @@ struct spdif_mixer_control {
88 * @rxclk: rx clock sources for capture 88 * @rxclk: rx clock sources for capture
89 * @coreclk: core clock for register access via DMA 89 * @coreclk: core clock for register access via DMA
90 * @sysclk: system clock for rx clock rate measurement 90 * @sysclk: system clock for rx clock rate measurement
91 * @spbaclk: SPBA clock (optional, depending on SoC design)
91 * @dma_params_tx: DMA parameters for transmit channel 92 * @dma_params_tx: DMA parameters for transmit channel
92 * @dma_params_rx: DMA parameters for receive channel 93 * @dma_params_rx: DMA parameters for receive channel
93 */ 94 */
@@ -106,6 +107,7 @@ struct fsl_spdif_priv {
106 struct clk *rxclk; 107 struct clk *rxclk;
107 struct clk *coreclk; 108 struct clk *coreclk;
108 struct clk *sysclk; 109 struct clk *sysclk;
110 struct clk *spbaclk;
109 struct snd_dmaengine_dai_dma_data dma_params_tx; 111 struct snd_dmaengine_dai_dma_data dma_params_tx;
110 struct snd_dmaengine_dai_dma_data dma_params_rx; 112 struct snd_dmaengine_dai_dma_data dma_params_rx;
111 /* regcache for SRPC */ 113 /* regcache for SRPC */
@@ -474,6 +476,14 @@ static int fsl_spdif_startup(struct snd_pcm_substream *substream,
474 return ret; 476 return ret;
475 } 477 }
476 478
479 if (!IS_ERR(spdif_priv->spbaclk)) {
480 ret = clk_prepare_enable(spdif_priv->spbaclk);
481 if (ret) {
482 dev_err(&pdev->dev, "failed to enable spba clock\n");
483 goto err_spbaclk;
484 }
485 }
486
477 ret = spdif_softreset(spdif_priv); 487 ret = spdif_softreset(spdif_priv);
478 if (ret) { 488 if (ret) {
479 dev_err(&pdev->dev, "failed to soft reset\n"); 489 dev_err(&pdev->dev, "failed to soft reset\n");
@@ -515,6 +525,9 @@ disable_txclk:
515 for (i--; i >= 0; i--) 525 for (i--; i >= 0; i--)
516 clk_disable_unprepare(spdif_priv->txclk[i]); 526 clk_disable_unprepare(spdif_priv->txclk[i]);
517err: 527err:
528 if (!IS_ERR(spdif_priv->spbaclk))
529 clk_disable_unprepare(spdif_priv->spbaclk);
530err_spbaclk:
518 clk_disable_unprepare(spdif_priv->coreclk); 531 clk_disable_unprepare(spdif_priv->coreclk);
519 532
520 return ret; 533 return ret;
@@ -548,6 +561,8 @@ static void fsl_spdif_shutdown(struct snd_pcm_substream *substream,
548 spdif_intr_status_clear(spdif_priv); 561 spdif_intr_status_clear(spdif_priv);
549 regmap_update_bits(regmap, REG_SPDIF_SCR, 562 regmap_update_bits(regmap, REG_SPDIF_SCR,
550 SCR_LOW_POWER, SCR_LOW_POWER); 563 SCR_LOW_POWER, SCR_LOW_POWER);
564 if (!IS_ERR(spdif_priv->spbaclk))
565 clk_disable_unprepare(spdif_priv->spbaclk);
551 clk_disable_unprepare(spdif_priv->coreclk); 566 clk_disable_unprepare(spdif_priv->coreclk);
552 } 567 }
553} 568}
@@ -1261,6 +1276,10 @@ static int fsl_spdif_probe(struct platform_device *pdev)
1261 return PTR_ERR(spdif_priv->coreclk); 1276 return PTR_ERR(spdif_priv->coreclk);
1262 } 1277 }
1263 1278
1279 spdif_priv->spbaclk = devm_clk_get(&pdev->dev, "spba");
1280 if (IS_ERR(spdif_priv->spbaclk))
1281 dev_warn(&pdev->dev, "no spba clock in devicetree\n");
1282
1264 /* Select clock source for rx/tx clock */ 1283 /* Select clock source for rx/tx clock */
1265 spdif_priv->rxclk = devm_clk_get(&pdev->dev, "rxtx1"); 1284 spdif_priv->rxclk = devm_clk_get(&pdev->dev, "rxtx1");
1266 if (IS_ERR(spdif_priv->rxclk)) { 1285 if (IS_ERR(spdif_priv->rxclk)) {