]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ASoC: fsl_sai: Add PDM daifmt support
authorShengjiu Wang <shengjiu.wang@nxp.com>
Fri, 17 Jun 2022 07:44:31 +0000 (15:44 +0800)
committerMark Brown <broonie@kernel.org>
Mon, 27 Jun 2022 12:18:06 +0000 (13:18 +0100)
PDM format is used for 1-bit stream, so clear the FBT and SYWD,
and the each dataline only has one channel data.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Link: https://lore.kernel.org/r/1655451877-16382-2-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 4f5bd9597c746a9fdfdd816741e1d191ede803d9..d11ee3b6f1639fac166e57aeb790bac347a1154b 100644 (file)
@@ -224,6 +224,7 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
        if (!sai->is_lsb_first)
                val_cr4 |= FSL_SAI_CR4_MF;
 
+       sai->is_pdm_mode = false;
        /* DAI mode */
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
@@ -262,6 +263,11 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
                val_cr2 |= FSL_SAI_CR2_BCP;
                sai->is_dsp_mode = true;
                break;
+       case SND_SOC_DAIFMT_PDM:
+               val_cr2 |= FSL_SAI_CR2_BCP;
+               val_cr4 &= ~FSL_SAI_CR4_MF;
+               sai->is_pdm_mode = true;
+               break;
        case SND_SOC_DAIFMT_RIGHT_J:
                /* To be done */
        default:
@@ -470,6 +476,13 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
 
        pins = DIV_ROUND_UP(channels, slots);
 
+       /*
+        * PDM mode, channels are independent
+        * each channels are on one dataline/FIFO.
+        */
+       if (sai->is_pdm_mode)
+               pins = channels;
+
        if (!sai->is_consumer_mode) {
                if (sai->bclk_ratio)
                        ret = fsl_sai_set_bclk(cpu_dai, tx,
@@ -492,13 +505,13 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
                }
        }
 
-       if (!sai->is_dsp_mode)
+       if (!sai->is_dsp_mode && !sai->is_pdm_mode)
                val_cr4 |= FSL_SAI_CR4_SYWD(slot_width);
 
        val_cr5 |= FSL_SAI_CR5_WNW(slot_width);
        val_cr5 |= FSL_SAI_CR5_W0W(slot_width);
 
-       if (sai->is_lsb_first)
+       if (sai->is_lsb_first || sai->is_pdm_mode)
                val_cr5 |= FSL_SAI_CR5_FBT(0);
        else
                val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1);
index 1c8f5ca07f9d0fda6e605ede13200d1d9d6aff7a..bc2a86a413e1055104f6191a40b2e880b86160b9 100644 (file)
@@ -259,6 +259,7 @@ struct fsl_sai {
        bool is_consumer_mode;
        bool is_lsb_first;
        bool is_dsp_mode;
+       bool is_pdm_mode;
        bool synchronous[2];
 
        unsigned int mclk_id[2];