]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
ASoC: fsl_sai: Support multiple data channel enable bits
authorShengjiu Wang <shengjiu.wang@nxp.com>
Tue, 1 Sep 2020 11:01:08 +0000 (19:01 +0800)
committerMark Brown <broonie@kernel.org>
Thu, 3 Sep 2020 13:47:36 +0000 (14:47 +0100)
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>
sound/soc/fsl/fsl_sai.c
sound/soc/fsl/fsl_sai.h

index 62c5fdb678fc4c1498326d5cf5af54e3b1703539..38c7bcbb361d3728a6185abf35aa67d7ab1e322b 100644 (file)
@@ -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)
index 6aba7d28f5f344ab641dc3e247786ebd2a80510b..5f630be748531e609582a5e260d0ae0270be65d4 100644 (file)
 #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