aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolin Chen <Guangyu.Chen@freescale.com>2014-04-24 06:52:24 -0400
committerMark Brown <broonie@linaro.org>2014-04-24 08:11:16 -0400
commit08f7336e6404698158966d0c8a2937d3580e2693 (patch)
treec753ef45a3500322af5f625c71e6915adab7e26c
parentc9eaa447e77efe77b7fa4c953bd62de8297fd6c5 (diff)
ASoC: fsl_spdif: Add core clock control for DMA access
Regmap is able to enable/disable the core clock automatically each time it's going to access the registers. But for DMA cases during playback or recording, it's totally beyong control of regmap. So we have to open the clock manually. Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--sound/soc/fsl/fsl_spdif.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 6452ca83d889..ebddddcd55f8 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -80,6 +80,7 @@ struct fsl_spdif_priv {
80 u8 rxclk_src; 80 u8 rxclk_src;
81 struct clk *txclk[SPDIF_TXRATE_MAX]; 81 struct clk *txclk[SPDIF_TXRATE_MAX];
82 struct clk *rxclk; 82 struct clk *rxclk;
83 struct clk *coreclk;
83 struct snd_dmaengine_dai_dma_data dma_params_tx; 84 struct snd_dmaengine_dai_dma_data dma_params_tx;
84 struct snd_dmaengine_dai_dma_data dma_params_rx; 85 struct snd_dmaengine_dai_dma_data dma_params_rx;
85 86
@@ -423,10 +424,16 @@ static int fsl_spdif_startup(struct snd_pcm_substream *substream,
423 424
424 /* Reset module and interrupts only for first initialization */ 425 /* Reset module and interrupts only for first initialization */
425 if (!cpu_dai->active) { 426 if (!cpu_dai->active) {
427 ret = clk_prepare_enable(spdif_priv->coreclk);
428 if (ret) {
429 dev_err(&pdev->dev, "failed to enable core clock\n");
430 return ret;
431 }
432
426 ret = spdif_softreset(spdif_priv); 433 ret = spdif_softreset(spdif_priv);
427 if (ret) { 434 if (ret) {
428 dev_err(&pdev->dev, "failed to soft reset\n"); 435 dev_err(&pdev->dev, "failed to soft reset\n");
429 return ret; 436 goto err;
430 } 437 }
431 438
432 /* Disable all the interrupts */ 439 /* Disable all the interrupts */
@@ -454,6 +461,11 @@ static int fsl_spdif_startup(struct snd_pcm_substream *substream,
454 regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_LOW_POWER, 0); 461 regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_LOW_POWER, 0);
455 462
456 return 0; 463 return 0;
464
465err:
466 clk_disable_unprepare(spdif_priv->coreclk);
467
468 return ret;
457} 469}
458 470
459static void fsl_spdif_shutdown(struct snd_pcm_substream *substream, 471static void fsl_spdif_shutdown(struct snd_pcm_substream *substream,
@@ -484,6 +496,7 @@ static void fsl_spdif_shutdown(struct snd_pcm_substream *substream,
484 spdif_intr_status_clear(spdif_priv); 496 spdif_intr_status_clear(spdif_priv);
485 regmap_update_bits(regmap, REG_SPDIF_SCR, 497 regmap_update_bits(regmap, REG_SPDIF_SCR,
486 SCR_LOW_POWER, SCR_LOW_POWER); 498 SCR_LOW_POWER, SCR_LOW_POWER);
499 clk_disable_unprepare(spdif_priv->coreclk);
487 } 500 }
488} 501}
489 502
@@ -1134,6 +1147,13 @@ static int fsl_spdif_probe(struct platform_device *pdev)
1134 return ret; 1147 return ret;
1135 } 1148 }
1136 1149
1150 /* Get core clock for data register access via DMA */
1151 spdif_priv->coreclk = devm_clk_get(&pdev->dev, "core");
1152 if (IS_ERR(spdif_priv->coreclk)) {
1153 dev_err(&pdev->dev, "no core clock in devicetree\n");
1154 return PTR_ERR(spdif_priv->coreclk);
1155 }
1156
1137 /* Select clock source for rx/tx clock */ 1157 /* Select clock source for rx/tx clock */
1138 spdif_priv->rxclk = devm_clk_get(&pdev->dev, "rxtx1"); 1158 spdif_priv->rxclk = devm_clk_get(&pdev->dev, "rxtx1");
1139 if (IS_ERR(spdif_priv->rxclk)) { 1159 if (IS_ERR(spdif_priv->rxclk)) {