aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl/fsl_sai.c
diff options
context:
space:
mode:
authorXiubo Li <Li.Xiubo@freescale.com>2013-12-24 23:40:04 -0500
committerMark Brown <broonie@linaro.org>2013-12-30 07:17:07 -0500
commite5d0fa9c3ec59a40e0285d96b65b7f62875acd42 (patch)
treef3c6be53294af719583f448d78768bc73d580634 /sound/soc/fsl/fsl_sai.c
parente6dc12d7198eddba2e3e7a13feab5c7edde7ba1d (diff)
ASoC: fsl_sai: Add disable operation for the corresponding data channel.
Enables/Disables the corresponding data channel for tx/rx operation. A channel must be enabled before its FIFO is accessed, and then disable it when tx/rx is stopped or idle. 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.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 596aabbf9037..af802465456e 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -124,20 +124,17 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
124 unsigned int fmt, int fsl_dir) 124 unsigned int fmt, int fsl_dir)
125{ 125{
126 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 126 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
127 u32 val_cr2, val_cr3, val_cr4, reg_cr2, reg_cr3, reg_cr4; 127 u32 val_cr2, val_cr4, reg_cr2, reg_cr4;
128 128
129 if (fsl_dir == FSL_FMT_TRANSMITTER) { 129 if (fsl_dir == FSL_FMT_TRANSMITTER) {
130 reg_cr2 = FSL_SAI_TCR2; 130 reg_cr2 = FSL_SAI_TCR2;
131 reg_cr3 = FSL_SAI_TCR3;
132 reg_cr4 = FSL_SAI_TCR4; 131 reg_cr4 = FSL_SAI_TCR4;
133 } else { 132 } else {
134 reg_cr2 = FSL_SAI_RCR2; 133 reg_cr2 = FSL_SAI_RCR2;
135 reg_cr3 = FSL_SAI_RCR3;
136 reg_cr4 = FSL_SAI_RCR4; 134 reg_cr4 = FSL_SAI_RCR4;
137 } 135 }
138 136
139 val_cr2 = sai_readl(sai, sai->base + reg_cr2); 137 val_cr2 = sai_readl(sai, sai->base + reg_cr2);
140 val_cr3 = sai_readl(sai, sai->base + reg_cr3);
141 val_cr4 = sai_readl(sai, sai->base + reg_cr4); 138 val_cr4 = sai_readl(sai, sai->base + reg_cr4);
142 139
143 if (sai->big_endian_data) 140 if (sai->big_endian_data)
@@ -188,13 +185,10 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
188 return -EINVAL; 185 return -EINVAL;
189 } 186 }
190 187
191 val_cr3 |= FSL_SAI_CR3_TRCE;
192
193 if (fsl_dir == FSL_FMT_RECEIVER) 188 if (fsl_dir == FSL_FMT_RECEIVER)
194 val_cr2 |= FSL_SAI_CR2_SYNC; 189 val_cr2 |= FSL_SAI_CR2_SYNC;
195 190
196 sai_writel(sai, val_cr2, sai->base + reg_cr2); 191 sai_writel(sai, val_cr2, sai->base + reg_cr2);
197 sai_writel(sai, val_cr3, sai->base + reg_cr3);
198 sai_writel(sai, val_cr4, sai->base + reg_cr4); 192 sai_writel(sai, val_cr4, sai->base + reg_cr4);
199 193
200 return 0; 194 return 0;
@@ -278,7 +272,7 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
278 struct snd_soc_dai *cpu_dai) 272 struct snd_soc_dai *cpu_dai)
279{ 273{
280 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 274 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
281 unsigned int tcsr, rcsr; 275 u32 tcsr, rcsr, val_cr3, reg_cr3;
282 276
283 tcsr = sai_readl(sai, sai->base + FSL_SAI_TCSR); 277 tcsr = sai_readl(sai, sai->base + FSL_SAI_TCSR);
284 rcsr = sai_readl(sai, sai->base + FSL_SAI_RCSR); 278 rcsr = sai_readl(sai, sai->base + FSL_SAI_RCSR);
@@ -286,17 +280,24 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
286 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 280 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
287 tcsr |= FSL_SAI_CSR_FRDE; 281 tcsr |= FSL_SAI_CSR_FRDE;
288 rcsr &= ~FSL_SAI_CSR_FRDE; 282 rcsr &= ~FSL_SAI_CSR_FRDE;
283 reg_cr3 = FSL_SAI_TCR3;
289 } else { 284 } else {
290 rcsr |= FSL_SAI_CSR_FRDE; 285 rcsr |= FSL_SAI_CSR_FRDE;
291 tcsr &= ~FSL_SAI_CSR_FRDE; 286 tcsr &= ~FSL_SAI_CSR_FRDE;
287 reg_cr3 = FSL_SAI_RCR3;
292 } 288 }
293 289
290 val_cr3 = sai_readl(sai, sai->base + reg_cr3);
291
294 switch (cmd) { 292 switch (cmd) {
295 case SNDRV_PCM_TRIGGER_START: 293 case SNDRV_PCM_TRIGGER_START:
296 case SNDRV_PCM_TRIGGER_RESUME: 294 case SNDRV_PCM_TRIGGER_RESUME:
297 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 295 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
298 tcsr |= FSL_SAI_CSR_TERE; 296 tcsr |= FSL_SAI_CSR_TERE;
299 rcsr |= FSL_SAI_CSR_TERE; 297 rcsr |= FSL_SAI_CSR_TERE;
298 val_cr3 |= FSL_SAI_CR3_TRCE;
299
300 sai_writel(sai, val_cr3, sai->base + reg_cr3);
300 sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR); 301 sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR);
301 sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR); 302 sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR);
302 break; 303 break;
@@ -308,8 +309,12 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
308 tcsr &= ~FSL_SAI_CSR_TERE; 309 tcsr &= ~FSL_SAI_CSR_TERE;
309 rcsr &= ~FSL_SAI_CSR_TERE; 310 rcsr &= ~FSL_SAI_CSR_TERE;
310 } 311 }
312
313 val_cr3 &= ~FSL_SAI_CR3_TRCE;
314
311 sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR); 315 sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR);
312 sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR); 316 sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR);
317 sai_writel(sai, val_cr3, sai->base + reg_cr3);
313 break; 318 break;
314 default: 319 default:
315 return -EINVAL; 320 return -EINVAL;