diff options
author | Misael Lopez Cruz | 2013-06-26 02:42:04 -0500 |
---|---|---|
committer | Misael Lopez Cruz | 2013-07-22 14:43:09 -0500 |
commit | 800447757970875a01a5b268ece0c83808d0903a (patch) | |
tree | 8ffac8673ddf06b3401b82f9ee659933d0f04761 | |
parent | c01aab89dc75e139d8762b058f419490c6a3dad4 (diff) | |
download | kernel-audio-800447757970875a01a5b268ece0c83808d0903a.tar.gz kernel-audio-800447757970875a01a5b268ece0c83808d0903a.tar.xz kernel-audio-800447757970875a01a5b268ece0c83808d0903a.zip |
ASoC: davinci-mcasp: Enable TX FSG for master mode
McASP is configured by default in synchronous mode so the TX frame sync
is also used for RX. If McASP is also in master mode (for FSYNC), the
transmit FSG needs to be running to provide the frame sync needed for RX.
In some cases, AFSR/ACLKR pins are not even used so AFSX/ACLKX pins have
to be active for RX too, this requires TX clock dividers to be released
from reset.
Change-Id: Iff0b7b93ed2665b7da8219e435fece512c4551e8
Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com>
-rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index b215c0b2ae50..6ec241335cc3 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -348,8 +348,24 @@ static inline void mcasp_set_ctl_reg(void __iomem *regs, u32 val) | |||
348 | 348 | ||
349 | static void mcasp_start_rx(struct davinci_audio_dev *dev) | 349 | static void mcasp_start_rx(struct davinci_audio_dev *dev) |
350 | { | 350 | { |
351 | u32 rxfmctl = mcasp_get_reg(dev->base + DAVINCI_MCASP_RXFMCTL_REG); | ||
352 | |||
351 | mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST); | 353 | mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST); |
352 | mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXCLKRST); | 354 | mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXCLKRST); |
355 | |||
356 | /* | ||
357 | * Enable TX FSG when McASP is in sync mode and is master since the | ||
358 | * TX section provides FSYNC for RX too. TX clk dividers are also | ||
359 | * enabled for cases where ACLKR pin is not connected (typically | ||
360 | * done when AFSR is not used either) | ||
361 | */ | ||
362 | if (rxfmctl & AFSRE) { | ||
363 | mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, | ||
364 | TXHCLKRST); | ||
365 | mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, | ||
366 | TXCLKRST); | ||
367 | } | ||
368 | |||
353 | mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSERCLR); | 369 | mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSERCLR); |
354 | mcasp_set_reg(dev->base + DAVINCI_MCASP_RXBUF_REG, 0); | 370 | mcasp_set_reg(dev->base + DAVINCI_MCASP_RXBUF_REG, 0); |
355 | 371 | ||
@@ -359,6 +375,10 @@ static void mcasp_start_rx(struct davinci_audio_dev *dev) | |||
359 | 375 | ||
360 | mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSMRST); | 376 | mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSMRST); |
361 | mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXFSRST); | 377 | mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXFSRST); |
378 | |||
379 | if (rxfmctl & AFSRE) | ||
380 | mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, | ||
381 | TXFSRST); | ||
362 | } | 382 | } |
363 | 383 | ||
364 | static void mcasp_start_tx(struct davinci_audio_dev *dev) | 384 | static void mcasp_start_tx(struct davinci_audio_dev *dev) |
@@ -431,13 +451,28 @@ static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) | |||
431 | 451 | ||
432 | static void mcasp_stop_rx(struct davinci_audio_dev *dev) | 452 | static void mcasp_stop_rx(struct davinci_audio_dev *dev) |
433 | { | 453 | { |
454 | u32 gblctl = mcasp_get_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG); | ||
455 | u32 rxfmctl = mcasp_get_reg(dev->base + DAVINCI_MCASP_RXFMCTL_REG); | ||
456 | |||
457 | /* Disable TX FSG if RX was the only active user */ | ||
458 | if ((rxfmctl & AFSRE) && !(gblctl & TXSMRST)) | ||
459 | mcasp_set_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, 0); | ||
460 | |||
434 | mcasp_set_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, 0); | 461 | mcasp_set_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, 0); |
435 | mcasp_set_reg(dev->base + DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF); | 462 | mcasp_set_reg(dev->base + DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF); |
436 | } | 463 | } |
437 | 464 | ||
438 | static void mcasp_stop_tx(struct davinci_audio_dev *dev) | 465 | static void mcasp_stop_tx(struct davinci_audio_dev *dev) |
439 | { | 466 | { |
440 | mcasp_set_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, 0); | 467 | u32 gblctl = mcasp_get_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG); |
468 | u32 rxfmctl = mcasp_get_reg(dev->base + DAVINCI_MCASP_RXFMCTL_REG); | ||
469 | u32 val = 0; | ||
470 | |||
471 | /* Keep FSG active until RX section is stopped too */ | ||
472 | if ((rxfmctl & AFSRE) && (gblctl & RXSMRST)) | ||
473 | val = TXHCLKRST | TXCLKRST | TXFSRST; | ||
474 | |||
475 | mcasp_set_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, val); | ||
441 | mcasp_set_reg(dev->base + DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF); | 476 | mcasp_set_reg(dev->base + DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF); |
442 | } | 477 | } |
443 | 478 | ||