mirror of https://github.com/thesofproject/sof.git
src: dai-zephyr: copy data to all available sinks
In the case where the copier has more than one output and, additionally, we will be using a pin other than pin 0 (for example, when we want to copy data from pin 1 of a gateway-type copier to the next pipeline), it is necessary to copy data in playback path from the source to the output for all possible active sinks. Signed-off-by: Damian Nikodem <damian.nikodem@intel.com>
This commit is contained in:
parent
ff0635ee84
commit
213306433f
|
@ -534,14 +534,14 @@ int dma_buffer_copy_to(struct comp_buffer __sparse_cache *source,
|
|||
dma_process_func process, uint32_t sink_bytes, uint32_t chmap);
|
||||
|
||||
/*
|
||||
* 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, uint32_t chmap);
|
||||
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, uint32_t chmap);
|
||||
|
||||
/* generic DMA DSP <-> Host copier */
|
||||
|
||||
|
|
|
@ -268,16 +268,56 @@ 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 &&
|
||||
sink->hw_params_configured) {
|
||||
ret = stream_copy_from_no_consume(dd->local_buffer, sink,
|
||||
converter[j], bytes, dd->chmap);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ret = dma_buffer_copy_to(dd->local_buffer, dd->dma_buffer,
|
||||
dd->process, bytes, dd->chmap);
|
||||
} 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, dd->chmap);
|
||||
ret = stream_copy_from_no_consume(dd->dma_buffer, dd->local_buffer,
|
||||
dd->process, bytes, dd->chmap);
|
||||
#if CONFIG_IPC_MAJOR_4
|
||||
struct list_item *sink_list;
|
||||
/* Skip in case of endpoint DAI devices created by the copier */
|
||||
|
@ -316,9 +356,9 @@ dai_dma_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes,
|
|||
|
||||
if (sink_dev && sink_dev->state == COMP_STATE_ACTIVE &&
|
||||
sink->hw_params_configured)
|
||||
ret = dma_buffer_copy_from_no_consume(dd->dma_buffer,
|
||||
sink, converter[j],
|
||||
bytes, dd->chmap);
|
||||
ret = stream_copy_from_no_consume(dd->dma_buffer,
|
||||
sink, converter[j],
|
||||
bytes, dd->chmap);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1553,6 +1593,27 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun
|
|||
src_frames = audio_stream_get_avail_frames(&dd->local_buffer->stream);
|
||||
sink_frames = free_bytes / audio_stream_frame_bytes(&dd->dma_buffer->stream);
|
||||
frames = MIN(src_frames, sink_frames);
|
||||
|
||||
struct list_item *sink_list;
|
||||
/*
|
||||
* In the case of playback DAI's with multiple sink buffers, compute the
|
||||
* minimum number of frames based on the DMA avail_bytes and the free
|
||||
* samples in all active sink buffers.
|
||||
*/
|
||||
list_for_item(sink_list, &dev->bsink_list) {
|
||||
struct comp_dev *sink_dev;
|
||||
struct comp_buffer *sink;
|
||||
|
||||
sink = container_of(sink_list, struct comp_buffer, source_list);
|
||||
sink_dev = sink->sink;
|
||||
|
||||
if (sink_dev && sink_dev->state == COMP_STATE_ACTIVE &&
|
||||
sink->hw_params_configured) {
|
||||
sink_frames =
|
||||
audio_stream_get_free_frames(&sink->stream);
|
||||
frames = MIN(frames, sink_frames);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
struct list_item *sink_list;
|
||||
|
||||
|
|
|
@ -447,9 +447,8 @@ 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, uint32_t chmap)
|
||||
int stream_copy_from_no_consume(struct comp_buffer *source, struct comp_buffer *sink,
|
||||
dma_process_func process, uint32_t source_bytes, uint32_t chmap)
|
||||
{
|
||||
int source_channels = audio_stream_get_channels(&source->stream);
|
||||
int sink_channels = audio_stream_get_channels(&sink->stream);
|
||||
|
|
|
@ -534,14 +534,14 @@ int dma_buffer_copy_from(struct comp_buffer *source,
|
|||
dma_process_func process, uint32_t source_bytes, uint32_t chmap);
|
||||
|
||||
/*
|
||||
* 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, uint32_t chmap);
|
||||
int stream_copy_from_no_consume(struct comp_buffer *source,
|
||||
struct comp_buffer *sink,
|
||||
dma_process_func process,
|
||||
uint32_t source_bytes, uint32_t chmap);
|
||||
|
||||
/* copies data to DMA buffer using provided processing function */
|
||||
int dma_buffer_copy_to(struct comp_buffer *source,
|
||||
|
|
Loading…
Reference in New Issue