From f6d460ab12bad902e28a88df4e663a5e423ef3c0 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 25 Dec 2013 12:40:04 +0800 Subject: 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 Signed-off-by: Mark Brown --- This patch is pulled back from upstream: commit e5d0fa9c3ec59a40e0285d96b65b7f62875acd42 Change-Id: I44a321c2f74580bc6387688777434c88f027c17b Reviewed-on: http://git.am.freescale.net:8181/19747 Tested-by: Review Code-CDREVIEW Reviewed-by: Zhengxiong Jin diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index a414f72..ba4d9c8 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, unsigned int fmt, int fsl_dir) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - u32 val_cr2, val_cr3, val_cr4, reg_cr2, reg_cr3, reg_cr4; + u32 val_cr2, val_cr4, reg_cr2, reg_cr4; if (fsl_dir == FSL_FMT_TRANSMITTER) { reg_cr2 = FSL_SAI_TCR2; - reg_cr3 = FSL_SAI_TCR3; reg_cr4 = FSL_SAI_TCR4; } else { reg_cr2 = FSL_SAI_RCR2; - reg_cr3 = FSL_SAI_RCR3; reg_cr4 = FSL_SAI_RCR4; } val_cr2 = sai_readl(sai, sai->base + reg_cr2); - val_cr3 = sai_readl(sai, sai->base + reg_cr3); val_cr4 = sai_readl(sai, sai->base + reg_cr4); if (sai->big_endian_data) @@ -188,13 +185,10 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, return -EINVAL; } - val_cr3 |= FSL_SAI_CR3_TRCE; - if (fsl_dir == FSL_FMT_RECEIVER) val_cr2 |= FSL_SAI_CR2_SYNC; sai_writel(sai, val_cr2, sai->base + reg_cr2); - sai_writel(sai, val_cr3, sai->base + reg_cr3); sai_writel(sai, val_cr4, sai->base + reg_cr4); return 0; @@ -278,7 +272,7 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - unsigned int tcsr, rcsr; + u32 tcsr, rcsr, val_cr3, reg_cr3; tcsr = sai_readl(sai, sai->base + FSL_SAI_TCSR); 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, if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { tcsr |= FSL_SAI_CSR_FRDE; rcsr &= ~FSL_SAI_CSR_FRDE; + reg_cr3 = FSL_SAI_TCR3; } else { rcsr |= FSL_SAI_CSR_FRDE; tcsr &= ~FSL_SAI_CSR_FRDE; + reg_cr3 = FSL_SAI_RCR3; } + val_cr3 = sai_readl(sai, sai->base + reg_cr3); + switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: tcsr |= FSL_SAI_CSR_TERE; rcsr |= FSL_SAI_CSR_TERE; + val_cr3 |= FSL_SAI_CR3_TRCE; + + sai_writel(sai, val_cr3, sai->base + reg_cr3); sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR); sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR); break; @@ -308,8 +309,12 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, tcsr &= ~FSL_SAI_CSR_TERE; rcsr &= ~FSL_SAI_CSR_TERE; } + + val_cr3 &= ~FSL_SAI_CR3_TRCE; + sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR); sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR); + sai_writel(sai, val_cr3, sai->base + reg_cr3); break; default: return -EINVAL; -- cgit v0.10.2