diff options
author | Xiubo Li <Li.Xiubo@freescale.com> | 2013-12-24 23:40:04 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-12-30 07:17:07 -0500 |
commit | e5d0fa9c3ec59a40e0285d96b65b7f62875acd42 (patch) | |
tree | f3c6be53294af719583f448d78768bc73d580634 /sound/soc/fsl/fsl_sai.c | |
parent | e6dc12d7198eddba2e3e7a13feab5c7edde7ba1d (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.c | 21 |
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; |