Upstream pipeline topology is unknown to the DAI so we must check that the DMA r_ptr != source pipeline w_ptr for all DAI sources.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/audio/dai.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/src/audio/dai.c b/src/audio/dai.c index 2fbfc5f..1afbc87 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -492,6 +492,30 @@ static int dai_reset(struct comp_dev *dev) return 0; }
+/* the configuration of the upstream pipeline is unknown + * to the DAI so we have to check that the r_ptr != w_ptr for the + * DAI DMA buffer. This is not required for capture as the pipeline is + * run after the first period has been copied (i.e. r_ptr != w_ptr). + */ +static void dai_pointer_init(struct comp_dev *dev) +{ + struct comp_buffer *dma_buffer; + struct dai_data *dd = comp_get_drvdata(dev); + + /* advance w/r pointer by one period if equal at stream start */ + if (dev->params.direction == SOF_IPC_STREAM_PLAYBACK) { + dma_buffer = list_first_item(&dev->bsource_list, + struct comp_buffer, sink_list); + + if (dma_buffer->w_ptr != dma_buffer->r_ptr) + return; + + /* advance source pipeline w_ptr by one period + * this places pipeline w_ptr in period before DAI r_ptr */ + comp_update_buffer_produce(dma_buffer, dd->period_bytes); + } +} + /* used to pass standard and bespoke command (with data) to component */ static int dai_cmd(struct comp_dev *dev, int cmd, void *data) { @@ -511,6 +535,8 @@ static int dai_cmd(struct comp_dev *dev, int cmd, void *data) case COMP_CMD_RELEASE: case COMP_CMD_START:
+ dai_pointer_init(dev); + /* only start the DAI if we are not XRUN handling */ if (dd->xrun == 0) {