summaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl
diff options
context:
space:
mode:
authorZidan Wang <zidan.wang@freescale.com>2015-11-09 19:03:13 +0800
committerMark Brown <broonie@kernel.org>2015-11-17 18:51:39 +0000
commit51659ca069ce5bdf20675a7967a39ef8419e87f2 (patch)
tree7360e08ba6befe3d51b9ac0597f24493d6dab6c7 /sound/soc/fsl
parent9cc58712358cbfe51248ef369fc50671149b60fc (diff)
downloadlinux-stable-51659ca069ce5bdf20675a7967a39ef8419e87f2.tar.gz
linux-stable-51659ca069ce5bdf20675a7967a39ef8419e87f2.tar.bz2
linux-stable-51659ca069ce5bdf20675a7967a39ef8419e87f2.zip
ASoC: fsl-sai: set xCR4/xCR5/xMR for SAI master mode
For SAI master mode, when Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will generate bclk and frame clock for Tx(Rx), we should set RCR4(TCR4), RCR5(TCR5) and RMR(TMR) for playback(capture), or there will be sync error sometimes. Signed-off-by: Zidan Wang <zidan.wang@freescale.com> Acked-by: Nicolin Chen <nicoleotsuka@gmail.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r--sound/soc/fsl/fsl_sai.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 7e421a97c090..520dbadaa8b1 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -427,6 +427,35 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
val_cr4 |= FSL_SAI_CR4_FRSZ(channels);
+ /*
+ * For SAI master mode, when Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will
+ * generate bclk and frame clock for Tx(Rx), we should set RCR4(TCR4),
+ * RCR5(TCR5) and RMR(TMR) for playback(capture), or there will be sync
+ * error.
+ */
+
+ if (!sai->is_slave_mode) {
+ if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) {
+ regmap_update_bits(sai->regmap, FSL_SAI_TCR4,
+ FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
+ val_cr4);
+ regmap_update_bits(sai->regmap, FSL_SAI_TCR5,
+ FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
+ FSL_SAI_CR5_FBT_MASK, val_cr5);
+ regmap_write(sai->regmap, FSL_SAI_TMR,
+ ~0UL - ((1 << channels) - 1));
+ } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) {
+ regmap_update_bits(sai->regmap, FSL_SAI_RCR4,
+ FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
+ val_cr4);
+ regmap_update_bits(sai->regmap, FSL_SAI_RCR5,
+ FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
+ FSL_SAI_CR5_FBT_MASK, val_cr5);
+ regmap_write(sai->regmap, FSL_SAI_RMR,
+ ~0UL - ((1 << channels) - 1));
+ }
+ }
+
regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
val_cr4);