diff options
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 537dc69256f0..88baaf3f7a45 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -266,6 +266,7 @@ struct fsl_ssi { bool synchronous; bool use_dma; bool use_dual_fifo; + bool use_dyna_fifo; bool has_ipg_clk_name; unsigned int fifo_depth; unsigned int slot_width; @@ -644,7 +645,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, * task from fifo0, fifo1 would be neglected at the end of each * period. But SSI would still access fifo1 with an invalid data. */ - if (ssi->use_dual_fifo) + if (ssi->use_dual_fifo || ssi->use_dyna_fifo) snd_pcm_hw_constraint_step(substream->runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2); @@ -798,6 +799,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, unsigned int sample_size = params_width(hw_params); u32 wl = SSI_SxCCR_WL(sample_size); int ret; + struct fsl_ssi_regvals *vals = ssi->regvals; if (fsl_ssi_is_i2s_master(ssi)) { ret = fsl_ssi_set_bclk(substream, dai, hw_params); @@ -847,6 +849,24 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, tx2 = tx || ssi->synchronous; regmap_update_bits(regs, REG_SSI_SxCCR(tx2), SSI_SxCCR_WL_MASK, wl); + if (ssi->use_dyna_fifo) { + if (channels == 1) { + ssi->dma_params_tx.fifo_num = 1; + ssi->dma_params_rx.fifo_num = 1; + vals[RX].srcr &= ~SSI_SRCR_RFEN1; + vals[TX].stcr &= ~SSI_STCR_TFEN1; + vals[RX].scr &= ~SSI_SCR_TCH_EN; + vals[TX].scr &= ~SSI_SCR_TCH_EN; + } else { + ssi->dma_params_tx.fifo_num = 2; + ssi->dma_params_rx.fifo_num = 2; + vals[RX].srcr |= SSI_SRCR_RFEN1; + vals[TX].stcr |= SSI_STCR_TFEN1; + vals[RX].scr |= SSI_SCR_TCH_EN; + vals[TX].scr |= SSI_SCR_TCH_EN; + } + } + return 0; } @@ -1324,6 +1344,8 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev, dev_dbg(dev, "failed to get baud clock: %ld\n", PTR_ERR(ssi->baudclk)); + ssi->dma_params_rx.chan_name = "rx"; + ssi->dma_params_tx.chan_name = "tx"; ssi->dma_params_tx.maxburst = ssi->dma_maxburst; ssi->dma_params_rx.maxburst = ssi->dma_maxburst; ssi->dma_params_tx.addr = ssi->ssi_phys + REG_SSI_STX0; @@ -1349,7 +1371,7 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev, if (ret) goto error_pcm; } else { - ret = imx_pcm_dma_init(pdev, IMX_SSI_DMABUF_SIZE); + ret = imx_pcm_platform_register(&pdev->dev); if (ret) goto error_pcm; } @@ -1430,6 +1452,8 @@ static int fsl_ssi_probe_from_dt(struct fsl_ssi *ssi) if (ssi->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) ssi->use_dual_fifo = true; + if (ssi->use_dma && !ret && dmas[2] == IMX_DMATYPE_MULTI_SAI) + ssi->use_dyna_fifo = true; /* * Backward compatible for older bindings by manually triggering the * machine driver's probe(). Use /compatible property, including the |