aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl/fsl_sai.c
diff options
context:
space:
mode:
authorXiubo Li <Li.Xiubo@freescale.com>2013-12-31 02:33:21 -0500
committerMark Brown <broonie@linaro.org>2013-12-31 07:23:10 -0500
commit496a39d9ec238569fac6daceac8f5420c5edc2f1 (patch)
treed69b822dd012c1856a37c0e5b50a382b455b68cf /sound/soc/fsl/fsl_sai.c
parente5d0fa9c3ec59a40e0285d96b65b7f62875acd42 (diff)
ASoC: fsl_sai: Fix one bug for hardware limitation.
This is maybe one bug or a limitation of the hardware that the {T,R}CR2's Synchronous Mode bits must be set as late as possible, or the SAI device maybe hanged up, and there has not any explaination about this limitation in the SAI Data Sheet. And the {T,R}CR2's Synchronous Mode bits must be set at the same time whether for Tx or Rx stream. Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/fsl/fsl_sai.c')
-rw-r--r--sound/soc/fsl/fsl_sai.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index af802465456e..2ece14716c67 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -145,7 +145,6 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
145 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 145 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
146 case SND_SOC_DAIFMT_I2S: 146 case SND_SOC_DAIFMT_I2S:
147 val_cr4 |= FSL_SAI_CR4_FSE; 147 val_cr4 |= FSL_SAI_CR4_FSE;
148 val_cr4 |= FSL_SAI_CR4_FSP;
149 break; 148 break;
150 default: 149 default:
151 return -EINVAL; 150 return -EINVAL;
@@ -185,9 +184,6 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
185 return -EINVAL; 184 return -EINVAL;
186 } 185 }
187 186
188 if (fsl_dir == FSL_FMT_RECEIVER)
189 val_cr2 |= FSL_SAI_CR2_SYNC;
190
191 sai_writel(sai, val_cr2, sai->base + reg_cr2); 187 sai_writel(sai, val_cr2, sai->base + reg_cr2);
192 sai_writel(sai, val_cr4, sai->base + reg_cr4); 188 sai_writel(sai, val_cr4, sai->base + reg_cr4);
193 189
@@ -253,6 +249,7 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
253 val_cr5 |= FSL_SAI_CR5_WNW(word_width); 249 val_cr5 |= FSL_SAI_CR5_WNW(word_width);
254 val_cr5 |= FSL_SAI_CR5_W0W(word_width); 250 val_cr5 |= FSL_SAI_CR5_W0W(word_width);
255 251
252 val_cr5 &= ~FSL_SAI_CR5_FBT_MASK;
256 if (sai->big_endian_data) 253 if (sai->big_endian_data)
257 val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1); 254 val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1);
258 else 255 else
@@ -272,7 +269,15 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
272 struct snd_soc_dai *cpu_dai) 269 struct snd_soc_dai *cpu_dai)
273{ 270{
274 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 271 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
275 u32 tcsr, rcsr, val_cr3, reg_cr3; 272 u32 tcsr, rcsr, val_cr2, val_cr3, reg_cr3;
273
274 val_cr2 = sai_readl(sai, sai->base + FSL_SAI_TCR2);
275 val_cr2 &= ~FSL_SAI_CR2_SYNC;
276 sai_writel(sai, val_cr2, sai->base + FSL_SAI_TCR2);
277
278 val_cr2 = sai_readl(sai, sai->base + FSL_SAI_RCR2);
279 val_cr2 |= FSL_SAI_CR2_SYNC;
280 sai_writel(sai, val_cr2, sai->base + FSL_SAI_RCR2);
276 281
277 tcsr = sai_readl(sai, sai->base + FSL_SAI_TCSR); 282 tcsr = sai_readl(sai, sai->base + FSL_SAI_TCSR);
278 rcsr = sai_readl(sai, sai->base + FSL_SAI_RCSR); 283 rcsr = sai_readl(sai, sai->base + FSL_SAI_RCSR);