diff options
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r-- | sound/soc/fsl/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 28 |
2 files changed, 28 insertions, 2 deletions
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 324988dea4bd..07f8f141727d 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -212,7 +212,7 @@ config SND_SOC_IMX_SPDIF config SND_SOC_IMX_MC13783 tristate "SoC Audio support for I.MX boards with mc13783" - depends on MFD_MC13783 && ARM + depends on MFD_MC13XXX && ARM select SND_SOC_IMX_SSI select SND_SOC_IMX_AUDMUX select SND_SOC_MC13783 diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 1c791ddbf006..5428a1fda260 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -164,6 +164,7 @@ struct fsl_ssi_private { bool baudclk_locked; bool irq_stats; bool offline_config; + bool use_dual_fifo; u8 i2s_mode; spinlock_t baudclk_lock; struct clk *baudclk; @@ -721,6 +722,12 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private) CCSR_SSI_SxCCR_DC(2)); } + if (ssi_private->use_dual_fifo) { + write_ssi_mask(&ssi->srcr, 0, CCSR_SSI_SRCR_RFEN1); + write_ssi_mask(&ssi->stcr, 0, CCSR_SSI_STCR_TFEN1); + write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_TCH_EN); + } + return 0; } @@ -752,6 +759,15 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); } + /* When using dual fifo mode, it is safer to ensure an even period + * size. If appearing to an odd number while DMA always starts its + * 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) + snd_pcm_hw_constraint_step(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2); + return 0; } @@ -1365,7 +1381,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) if (hw_type == FSL_SSI_MX21 || hw_type == FSL_SSI_MX51 || hw_type == FSL_SSI_MX35) { - u32 dma_events[2]; + u32 dma_events[2], dmas[4]; ssi_private->ssi_on_imx = true; ssi_private->clk = devm_clk_get(&pdev->dev, NULL); @@ -1421,6 +1437,16 @@ static int fsl_ssi_probe(struct platform_device *pdev) goto error_clk; } } + /* Should this be merge with the above? */ + if (!of_property_read_u32_array(pdev->dev.of_node, "dmas", dmas, 4) + && dmas[2] == IMX_DMATYPE_SSI_DUAL) { + ssi_private->use_dual_fifo = true; + /* When using dual fifo mode, we need to keep watermark + * as even numbers due to dma script limitation. + */ + ssi_private->dma_params_tx.maxburst &= ~0x1; + ssi_private->dma_params_rx.maxburst &= ~0x1; + } shared = of_device_is_compatible(of_get_parent(np), "fsl,spba-bus"); |