From 1c21a97839ca990065a25ed29b8ba5ca38a42d2b Mon Sep 17 00:00:00 2001 From: Daniel Baluta <daniel.baluta@nxp.com> Date: Sat, 31 Aug 2019 01:55:14 +0300 Subject: [PATCH] ASoC: fsl_sai: Set SAI Channel Mode to Output Mode From SAI datasheet: CHMOD, configures if transmit data pins are configured for TDM mode or Output mode. * (0) TDM mode, transmit data pins are tri-stated when slots are masked or channels are disabled. * (1) Output mode, transmit data pins are never tri-stated and will output zero when slots are masked or channels are disabled. When data pins are tri-stated, there is noise on some channels when FS clock value is high and data is read while fsclk is transitioning from high to low. Fix this by setting CHMOD to Output Mode so that pins will output zero when slots are masked or channels are disabled. Cc: NXP Linux Team <linux-imx@nxp.com> Signed-off-by: Cosmin-Gabriel Samoila <cosmin.samoila@nxp.com> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com> --- sound/soc/fsl/fsl_sai.c | 15 ++++++++++++--- sound/soc/fsl/fsl_sai.h | 2 ++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 54bc4752f95c9..e2face0a2ffdc 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -524,6 +524,12 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, val_cr4 |= FSL_SAI_CR4_FRSZ(slots); + /* + * set CHMOD to Output Mode so that transmit data pins will + * output zero when slots are masked or channels are disabled + */ + val_cr4 |= FSL_SAI_CR4_CHMOD; + /* * 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), @@ -534,14 +540,16 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, if (!sai->slave_mode[tx]) { if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) { regmap_update_bits(sai->regmap, FSL_SAI_TCR4(offset), - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, + FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK | + FSL_SAI_CR4_CHMOD_MASK, val_cr4); regmap_update_bits(sai->regmap, FSL_SAI_TCR5(offset), FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | FSL_SAI_CR5_FBT_MASK, val_cr5); } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) { regmap_update_bits(sai->regmap, FSL_SAI_RCR4(offset), - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, + FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK | + FSL_SAI_CR4_CHMOD_MASK, val_cr4); regmap_update_bits(sai->regmap, FSL_SAI_RCR5(offset), FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | @@ -559,7 +567,8 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, } regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset), - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, + FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK | + FSL_SAI_CR4_CHMOD_MASK, val_cr4); regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, offset), FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index 290b87acb2ff5..6548f797dc581 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -108,6 +108,8 @@ #define FSL_SAI_CR4_FRSZ_MASK (0x1f << 16) #define FSL_SAI_CR4_SYWD(x) (((x) - 1) << 8) #define FSL_SAI_CR4_SYWD_MASK (0x1f << 8) +#define FSL_SAI_CR4_CHMOD BIT(5) +#define FSL_SAI_CR4_CHMOD_MASK GENMASK(5, 5) #define FSL_SAI_CR4_MF BIT(4) #define FSL_SAI_CR4_FSE BIT(3) #define FSL_SAI_CR4_FSP BIT(1) -- GitLab