summaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@nxp.com>2020-09-01 19:01:08 +0800
committerMark Brown <broonie@kernel.org>2020-09-03 14:47:36 +0100
commit770f58d7d2c58b8ff31d3694ce14a785c2e75009 (patch)
tree453f8c1bf89a100c4613650b06828bb8164d8a03 /sound/soc/fsl
parenta57307ca6b661e16f9435a25f376ac277c3de697 (diff)
downloadlinux-stable-770f58d7d2c58b8ff31d3694ce14a785c2e75009.tar.gz
linux-stable-770f58d7d2c58b8ff31d3694ce14a785c2e75009.tar.bz2
linux-stable-770f58d7d2c58b8ff31d3694ce14a785c2e75009.zip
ASoC: fsl_sai: Support multiple data channel enable bits
One data channel is one data line. From imx7ulp, the SAI IP is enhanced to support multiple data channels. If there is only two channels input and slots is 2, then enable one data channel is enough for data transfer. So enable the TCE/RCE and transmit/receive mask register according to the input channels and slots configuration. Move the data channel enablement from startup() to hw_params(). Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com> Acked-by: Nicolin Chen <nicoleotsuka@gmail.com> Link: https://lore.kernel.org/r/1598958068-10552-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r--sound/soc/fsl/fsl_sai.c30
-rw-r--r--sound/soc/fsl/fsl_sai.h2
2 files changed, 13 insertions, 19 deletions
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 62c5fdb678fc..38c7bcbb361d 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -443,6 +443,7 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
u32 slots = (channels == 1) ? 2 : channels;
u32 slot_width = word_width;
int adir = tx ? RX : TX;
+ u32 pins;
int ret;
if (sai->slots)
@@ -451,6 +452,8 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
if (sai->slot_width)
slot_width = sai->slot_width;
+ pins = DIV_ROUND_UP(channels, slots);
+
if (!sai->is_slave_mode) {
if (sai->bclk_ratio)
ret = fsl_sai_set_bclk(cpu_dai, tx,
@@ -501,13 +504,17 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
FSL_SAI_CR5_FBT_MASK, val_cr5);
}
+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),
+ FSL_SAI_CR3_TRCE_MASK,
+ FSL_SAI_CR3_TRCE((1 << pins) - 1));
regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
val_cr4);
regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs),
FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
FSL_SAI_CR5_FBT_MASK, val_cr5);
- regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << channels) - 1));
+ regmap_write(sai->regmap, FSL_SAI_xMR(tx),
+ ~0UL - ((1 << min(channels, slots)) - 1));
return 0;
}
@@ -517,6 +524,10 @@ static int fsl_sai_hw_free(struct snd_pcm_substream *substream,
{
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ unsigned int ofs = sai->soc_data->reg_offset;
+
+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),
+ FSL_SAI_CR3_TRCE_MASK, 0);
if (!sai->is_slave_mode &&
sai->mclk_streams & BIT(substream->stream)) {
@@ -651,14 +662,9 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned int ofs = sai->soc_data->reg_offset;
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
int ret;
- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),
- FSL_SAI_CR3_TRCE_MASK,
- FSL_SAI_CR3_TRCE);
-
/*
* EDMA controller needs period size to be a multiple of
* tx/rx maxburst
@@ -675,17 +681,6 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
return ret;
}
-static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *cpu_dai)
-{
- struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned int ofs = sai->soc_data->reg_offset;
- bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
-
- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),
- FSL_SAI_CR3_TRCE_MASK, 0);
-}
-
static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
.set_bclk_ratio = fsl_sai_set_dai_bclk_ratio,
.set_sysclk = fsl_sai_set_dai_sysclk,
@@ -695,7 +690,6 @@ static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
.hw_free = fsl_sai_hw_free,
.trigger = fsl_sai_trigger,
.startup = fsl_sai_startup,
- .shutdown = fsl_sai_shutdown,
};
static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index 6aba7d28f5f3..5f630be74853 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -109,7 +109,7 @@
#define FSL_SAI_CR2_DIV_MASK 0xff
/* SAI Transmit and Receive Configuration 3 Register */
-#define FSL_SAI_CR3_TRCE BIT(16)
+#define FSL_SAI_CR3_TRCE(x) ((x) << 16)
#define FSL_SAI_CR3_TRCE_MASK GENMASK(23, 16)
#define FSL_SAI_CR3_WDFL(x) (x)
#define FSL_SAI_CR3_WDFL_MASK 0x1f