diff options
author | Troy Kisky <troy.kisky@boundarydevices.com> | 2009-07-04 22:29:57 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-07-05 07:59:08 -0400 |
commit | f5cfa954e6812c09e3a4b89e8009b22285b860a3 (patch) | |
tree | bd271c7a69ba99afbf35c3f96fac62e627705f5a /sound/soc/davinci | |
parent | 9333b594a08f2b2d8b7d96260164817acdbc5cab (diff) |
ASoC: DaVinci: i2s, fix mcbsp_word_length update
Code previously just "ors" in this field without clearing
first. Fix, by never reading this register.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/davinci')
-rw-r--r-- | sound/soc/davinci/davinci-i2s.c | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c index 5b31b56e2e92..6fa1b6aebc30 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c | |||
@@ -63,6 +63,7 @@ | |||
63 | #define DAVINCI_MCBSP_RCR_RWDLEN1(v) ((v) << 5) | 63 | #define DAVINCI_MCBSP_RCR_RWDLEN1(v) ((v) << 5) |
64 | #define DAVINCI_MCBSP_RCR_RFRLEN1(v) ((v) << 8) | 64 | #define DAVINCI_MCBSP_RCR_RFRLEN1(v) ((v) << 8) |
65 | #define DAVINCI_MCBSP_RCR_RDATDLY(v) ((v) << 16) | 65 | #define DAVINCI_MCBSP_RCR_RDATDLY(v) ((v) << 16) |
66 | #define DAVINCI_MCBSP_RCR_RFIG (1 << 18) | ||
66 | #define DAVINCI_MCBSP_RCR_RWDLEN2(v) ((v) << 21) | 67 | #define DAVINCI_MCBSP_RCR_RWDLEN2(v) ((v) << 21) |
67 | 68 | ||
68 | #define DAVINCI_MCBSP_XCR_XWDLEN1(v) ((v) << 5) | 69 | #define DAVINCI_MCBSP_XCR_XWDLEN1(v) ((v) << 5) |
@@ -104,6 +105,9 @@ static struct davinci_pcm_dma_params davinci_i2s_pcm_in = { | |||
104 | 105 | ||
105 | struct davinci_mcbsp_dev { | 106 | struct davinci_mcbsp_dev { |
106 | void __iomem *base; | 107 | void __iomem *base; |
108 | #define MOD_DSP_A 0 | ||
109 | #define MOD_DSP_B 1 | ||
110 | int mode; | ||
107 | u32 pcr; | 111 | u32 pcr; |
108 | struct clk *clk; | 112 | struct clk *clk; |
109 | struct davinci_pcm_dma_params *dma_params[2]; | 113 | struct davinci_pcm_dma_params *dma_params[2]; |
@@ -225,12 +229,11 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
225 | struct davinci_mcbsp_dev *dev = cpu_dai->private_data; | 229 | struct davinci_mcbsp_dev *dev = cpu_dai->private_data; |
226 | unsigned int pcr; | 230 | unsigned int pcr; |
227 | unsigned int srgr; | 231 | unsigned int srgr; |
228 | unsigned int rcr; | ||
229 | unsigned int xcr; | ||
230 | srgr = DAVINCI_MCBSP_SRGR_FSGM | | 232 | srgr = DAVINCI_MCBSP_SRGR_FSGM | |
231 | DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) | | 233 | DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) | |
232 | DAVINCI_MCBSP_SRGR_FWID(DEFAULT_BITPERSAMPLE - 1); | 234 | DAVINCI_MCBSP_SRGR_FWID(DEFAULT_BITPERSAMPLE - 1); |
233 | 235 | ||
236 | /* set master/slave audio interface */ | ||
234 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 237 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
235 | case SND_SOC_DAIFMT_CBS_CFS: | 238 | case SND_SOC_DAIFMT_CBS_CFS: |
236 | /* cpu is master */ | 239 | /* cpu is master */ |
@@ -255,11 +258,8 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
255 | return -EINVAL; | 258 | return -EINVAL; |
256 | } | 259 | } |
257 | 260 | ||
258 | rcr = DAVINCI_MCBSP_RCR_RFRLEN1(1); | 261 | /* interface format */ |
259 | xcr = DAVINCI_MCBSP_XCR_XFIG | DAVINCI_MCBSP_XCR_XFRLEN1(1); | ||
260 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 262 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
261 | case SND_SOC_DAIFMT_DSP_B: | ||
262 | break; | ||
263 | case SND_SOC_DAIFMT_I2S: | 263 | case SND_SOC_DAIFMT_I2S: |
264 | /* Davinci doesn't support TRUE I2S, but some codecs will have | 264 | /* Davinci doesn't support TRUE I2S, but some codecs will have |
265 | * the left and right channels contiguous. This allows | 265 | * the left and right channels contiguous. This allows |
@@ -279,8 +279,10 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
279 | */ | 279 | */ |
280 | fmt ^= SND_SOC_DAIFMT_NB_IF; | 280 | fmt ^= SND_SOC_DAIFMT_NB_IF; |
281 | case SND_SOC_DAIFMT_DSP_A: | 281 | case SND_SOC_DAIFMT_DSP_A: |
282 | rcr |= DAVINCI_MCBSP_RCR_RDATDLY(1); | 282 | dev->mode = MOD_DSP_A; |
283 | xcr |= DAVINCI_MCBSP_XCR_XDATDLY(1); | 283 | break; |
284 | case SND_SOC_DAIFMT_DSP_B: | ||
285 | dev->mode = MOD_DSP_B; | ||
284 | break; | 286 | break; |
285 | default: | 287 | default: |
286 | printk(KERN_ERR "%s:bad format\n", __func__); | 288 | printk(KERN_ERR "%s:bad format\n", __func__); |
@@ -342,8 +344,6 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
342 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr); | 344 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr); |
343 | dev->pcr = pcr; | 345 | dev->pcr = pcr; |
344 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr); | 346 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr); |
345 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr); | ||
346 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr); | ||
347 | return 0; | 347 | return 0; |
348 | } | 348 | } |
349 | 349 | ||
@@ -377,6 +377,15 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, | |||
377 | srgr |= DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1); | 377 | srgr |= DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1); |
378 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr); | 378 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr); |
379 | 379 | ||
380 | rcr = DAVINCI_MCBSP_RCR_RFIG; | ||
381 | xcr = DAVINCI_MCBSP_XCR_XFIG; | ||
382 | if (dev->mode == MOD_DSP_B) { | ||
383 | rcr |= DAVINCI_MCBSP_RCR_RDATDLY(0); | ||
384 | xcr |= DAVINCI_MCBSP_XCR_XDATDLY(0); | ||
385 | } else { | ||
386 | rcr |= DAVINCI_MCBSP_RCR_RDATDLY(1); | ||
387 | xcr |= DAVINCI_MCBSP_XCR_XDATDLY(1); | ||
388 | } | ||
380 | /* Determine xfer data type */ | 389 | /* Determine xfer data type */ |
381 | switch (params_format(params)) { | 390 | switch (params_format(params)) { |
382 | case SNDRV_PCM_FORMAT_S8: | 391 | case SNDRV_PCM_FORMAT_S8: |
@@ -396,19 +405,18 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, | |||
396 | return -EINVAL; | 405 | return -EINVAL; |
397 | } | 406 | } |
398 | 407 | ||
399 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | 408 | rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(1); |
400 | rcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_RCR_REG); | 409 | xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(1); |
401 | rcr |= DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) | | ||
402 | DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length); | ||
403 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr); | ||
404 | 410 | ||
405 | } else { | 411 | rcr |= DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) | |
406 | xcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_XCR_REG); | 412 | DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length); |
407 | xcr |= DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) | | 413 | xcr |= DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) | |
408 | DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length); | 414 | DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length); |
409 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr); | ||
410 | 415 | ||
411 | } | 416 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
417 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr); | ||
418 | else | ||
419 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr); | ||
412 | return 0; | 420 | return 0; |
413 | } | 421 | } |
414 | 422 | ||