Commit b7b01d34 authored by Benoît Thébaudeau's avatar Benoît Thébaudeau Committed by Mark Brown

ASoC: imx-ssi: Fix DAI hardware signal inversions

SND_SOC_DAIFMT_{IB|NB}_{IF|NF} are defined as inverting or not BCLK or
FRM relatively to what is standard for the specified DAI hardware audio
format. Consequently, the absolute polarities of these signals cannot be
derived only from these settings as this driver did. The format has to
be taken into account too.

This fixes inverted left/right channels in I²S mode.
Signed-off-by: default avatarBenoît Thébaudeau <benoit@wsystem.com>
Acked-by: default avatarNicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 6ff33f39
...@@ -95,7 +95,8 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) ...@@ -95,7 +95,8 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S: case SND_SOC_DAIFMT_I2S:
/* data on rising edge of bclk, frame low 1clk before data */ /* data on rising edge of bclk, frame low 1clk before data */
strcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0; strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP | SSI_STCR_TFSI |
SSI_STCR_TEFS;
scr |= SSI_SCR_NET; scr |= SSI_SCR_NET;
if (ssi->flags & IMX_SSI_USE_I2S_SLAVE) { if (ssi->flags & IMX_SSI_USE_I2S_SLAVE) {
scr &= ~SSI_I2S_MODE_MASK; scr &= ~SSI_I2S_MODE_MASK;
...@@ -104,33 +105,31 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) ...@@ -104,33 +105,31 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
break; break;
case SND_SOC_DAIFMT_LEFT_J: case SND_SOC_DAIFMT_LEFT_J:
/* data on rising edge of bclk, frame high with data */ /* data on rising edge of bclk, frame high with data */
strcr |= SSI_STCR_TXBIT0; strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP;
break; break;
case SND_SOC_DAIFMT_DSP_B: case SND_SOC_DAIFMT_DSP_B:
/* data on rising edge of bclk, frame high with data */ /* data on rising edge of bclk, frame high with data */
strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0; strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP | SSI_STCR_TFSL;
break; break;
case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_A:
/* data on rising edge of bclk, frame high 1clk before data */ /* data on rising edge of bclk, frame high 1clk before data */
strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0 | SSI_STCR_TEFS; strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP | SSI_STCR_TFSL |
SSI_STCR_TEFS;
break; break;
} }
/* DAI clock inversion */ /* DAI clock inversion */
switch (fmt & SND_SOC_DAIFMT_INV_MASK) { switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_IB_IF: case SND_SOC_DAIFMT_IB_IF:
strcr |= SSI_STCR_TFSI; strcr ^= SSI_STCR_TSCKP | SSI_STCR_TFSI;
strcr &= ~SSI_STCR_TSCKP;
break; break;
case SND_SOC_DAIFMT_IB_NF: case SND_SOC_DAIFMT_IB_NF:
strcr &= ~(SSI_STCR_TSCKP | SSI_STCR_TFSI); strcr ^= SSI_STCR_TSCKP;
break; break;
case SND_SOC_DAIFMT_NB_IF: case SND_SOC_DAIFMT_NB_IF:
strcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP; strcr ^= SSI_STCR_TFSI;
break; break;
case SND_SOC_DAIFMT_NB_NF: case SND_SOC_DAIFMT_NB_NF:
strcr &= ~SSI_STCR_TFSI;
strcr |= SSI_STCR_TSCKP;
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment