diff options
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r-- | sound/soc/fsl/fsl_sai.c | 17 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_sai.h | 1 |
2 files changed, 16 insertions, 2 deletions
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 4f5bd9597c74..d11ee3b6f163 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -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); diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index 1c8f5ca07f9d..bc2a86a413e1 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -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]; |