diff --git a/posix/include/sof/lib/dma.h b/posix/include/sof/lib/dma.h index af9e4191cbbb..7c083958eade 100644 --- a/posix/include/sof/lib/dma.h +++ b/posix/include/sof/lib/dma.h @@ -538,13 +538,13 @@ int dma_buffer_copy_to(struct comp_buffer __sparse_cache *source, dma_process_func process, uint32_t sink_bytes); /* - * Used when copying DMA buffer bytes into multiple sink buffers, one at a time using the provided + * Used when copying stream audio into multiple sink buffers, one at a time using the provided * conversion function. DMA buffer consume should be performed after the data has been copied * to all sinks. */ -int dma_buffer_copy_from_no_consume(struct comp_buffer __sparse_cache *source, - struct comp_buffer __sparse_cache *sink, - dma_process_func process, uint32_t source_bytes); +int stream_copy_from_no_consume(struct comp_buffer __sparse_cache *source, + struct comp_buffer __sparse_cache *sink, + dma_process_func process, uint32_t source_bytes); /* generic DMA DSP <-> Host copier */ diff --git a/src/audio/dai-zephyr.c b/src/audio/dai-zephyr.c index 872a1ee9bd61..d5883caadbd5 100644 --- a/src/audio/dai-zephyr.c +++ b/src/audio/dai-zephyr.c @@ -268,16 +268,55 @@ dai_dma_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes, } if (dev->direction == SOF_IPC_STREAM_PLAYBACK) { +#if CONFIG_IPC_MAJOR_4 + struct list_item *sink_list; + /* + * copy from local buffer to all sinks that are not gateway buffers + * using the right PCM converter function. + */ + list_for_item(sink_list, &dev->bsink_list) { + struct comp_dev *sink_dev; + struct comp_buffer *sink; + int j; + + sink = container_of(sink_list, struct comp_buffer, source_list); + + if (sink == dd->dma_buffer) + continue; + + sink_dev = sink->sink; + + j = IPC4_SRC_QUEUE_ID(buf_get_id(sink)); + + if (j >= IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT) { + comp_err(dev, "Sink queue ID: %d >= max output pin count: %d\n", + j, IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT); + ret = -EINVAL; + continue; + } + + if (!converter[j]) { + comp_err(dev, "No PCM converter for sink queue %d\n", j); + ret = -EINVAL; + continue; + } + + if (sink_dev && sink_dev->state == COMP_STATE_ACTIVE) { + ret = stream_copy_from_no_consume(dd->local_buffer, sink, + converter[j], bytes); + } + } +#endif ret = dma_buffer_copy_to(dd->local_buffer, dd->dma_buffer, dd->process, bytes); } else { audio_stream_invalidate(&dd->dma_buffer->stream, bytes); /* * The PCM converter functions used during DMA buffer copy can never fail, - * so no need to check the return value of dma_buffer_copy_from_no_consume(). + * so no need to check the return value of stream_copy_from_no_consume(). */ - ret = dma_buffer_copy_from_no_consume(dd->dma_buffer, dd->local_buffer, - dd->process, bytes); + ret = stream_copy_from_no_consume(dd->dma_buffer, dd->local_buffer, + dd->process, bytes); #if CONFIG_IPC_MAJOR_4 struct list_item *sink_list; /* Skip in case of endpoint DAI devices created by the copier */ @@ -315,9 +354,9 @@ dai_dma_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes, } if (sink_dev && sink_dev->state == COMP_STATE_ACTIVE) - ret = dma_buffer_copy_from_no_consume(dd->dma_buffer, - sink, converter[j], - bytes); + ret = stream_copy_from_no_consume(dd->dma_buffer, + sink, converter[j], + bytes); } } #endif @@ -1520,6 +1559,7 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun /* calculate minimum size to copy */ if (dev->direction == SOF_IPC_STREAM_PLAYBACK) { + struct list_item *sink_list; src_samples = audio_stream_get_avail_samples(&dd->local_buffer->stream); sink_samples = free_bytes / sampling; samples = MIN(src_samples, sink_samples); diff --git a/src/lib/dma.c b/src/lib/dma.c index f124a040c4c3..18eb1c9f4dac 100644 --- a/src/lib/dma.c +++ b/src/lib/dma.c @@ -379,9 +379,9 @@ int dma_buffer_copy_to(struct comp_buffer *source, return ret; } -int dma_buffer_copy_from_no_consume(struct comp_buffer *source, - struct comp_buffer *sink, - dma_process_func process, uint32_t source_bytes) +int stream_copy_from_no_consume(struct comp_buffer *source, + struct comp_buffer *sink, + dma_process_func process, uint32_t source_bytes) { struct audio_stream *istream = &source->stream; uint32_t samples = source_bytes / diff --git a/xtos/include/sof/lib/dma.h b/xtos/include/sof/lib/dma.h index 6ae18f24a1bd..43b316448dae 100644 --- a/xtos/include/sof/lib/dma.h +++ b/xtos/include/sof/lib/dma.h @@ -538,13 +538,13 @@ int dma_buffer_copy_from(struct comp_buffer *source, dma_process_func process, uint32_t source_bytes); /* - * Used when copying DMA buffer bytes into multiple sink buffers, one at a time using the provided + * Used when copying stream audio into multiple sink buffers, one at a time using the provided * conversion function. DMA buffer consume should be performed after the data has been copied * to all sinks. */ -int dma_buffer_copy_from_no_consume(struct comp_buffer *source, - struct comp_buffer *sink, - dma_process_func process, uint32_t source_bytes); +int stream_copy_from_no_consume(struct comp_buffer *source, + struct comp_buffer *sink, + dma_process_func process, uint32_t source_bytes); /* copies data to DMA buffer using provided processing function */ int dma_buffer_copy_to(struct comp_buffer *source,