summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2014-01-28 11:02:19 +1100
committerStephen Rothwell <sfr@canb.auug.org.au>2014-01-28 11:02:19 +1100
commite2004ed8aa008e3388292042075fae78262aabce (patch)
tree5f16a35fba0058e793d6c89cc31bebf0fed7acfc /sound
parentf415de301a9b4f229bebabe3fa3965bf9cf242f9 (diff)
parent468241ca59039e5db887f2b4a65f1167f93a500c (diff)
Merge remote-tracking branch 'slave-dma/next'
Conflicts: sound/soc/fsl/fsl_ssi.c
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/fsl/fsl_ssi.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index f9090b167ad7..7b1772dbedc5 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -161,6 +161,7 @@ struct fsl_ssi_private {
bool ssi_on_imx;
bool imx_ac97;
bool use_dma;
+ bool use_dual_fifo;
bool baudclk_locked;
bool irq_stats;
bool offline_config;
@@ -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;
}
@@ -1370,7 +1386,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);
@@ -1434,6 +1450,15 @@ static int fsl_ssi_probe(struct platform_device *pdev)
dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
+ 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;
+ }
}
/*