summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@nxp.com>2017-03-08 19:44:47 +0200
committerAnson Huang <Anson.Huang@nxp.com>2017-06-08 21:00:38 +0800
commit044b1c44c907d2054b470f88d2442a2e67d0e504 (patch)
treeb2e2477435956a5295fede00964acc3c3b3529a6 /sound
parentac337e78f0a6629039f97ef1838faa20cd845e22 (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.c15
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) {