diff options
author | Shengjiu Wang <shengjiu.wang@nxp.com> | 2017-03-08 19:44:47 +0200 |
---|---|---|
committer | Anson Huang <Anson.Huang@nxp.com> | 2017-06-08 21:00:38 +0800 |
commit | 044b1c44c907d2054b470f88d2442a2e67d0e504 (patch) | |
tree | b2e2477435956a5295fede00964acc3c3b3529a6 /sound | |
parent | ac337e78f0a6629039f97ef1838faa20cd845e22 (diff) |
MLK-14316 ASoC: fsl_ssi: Fix playback and capture with mono stream
After starting playback with a single channel SSI runs in Normal mode
(SCR.net = 0b, SCR.i2s_mode = 00b). But, if starting also capture
in parallel with playback the SSI mode changes which breaks the playback.
This happens because, we can change SSI mode from two distinct places:
* _fsl_ssi_set_dai_fmt
* fsl_ssi_hw_params
When running playback and capture in parallel for a mono channel, changing
hw params for the second stream will have no effect.
This patch allows changing the mode only from fsl_ssi_hw_parms so that
we have an atomic view of SSI mode.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 6791ef7038d4..c64a0c3869af 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -845,6 +845,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, int ret; u32 scr_val; int enabled; + u8 i2smode = ssi_private->i2s_mode; regmap_read(regs, CCSR_SSI_SCR, &scr_val); enabled = scr_val & CCSR_SSI_SCR_SSIEN; @@ -872,7 +873,6 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, } if (!fsl_ssi_is_ac97(ssi_private)) { - u8 i2smode; /* * Switch to normal net mode in order to have a frame sync * signal every 32 bits instead of 16 bits @@ -880,14 +880,14 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, if (fsl_ssi_is_i2s_cbm_cfs(ssi_private) && sample_size == 16) i2smode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET; - else - i2smode = ssi_private->i2s_mode; - - regmap_update_bits(regs, CCSR_SSI_SCR, - CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK, - channels == 1 ? 0 : i2smode); + if (channels == 1) + i2smode = 0; } + regmap_update_bits(regs, CCSR_SSI_SCR, + CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK, + i2smode); + /* * FIXME: The documentation says that SxCCR[WL] should not be * modified while the SSI is enabled. The only time this can @@ -1000,7 +1000,6 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev, default: return -EINVAL; } - scr |= ssi_private->i2s_mode; /* DAI clock inversion */ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |