aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2014-05-27 04:24:20 -0400
committerMark Brown <broonie@linaro.org>2014-06-01 06:55:07 -0400
commit8dd51e23a1ef3b5f22eeff4827260b75bafba620 (patch)
tree62754178efdd7c78ddb93aa5dc9f9ceb748e97cb /sound
parent85e59af24056ca7ffaf617cf6201c519e31dc668 (diff)
ASoC: fsl-ssi: set bitclock in master mode from hw_params
The fsl_ssi driver uses the .set_sysclk callback to configure the bitclock for master mode. This is unnecessary since the bitclock is known in hw_params. This patch configures the bitclock from .hw_params. .set_dai_sysclk now sets a bitclock frequency which is preferred over the default calculated bitclock frequency. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Markus Pargmann <mpa@pengutronix.de> Tested-By: Michael Grzeschik <mgr@pengutronix.de> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/fsl/fsl_ssi.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 18eacf5e399d..930095b1b72a 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -166,6 +166,7 @@ struct fsl_ssi_private {
166 spinlock_t baudclk_lock; 166 spinlock_t baudclk_lock;
167 struct clk *baudclk; 167 struct clk *baudclk;
168 struct clk *clk; 168 struct clk *clk;
169 unsigned int bitclk_freq;
169 struct snd_dmaengine_dai_dma_data dma_params_tx; 170 struct snd_dmaengine_dai_dma_data dma_params_tx;
170 struct snd_dmaengine_dai_dma_data dma_params_rx; 171 struct snd_dmaengine_dai_dma_data dma_params_rx;
171 struct imx_pcm_fiq_params fiq_params; 172 struct imx_pcm_fiq_params fiq_params;
@@ -236,6 +237,12 @@ static bool fsl_ssi_is_ac97(struct fsl_ssi_private *ssi_private)
236 return !!(ssi_private->dai_fmt & SND_SOC_DAIFMT_AC97); 237 return !!(ssi_private->dai_fmt & SND_SOC_DAIFMT_AC97);
237} 238}
238 239
240static bool fsl_ssi_is_i2s_master(struct fsl_ssi_private *ssi_private)
241{
242 return (ssi_private->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
243 SND_SOC_DAIFMT_CBS_CFS;
244}
245
239/** 246/**
240 * fsl_ssi_isr: SSI interrupt handler 247 * fsl_ssi_isr: SSI interrupt handler
241 * 248 *
@@ -509,7 +516,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
509} 516}
510 517
511/** 518/**
512 * fsl_ssi_set_dai_sysclk - configure Digital Audio Interface bit clock 519 * fsl_ssi_set_bclk - configure Digital Audio Interface bit clock
513 * 520 *
514 * Note: This function can be only called when using SSI as DAI master 521 * Note: This function can be only called when using SSI as DAI master
515 * 522 *
@@ -517,8 +524,9 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
517 * freq: Output BCLK frequency = samplerate * 32 (fixed) * channels 524 * freq: Output BCLK frequency = samplerate * 32 (fixed) * channels
518 * dir: SND_SOC_CLOCK_OUT -> TxBCLK, SND_SOC_CLOCK_IN -> RxBCLK. 525 * dir: SND_SOC_CLOCK_OUT -> TxBCLK, SND_SOC_CLOCK_IN -> RxBCLK.
519 */ 526 */
520static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai, 527static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
521 int clk_id, unsigned int freq, int dir) 528 struct snd_soc_dai *cpu_dai,
529 struct snd_pcm_hw_params *hw_params)
522{ 530{
523 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); 531 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
524 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 532 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
@@ -526,6 +534,13 @@ static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
526 u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i; 534 u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i;
527 unsigned long flags, clkrate, baudrate, tmprate; 535 unsigned long flags, clkrate, baudrate, tmprate;
528 u64 sub, savesub = 100000; 536 u64 sub, savesub = 100000;
537 unsigned int freq;
538
539 /* Prefer the explicitly set bitclock frequency */
540 if (ssi_private->bitclk_freq)
541 freq = ssi_private->bitclk_freq;
542 else
543 freq = params_channels(hw_params) * 32 * params_rate(hw_params);
529 544
530 /* Don't apply it to any non-baudclk circumstance */ 545 /* Don't apply it to any non-baudclk circumstance */
531 if (IS_ERR(ssi_private->baudclk)) 546 if (IS_ERR(ssi_private->baudclk))
@@ -583,7 +598,7 @@ static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
583 mask = CCSR_SSI_SxCCR_PM_MASK | CCSR_SSI_SxCCR_DIV2 | 598 mask = CCSR_SSI_SxCCR_PM_MASK | CCSR_SSI_SxCCR_DIV2 |
584 CCSR_SSI_SxCCR_PSR; 599 CCSR_SSI_SxCCR_PSR;
585 600
586 if (dir == SND_SOC_CLOCK_OUT || synchronous) 601 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || synchronous)
587 write_ssi_mask(&ssi->stccr, mask, stccr); 602 write_ssi_mask(&ssi->stccr, mask, stccr);
588 else 603 else
589 write_ssi_mask(&ssi->srccr, mask, stccr); 604 write_ssi_mask(&ssi->srccr, mask, stccr);
@@ -604,6 +619,16 @@ static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
604 return 0; 619 return 0;
605} 620}
606 621
622static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
623 int clk_id, unsigned int freq, int dir)
624{
625 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
626
627 ssi_private->bitclk_freq = freq;
628
629 return 0;
630}
631
607/** 632/**
608 * fsl_ssi_hw_params - program the sample size 633 * fsl_ssi_hw_params - program the sample size
609 * 634 *
@@ -627,6 +652,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
627 snd_pcm_format_width(params_format(hw_params)); 652 snd_pcm_format_width(params_format(hw_params));
628 u32 wl = CCSR_SSI_SxCCR_WL(sample_size); 653 u32 wl = CCSR_SSI_SxCCR_WL(sample_size);
629 int enabled = read_ssi(&ssi->scr) & CCSR_SSI_SCR_SSIEN; 654 int enabled = read_ssi(&ssi->scr) & CCSR_SSI_SCR_SSIEN;
655 int ret;
630 656
631 /* 657 /*
632 * If we're in synchronous mode, and the SSI is already enabled, 658 * If we're in synchronous mode, and the SSI is already enabled,
@@ -635,6 +661,12 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
635 if (enabled && ssi_private->cpu_dai_drv.symmetric_rates) 661 if (enabled && ssi_private->cpu_dai_drv.symmetric_rates)
636 return 0; 662 return 0;
637 663
664 if (fsl_ssi_is_i2s_master(ssi_private)) {
665 ret = fsl_ssi_set_bclk(substream, cpu_dai, hw_params);
666 if (ret)
667 return ret;
668 }
669
638 /* 670 /*
639 * FIXME: The documentation says that SxCCR[WL] should not be 671 * FIXME: The documentation says that SxCCR[WL] should not be
640 * modified while the SSI is enabled. The only time this can 672 * modified while the SSI is enabled. The only time this can