summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorNicolin Chen <Guangyu.Chen@freescale.com>2014-01-06 16:55:07 +0800
committerNicolin Chen <Guangyu.Chen@freescale.com>2014-01-16 19:27:49 +0800
commit6f77992ba7b282df9168de9cea1c9f3374cf23b0 (patch)
tree71144ad8889e6a2135a435323015f71055407669 /sound
parent51eb47421c36dbb4d7542cd79f6f2e63e9e0df4a (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.c11
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;
}