diff options
Diffstat (limited to 'sound/soc/fsl/fsl_sai.c')
-rw-r--r-- | sound/soc/fsl/fsl_sai.c | 90 |
1 files changed, 62 insertions, 28 deletions
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index ed2b4780c470..af1a168d35e3 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -163,14 +163,46 @@ out: return iret; } -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) +static int fsl_sai_set_dai_tdm_slot_tx(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); + bool tx = true; + + sai->slots[tx] = slots; + sai->slot_width[tx] = slot_width; + + return 0; +} + +static int fsl_sai_set_dai_tdm_slot_rx(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); + bool tx = false; + + sai->slots[tx] = slots; + sai->slot_width[tx] = slot_width; + + return 0; +} + +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) +{ + int ret; + + ret = fsl_sai_set_dai_tdm_slot_tx(cpu_dai, tx_mask, rx_mask, slots, slot_width); + if (ret) + return ret; - sai->slots = slots; - sai->slot_width = slot_width; + return fsl_sai_set_dai_tdm_slot_rx(cpu_dai, tx_mask, rx_mask, slots, slot_width); +} +static int fsl_sai_xlate_tdm_slot_mask(unsigned int slots, + unsigned int *tx_mask, unsigned int *rx_mask) +{ + /* Leave it empty, don't change the value of tx_mask and rx_mask */ return 0; } @@ -238,22 +270,22 @@ static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, if (dir == SND_SOC_CLOCK_IN) return 0; - if (freq > 0 && clk_id != FSL_SAI_CLK_BUS) { - if (clk_id < 0 || clk_id >= FSL_SAI_MCLK_MAX) { - dev_err(cpu_dai->dev, "Unknown clock id: %d\n", clk_id); - return -EINVAL; - } + if (clk_id < 0 || clk_id >= FSL_SAI_MCLK_MAX) { + dev_err(cpu_dai->dev, "Unknown clock id: %d\n", clk_id); + return -EINVAL; + } - if (IS_ERR_OR_NULL(sai->mclk_clk[clk_id])) { - dev_err(cpu_dai->dev, "Unassigned clock: %d\n", clk_id); - return -EINVAL; - } + if (IS_ERR_OR_NULL(sai->mclk_clk[clk_id])) { + dev_err(cpu_dai->dev, "Unassigned clock: %d\n", clk_id); + return -EINVAL; + } - if (sai->mclk_streams == 0) { - ret = fsl_sai_set_mclk_rate(cpu_dai, clk_id, freq); - if (ret < 0) - return ret; - } + if (sai->mclk_streams == 0 && freq > 0) { + ret = fsl_sai_set_mclk_rate(cpu_dai, + clk_id ? clk_id : FSL_SAI_CLK_MAST1, + freq); + if (ret < 0) + return ret; } ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, true); @@ -280,7 +312,7 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, val_cr4 |= FSL_SAI_CR4_MF; sai->is_pdm_mode = false; - sai->is_dsp_mode = false; + sai->is_dsp_mode[tx] = false; /* DAI mode */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: @@ -309,7 +341,7 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, */ val_cr2 |= FSL_SAI_CR2_BCP; val_cr4 |= FSL_SAI_CR4_FSE; - sai->is_dsp_mode = true; + sai->is_dsp_mode[tx] = true; break; case SND_SOC_DAIFMT_DSP_B: /* @@ -317,7 +349,7 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, * frame sync asserts with the first bit of the frame. */ val_cr2 |= FSL_SAI_CR2_BCP; - sai->is_dsp_mode = true; + sai->is_dsp_mode[tx] = true; break; case SND_SOC_DAIFMT_PDM: val_cr2 |= FSL_SAI_CR2_BCP; @@ -541,11 +573,11 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, u32 watermark; int ret, i; - if (sai->slot_width) - slot_width = sai->slot_width; + if (sai->slot_width[tx]) + slot_width = sai->slot_width[tx]; - if (sai->slots) - slots = sai->slots; + if (sai->slots[tx]) + slots = sai->slots[tx]; else if (sai->bclk_ratio) slots = sai->bclk_ratio / slot_width; @@ -600,7 +632,7 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, } } - if (!sai->is_dsp_mode && !sai->is_pdm_mode) + if (!sai->is_dsp_mode[tx] && !sai->is_pdm_mode) val_cr4 |= FSL_SAI_CR4_SYWD(slot_width); val_cr5 |= FSL_SAI_CR5_WNW(slot_width); @@ -932,7 +964,8 @@ static const struct snd_soc_dai_ops fsl_sai_pcm_dai_tx_ops = { .set_bclk_ratio = fsl_sai_set_dai_bclk_ratio, .set_sysclk = fsl_sai_set_dai_sysclk, .set_fmt = fsl_sai_set_dai_fmt_tx, - .set_tdm_slot = fsl_sai_set_dai_tdm_slot, + .set_tdm_slot = fsl_sai_set_dai_tdm_slot_tx, + .xlate_tdm_slot_mask = fsl_sai_xlate_tdm_slot_mask, .hw_params = fsl_sai_hw_params, .hw_free = fsl_sai_hw_free, .trigger = fsl_sai_trigger, @@ -944,7 +977,8 @@ static const struct snd_soc_dai_ops fsl_sai_pcm_dai_rx_ops = { .set_bclk_ratio = fsl_sai_set_dai_bclk_ratio, .set_sysclk = fsl_sai_set_dai_sysclk, .set_fmt = fsl_sai_set_dai_fmt_rx, - .set_tdm_slot = fsl_sai_set_dai_tdm_slot, + .set_tdm_slot = fsl_sai_set_dai_tdm_slot_rx, + .xlate_tdm_slot_mask = fsl_sai_xlate_tdm_slot_mask, .hw_params = fsl_sai_hw_params, .hw_free = fsl_sai_hw_free, .trigger = fsl_sai_trigger, |