summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@freescale.com>2014-10-13 11:11:29 +0800
committerShengjiu Wang <shengjiu.wang@freescale.com>2014-10-15 18:26:10 +0800
commit05a4885915f543f41e6284c8a87e8826786296aa (patch)
tree7a97e3d90f4f7b012a13947c3c65db7458e27f00 /sound
parent19bf85a793677adb58d816a7264d455dda710143 (diff)
MLK-9684-5: ASoC: fsl-ssi: fix baudclk handling
Baudclk is esai_extal, which is set CLK_SET_PARENT_GATE flags, so when the clock is enabled, we can't change the rate later. As we will change the rate in fsl_ssi_set_bclk(), so remove the enable and disable to hw_params() and hw_free(). Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/fsl/fsl_ssi.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 36ffb9324b59..e36fa06cdb8f 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -147,6 +147,7 @@ struct fsl_ssi_private {
struct clk *coreclk;
struct clk *clk;
unsigned int bitclk_freq;
+ unsigned int baudclk_streams;
struct snd_dmaengine_dai_dma_data dma_params_tx;
struct snd_dmaengine_dai_dma_data dma_params_rx;
@@ -358,7 +359,6 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
pm_runtime_get_sync(dai->dev);
clk_prepare_enable(ssi_private->coreclk);
- clk_prepare_enable(ssi_private->clk);
/* When using dual fifo mode, it would be safer if we ensure
* its period size to be an even number. If appearing to an
@@ -502,6 +502,15 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
ret = fsl_ssi_set_bclk(substream, cpu_dai, hw_params);
if (ret)
return ret;
+
+ /* Do not enable the clock if it is already enabled */
+ if (!(ssi_private->baudclk_streams & BIT(substream->stream))) {
+ ret = clk_prepare_enable(ssi_private->clk);
+ if (ret)
+ return ret;
+
+ ssi_private->baudclk_streams |= BIT(substream->stream);
+ }
}
/*
* FIXME: The documentation says that SxCCR[WL] should not be
@@ -526,6 +535,22 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
return 0;
}
+static int fsl_ssi_hw_free(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *cpu_dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct fsl_ssi_private *ssi_private =
+ snd_soc_dai_get_drvdata(rtd->cpu_dai);
+
+ if (ssi_private->i2s_mode == CCSR_SSI_SCR_I2S_MODE_MASTER &&
+ ssi_private->baudclk_streams & BIT(substream->stream)) {
+ clk_disable_unprepare(ssi_private->clk);
+ ssi_private->baudclk_streams &= ~BIT(substream->stream);
+ }
+
+ return 0;
+}
+
/**
* fsl_ssi_trigger: start and stop the DMA transfer.
*
@@ -852,7 +877,6 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
}
if (ssi_private->ssi_on_imx) {
- clk_disable_unprepare(ssi_private->clk);
clk_disable_unprepare(ssi_private->coreclk);
pm_runtime_put_sync(dai->dev);
@@ -874,6 +898,7 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
static const struct snd_soc_dai_ops fsl_ssi_dai_ops = {
.startup = fsl_ssi_startup,
.hw_params = fsl_ssi_hw_params,
+ .hw_free = fsl_ssi_hw_free,
.set_fmt = fsl_ssi_set_dai_fmt,
.set_sysclk = fsl_ssi_set_dai_sysclk,
.set_tdm_slot = fsl_ssi_set_dai_tdm_slot,