aboutsummaryrefslogtreecommitdiff
path: root/sound/soc/fsl/fsl_dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/fsl/fsl_dma.c')
-rw-r--r--sound/soc/fsl/fsl_dma.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index b3eb8570cd7..2c4892c853c 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -697,6 +697,23 @@ static snd_pcm_uframes_t fsl_dma_pointer(struct snd_pcm_substream *substream)
else
position = in_be32(&dma_channel->dar);
+ /*
+ * When capture is started, the SSI immediately starts to fill its FIFO.
+ * This means that the DMA controller is not started until the FIFO is
+ * full. However, ALSA calls this function before that happens, when
+ * MR.DAR is still zero. In this case, just return zero to indicate
+ * that nothing has been received yet.
+ */
+ if (!position)
+ return 0;
+
+ if ((position < dma_private->dma_buf_phys) ||
+ (position > dma_private->dma_buf_end)) {
+ dev_err(substream->pcm->card->dev,
+ "dma pointer is out of range, halting stream\n");
+ return SNDRV_PCM_POS_XRUN;
+ }
+
frames = bytes_to_frames(runtime, position - dma_private->dma_buf_phys);
/*