diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/fsl/fsl_sai.c | 31 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_sai.h | 3 |
2 files changed, 28 insertions, 6 deletions
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 520dbadaa8b1..43ba5dc26775 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -126,6 +126,17 @@ out: return IRQ_HANDLED; } +static int fsl_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, + u32 rx_mask, int slots, int slot_width) +{ + struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); + + sai->slots = slots; + sai->slot_width = slot_width; + + return 0; +} + static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int fsl_dir) { @@ -395,11 +406,19 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, unsigned int channels = params_channels(params); u32 word_width = snd_pcm_format_width(params_format(params)); u32 val_cr4 = 0, val_cr5 = 0; + u32 slots = (channels == 1) ? 2 : channels; + u32 slot_width = word_width; int ret; + if (sai->slots) + slots = sai->slots; + + if (sai->slot_width) + slot_width = sai->slot_width; + if (!sai->is_slave_mode) { ret = fsl_sai_set_bclk(cpu_dai, tx, - 2 * word_width * params_rate(params)); + slots * slot_width * params_rate(params)); if (ret) return ret; @@ -411,21 +430,20 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, sai->mclk_streams |= BIT(substream->stream); } - } if (!sai->is_dsp_mode) - val_cr4 |= FSL_SAI_CR4_SYWD(word_width); + val_cr4 |= FSL_SAI_CR4_SYWD(slot_width); - val_cr5 |= FSL_SAI_CR5_WNW(word_width); - val_cr5 |= FSL_SAI_CR5_W0W(word_width); + val_cr5 |= FSL_SAI_CR5_WNW(slot_width); + val_cr5 |= FSL_SAI_CR5_W0W(slot_width); if (sai->is_lsb_first) val_cr5 |= FSL_SAI_CR5_FBT(0); else val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1); - val_cr4 |= FSL_SAI_CR4_FRSZ(channels); + val_cr4 |= FSL_SAI_CR4_FRSZ(slots); /* * For SAI master mode, when Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will @@ -591,6 +609,7 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream, static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { .set_sysclk = fsl_sai_set_dai_sysclk, .set_fmt = fsl_sai_set_dai_fmt, + .set_tdm_slot = fsl_sai_set_dai_tdm_slot, .hw_params = fsl_sai_hw_params, .hw_free = fsl_sai_hw_free, .trigger = fsl_sai_trigger, diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index b95fbc3f68eb..d9ed7be8cb34 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -143,6 +143,9 @@ struct fsl_sai { unsigned int mclk_id[2]; unsigned int mclk_streams; + unsigned int slots; + unsigned int slot_width; + struct snd_dmaengine_dai_dma_data dma_params_rx; struct snd_dmaengine_dai_dma_data dma_params_tx; }; |