diff options
author | Nicolin Chen <Guangyu.Chen@freescale.com> | 2014-01-06 16:55:07 +0800 |
---|---|---|
committer | Nicolin Chen <Guangyu.Chen@freescale.com> | 2014-01-16 19:27:49 +0800 |
commit | 6f77992ba7b282df9168de9cea1c9f3374cf23b0 (patch) | |
tree | 71144ad8889e6a2135a435323015f71055407669 /sound | |
parent | 51eb47421c36dbb4d7542cd79f6f2e63e9e0df4a (diff) |
ENGR00295423-3 ASoC: fsl_ssi: Don't disable SSIEN if SSI is already enabled
If disabling SSI when SSI is already in the working state, the whole running
substream would be broken. Thus we here replace it to a safer way -- saving
the current SSIEN value and restore it afterward.
This patch also adds a slot number checking code before setting slot number.
Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
(cherry picked from commit 2f71335a5b39afec4cf976b45683e5de1baed31d)
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 46f574895f73..0d711544c023 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -756,6 +756,14 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, { struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); struct ccsr_ssi __iomem *ssi = ssi_private->ssi; + u32 val; + + /* The slot number should be >= 2 if using Network mode or I2S mode */ + val = read_ssi(&ssi->scr) & (CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_NET); + if (val && slots < 2) { + dev_err(cpu_dai->dev, "slot number should be >= 2 in I2S or NET\n"); + return -EINVAL; + } write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK, CCSR_SSI_SxCCR_DC(slots)); @@ -765,10 +773,11 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, /* The register SxMSKs need SSI to provide essential clock due to * hardware design. So we here temporarily enable SSI to set them. */ + val = read_ssi(&ssi->scr) & CCSR_SSI_SCR_SSIEN; write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN); write_ssi(tx_mask, &ssi->stmsk); write_ssi(rx_mask, &ssi->srmsk); - write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0); + write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, val); return 0; } |