diff options
author | Xiubo Li <Li.Xiubo@freescale.com> | 2014-02-26 19:45:01 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-02-26 23:36:01 -0500 |
commit | a3f7dcc9cc0392528bff75b17adfcd74fb8a0ecd (patch) | |
tree | 2293cbe5a39c6b2aa3d6b3c8e846308c4a2a1d15 /sound/soc/fsl/fsl_sai.c | |
parent | 13cde090030c7d00e991c85b87c12891cc8e4df4 (diff) |
ASoC: fsl-sai: Add SND_SOC_DAIFMT_DSP_A/B support.
o Add SND_SOC_DAIFMT_DSP_A support.
o Add SND_SOC_DAIFMT_DSP_B support.
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 | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 26d9f5ed6959..c4a423111673 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c | |||
@@ -108,15 +108,44 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, | |||
108 | /* DAI mode */ | 108 | /* DAI mode */ |
109 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 109 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
110 | case SND_SOC_DAIFMT_I2S: | 110 | case SND_SOC_DAIFMT_I2S: |
111 | /* Data on rising edge of bclk, frame low, 1clk before data */ | 111 | /* |
112 | * Frame low, 1clk before data, one word length for frame sync, | ||
113 | * frame sync starts one serial clock cycle earlier, | ||
114 | * that is, together with the last bit of the previous | ||
115 | * data word. | ||
116 | */ | ||
112 | val_cr2 &= ~FSL_SAI_CR2_BCP; | 117 | val_cr2 &= ~FSL_SAI_CR2_BCP; |
113 | val_cr4 |= FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP; | 118 | val_cr4 |= FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP; |
114 | break; | 119 | break; |
115 | case SND_SOC_DAIFMT_LEFT_J: | 120 | case SND_SOC_DAIFMT_LEFT_J: |
116 | /* Data on rising edge of bclk, frame high, 0clk before data */ | 121 | /* |
122 | * Frame high, one word length for frame sync, | ||
123 | * frame sync asserts with the first bit of the frame. | ||
124 | */ | ||
117 | val_cr2 &= ~FSL_SAI_CR2_BCP; | 125 | val_cr2 &= ~FSL_SAI_CR2_BCP; |
118 | val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP); | 126 | val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP); |
119 | break; | 127 | break; |
128 | case SND_SOC_DAIFMT_DSP_A: | ||
129 | /* | ||
130 | * Frame high, 1clk before data, one bit for frame sync, | ||
131 | * frame sync starts one serial clock cycle earlier, | ||
132 | * that is, together with the last bit of the previous | ||
133 | * data word. | ||
134 | */ | ||
135 | val_cr2 &= ~FSL_SAI_CR2_BCP; | ||
136 | val_cr4 &= ~FSL_SAI_CR4_FSP; | ||
137 | val_cr4 |= FSL_SAI_CR4_FSE; | ||
138 | sai->is_dsp_mode = true; | ||
139 | break; | ||
140 | case SND_SOC_DAIFMT_DSP_B: | ||
141 | /* | ||
142 | * Frame high, one bit for frame sync, | ||
143 | * frame sync asserts with the first bit of the frame. | ||
144 | */ | ||
145 | val_cr2 &= ~FSL_SAI_CR2_BCP; | ||
146 | val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP); | ||
147 | sai->is_dsp_mode = true; | ||
148 | break; | ||
120 | case SND_SOC_DAIFMT_RIGHT_J: | 149 | case SND_SOC_DAIFMT_RIGHT_J: |
121 | /* To be done */ | 150 | /* To be done */ |
122 | default: | 151 | default: |
@@ -219,7 +248,9 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, | |||
219 | val_cr5 &= ~FSL_SAI_CR5_W0W_MASK; | 248 | val_cr5 &= ~FSL_SAI_CR5_W0W_MASK; |
220 | val_cr5 &= ~FSL_SAI_CR5_FBT_MASK; | 249 | val_cr5 &= ~FSL_SAI_CR5_FBT_MASK; |
221 | 250 | ||
222 | val_cr4 |= FSL_SAI_CR4_SYWD(word_width); | 251 | if (!sai->is_dsp_mode) |
252 | val_cr4 |= FSL_SAI_CR4_SYWD(word_width); | ||
253 | |||
223 | val_cr5 |= FSL_SAI_CR5_WNW(word_width); | 254 | val_cr5 |= FSL_SAI_CR5_WNW(word_width); |
224 | val_cr5 |= FSL_SAI_CR5_W0W(word_width); | 255 | val_cr5 |= FSL_SAI_CR5_W0W(word_width); |
225 | 256 | ||
@@ -245,6 +276,10 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
245 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | 276 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
246 | u32 tcsr, rcsr; | 277 | u32 tcsr, rcsr; |
247 | 278 | ||
279 | /* | ||
280 | * The transmitter bit clock and frame sync are to be | ||
281 | * used by both the transmitter and receiver. | ||
282 | */ | ||
248 | regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, | 283 | regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, |
249 | ~FSL_SAI_CR2_SYNC); | 284 | ~FSL_SAI_CR2_SYNC); |
250 | regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC, | 285 | regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC, |
@@ -261,6 +296,10 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
261 | tcsr &= ~FSL_SAI_CSR_FRDE; | 296 | tcsr &= ~FSL_SAI_CSR_FRDE; |
262 | } | 297 | } |
263 | 298 | ||
299 | /* | ||
300 | * It is recommended that the transmitter is the last enabled | ||
301 | * and the first disabled. | ||
302 | */ | ||
264 | switch (cmd) { | 303 | switch (cmd) { |
265 | case SNDRV_PCM_TRIGGER_START: | 304 | case SNDRV_PCM_TRIGGER_START: |
266 | case SNDRV_PCM_TRIGGER_RESUME: | 305 | case SNDRV_PCM_TRIGGER_RESUME: |