summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@nxp.com>2018-09-28 15:16:57 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:34:19 +0800
commitfb0d364b23d248351072dbc53cf13039d77fea43 (patch)
treec768bc111bc63e740cca4a28c4e6068c84141cbb
parentfc1d47bfae5cbbb91b1517dd72ba42e66d55d903 (diff)
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 <shengjiu.wang@nxp.com> (cherry picked from commit 9d71068cf7d1fc1ec36e5fb34a321c1bdbaad324)
-rw-r--r--sound/soc/fsl/fsl_ssi.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 752b4af5f648..45e9de81cea9 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -234,6 +234,7 @@ struct fsl_ssi_private {
u8 i2s_mode;
bool use_dma;
bool use_dual_fifo;
+ bool use_dyna_fifo;
bool has_ipg_clk_name;
unsigned int fifo_depth;
struct fsl_ssi_rxtx_reg_val rxtx_reg_val;
@@ -677,7 +678,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_private->use_dual_fifo)
+ if (ssi_private->use_dual_fifo || ssi_private->use_dyna_fifo)
snd_pcm_hw_constraint_step(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2);
@@ -853,6 +854,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
u32 scr_val;
int enabled;
u8 i2smode = ssi_private->i2s_mode;
+ struct fsl_ssi_rxtx_reg_val *reg = &ssi_private->rxtx_reg_val;
if (fsl_ssi_is_i2s_master(ssi_private)) {
ret = fsl_ssi_set_bclk(substream, cpu_dai, hw_params);
@@ -914,6 +916,24 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
regmap_update_bits(regs, CCSR_SSI_SRCCR, CCSR_SSI_SxCCR_WL_MASK,
wl);
+ if (ssi_private->use_dyna_fifo) {
+ if (channels == 1) {
+ ssi_private->dma_params_tx.fifo_num = 1;
+ ssi_private->dma_params_rx.fifo_num = 1;
+ reg->rx.srcr &= ~CCSR_SSI_SRCR_RFEN1;
+ reg->tx.stcr &= ~CCSR_SSI_STCR_TFEN1;
+ reg->rx.scr &= ~CCSR_SSI_SCR_TCH_EN;
+ reg->tx.scr &= ~CCSR_SSI_SCR_TCH_EN;
+ } else {
+ ssi_private->dma_params_tx.fifo_num = 2;
+ ssi_private->dma_params_rx.fifo_num = 2;
+ reg->rx.srcr |= CCSR_SSI_SRCR_RFEN1;
+ reg->tx.stcr |= CCSR_SSI_STCR_TFEN1;
+ reg->rx.scr |= CCSR_SSI_SCR_TCH_EN;
+ reg->tx.scr |= CCSR_SSI_SCR_TCH_EN;
+ }
+ }
+
return 0;
}
@@ -1368,6 +1388,8 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
dev_dbg(&pdev->dev, "could not get baud clock: %ld\n",
PTR_ERR(ssi_private->baudclk));
+ ssi_private->dma_params_rx.chan_name = "rx";
+ ssi_private->dma_params_tx.chan_name = "tx";
ssi_private->dma_params_tx.maxburst = ssi_private->dma_maxburst;
ssi_private->dma_params_rx.maxburst = ssi_private->dma_maxburst;
ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + CCSR_SSI_STX0;
@@ -1383,6 +1405,9 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
ssi_private->dma_params_rx.maxburst &= ~0x1;
}
+ if (ssi_private->use_dma && !ret && dmas[2] == IMX_DMATYPE_MULTI_SAI)
+ ssi_private->use_dyna_fifo = true;
+
if (of_property_read_u32(np, "fsl,dma-buffer-size", &buffer_size))
buffer_size = IMX_SSI_DMABUF_SIZE;
@@ -1406,7 +1431,7 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
if (ret)
goto error_pcm;
} else {
- ret = imx_pcm_dma_init(pdev, buffer_size);
+ ret = imx_pcm_platform_register(&pdev->dev);
if (ret)
goto error_pcm;
}