From 24a3bee2e17b29cbeb0517a86e8822c5e1ac0884 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 28 Sep 2018 15:16:57 +0800 Subject: MLK-15975-1: ASoC: fsl_ssi: support multi fifo script With dual fifo enabled, the case recording mono sound in the background, playback sound twice in parallal, the second time playback sound may distort, the possible reason is using dual fifo to playback mono sound is not recommended. This patch is to provide a option to use multi fifo script, which can be dynamically configured as one fifo or two fifo mode. Signed-off-by: Shengjiu Wang (cherry picked from commit 9d71068cf7d1fc1ec36e5fb34a321c1bdbaad324) --- sound/soc/fsl/fsl_ssi.c | 28 ++++++++++++++++++++++++++-- 1 file 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 -- cgit v1.2.3 From f25a2423464bfb3e352c6a898f9e51e1e31895d1 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 22 Nov 2019 15:45:33 +0800 Subject: LF-106: ASoC: fsl_ssi: request BUS_FREQ_AUDIO request BUS_FREQ_AUDIO Signed-off-by: Shengjiu Wang --- sound/soc/fsl/fsl_ssi.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 88baaf3f7a45..c3c760067b50 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include #include @@ -1572,6 +1574,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) } dev_set_drvdata(dev, ssi); + pm_runtime_enable(&pdev->dev); if (ssi->soc->imx) { ret = fsl_ssi_imx_probe(pdev, ssi, iomem); @@ -1671,6 +1674,20 @@ static int fsl_ssi_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int fsl_ssi_runtime_resume(struct device *dev) +{ + request_bus_freq(BUS_FREQ_AUDIO); + return 0; +} + +static int fsl_ssi_runtime_suspend(struct device *dev) +{ + release_bus_freq(BUS_FREQ_AUDIO); + return 0; +} +#endif + #ifdef CONFIG_PM_SLEEP static int fsl_ssi_suspend(struct device *dev) { @@ -1705,6 +1722,8 @@ static int fsl_ssi_resume(struct device *dev) static const struct dev_pm_ops fsl_ssi_pm = { SET_SYSTEM_SLEEP_PM_OPS(fsl_ssi_suspend, fsl_ssi_resume) + SET_RUNTIME_PM_OPS(fsl_ssi_runtime_suspend, fsl_ssi_runtime_resume, + NULL) }; static struct platform_driver fsl_ssi_driver = { -- cgit v1.2.3