ASoC: fsl-sai: set xCR4/xCR5/xMR for SAI master mode
diff mbox

Message ID 090f3aafd8c07a5a29e97c568c6fc0602a0bd5ad.1447066800.git.zidan.wang@freescale.com
State Accepted
Commit 51659ca069ce5bdf20675a7967a39ef8419e87f2
Headers show

Commit Message

Zidan Wang Nov. 9, 2015, 11:03 a.m. UTC
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>
---
 sound/soc/fsl/fsl_sai.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

Comments

Nicolin Chen Nov. 15, 2015, 3:13 a.m. UTC | #1
On Mon, Nov 09, 2015 at 07:03:13PM +0800, Zidan Wang wrote:
> 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>

> ---
>  sound/soc/fsl/fsl_sai.c | 29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
> index 14c3078..9d74ff3 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);
> -- 
> 1.9.1
>

Patch
diff mbox

diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 14c3078..9d74ff3 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);