diff --git a/src/audio/module_adapter/CMakeLists.txt b/src/audio/module_adapter/CMakeLists.txt index e803f78ba91a..99903436b9d4 100644 --- a/src/audio/module_adapter/CMakeLists.txt +++ b/src/audio/module_adapter/CMakeLists.txt @@ -1,7 +1,11 @@ # SPDX-License-Identifier: BSD-3-Clause -add_local_sources(sof module_adapter.c module/generic.c) +if(CONFIG_IPC_MAJOR_3) + add_local_sources(sof module_adapter.c module_adapter_ipc3.c module/generic.c) +elseif(CONFIG_IPC_MAJOR_4) + add_local_sources(sof module_adapter.c module_adapter_ipc4.c module/generic.c) +endif() if((NOT CONFIG_LIBRARY) OR CONFIG_LIBRARY_STATIC) if(CONFIG_CADENCE_CODEC) diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index e28541560403..5667130fb4b4 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -24,19 +24,6 @@ LOG_MODULE_REGISTER(module_adapter, CONFIG_SOF_LOG_LEVEL); -/* - * helpers to determine processing type - * Needed till all the modules use PROCESSING_MODE_SINK_SOURCE - */ -#define IS_PROCESSING_MODE_AUDIO_STREAM(mod) \ - (!!((struct module_data *)&(mod)->priv)->ops->process_audio_stream) - -#define IS_PROCESSING_MODE_RAW_DATA(mod) \ - (!!((struct module_data *)&(mod)->priv)->ops->process_raw_data) - -#define IS_PROCESSING_MODE_SINK_SOURCE(mod) \ - (!!((struct module_data *)&(mod)->priv)->ops->process) - /* * \brief Create a module adapter component. * \param[in] drv - component driver pointer. @@ -90,62 +77,12 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, comp_set_drvdata(dev, mod); list_init(&mod->sink_buffer_list); -#if CONFIG_IPC_MAJOR_3 - const unsigned char *data; - uint32_t size; - - switch (config->type) { - case SOF_COMP_VOLUME: - { - const struct ipc_config_volume *ipc_volume = spec; - - size = sizeof(*ipc_volume); - data = spec; - break; - } - case SOF_COMP_SRC: - { - const struct ipc_config_src *ipc_src = spec; - - size = sizeof(*ipc_src); - data = spec; - break; - } - default: - { - const struct ipc_config_process *ipc_module_adapter = spec; - - size = ipc_module_adapter->size; - data = ipc_module_adapter->data; - break; - } - } - - /* Copy initial config */ - if (size) { - ret = module_load_config(dev, data, size); - if (ret) { - comp_err(dev, "module_adapter_new() error %d: config loading has failed.", - ret); - goto err; - } - dst->init_data = dst->data; - } else { + ret = module_adapter_init_data(dev, dst, config, spec); + if (ret) { + comp_err(dev, "module_adapter_new() %d: module init data failed", + ret); goto err; } -#else - if (drv->type == SOF_COMP_MODULE_ADAPTER) { - const struct ipc_config_process *ipc_module_adapter = spec; - - dst->init_data = ipc_module_adapter->data; - dst->size = ipc_module_adapter->size; - dst->avail = true; - - memcpy(&dst->base_cfg, ipc_module_adapter->data, sizeof(dst->base_cfg)); - } else { - dst->init_data = spec; - } -#endif /* Modules must modify them if they support more than 1 source/sink */ mod->max_sources = 1; @@ -159,9 +96,7 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, goto err; } -#if CONFIG_IPC_MAJOR_4 - dst->init_data = NULL; -#endif + module_adapter_reset_data(dst); dev->state = COMP_STATE_READY; comp_dbg(dev, "module_adapter_new() done"); @@ -325,18 +260,7 @@ int module_adapter_prepare(struct comp_dev *dev) return -EINVAL; } -#if CONFIG_IPC_MAJOR_3 - /* Check if audio stream client has only one source and one sink buffer to use a - * simplified copy function. - */ - if (IS_PROCESSING_MODE_AUDIO_STREAM(mod) && mod->num_input_buffers == 1 && - mod->num_output_buffers == 1) { - mod->source_comp_buffer = list_first_item(&dev->bsource_list, - struct comp_buffer, sink_list); - mod->sink_comp_buffer = sink; - mod->stream_copy_single_to_single = true; - } -#endif + module_adapter_check_data(mod, dev, sink); /* allocate memory for input buffers */ if (mod->max_sources) { @@ -551,10 +475,7 @@ int module_adapter_params(struct comp_dev *dev, struct sof_ipc_stream_params *pa return ret; } -#if CONFIG_IPC_MAJOR_4 - ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); - ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, mod->stream_params); -#endif + module_adapter_set_params(mod, params); return 0; } @@ -736,7 +657,7 @@ static void module_adapter_process_output(struct comp_dev *dev) mod->total_data_produced += mod->output_buffers[0].size; } -static uint32_t +uint32_t module_single_sink_setup(struct comp_dev *dev, struct comp_buffer __sparse_cache **source_c, struct comp_buffer __sparse_cache **sinks_c) @@ -777,7 +698,7 @@ module_single_sink_setup(struct comp_dev *dev, return num_input_buffers; } -static uint32_t +uint32_t module_single_source_setup(struct comp_dev *dev, struct comp_buffer __sparse_cache **source_c, struct comp_buffer __sparse_cache **sinks_c) @@ -820,7 +741,7 @@ module_single_source_setup(struct comp_dev *dev, return num_output_buffers; } -static int module_adapter_audio_stream_copy_1to1(struct comp_dev *dev) +int module_adapter_audio_stream_copy_1to1(struct comp_dev *dev) { struct processing_module *mod = comp_get_drvdata(dev); struct comp_buffer __sparse_cache *source_c; @@ -869,144 +790,6 @@ static int module_adapter_audio_stream_copy_1to1(struct comp_dev *dev) return ret; } -static int module_adapter_audio_stream_type_copy(struct comp_dev *dev) -{ - struct comp_buffer __sparse_cache *source_c[PLATFORM_MAX_STREAMS]; - struct comp_buffer __sparse_cache *sinks_c[PLATFORM_MAX_STREAMS]; - struct processing_module *mod = comp_get_drvdata(dev); - struct list_item *blist; - uint32_t num_input_buffers, num_output_buffers; - int ret, i = 0; - - /* handle special case of HOST/DAI type components */ - if (dev->ipc_config.type == SOF_COMP_HOST || dev->ipc_config.type == SOF_COMP_DAI) -#if CONFIG_IPC_MAJOR_3 - return module_process_legacy(mod, NULL, 0, NULL, 0); -#else - return module_process_stream(mod, NULL, 0, NULL, 0); -#endif - - if (mod->stream_copy_single_to_single) - return module_adapter_audio_stream_copy_1to1(dev); - - /* acquire all sink and source buffers */ - list_for_item(blist, &dev->bsink_list) { - struct comp_buffer *sink; - - sink = container_of(blist, struct comp_buffer, source_list); - sinks_c[i++] = buffer_acquire(sink); - } - num_output_buffers = i; - if (num_output_buffers > mod->max_sinks) { - comp_err(dev, "Invalid number of sinks %d\n", num_output_buffers); - return -EINVAL; - } - - i = 0; - list_for_item(blist, &dev->bsource_list) { - struct comp_buffer *source; - - source = container_of(blist, struct comp_buffer, sink_list); - source_c[i++] = buffer_acquire(source); - } - num_input_buffers = i; - if (num_input_buffers > mod->max_sources) { - comp_err(dev, "Invalid number of sinks %d\n", num_input_buffers); - return -EINVAL; - } - - /* setup active input/output buffers for processing */ - if (num_output_buffers == 1) { - module_single_sink_setup(dev, source_c, sinks_c); - if (sinks_c[0]->sink->state != dev->state) { - num_output_buffers = 0; - buffer_release(sinks_c[0]); - } - } else if (num_input_buffers == 1) { - module_single_source_setup(dev, source_c, sinks_c); - if (source_c[0]->source->state != dev->state) { - num_input_buffers = 0; - buffer_release(source_c[0]); - } - } else { - ret = -EINVAL; - goto out; - } - - ret = module_process_legacy(mod, mod->input_buffers, num_input_buffers, - mod->output_buffers, num_output_buffers); - if (ret) { - if (ret != -ENOSPC && ret != -ENODATA) { - comp_err(dev, - "module_adapter_audio_stream_type_copy() failed with error: %x", - ret); - goto out; - } - - ret = 0; - } - - /* consume from all active input buffers */ - for (i = 0; i < num_input_buffers; i++) { - struct comp_buffer __sparse_cache *src_c; - - src_c = attr_container_of(mod->input_buffers[i].data, - struct comp_buffer __sparse_cache, - stream, __sparse_cache); - if (mod->input_buffers[i].consumed) - audio_stream_consume(&src_c->stream, mod->input_buffers[i].consumed); - } - - /* compute data consumed based on pin 0 since it is processed with base config - * which is set for pin 0 - */ - mod->total_data_consumed += mod->input_buffers[0].consumed; - - /* release all source buffers */ - for (i = 0; i < num_input_buffers; i++) { - buffer_release(source_c[i]); - mod->input_buffers[i].size = 0; - mod->input_buffers[i].consumed = 0; - } - - /* produce data into all active output buffers */ - for (i = 0; i < num_output_buffers; i++) { - struct comp_buffer __sparse_cache *sink_c; - - sink_c = attr_container_of(mod->output_buffers[i].data, - struct comp_buffer __sparse_cache, - stream, __sparse_cache); - - if (!mod->skip_sink_buffer_writeback) - buffer_stream_writeback(sink_c, mod->output_buffers[i].size); - if (mod->output_buffers[i].size) - comp_update_buffer_produce(sink_c, mod->output_buffers[i].size); - } - - mod->total_data_produced += mod->output_buffers[0].size; - - /* release all sink buffers */ - for (i = 0; i < num_output_buffers; i++) { - buffer_release(sinks_c[i]); - mod->output_buffers[i].size = 0; - } - - return 0; -out: - for (i = 0; i < num_output_buffers; i++) { - buffer_release(sinks_c[i]); - mod->output_buffers[i].size = 0; - } - - for (i = 0; i < num_input_buffers; i++) { - buffer_release(source_c[i]); - mod->input_buffers[i].size = 0; - mod->input_buffers[i].consumed = 0; - } - - return ret; -} - static int module_adapter_sink_source_copy(struct comp_dev *dev) { struct comp_buffer __sparse_cache *source_buffers_c[PLATFORM_MAX_STREAMS]; @@ -1316,34 +1099,6 @@ int module_adapter_cmd(struct comp_dev *dev, int cmd, void *data, int max_data_s return ret; } -#if CONFIG_IPC_MAJOR_3 -static int module_source_status_count(struct comp_dev *dev, uint32_t status) -{ - struct list_item *blist; - int count = 0; - - /* count source with state == status */ - list_for_item(blist, &dev->bsource_list) { - /* - * FIXME: this is racy, state can be changed by another core. - * This is implicitly protected by serialised IPCs. Even when - * IPCs are processed in the pipeline thread, the next IPC will - * not be sent until the thread has processed and replied to the - * current one. - */ - struct comp_buffer *source = container_of(blist, struct comp_buffer, - sink_list); - struct comp_buffer __sparse_cache *source_c = buffer_acquire(source); - - if (source_c->source && source_c->source->state == status) - count++; - buffer_release(source_c); - } - - return count; -} -#endif - int module_adapter_trigger(struct comp_dev *dev, int cmd) { struct processing_module *mod = comp_get_drvdata(dev); @@ -1366,28 +1121,7 @@ int module_adapter_trigger(struct comp_dev *dev, int cmd) return PPL_STATUS_PATH_STOP; } -#if CONFIG_IPC_MAJOR_3 - if (mod->num_input_buffers > 1) { - bool sources_active; - int ret; - - sources_active = module_source_status_count(dev, COMP_STATE_ACTIVE) || - module_source_status_count(dev, COMP_STATE_PAUSED); - - /* don't stop/start module if one of the sources is active/paused */ - if ((cmd == COMP_TRIGGER_STOP || cmd == COMP_TRIGGER_PRE_START) && sources_active) { - dev->state = COMP_STATE_ACTIVE; - return PPL_STATUS_PATH_STOP; - } - - ret = comp_set_state(dev, cmd); - if (ret == COMP_STATUS_STATE_ALREADY_SET) - return PPL_STATUS_PATH_STOP; - - return ret; - } -#endif - return comp_set_state(dev, cmd); + return module_adapter_set_state(mod, dev, cmd); } int module_adapter_reset(struct comp_dev *dev) @@ -1583,254 +1317,3 @@ int module_adapter_ts_get_op(struct comp_dev *dev, struct timestamp_data *tsd) return -EOPNOTSUPP; } - -#if CONFIG_IPC_MAJOR_4 -int module_set_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, - bool last_block, uint32_t data_offset_size, const char *data) -{ - struct processing_module *mod = comp_get_drvdata(dev); - struct module_data *md = &mod->priv; - enum module_cfg_fragment_position pos; - size_t fragment_size; - - /* set fragment position */ - pos = first_last_block_to_frag_pos(first_block, last_block); - - switch (pos) { - case MODULE_CFG_FRAGMENT_SINGLE: - fragment_size = data_offset_size; - break; - case MODULE_CFG_FRAGMENT_MIDDLE: - fragment_size = MAILBOX_DSPBOX_SIZE; - break; - case MODULE_CFG_FRAGMENT_FIRST: - md->new_cfg_size = data_offset_size; - fragment_size = MAILBOX_DSPBOX_SIZE; - break; - case MODULE_CFG_FRAGMENT_LAST: - fragment_size = md->new_cfg_size - data_offset_size; - break; - default: - comp_err(dev, "module_set_large_config(): invalid fragment position"); - return -EINVAL; - } - - if (md->ops->set_configuration) - return md->ops->set_configuration(mod, param_id, pos, data_offset_size, - (const uint8_t *)data, - fragment_size, NULL, 0); - return 0; -} - -int module_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, - bool last_block, uint32_t *data_offset_size, char *data) -{ - struct processing_module *mod = comp_get_drvdata(dev); - struct module_data *md = &mod->priv; - size_t fragment_size; - - /* set fragment size */ - if (first_block) { - if (last_block) - fragment_size = md->cfg.size; - else - fragment_size = SOF_IPC_MSG_MAX_SIZE; - } else { - if (!last_block) - fragment_size = SOF_IPC_MSG_MAX_SIZE; - else - fragment_size = md->cfg.size - *data_offset_size; - } - - if (md->ops->get_configuration) - return md->ops->get_configuration(mod, param_id, data_offset_size, - (uint8_t *)data, fragment_size); - return 0; -} - -int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *value) -{ - struct processing_module *mod = comp_get_drvdata(dev); - - switch (type) { - case COMP_ATTR_BASE_CONFIG: - memcpy_s(value, sizeof(struct ipc4_base_module_cfg), - &mod->priv.cfg.base_cfg, sizeof(mod->priv.cfg.base_cfg)); - break; - default: - return -EINVAL; - } - - return 0; -} - -static bool module_adapter_multi_sink_source_check(struct comp_dev *dev) -{ - struct processing_module *mod = comp_get_drvdata(dev); - struct list_item *blist; - int num_sources = 0; - int num_sinks = 0; - - list_for_item(blist, &dev->bsource_list) - num_sources++; - - list_for_item(blist, &dev->bsink_list) - num_sinks++; - - comp_dbg(dev, "num_sources=%d num_sinks=%d", num_sources, num_sinks); - - if (num_sources != 1 || num_sinks != 1) - return true; - - /* re-assign the source/sink modules */ - mod->sink_comp_buffer = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - mod->source_comp_buffer = list_first_item(&dev->bsource_list, - struct comp_buffer, sink_list); - - return false; -} - -int module_adapter_bind(struct comp_dev *dev, void *data) -{ - struct module_source_info __sparse_cache *mod_source_info; - struct processing_module *mod = comp_get_drvdata(dev); - struct ipc4_module_bind_unbind *bu; - struct comp_dev *source_dev; - int source_index; - int src_id; - int ret; - - ret = module_bind(mod, data); - if (ret < 0) - return ret; - - bu = (struct ipc4_module_bind_unbind *)data; - src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id); - - mod->stream_copy_single_to_single = !module_adapter_multi_sink_source_check(dev); - - /* nothing to do if this module is the source during bind */ - if (dev->ipc_config.id == src_id) - return 0; - - source_dev = ipc4_get_comp_dev(src_id); - if (!source_dev) { - comp_err(dev, "module_adapter_bind: no source with ID %d found", src_id); - return -EINVAL; - } - - mod_source_info = module_source_info_acquire(mod->source_info); - - source_index = find_module_source_index(mod_source_info, source_dev); - /* - * this should never happen as source_info should have been already cleared in - * module_adapter_unbind() - */ - if (source_index >= 0) - mod_source_info->sources[source_index] = NULL; - - /* find an empty slot in the source_info array */ - source_index = find_module_source_index(mod_source_info, NULL); - if (source_index < 0) { - /* no free slot in module source_info array */ - comp_err(dev, "Too many inputs!"); - module_source_info_release(mod_source_info); - return -ENOMEM; - } - - /* set the source dev pointer */ - mod_source_info->sources[source_index] = source_dev; - - module_source_info_release(mod_source_info); - - return 0; -} - -int module_adapter_unbind(struct comp_dev *dev, void *data) -{ - struct module_source_info __sparse_cache *mod_source_info; - struct processing_module *mod = comp_get_drvdata(dev); - struct ipc4_module_bind_unbind *bu; - struct comp_dev *source_dev; - int source_index; - int src_id; - int ret; - - ret = module_unbind(mod, data); - if (ret < 0) - return ret; - - bu = (struct ipc4_module_bind_unbind *)data; - src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id); - - mod->stream_copy_single_to_single = !module_adapter_multi_sink_source_check(dev); - - /* nothing to do if this module is the source during unbind */ - if (dev->ipc_config.id == src_id) - return 0; - - source_dev = ipc4_get_comp_dev(src_id); - if (!source_dev) { - comp_err(dev, "module_adapter_bind: no source with ID %d found", src_id); - return -EINVAL; - } - - mod_source_info = module_source_info_acquire(mod->source_info); - - /* find the index of the source in the sources array and clear it */ - source_index = find_module_source_index(mod_source_info, source_dev); - if (source_index >= 0) - mod_source_info->sources[source_index] = NULL; - - module_source_info_release(mod_source_info); - - return 0; -} - -uint64_t module_adapter_get_total_data_processed(struct comp_dev *dev, - uint32_t stream_no, bool input) -{ - struct processing_module *mod = comp_get_drvdata(dev); - struct module_data *md = &mod->priv; - - if (md->ops->endpoint_ops && md->ops->endpoint_ops->get_total_data_processed) - return md->ops->endpoint_ops->get_total_data_processed(dev, stream_no, input); - - if (input) - return mod->total_data_produced; - else - return mod->total_data_consumed; -} -#else -int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *value) -{ - return -EINVAL; -} -int module_set_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, - bool last_block, uint32_t data_offset, const char *data) -{ - return 0; -} - -int module_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, - bool last_block, uint32_t *data_offset, char *data) -{ - return 0; -} - -int module_adapter_bind(struct comp_dev *dev, void *data) -{ - return 0; -} - -int module_adapter_unbind(struct comp_dev *dev, void *data) -{ - return 0; -} - -uint64_t module_adapter_get_total_data_processed(struct comp_dev *dev, - uint32_t stream_no, bool input) -{ - return 0; -} -#endif diff --git a/src/audio/module_adapter/module_adapter_ipc3.c b/src/audio/module_adapter/module_adapter_ipc3.c new file mode 100644 index 000000000000..09df939a6bc9 --- /dev/null +++ b/src/audio/module_adapter/module_adapter_ipc3.c @@ -0,0 +1,330 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. +// +// Author: Baofeng Tian <baofeng.tian@intel.com> + +/** + * \file + * \brief Module Adapter ipc3: module adapter ipc3 specific code + * \author Baofeng Tian <baofeng.tian@intel.com> + */ + +#include <sof/audio/buffer.h> +#include <sof/audio/component.h> +#include <sof/audio/ipc-config.h> +#include <sof/audio/module_adapter/module/generic.h> +#include <sof/audio/pipeline.h> +#include <sof/common.h> +#include <sof/platform.h> +#include <sof/ut.h> +#include <rtos/interrupt.h> +#include <limits.h> +#include <stdint.h> + +LOG_MODULE_DECLARE(module_adapter, CONFIG_SOF_LOG_LEVEL); + +/* + * \module adapter data initialize. + * \param[in] dev - device. + * \param[in] config - component ipc descriptor pointer. + * \param[in] dst - module adapter config data. + * \param[in] spec - passdowned data from driver. + * + * \return: 0 - no error; < 0, error happened. + */ +int module_adapter_init_data(struct comp_dev *dev, + struct module_config *dst, + const struct comp_ipc_config *config, + const void *spec) +{ + int ret; + + const unsigned char *data; + uint32_t size; + + switch (config->type) { + case SOF_COMP_VOLUME: + { + const struct ipc_config_volume *ipc_volume = spec; + + size = sizeof(*ipc_volume); + data = spec; + break; + } + case SOF_COMP_SRC: + { + const struct ipc_config_src *ipc_src = spec; + + size = sizeof(*ipc_src); + data = spec; + break; + } + default: + { + const struct ipc_config_process *ipc_module_adapter = spec; + + size = ipc_module_adapter->size; + data = ipc_module_adapter->data; + break; + } + } + + /* Copy initial config */ + if (size) { + ret = module_load_config(dev, data, size); + if (ret < 0) { + comp_err(dev, "module_adapter_new() error %d: config loading has failed.", + ret); + return ret; + } + dst->init_data = dst->data; + } else { + return -EINVAL; + } + + return 0; +} + +void module_adapter_reset_data(struct module_config *dst) +{ +} + +void module_adapter_check_data(struct processing_module *mod, struct comp_dev *dev, + struct comp_buffer *sink) +{ + /* Check if audio stream client has only one source and one sink buffer to use a + * simplified copy function. + */ + if (IS_PROCESSING_MODE_AUDIO_STREAM(mod) && mod->num_input_buffers == 1 && + mod->num_output_buffers == 1) { + mod->source_comp_buffer = list_first_item(&dev->bsource_list, + struct comp_buffer, sink_list); + mod->sink_comp_buffer = sink; + mod->stream_copy_single_to_single = true; + } +} + +void module_adapter_set_params(struct processing_module *mod, struct sof_ipc_stream_params *params) +{ +} + +int module_adapter_audio_stream_type_copy(struct comp_dev *dev) +{ + struct comp_buffer __sparse_cache *source_c[PLATFORM_MAX_STREAMS]; + struct comp_buffer __sparse_cache *sinks_c[PLATFORM_MAX_STREAMS]; + struct processing_module *mod = comp_get_drvdata(dev); + struct list_item *blist; + uint32_t num_input_buffers, num_output_buffers; + int ret, i = 0; + + /* handle special case of HOST/DAI type components */ + if (dev->ipc_config.type == SOF_COMP_HOST || dev->ipc_config.type == SOF_COMP_DAI) + return module_process_legacy(mod, NULL, 0, NULL, 0); + + if (mod->stream_copy_single_to_single) + return module_adapter_audio_stream_copy_1to1(dev); + + /* acquire all sink and source buffers */ + list_for_item(blist, &dev->bsink_list) { + struct comp_buffer *sink; + + sink = container_of(blist, struct comp_buffer, source_list); + sinks_c[i++] = buffer_acquire(sink); + } + num_output_buffers = i; + if (num_output_buffers > mod->max_sinks) { + comp_err(dev, "Invalid number of sinks %d\n", num_output_buffers); + return -EINVAL; + } + + i = 0; + list_for_item(blist, &dev->bsource_list) { + struct comp_buffer *source; + + source = container_of(blist, struct comp_buffer, sink_list); + source_c[i++] = buffer_acquire(source); + } + num_input_buffers = i; + if (num_input_buffers > mod->max_sources) { + comp_err(dev, "Invalid number of sinks %d\n", num_input_buffers); + return -EINVAL; + } + + /* setup active input/output buffers for processing */ + if (num_output_buffers == 1) { + module_single_sink_setup(dev, source_c, sinks_c); + if (sinks_c[0]->sink->state != dev->state) { + num_output_buffers = 0; + buffer_release(sinks_c[0]); + } + } else if (num_input_buffers == 1) { + module_single_source_setup(dev, source_c, sinks_c); + if (source_c[0]->source->state != dev->state) { + num_input_buffers = 0; + buffer_release(source_c[0]); + } + } else { + ret = -EINVAL; + goto out; + } + + ret = module_process_legacy(mod, mod->input_buffers, num_input_buffers, + mod->output_buffers, num_output_buffers); + if (ret) { + if (ret != -ENOSPC && ret != -ENODATA) { + comp_err(dev, + "module_adapter_audio_stream_type_copy() failed with error: %x", + ret); + goto out; + } + + ret = 0; + } + + /* consume from all active input buffers */ + for (i = 0; i < num_input_buffers; i++) { + struct comp_buffer __sparse_cache *src_c; + + src_c = attr_container_of(mod->input_buffers[i].data, + struct comp_buffer __sparse_cache, + stream, __sparse_cache); + if (mod->input_buffers[i].consumed) + audio_stream_consume(&src_c->stream, mod->input_buffers[i].consumed); + } + + /* compute data consumed based on pin 0 since it is processed with base config + * which is set for pin 0 + */ + mod->total_data_consumed += mod->input_buffers[0].consumed; + + /* release all source buffers */ + for (i = 0; i < num_input_buffers; i++) { + buffer_release(source_c[i]); + mod->input_buffers[i].size = 0; + mod->input_buffers[i].consumed = 0; + } + + /* produce data into all active output buffers */ + for (i = 0; i < num_output_buffers; i++) { + struct comp_buffer __sparse_cache *sink_c; + + sink_c = attr_container_of(mod->output_buffers[i].data, + struct comp_buffer __sparse_cache, + stream, __sparse_cache); + + if (!mod->skip_sink_buffer_writeback) + buffer_stream_writeback(sink_c, mod->output_buffers[i].size); + if (mod->output_buffers[i].size) + comp_update_buffer_produce(sink_c, mod->output_buffers[i].size); + } + + mod->total_data_produced += mod->output_buffers[0].size; + + /* release all sink buffers */ + for (i = 0; i < num_output_buffers; i++) { + buffer_release(sinks_c[i]); + mod->output_buffers[i].size = 0; + } + + return 0; +out: + for (i = 0; i < num_output_buffers; i++) { + buffer_release(sinks_c[i]); + mod->output_buffers[i].size = 0; + } + + for (i = 0; i < num_input_buffers; i++) { + buffer_release(source_c[i]); + mod->input_buffers[i].size = 0; + mod->input_buffers[i].consumed = 0; + } + + return ret; +} + +static int module_source_status_count(struct comp_dev *dev, uint32_t status) +{ + struct list_item *blist; + int count = 0; + + /* count source with state == status */ + list_for_item(blist, &dev->bsource_list) { + /* + * FIXME: this is racy, state can be changed by another core. + * This is implicitly protected by serialised IPCs. Even when + * IPCs are processed in the pipeline thread, the next IPC will + * not be sent until the thread has processed and replied to the + * current one. + */ + struct comp_buffer *source = container_of(blist, struct comp_buffer, + sink_list); + struct comp_buffer __sparse_cache *source_c = buffer_acquire(source); + + if (source_c->source && source_c->source->state == status) + count++; + buffer_release(source_c); + } + + return count; +} + +int module_adapter_set_state(struct processing_module *mod, struct comp_dev *dev, + int cmd) +{ + if (mod->num_input_buffers > 1) { + bool sources_active; + int ret; + + sources_active = module_source_status_count(dev, COMP_STATE_ACTIVE) || + module_source_status_count(dev, COMP_STATE_PAUSED); + + /* don't stop/start module if one of the sources is active/paused */ + if ((cmd == COMP_TRIGGER_STOP || cmd == COMP_TRIGGER_PRE_START) && sources_active) { + dev->state = COMP_STATE_ACTIVE; + return PPL_STATUS_PATH_STOP; + } + + ret = comp_set_state(dev, cmd); + if (ret == COMP_STATUS_STATE_ALREADY_SET) + return PPL_STATUS_PATH_STOP; + + return ret; + } + + return comp_set_state(dev, cmd); +} + +int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *value) +{ + return -EINVAL; +} + +int module_set_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, + bool last_block, uint32_t data_offset, const char *data) +{ + return 0; +} + +int module_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, + bool last_block, uint32_t *data_offset, char *data) +{ + return 0; +} + +int module_adapter_bind(struct comp_dev *dev, void *data) +{ + return 0; +} + +int module_adapter_unbind(struct comp_dev *dev, void *data) +{ + return 0; +} + +uint64_t module_adapter_get_total_data_processed(struct comp_dev *dev, + uint32_t stream_no, bool input) +{ + return 0; +} + diff --git a/src/audio/module_adapter/module_adapter_ipc4.c b/src/audio/module_adapter/module_adapter_ipc4.c new file mode 100644 index 000000000000..4010403e170c --- /dev/null +++ b/src/audio/module_adapter/module_adapter_ipc4.c @@ -0,0 +1,429 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. +// +// Author: Baofeng Tian <baofeng.tian@intel.com> + +/** + * \file + * \brief Module Adapter ipc4: module adapter ipc4 specific code + * \author Baofeng Tian <baofeng.tian@intel.com> + */ + +#include <sof/audio/buffer.h> +#include <sof/audio/component.h> +#include <sof/audio/ipc-config.h> +#include <sof/audio/module_adapter/module/generic.h> +#include <sof/audio/pipeline.h> +#include <sof/common.h> +#include <sof/platform.h> +#include <sof/ut.h> +#include <rtos/interrupt.h> +#include <limits.h> +#include <stdint.h> + +LOG_MODULE_DECLARE(module_adapter, CONFIG_SOF_LOG_LEVEL); + +/* + * \module adapter data initialize. + * \param[in] dev - device. + * \param[in] config - component ipc descriptor pointer. + * \param[in] dst - module adapter config data. + * \param[in] spec - passdowned data from driver. + * + * \return: 0 - no error; < 0, error happened. + */ +int module_adapter_init_data(struct comp_dev *dev, + struct module_config *dst, + const struct comp_ipc_config *config, + const void *spec) +{ + if (dev->drv->type == SOF_COMP_MODULE_ADAPTER) { + const struct ipc_config_process *ipc_module_adapter = spec; + + dst->init_data = ipc_module_adapter->data; + dst->size = ipc_module_adapter->size; + dst->avail = true; + + memcpy_s(&dst->base_cfg, sizeof(dst->base_cfg), ipc_module_adapter->data, + sizeof(dst->base_cfg)); + } else { + dst->init_data = spec; + } + + return 0; +} + +void module_adapter_reset_data(struct module_config *dst) +{ + dst->init_data = NULL; +} + +void module_adapter_check_data(struct processing_module *mod, struct comp_dev *dev, + struct comp_buffer *sink) +{ +} + +void module_adapter_set_params(struct processing_module *mod, struct sof_ipc_stream_params *params) +{ + ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); + ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, mod->stream_params); +} + +int module_adapter_audio_stream_type_copy(struct comp_dev *dev) +{ + struct comp_buffer __sparse_cache *source_c[PLATFORM_MAX_STREAMS]; + struct comp_buffer __sparse_cache *sinks_c[PLATFORM_MAX_STREAMS]; + struct processing_module *mod = comp_get_drvdata(dev); + struct list_item *blist; + uint32_t num_input_buffers, num_output_buffers; + int ret, i = 0; + + /* handle special case of HOST/DAI type components */ + if (dev->ipc_config.type == SOF_COMP_HOST || dev->ipc_config.type == SOF_COMP_DAI) + return module_process_stream(mod, NULL, 0, NULL, 0); + + if (mod->stream_copy_single_to_single) + return module_adapter_audio_stream_copy_1to1(dev); + + /* acquire all sink and source buffers */ + list_for_item(blist, &dev->bsink_list) { + struct comp_buffer *sink; + + sink = container_of(blist, struct comp_buffer, source_list); + sinks_c[i++] = buffer_acquire(sink); + } + num_output_buffers = i; + if (num_output_buffers > mod->max_sinks) { + comp_err(dev, "Invalid number of sinks %d\n", num_output_buffers); + return -EINVAL; + } + + i = 0; + list_for_item(blist, &dev->bsource_list) { + struct comp_buffer *source; + + source = container_of(blist, struct comp_buffer, sink_list); + source_c[i++] = buffer_acquire(source); + } + num_input_buffers = i; + if (num_input_buffers > mod->max_sources) { + comp_err(dev, "Invalid number of sinks %d\n", num_input_buffers); + return -EINVAL; + } + + /* setup active input/output buffers for processing */ + if (num_output_buffers == 1) { + module_single_sink_setup(dev, source_c, sinks_c); + if (sinks_c[0]->sink->state != dev->state) { + num_output_buffers = 0; + buffer_release(sinks_c[0]); + } + } else if (num_input_buffers == 1) { + module_single_source_setup(dev, source_c, sinks_c); + if (source_c[0]->source->state != dev->state) { + num_input_buffers = 0; + buffer_release(source_c[0]); + } + } else { + ret = -EINVAL; + goto out; + } + + ret = module_process_legacy(mod, mod->input_buffers, num_input_buffers, + mod->output_buffers, num_output_buffers); + if (ret) { + if (ret != -ENOSPC && ret != -ENODATA) { + comp_err(dev, + "module_adapter_audio_stream_type_copy() failed with error: %x", + ret); + goto out; + } + + ret = 0; + } + + /* consume from all active input buffers */ + for (i = 0; i < num_input_buffers; i++) { + struct comp_buffer __sparse_cache *src_c; + + src_c = attr_container_of(mod->input_buffers[i].data, + struct comp_buffer __sparse_cache, + stream, __sparse_cache); + if (mod->input_buffers[i].consumed) + audio_stream_consume(&src_c->stream, mod->input_buffers[i].consumed); + } + + /* compute data consumed based on pin 0 since it is processed with base config + * which is set for pin 0 + */ + mod->total_data_consumed += mod->input_buffers[0].consumed; + + /* release all source buffers */ + for (i = 0; i < num_input_buffers; i++) { + buffer_release(source_c[i]); + mod->input_buffers[i].size = 0; + mod->input_buffers[i].consumed = 0; + } + + /* produce data into all active output buffers */ + for (i = 0; i < num_output_buffers; i++) { + struct comp_buffer __sparse_cache *sink_c; + + sink_c = attr_container_of(mod->output_buffers[i].data, + struct comp_buffer __sparse_cache, + stream, __sparse_cache); + + if (!mod->skip_sink_buffer_writeback) + buffer_stream_writeback(sink_c, mod->output_buffers[i].size); + if (mod->output_buffers[i].size) + comp_update_buffer_produce(sink_c, mod->output_buffers[i].size); + } + + mod->total_data_produced += mod->output_buffers[0].size; + + /* release all sink buffers */ + for (i = 0; i < num_output_buffers; i++) { + buffer_release(sinks_c[i]); + mod->output_buffers[i].size = 0; + } + + return 0; +out: + for (i = 0; i < num_output_buffers; i++) { + buffer_release(sinks_c[i]); + mod->output_buffers[i].size = 0; + } + + for (i = 0; i < num_input_buffers; i++) { + buffer_release(source_c[i]); + mod->input_buffers[i].size = 0; + mod->input_buffers[i].consumed = 0; + } + + return ret; +} + +int module_adapter_set_state(struct processing_module *mod, struct comp_dev *dev, + int cmd) +{ + return comp_set_state(dev, cmd); +} + +int module_set_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, + bool last_block, uint32_t data_offset_size, const char *data) +{ + struct processing_module *mod = comp_get_drvdata(dev); + struct module_data *md = &mod->priv; + enum module_cfg_fragment_position pos; + size_t fragment_size; + + /* set fragment position */ + pos = first_last_block_to_frag_pos(first_block, last_block); + + switch (pos) { + case MODULE_CFG_FRAGMENT_SINGLE: + fragment_size = data_offset_size; + break; + case MODULE_CFG_FRAGMENT_MIDDLE: + fragment_size = MAILBOX_DSPBOX_SIZE; + break; + case MODULE_CFG_FRAGMENT_FIRST: + md->new_cfg_size = data_offset_size; + fragment_size = MAILBOX_DSPBOX_SIZE; + break; + case MODULE_CFG_FRAGMENT_LAST: + fragment_size = md->new_cfg_size - data_offset_size; + break; + default: + comp_err(dev, "module_set_large_config(): invalid fragment position"); + return -EINVAL; + } + + if (md->ops->set_configuration) + return md->ops->set_configuration(mod, param_id, pos, data_offset_size, + (const uint8_t *)data, + fragment_size, NULL, 0); + return 0; +} + +int module_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, + bool last_block, uint32_t *data_offset_size, char *data) +{ + struct processing_module *mod = comp_get_drvdata(dev); + struct module_data *md = &mod->priv; + size_t fragment_size; + + /* set fragment size */ + if (first_block) { + if (last_block) + fragment_size = md->cfg.size; + else + fragment_size = SOF_IPC_MSG_MAX_SIZE; + } else { + if (!last_block) + fragment_size = SOF_IPC_MSG_MAX_SIZE; + else + fragment_size = md->cfg.size - *data_offset_size; + } + + if (md->ops->get_configuration) + return md->ops->get_configuration(mod, param_id, data_offset_size, + (uint8_t *)data, fragment_size); + return 0; +} + +int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *value) +{ + struct processing_module *mod = comp_get_drvdata(dev); + + switch (type) { + case COMP_ATTR_BASE_CONFIG: + memcpy_s(value, sizeof(struct ipc4_base_module_cfg), + &mod->priv.cfg.base_cfg, sizeof(mod->priv.cfg.base_cfg)); + break; + default: + return -EINVAL; + } + + return 0; +} + +static bool module_adapter_multi_sink_source_check(struct comp_dev *dev) +{ + struct processing_module *mod = comp_get_drvdata(dev); + struct list_item *blist; + int num_sources = 0; + int num_sinks = 0; + + list_for_item(blist, &dev->bsource_list) + num_sources++; + + list_for_item(blist, &dev->bsink_list) + num_sinks++; + + comp_dbg(dev, "num_sources=%d num_sinks=%d", num_sources, num_sinks); + + if (num_sources != 1 || num_sinks != 1) + return true; + + /* re-assign the source/sink modules */ + mod->sink_comp_buffer = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + mod->source_comp_buffer = list_first_item(&dev->bsource_list, + struct comp_buffer, sink_list); + + return false; +} + +int module_adapter_bind(struct comp_dev *dev, void *data) +{ + struct module_source_info __sparse_cache *mod_source_info; + struct processing_module *mod = comp_get_drvdata(dev); + struct ipc4_module_bind_unbind *bu; + struct comp_dev *source_dev; + int source_index; + int src_id; + int ret; + + ret = module_bind(mod, data); + if (ret < 0) + return ret; + + bu = (struct ipc4_module_bind_unbind *)data; + src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id); + + mod->stream_copy_single_to_single = !module_adapter_multi_sink_source_check(dev); + + /* nothing to do if this module is the source during bind */ + if (dev->ipc_config.id == src_id) + return 0; + + source_dev = ipc4_get_comp_dev(src_id); + if (!source_dev) { + comp_err(dev, "module_adapter_bind: no source with ID %d found", src_id); + return -EINVAL; + } + + mod_source_info = module_source_info_acquire(mod->source_info); + + source_index = find_module_source_index(mod_source_info, source_dev); + /* + * this should never happen as source_info should have been already cleared in + * module_adapter_unbind() + */ + if (source_index >= 0) + mod_source_info->sources[source_index] = NULL; + + /* find an empty slot in the source_info array */ + source_index = find_module_source_index(mod_source_info, NULL); + if (source_index < 0) { + /* no free slot in module source_info array */ + comp_err(dev, "Too many inputs!"); + module_source_info_release(mod_source_info); + return -ENOMEM; + } + + /* set the source dev pointer */ + mod_source_info->sources[source_index] = source_dev; + + module_source_info_release(mod_source_info); + + return 0; +} + +int module_adapter_unbind(struct comp_dev *dev, void *data) +{ + struct module_source_info __sparse_cache *mod_source_info; + struct processing_module *mod = comp_get_drvdata(dev); + struct ipc4_module_bind_unbind *bu; + struct comp_dev *source_dev; + int source_index; + int src_id; + int ret; + + ret = module_unbind(mod, data); + if (ret < 0) + return ret; + + bu = (struct ipc4_module_bind_unbind *)data; + src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id); + + mod->stream_copy_single_to_single = !module_adapter_multi_sink_source_check(dev); + + /* nothing to do if this module is the source during unbind */ + if (dev->ipc_config.id == src_id) + return 0; + + source_dev = ipc4_get_comp_dev(src_id); + if (!source_dev) { + comp_err(dev, "module_adapter_bind: no source with ID %d found", src_id); + return -EINVAL; + } + + mod_source_info = module_source_info_acquire(mod->source_info); + + /* find the index of the source in the sources array and clear it */ + source_index = find_module_source_index(mod_source_info, source_dev); + if (source_index >= 0) + mod_source_info->sources[source_index] = NULL; + + module_source_info_release(mod_source_info); + + return 0; +} + +uint64_t module_adapter_get_total_data_processed(struct comp_dev *dev, + uint32_t stream_no, bool input) +{ + struct processing_module *mod = comp_get_drvdata(dev); + struct module_data *md = &mod->priv; + + if (md->ops->endpoint_ops && md->ops->endpoint_ops->get_total_data_processed) + return md->ops->endpoint_ops->get_total_data_processed(dev, stream_no, input); + + if (input) + return mod->total_data_produced; + else + return mod->total_data_consumed; +} + diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index 28f5c0765d0c..1dd9a4bfb0ec 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -21,6 +21,19 @@ #include "modules.h" #endif +/* + * helpers to determine processing type + * Needed till all the modules use PROCESSING_MODE_SINK_SOURCE + */ +#define IS_PROCESSING_MODE_AUDIO_STREAM(mod) \ + (!!((struct module_data *)&(mod)->priv)->ops->process_audio_stream) + +#define IS_PROCESSING_MODE_RAW_DATA(mod) \ + (!!((struct module_data *)&(mod)->priv)->ops->process_raw_data) + +#define IS_PROCESSING_MODE_SINK_SOURCE(mod) \ + (!!((struct module_data *)&(mod)->priv)->ops->process) + #define module_get_private_data(mod) (mod->priv.private) #define MAX_BLOB_SIZE 8192 #define MODULE_MAX_SOURCES 8 @@ -368,4 +381,24 @@ static inline int module_process_stream(struct processing_module *mod, output_buffers, num_output_buffers); } +int module_adapter_init_data(struct comp_dev *dev, + struct module_config *dst, + const struct comp_ipc_config *config, + const void *spec); +void module_adapter_reset_data(struct module_config *dst); +void module_adapter_check_data(struct processing_module *mod, struct comp_dev *dev, + struct comp_buffer *sink); +void module_adapter_set_params(struct processing_module *mod, struct sof_ipc_stream_params *params); +uint32_t +module_single_sink_setup(struct comp_dev *dev, + struct comp_buffer __sparse_cache **source_c, + struct comp_buffer __sparse_cache **sinks_c); +uint32_t +module_single_source_setup(struct comp_dev *dev, + struct comp_buffer __sparse_cache **source_c, + struct comp_buffer __sparse_cache **sinks_c); +int module_adapter_audio_stream_copy_1to1(struct comp_dev *dev); +int module_adapter_audio_stream_type_copy(struct comp_dev *dev); +int module_adapter_set_state(struct processing_module *mod, struct comp_dev *dev, + int cmd); #endif /* __SOF_AUDIO_MODULE_GENERIC__ */ diff --git a/test/cmocka/src/audio/eq_fir/CMakeLists.txt b/test/cmocka/src/audio/eq_fir/CMakeLists.txt index af9fa80d0b60..3369f2b97b06 100644 --- a/test/cmocka/src/audio/eq_fir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_fir/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(audio_for_eq_fir STATIC ${PROJECT_SOURCE_DIR}/src/math/fir_hifi3.c ${PROJECT_SOURCE_DIR}/src/math/numbers.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c + ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c diff --git a/test/cmocka/src/audio/eq_iir/CMakeLists.txt b/test/cmocka/src/audio/eq_iir/CMakeLists.txt index a72903d1c1df..a520a22fa441 100644 --- a/test/cmocka/src/audio/eq_iir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_iir/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(audio_for_eq_iir STATIC ${PROJECT_SOURCE_DIR}/src/math/iir_df2t_hifi3.c ${PROJECT_SOURCE_DIR}/src/math/numbers.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c + ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c diff --git a/test/cmocka/src/audio/mixer/CMakeLists.txt b/test/cmocka/src/audio/mixer/CMakeLists.txt index e422dd6ebf96..01aebc99223e 100644 --- a/test/cmocka/src/audio/mixer/CMakeLists.txt +++ b/test/cmocka/src/audio/mixer/CMakeLists.txt @@ -11,6 +11,7 @@ cmocka_test(mixer ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c + ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c diff --git a/test/cmocka/src/audio/mux/CMakeLists.txt b/test/cmocka/src/audio/mux/CMakeLists.txt index 59e3752599fc..c6f67ae89127 100644 --- a/test/cmocka/src/audio/mux/CMakeLists.txt +++ b/test/cmocka/src/audio/mux/CMakeLists.txt @@ -23,6 +23,7 @@ add_library( ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c + ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ) sof_append_relative_path_definitions(audio_mux) diff --git a/test/cmocka/src/audio/volume/CMakeLists.txt b/test/cmocka/src/audio/volume/CMakeLists.txt index a1cd1fd8cab2..f6530bc2b3b0 100644 --- a/test/cmocka/src/audio/volume/CMakeLists.txt +++ b/test/cmocka/src/audio/volume/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(audio_for_volume STATIC ${PROJECT_SOURCE_DIR}/src/audio/volume/volume_hifi3_with_peakvol.c ${PROJECT_SOURCE_DIR}/src/audio/volume/volume_hifi4_with_peakvol.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c + ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index e531eaabb690..12de15cfcde4 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -521,10 +521,19 @@ elseif(CONFIG_IPC_MAJOR_4) ) endif() +if(CONFIG_IPC_MAJOR_3) zephyr_library_sources_ifdef(CONFIG_COMP_MODULE_ADAPTER ${SOF_AUDIO_PATH}/module_adapter/module_adapter.c + ${SOF_AUDIO_PATH}/module_adapter/module_adapter_ipc3.c ${SOF_AUDIO_PATH}/module_adapter/module/generic.c ) +elseif(CONFIG_IPC_MAJOR_4) +zephyr_library_sources_ifdef(CONFIG_COMP_MODULE_ADAPTER + ${SOF_AUDIO_PATH}/module_adapter/module_adapter.c + ${SOF_AUDIO_PATH}/module_adapter/module_adapter_ipc4.c + ${SOF_AUDIO_PATH}/module_adapter/module/generic.c +) +endif() zephyr_library_sources_ifdef(CONFIG_LIBRARY_MANAGER ${SOF_SRC_PATH}/library_manager/lib_manager.c