diff options
author | Mark Brown <broonie@linaro.org> | 2014-08-04 11:31:12 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-08-04 11:31:12 -0400 |
commit | 3674b710a787bd3d9aea6497e134740bedcde79a (patch) | |
tree | 118dc1d1be6377fb2afdae4d0184bc27ad322b18 /sound/soc/fsl | |
parent | 0b773b202d73bfcb1bec28368dff76cbfb52054a (diff) | |
parent | a3fdc6749edf4dcb07df3a10bbdd9850ed5fd01a (diff) |
Merge remote-tracking branch 'asoc/fix/fsl-sai' into asoc-linus
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r-- | sound/soc/fsl/fsl_sai.c | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 1b6ee2ce849f..364410be3c4e 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c | |||
@@ -327,7 +327,7 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
327 | { | 327 | { |
328 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | 328 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
329 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | 329 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
330 | u32 tcsr, rcsr; | 330 | u32 xcsr, count = 100; |
331 | 331 | ||
332 | /* | 332 | /* |
333 | * The transmitter bit clock and frame sync are to be | 333 | * The transmitter bit clock and frame sync are to be |
@@ -338,9 +338,6 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
338 | regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC, | 338 | regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC, |
339 | FSL_SAI_CR2_SYNC); | 339 | FSL_SAI_CR2_SYNC); |
340 | 340 | ||
341 | regmap_read(sai->regmap, FSL_SAI_TCSR, &tcsr); | ||
342 | regmap_read(sai->regmap, FSL_SAI_RCSR, &rcsr); | ||
343 | |||
344 | /* | 341 | /* |
345 | * It is recommended that the transmitter is the last enabled | 342 | * It is recommended that the transmitter is the last enabled |
346 | * and the first disabled. | 343 | * and the first disabled. |
@@ -349,17 +346,16 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
349 | case SNDRV_PCM_TRIGGER_START: | 346 | case SNDRV_PCM_TRIGGER_START: |
350 | case SNDRV_PCM_TRIGGER_RESUME: | 347 | case SNDRV_PCM_TRIGGER_RESUME: |
351 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 348 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
352 | if (!(tcsr & FSL_SAI_CSR_FRDE || rcsr & FSL_SAI_CSR_FRDE)) { | 349 | regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), |
353 | regmap_update_bits(sai->regmap, FSL_SAI_RCSR, | 350 | FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); |
354 | FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); | 351 | |
355 | regmap_update_bits(sai->regmap, FSL_SAI_TCSR, | 352 | regmap_update_bits(sai->regmap, FSL_SAI_RCSR, |
356 | FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); | 353 | FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); |
357 | } | 354 | regmap_update_bits(sai->regmap, FSL_SAI_TCSR, |
355 | FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); | ||
358 | 356 | ||
359 | regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), | 357 | regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), |
360 | FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS); | 358 | FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS); |
361 | regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), | ||
362 | FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); | ||
363 | break; | 359 | break; |
364 | case SNDRV_PCM_TRIGGER_STOP: | 360 | case SNDRV_PCM_TRIGGER_STOP: |
365 | case SNDRV_PCM_TRIGGER_SUSPEND: | 361 | case SNDRV_PCM_TRIGGER_SUSPEND: |
@@ -370,14 +366,24 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
370 | FSL_SAI_CSR_xIE_MASK, 0); | 366 | FSL_SAI_CSR_xIE_MASK, 0); |
371 | 367 | ||
372 | /* Check if the opposite FRDE is also disabled */ | 368 | /* Check if the opposite FRDE is also disabled */ |
373 | if (!(tx ? rcsr & FSL_SAI_CSR_FRDE : tcsr & FSL_SAI_CSR_FRDE)) { | 369 | regmap_read(sai->regmap, FSL_SAI_xCSR(!tx), &xcsr); |
370 | if (!(xcsr & FSL_SAI_CSR_FRDE)) { | ||
374 | /* Disable both directions and reset their FIFOs */ | 371 | /* Disable both directions and reset their FIFOs */ |
375 | regmap_update_bits(sai->regmap, FSL_SAI_TCSR, | 372 | regmap_update_bits(sai->regmap, FSL_SAI_TCSR, |
376 | FSL_SAI_CSR_TERE | FSL_SAI_CSR_FR, | 373 | FSL_SAI_CSR_TERE, 0); |
377 | FSL_SAI_CSR_FR); | 374 | regmap_update_bits(sai->regmap, FSL_SAI_RCSR, |
375 | FSL_SAI_CSR_TERE, 0); | ||
376 | |||
377 | /* TERE will remain set till the end of current frame */ | ||
378 | do { | ||
379 | udelay(10); | ||
380 | regmap_read(sai->regmap, FSL_SAI_xCSR(tx), &xcsr); | ||
381 | } while (--count && xcsr & FSL_SAI_CSR_TERE); | ||
382 | |||
383 | regmap_update_bits(sai->regmap, FSL_SAI_TCSR, | ||
384 | FSL_SAI_CSR_FR, FSL_SAI_CSR_FR); | ||
378 | regmap_update_bits(sai->regmap, FSL_SAI_RCSR, | 385 | regmap_update_bits(sai->regmap, FSL_SAI_RCSR, |
379 | FSL_SAI_CSR_TERE | FSL_SAI_CSR_FR, | 386 | FSL_SAI_CSR_FR, FSL_SAI_CSR_FR); |
380 | FSL_SAI_CSR_FR); | ||
381 | } | 387 | } |
382 | break; | 388 | break; |
383 | default: | 389 | default: |