From c2cf368a8b44b46bcc176ef4b07e5e57bc8221f9 Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Tue, 2 Jul 2024 15:07:14 +0200 Subject: [PATCH] copier: Add bind function to configure source/sink buffers params Setting the source/sink buffers parameters in the copier_update_params function is not sufficient. If a sink buffer is attached during copier operation, the module will not set buffers parameters. Move the buffer parameter configurations to the new copier_bind bind function. Delete the sink buffers configurations from the copier_module_copy function. There is no need to configure sink buffers parameters on each copy. We are assured that they were configured at the time of bind. Fixes: #9123 Signed-off-by: Adrian Warecki --- src/audio/copier/copier.c | 48 +++++++++++++++++++++++++++++-- src/audio/copier/copier_generic.c | 24 ---------------- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/audio/copier/copier.c b/src/audio/copier/copier.c index 2c564ed57f38..aa95dd3e8cf1 100644 --- a/src/audio/copier/copier.c +++ b/src/audio/copier/copier.c @@ -518,9 +518,6 @@ static int copier_module_copy(struct processing_module *mod, if (sink_queue_id >= IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT) return -EINVAL; - /* update corresponding sink format in case it isn't updated */ - ipc4_update_buffer_format(sink_c, &cd->out_fmt[sink_queue_id]); - comp_get_copy_limits(src_c, sink_c, &processed_data); samples = processed_data.frames * @@ -990,10 +987,54 @@ static int copier_get_hw_params(struct comp_dev *dev, struct sof_ipc_stream_para return dai_common_get_hw_params(dd, dev, params, dir); } +static int copier_bind(struct processing_module *mod, void *data) +{ + const struct ipc4_module_bind_unbind *const bu = (struct ipc4_module_bind_unbind *)data; + struct copier_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; + struct comp_buffer *buffer; + uint32_t src_id, sink_id; + struct list_item *list; + + src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id); + sink_id = IPC4_COMP_ID(bu->extension.r.dst_module_id, bu->extension.r.dst_instance_id); + + if (dev->ipc_config.id == src_id) { + /* update sink format */ + list_for_item(list, &dev->bsink_list) { + buffer = container_of(list, struct comp_buffer, source_list); + uint32_t id = IPC4_SINK_QUEUE_ID(buf_get_id(buffer)); + + if (bu->extension.r.src_queue == id) { + ipc4_update_buffer_format(buffer, &cd->out_fmt[id]); + break; + } + } + } else if (dev->ipc_config.id == sink_id) { + /* + * force update the source buffer format to cover cases where the source module + * fails to set the sink buffer params + */ + if (!list_is_empty(&dev->bsource_list)) { + const struct ipc4_audio_format *const in_fmt = &cd->config.base.audio_fmt; + + buffer = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); + + ipc4_update_buffer_format(buffer, in_fmt); + } + } else { + comp_err(dev, "Invalid bind request %x -> %x", src_id, sink_id); + return -EINVAL; + } + + return 0; +} + static int copier_unbind(struct processing_module *mod, void *data) { struct copier_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; + FUN(); if (dev->ipc_config.type == SOF_COMP_DAI) { struct dai_data *dd = cd->dd[0]; @@ -1023,6 +1064,7 @@ static const struct module_interface copier_interface = { .free = copier_free, .set_configuration = copier_set_configuration, .get_configuration = copier_get_configuration, + .bind = copier_bind, .unbind = copier_unbind, .endpoint_ops = &copier_endpoint_ops, }; diff --git a/src/audio/copier/copier_generic.c b/src/audio/copier/copier_generic.c index b270e55461a6..f34183d439ba 100644 --- a/src/audio/copier/copier_generic.c +++ b/src/audio/copier/copier_generic.c @@ -79,30 +79,6 @@ void copier_update_params(struct copier_data *cd, struct comp_dev *dev, /* disable ipc3 stream position */ params->no_stream_position = 1; - /* update each sink format */ - list_for_item(sink_list, &dev->bsink_list) { - int j; - - sink = container_of(sink_list, struct comp_buffer, source_list); - - j = IPC4_SINK_QUEUE_ID(buf_get_id(sink)); - - ipc4_update_buffer_format(sink, &cd->out_fmt[j]); - } - - /* - * force update the source buffer format to cover cases where the source module - * fails to set the sink buffer params - */ - if (!list_is_empty(&dev->bsource_list)) { - struct ipc4_audio_format *in_fmt; - - source = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - - in_fmt = &cd->config.base.audio_fmt; - ipc4_update_buffer_format(source, in_fmt); - } - /* update params for the DMA buffer */ switch (dev->ipc_config.type) { case SOF_COMP_HOST: