diff options
-rw-r--r-- | sound/soc/fsl/fsl_spdif.c | 22 |
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 | |||
465 | err: | ||
466 | clk_disable_unprepare(spdif_priv->coreclk); | ||
467 | |||
468 | return ret; | ||
457 | } | 469 | } |
458 | 470 | ||
459 | static void fsl_spdif_shutdown(struct snd_pcm_substream *substream, | 471 | static 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)) { |