diff --git a/app/boards/intel_adsp_ace15_mtpm.conf b/app/boards/intel_adsp_ace15_mtpm.conf index 5ca3fbdbb4d1..9602f37ddda3 100644 --- a/app/boards/intel_adsp_ace15_mtpm.conf +++ b/app/boards/intel_adsp_ace15_mtpm.conf @@ -38,6 +38,7 @@ CONFIG_DMA_DW_LLI_POOL_SIZE=50 CONFIG_DMA_DW_SUSPEND_DRAIN=y CONFIG_INTEL_MODULES=y CONFIG_LIBRARY_MANAGER=y +CONFIG_LIBRARY_AUTH_SUPPORT=y CONFIG_INTEL_ADSP_TIMER=y CONFIG_MM_DRV_INTEL_ADSP_TLB_REMAP_UNUSED_RAM=y CONFIG_AMS=y diff --git a/app/boards/intel_adsp_ace20_lnl.conf b/app/boards/intel_adsp_ace20_lnl.conf index 99016e3a539c..5400e14efc58 100644 --- a/app/boards/intel_adsp_ace20_lnl.conf +++ b/app/boards/intel_adsp_ace20_lnl.conf @@ -32,6 +32,7 @@ CONFIG_DMA=y CONFIG_DMA_INTEL_ADSP_GPDMA=n CONFIG_INTEL_MODULES=y CONFIG_LIBRARY_MANAGER=y +CONFIG_LIBRARY_AUTH_SUPPORT=y CONFIG_INTEL_ADSP_TIMER=y CONFIG_MM_DRV_INTEL_ADSP_TLB_REMAP_UNUSED_RAM=y CONFIG_AMS=y diff --git a/src/audio/volume/volume_ipc4.c b/src/audio/volume/volume_ipc4.c index 9a9951169ce3..92d2dc4ee65f 100644 --- a/src/audio/volume/volume_ipc4.c +++ b/src/audio/volume/volume_ipc4.c @@ -54,10 +54,6 @@ static int set_volume_ipc4(struct vol_data *cd, uint32_t const channel, cd->tvolume[channel] = target_volume; /* init ramp start volume*/ cd->rvolume[channel] = 0; - /* init muted volume */ - cd->mvolume[channel] = 0; - /* set muted as false*/ - cd->muted[channel] = false; /* ATM there is support for the same ramp for all channels */ cd->ramp_type = ipc4_curve_type_convert((enum ipc4_curve_type)curve_type); @@ -164,6 +160,9 @@ int volume_init(struct processing_module *mod) target_volume[channel_cfg], vol->config[channel_cfg].curve_type, vol->config[channel_cfg].curve_duration); + + /* set muted as false*/ + cd->muted[channel] = false; } init_ramp(cd, vol->config[0].curve_duration, target_volume[0]); @@ -224,21 +223,30 @@ static int volume_set_volume(struct processing_module *mod, const uint8_t *data, if (cdata.channel_id == IPC4_ALL_CHANNELS_MASK) { for (i = 0; i < channels_count; i++) { - set_volume_ipc4(cd, i, cdata.target_volume, - cdata.curve_type, - cdata.curve_duration); - - volume_set_chan(mod, i, cd->tvolume[i], true); + if (cd->muted[i]) { + cd->mvolume[i] = cdata.target_volume; + } else { + set_volume_ipc4(cd, i, cdata.target_volume, + cdata.curve_type, + cdata.curve_duration); + + volume_set_chan(mod, i, cd->tvolume[i], true); + } if (cd->volume[i] != cd->tvolume[i]) cd->ramp_finished = false; } } else { - set_volume_ipc4(cd, cdata.channel_id, cdata.target_volume, - cdata.curve_type, - cdata.curve_duration); + if (cd->muted[cdata.channel_id]) { + cd->mvolume[cdata.channel_id] = cdata.target_volume; + } else { + set_volume_ipc4(cd, cdata.channel_id, + cdata.target_volume, + cdata.curve_type, + cdata.curve_duration); - volume_set_chan(mod, cdata.channel_id, cd->tvolume[cdata.channel_id], - true); + volume_set_chan(mod, cdata.channel_id, + cd->tvolume[cdata.channel_id], true); + } if (cd->volume[cdata.channel_id] != cd->tvolume[cdata.channel_id]) cd->ramp_finished = false; } @@ -297,6 +305,53 @@ static int volume_set_attenuation(struct processing_module *mod, const uint8_t * return 0; } +static int volume_set_switch(struct processing_module *mod, const uint8_t *data, + int data_size) +{ + struct vol_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; + struct sof_ipc4_control_msg_payload *ctl; + unsigned int channels_count, num_elems; + unsigned int i, val; + + if (data_size < sizeof(struct sof_ipc4_control_msg_payload)) { + comp_err(dev, "error: data_size %d should be bigger than %d", data_size, + sizeof(struct sof_ipc4_control_msg_payload)); + return -EINVAL; + } + + ctl = (struct sof_ipc4_control_msg_payload *)data; + + cd->ramp_finished = true; + + channels_count = mod->priv.cfg.base_cfg.audio_fmt.channels_count; + if (channels_count > SOF_IPC_MAX_CHANNELS) { + comp_err(dev, "Invalid channels count %u", channels_count); + return -EINVAL; + } + + num_elems = ctl->num_elems; + if (num_elems > channels_count) { + comp_warn(dev, "limit num_elems %d to %d", num_elems, channels_count); + num_elems = channels_count; + } + + for (i = 0; i < num_elems; i++) { + val = ctl->chanv[i].value; + comp_dbg(dev, "channel %i, value %u", i, val); + + if (val) + volume_set_chan_unmute(mod, i); + else + volume_set_chan_mute(mod, i); + + if (cd->volume[i] != cd->tvolume[i]) + cd->ramp_finished = false; + } + + return 0; +} + int volume_set_config(struct processing_module *mod, uint32_t config_id, enum module_cfg_fragment_position pos, uint32_t data_offset_size, const uint8_t *fragment, size_t fragment_size, uint8_t *response, @@ -323,6 +378,8 @@ int volume_set_config(struct processing_module *mod, uint32_t config_id, return volume_set_volume(mod, fragment, fragment_size); case IPC4_SET_ATTENUATION: return volume_set_attenuation(mod, fragment, fragment_size); + case SOF_IPC4_SWITCH_CONTROL_PARAM_ID: + return volume_set_switch(mod, fragment, fragment_size); default: comp_err(dev, "unsupported param %d", config_id); return -EINVAL; diff --git a/src/include/sof/auth_api_iface.h b/src/include/sof/auth_api_iface.h new file mode 100644 index 000000000000..ff8b1006076a --- /dev/null +++ b/src/include/sof/auth_api_iface.h @@ -0,0 +1,149 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 Intel Corporation. All rights reserved. + * + * Author: Jaroslaw Stelter + * Pawel Dobrowolski + */ +#ifndef __AUTH_API_IFACE_H__ +#define __AUTH_API_IFACE_H__ + +#include +#include +#include + +#define AUTH_API_VERSION_MAJOR (2) +#define AUTH_API_VERSION_MINOR (0) +#define AUTH_API_VERSION_PATCH (0) + +#define AUTH_SCRATCH_BUFF_SZ (0xA000) // 40kB + +/* + * Return codes supported by authentication engine: + * ADSP_AUTH_IMAGE_UNTRUSTED = 9040, + * ADSP_AUTH_CANNOT_ALLOCATE_SCRATCH_BUFF = 9041, + * ADSP_AUTH_INVALID_AUTH_API_CTX_PTR = 9042, + * ADSP_AUTH_SVN_VERIFICATION_FAIL = 9043, + * ADSP_AUTH_IFWI_PARTITION_FAIL = 9044, + * ADSP_AUTH_VERIFY_IMAGE_TYPE_FAIL = 9045, + * ADSP_AUTH_UNSUPPORTED_VERSION = 9046, + * ADSP_AUTH_INCOMPATIBLE_MANIFEST_VERSION = 9047, + */ + +struct auth_api_version_num { + uint8_t patch; + uint8_t minor; + uint8_t major; + uint8_t rsvd; +} __packed __aligned(4); + +enum auth_phase { + AUTH_PHASE_FIRST = 0, + AUTH_PHASE_MID = 1, + AUTH_PHASE_LAST = 2 +}; + +enum auth_result { + AUTH_NOT_COMPLETED = 0, + AUTH_IMAGE_TRUSTED = 1, + AUTH_IMAGE_UNTRUSTED = 2 +}; + +enum auth_image_type { + IMG_TYPE_ROM_EXT = 0, + IMG_TYPE_MAIN_FW = 1, + IMG_TYPE_LIB = 2 +}; + +struct auth_api_ctx; + +struct auth_api_version { + /* Interface to return authentication API version. + * Return value: version number represented by auth_api_version_num structure. + */ + struct auth_api_version_num (*version)(); +}; + +struct auth_api { + /* Interface to initialize authentication API and context. + * Parameters: + * ctx - pointer to the context instance of type auth_api_ctx. + * scratch_buff - pointer to scratch buffer. + * Scratch buffer must be located in L2 Local Memory (SHA Engine limitation). + * Caller is responsible to power up necessary L2 Local Memory banks. + * Address alignment must correspond to SHA384_IO_BUF_ALIGNMENT. + * scratch_buff_size – size must be the same as AUTH_SCRATCH_BUFF_SZ. + * Return value: + * ADSP_SUCCESS - successful initialization. + */ + int (*init)(struct auth_api_ctx *ctx, void *scratch_buff, size_t scratch_buff_size, + enum auth_image_type image_type); + + /* Interface to cleanup authentication API. + * Parameters: + * ctx - pointer to the context instance of type AuthApiCtx. + */ + void (*cleanup)(struct auth_api_ctx *ctx); + + /* Interface for initiating signed FW image (async) authentication process. + * Parameters: + * ctx - pointer to the context instance of type AuthApiCtx. + * chunk - pointer to the chunk of signed FW image. + * chunk_size - chunk size in bytes. + * phase - authentication phase. + * Must corresponds to one of the AuthPhase values. + * In case of one time FW authentication, where signed FW image size must be + * less or equal to scratch_buff_size, the caller must pass AUTH_PHASE_LAST. + * Return value: ADSP_SUCCESS when authentication process has been initiated + * successfully, or one of ADSP_FLV_* error codes in case of failure. + */ + int (*init_auth_proc)(struct auth_api_ctx *ctx, const void *chunk, size_t chunk_size, + enum auth_phase phase); + + /* Interface to return if authentication process is busy. + * Parameters: + * ctx - pointer to the context instance of type AuthApiCtx. + * This function can be used for authentication process synchronization. + * Return value: true if authentication process is busy. + */ + bool (*busy)(struct auth_api_ctx *ctx); + + /* Interface to return authentication result + * Parameters: + * ctx - pointer to the context instance of type AuthApiCtx. + * Return value: + * AUTH_NOT_COMPLETED - authentication is not completed, + * AUTH_IMAGE_TRUSTED - authentication completed and signed FW image is + * trusted, + * AUTH_IMAGE_UNTRUSTED - authentication completed, but signed FW image is + * untrusted. + */ + enum auth_result (*result)(struct auth_api_ctx *ctx); + + /* Interface to register status/error code logger. + * Parameters: + * ctx - pointer to the context instance of type AuthApiCtx. + * sts_logger - pointer to status logger. + * Return value: ADSP_SUCCESS when logger has been registered successfully. + */ + int (*register_status_logger)(struct auth_api_ctx *ctx, + struct status_logger_ctx *status_logger); + + /* Interface to unregister status/error code logger. + * Parameters: + * ctx - pointer to the context instance of type AuthApiCtx. + */ + void (*unregister_status_logger)(struct auth_api_ctx *ctx); +}; + +struct auth_api_ctx { + struct auth_api_version *version_api; + void *scratch_buff; + size_t scratch_buff_size; + enum auth_result result; + struct auth_api *auth_api; + enum auth_image_type image_type; + struct status_logger_ctx *status_logger; +}; + +#endif /* __SOF_LIB_MANAGER_H__ */ diff --git a/src/include/sof/lib_manager.h b/src/include/sof/lib_manager.h index 5e0e47fdacb7..3c44755b246d 100644 --- a/src/include/sof/lib_manager.h +++ b/src/include/sof/lib_manager.h @@ -64,6 +64,9 @@ #include #include +#if CONFIG_LIBRARY_AUTH_SUPPORT +#include +#endif #define LIB_MANAGER_MAX_LIBS 16 #define LIB_MANAGER_LIB_ID_SHIFT 12 @@ -86,6 +89,10 @@ struct ext_library { uint32_t lib_notif_count; void *runtime_data; +#if CONFIG_LIBRARY_AUTH_SUPPORT + struct auth_api_ctx auth_ctx; + void *auth_buffer; +#endif }; /* lib manager context, used by lib_notification */ diff --git a/src/library_manager/Kconfig b/src/library_manager/Kconfig index f9a71ebf6cda..37692164ee4f 100644 --- a/src/library_manager/Kconfig +++ b/src/library_manager/Kconfig @@ -13,4 +13,14 @@ config LIBRARY_MANAGER Externally developed modules both for SOF and Zephyr could be used if enabled. If unsure say N. + +config LIBRARY_AUTH_SUPPORT + bool "Library Authentication Support" + default n + help + This is support for dynamic modules authentication. + Externally developed modules both for SOF and Zephyr + could be used if enabled. + If unsure say N. + endmenu diff --git a/src/library_manager/lib_manager.c b/src/library_manager/lib_manager.c index b8f3644cf648..1274b63dd9d2 100644 --- a/src/library_manager/lib_manager.c +++ b/src/library_manager/lib_manager.c @@ -24,6 +24,10 @@ #include #include +#if CONFIG_LIBRARY_AUTH_SUPPORT +#include +#endif + #include #include #include @@ -46,6 +50,74 @@ struct lib_manager_dma_ext { static struct ext_library loader_ext_lib; +#if CONFIG_LIBRARY_AUTH_SUPPORT +static int lib_manager_auth_init(void) +{ + struct ext_library *ext_lib = ext_lib_get(); + int ret; + + if (auth_api_version().major != AUTH_API_VERSION_MAJOR) + return -EINVAL; + + ext_lib->auth_buffer = rballoc_align(0, SOF_MEM_CAPS_RAM, + AUTH_SCRATCH_BUFF_SZ, CONFIG_MM_DRV_PAGE_SIZE); + if (!ext_lib->auth_buffer) + return -ENOMEM; + + ret = auth_api_init(&ext_lib->auth_ctx, ext_lib->auth_buffer, + AUTH_SCRATCH_BUFF_SZ, IMG_TYPE_LIB); + if (ret != 0) { + tr_err(&lib_manager_tr, "lib_manager_auth_init() failed with error: %d", ret); + rfree(ext_lib->auth_buffer); + ret = -EACCES; + } + + return ret; +} + +static void lib_manager_auth_deinit(void) +{ + struct ext_library *ext_lib = ext_lib_get(); + + if (ext_lib->auth_buffer) + memset(ext_lib->auth_buffer, 0, AUTH_SCRATCH_BUFF_SZ); + + rfree(ext_lib->auth_buffer); + ext_lib->auth_buffer = NULL; + memset(&ext_lib->auth_ctx, 0, sizeof(struct auth_api_ctx)); +} + +static int lib_manager_auth_proc(const void *buffer_data, + size_t buffer_size, enum auth_phase phase) +{ + struct ext_library *ext_lib = ext_lib_get(); + int ret; + + ret = auth_api_init_auth_proc(&ext_lib->auth_ctx, buffer_data, buffer_size, phase); + + if (ret != 0) { + tr_err(&lib_manager_tr, "lib_manager_auth_proc() failed with error: %d", ret); + return -ENOTSUP; + } + + /* The auth_api_busy() will timeouts internally in case of failure */ + while (auth_api_busy(&ext_lib->auth_ctx)) + ; + + ret = auth_api_result(&ext_lib->auth_ctx); + + if (ret != AUTH_IMAGE_TRUSTED) { + tr_err(&lib_manager_tr, "lib_manager_auth_proc() Untrasted library!"); + return -EACCES; + } + + if (phase == AUTH_PHASE_LAST) + auth_api_cleanup(&ext_lib->auth_ctx); + + return 0; +} +#endif /* CONFIG_LIBRARY_AUTH_SUPPORT */ + #if IS_ENABLED(CONFIG_MM_DRV) #define PAGE_SZ CONFIG_MM_DRV_PAGE_SIZE @@ -582,6 +654,16 @@ static int lib_manager_store_library(struct lib_manager_dma_ext *dma_ext, tr_dbg(&lib_manager_tr, "lib_manager_store_library(): pointer: %p", (__sparse_force void *)library_base_address); +#if CONFIG_LIBRARY_AUTH_SUPPORT + /* AUTH_PHASE_FIRST - checks library manifest only. */ + ret = lib_manager_auth_proc((__sparse_force void *)man_buffer, + MAN_MAX_SIZE_V1_8, AUTH_PHASE_FIRST); + if (ret < 0) { + rfree((__sparse_force void *)library_base_address); + return ret; + } +#endif /* CONFIG_LIBRARY_AUTH_SUPPORT */ + /* Copy data from temp_mft_buf to destination memory (pointed by library_base_address) */ memcpy_s((__sparse_force void *)library_base_address, MAN_MAX_SIZE_V1_8, (__sparse_force void *)man_buffer, MAN_MAX_SIZE_V1_8); @@ -594,6 +676,16 @@ static int lib_manager_store_library(struct lib_manager_dma_ext *dma_ext, return ret; } +#if CONFIG_LIBRARY_AUTH_SUPPORT + /* AUTH_PHASE_LAST - do final library authentication checks */ + ret = lib_manager_auth_proc((__sparse_force void *)library_base_address, + preload_size - MAN_MAX_SIZE_V1_8, AUTH_PHASE_LAST); + if (ret < 0) { + rfree((__sparse_force void *)library_base_address); + return ret; + } +#endif /* CONFIG_LIBRARY_AUTH_SUPPORT */ + /* Now update sof context with new library */ lib_manager_update_sof_ctx((__sparse_force void *)library_base_address, lib_id); @@ -703,7 +795,7 @@ int lib_manager_load_library(uint32_t dma_id, uint32_t lib_id, uint32_t type) /* allocate temporary manifest buffer */ man_tmp_buffer = (__sparse_force void __sparse_cache *) rballoc_align(0, SOF_MEM_CAPS_DMA, - MAN_MAX_SIZE_V1_8, dma_ext->addr_align); + MAN_MAX_SIZE_V1_8, CONFIG_MM_DRV_PAGE_SIZE); if (!man_tmp_buffer) { ret = -ENOMEM; goto cleanup; @@ -714,8 +806,19 @@ int lib_manager_load_library(uint32_t dma_id, uint32_t lib_id, uint32_t type) if (ret < 0) goto stop_dma; +#if CONFIG_LIBRARY_AUTH_SUPPORT + /* Initialize authentication support */ + ret = lib_manager_auth_init(); + if (ret < 0) + goto stop_dma; +#endif /* CONFIG_LIBRARY_AUTH_SUPPORT */ + ret = lib_manager_store_library(dma_ext, man_tmp_buffer, lib_id); +#if CONFIG_LIBRARY_AUTH_SUPPORT + lib_manager_auth_deinit(); +#endif /* CONFIG_LIBRARY_AUTH_SUPPORT */ + stop_dma: ret2 = dma_stop(dma_ext->chan->dma->z_dev, dma_ext->chan->index); if (ret2 < 0) { diff --git a/src/platform/intel/ace/include/auth/intel_auth_api.h b/src/platform/intel/ace/include/auth/intel_auth_api.h new file mode 100644 index 000000000000..69a9e0cd8ca2 --- /dev/null +++ b/src/platform/intel/ace/include/auth/intel_auth_api.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 Intel Corporation. All rights reserved. + * + * Author: Jaroslaw Stelter + * Pawel Dobrowolski + */ +#ifndef INTEL_AUTH_API_H +#define INTEL_AUTH_API_H + +#include + +#define AUTH_API_CALLBACKS_ADDR (0x162000 + 0x140) + +/* The same as auth_api->init. */ +inline int auth_api_init(struct auth_api_ctx *ctx, + void *scratch_buff, + size_t scratch_buff_size, + enum auth_image_type image_type) +{ + struct auth_api_ctx **auth_api_callbacks = + (struct auth_api_ctx **)AUTH_API_CALLBACKS_ADDR; + + ctx->version_api = (*auth_api_callbacks)->version_api; + ctx->auth_api = (*auth_api_callbacks)->auth_api; + return ctx->auth_api->init(ctx, scratch_buff, scratch_buff_size, image_type); +} + +/* The same as auth_api->cleanup. */ +inline void auth_api_cleanup(struct auth_api_ctx *ctx) +{ + ctx->auth_api->cleanup(ctx); +} + +/* The same as auth_api->init_auth_proc. */ +inline int auth_api_init_auth_proc(struct auth_api_ctx *ctx, + const void *chunk, + size_t chunk_size, + enum auth_phase phase) +{ + return ctx->auth_api->init_auth_proc(ctx, chunk, chunk_size, phase); +} + +/* The same as auth_api->busy. */ +inline bool auth_api_busy(struct auth_api_ctx *ctx) +{ + return ctx->auth_api->busy(ctx); +} + +/* The same as auth_api->result. */ +inline enum auth_result auth_api_result(struct auth_api_ctx *ctx) +{ + return ctx->auth_api->result(ctx); +} + +/* The same as auth_api->register_status_logger. */ +inline int auth_api_register_status_logger(struct auth_api_ctx *ctx, + struct status_logger_ctx *status_logger) +{ + return ctx->auth_api->register_status_logger(ctx, status_logger); +} + +/* The same as AuthApi::UnregisterStatusLogger. */ +inline void auth_api_unregister_status_logger(struct auth_api_ctx *ctx) +{ + ctx->auth_api->unregister_status_logger(ctx); +} + +/* The same as auth_api->version. */ +inline struct auth_api_version_num auth_api_version(void) +{ + struct auth_api_ctx **auth_api_callbacks = + (struct auth_api_ctx **)AUTH_API_CALLBACKS_ADDR; + return (*auth_api_callbacks)->version_api->version(); +} + +#endif /* INTEL_AUTH_API_H */ + diff --git a/src/platform/intel/ace/include/auth/intel_status_logger_api.h b/src/platform/intel/ace/include/auth/intel_status_logger_api.h new file mode 100644 index 000000000000..eca4162219da --- /dev/null +++ b/src/platform/intel/ace/include/auth/intel_status_logger_api.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 Intel Corporation. All rights reserved. + * + * Author: Jaroslaw Stelter + * Pawel Dobrowolski + */ +#ifndef INTEL_STATUS_LOGGER_API +#define INTEL_STATUS_LOGGER_API + +#include "stdint.h" +#include "intel_status_logger_iface.h" + +inline void sts_log_init(struct status_logger_ctx *ctx) +{ + ctx->cb.init(ctx); +} + +inline void sts_log_cleanup(struct status_logger_ctx *ctx) +{ + ctx->cb.cleanup(ctx); +} + +inline void sts_log_report_error(struct status_logger_ctx *ctx, int error_code) +{ + ctx->cb.report_error(ctx, error_code); +} + +inline void sts_log_set_boot_state(struct status_logger_ctx *ctx, uint32_t state) +{ + ctx->cb.set_boot_state(ctx, state); +} + +inline void sts_log_set_wait_state(struct status_logger_ctx *ctx, uint32_t state) +{ + ctx->cb.set_wait_state(ctx, state); +} + +inline void sts_log_set_module(struct status_logger_ctx *ctx, uint32_t mod) +{ + ctx->cb.set_module(ctx, mod); +} + +#endif /*INTEL_STATUS_LOGGER_API*/ diff --git a/src/platform/intel/ace/include/auth/intel_status_logger_iface.h b/src/platform/intel/ace/include/auth/intel_status_logger_iface.h new file mode 100644 index 000000000000..4a22a072bebc --- /dev/null +++ b/src/platform/intel/ace/include/auth/intel_status_logger_iface.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 Intel Corporation. All rights reserved. + * + * Author: Jaroslaw Stelter + * Pawel Dobrowolski + */ +#ifndef INTEL_STATUS_LOGGER_IFACE +#define INTEL_STATUS_LOGGER_IFACE + +#include "stdint.h" + +struct status_logger_ctx; + +/* Status Logger Interface callbacks. */ +struct status_logger_iface { + /* Interface to initialize Status Logger context. + * Parameters: + * @param status_logger_ctx *ctx - pointer to the context instance. + * Return value: + * 0 - SUCCESS - successful initialization. + */ + int (*init)(struct status_logger_ctx *ctx); + + /* Interface to cleanup Status Logger context. + * Parameters: + * @param status_logger_ctx *ctx - pointer to the context instance. + */ + void (*cleanup)(struct status_logger_ctx *ctx); + + /** + * Reports critical rom error. Halts execution. + * Parameters: + * @param status_logger_ctx *ctx - pointer to the context instance. + * @param error_code - error code to report + */ + void (*report_error)(struct status_logger_ctx *ctx, int error_code); + + /** + * Reports boot status. + * Parameters: + * @param status_logger_ctx *ctx - pointer to the context instance. + * @param uint32_t state - boot state code to report. + */ + void (*set_boot_state)(struct status_logger_ctx *ctx, uint32_t state); + + /** + * Reports that caller is waiting on some external event or action. + * Parameters: + * @param status_logger_ctx *ctx - pointer to the context instance. + * @param uint32_t state - reason of waiting. + */ + void (*set_wait_state)(struct status_logger_ctx *ctx, uint32_t state); + + /** + * Set module type in FSR. + * Parameters: + * @param status_logger_ctx *ctx - pointer to the context instance. + * @param mod module id + */ + + void (*set_module)(struct status_logger_ctx *ctx, uint32_t mod); +} __packed __aligned(4); + +/* Design note: Compiler was not able to generate proper call assembly code using standard C++ + * inheritance in Auth API implementation. That's why we do explicit callbacks assignment, + * following C-like OOP. + */ +struct status_logger_ctx { + struct status_logger_iface cb; +}; + +#endif /*INTEL_STATUS_LOGGER_IFACE*/ diff --git a/tools/topology/topology2/include/components/gain.conf b/tools/topology/topology2/include/components/gain.conf index 3343365880fd..757bcb24ff72 100644 --- a/tools/topology/topology2/include/components/gain.conf +++ b/tools/topology/topology2/include/components/gain.conf @@ -152,6 +152,41 @@ Class.Widget."gain" { } } } + + # mute switch control + mixer."2" { + Object.Base.channel.1 { + name "flw" + reg 2 + shift 0 + } + Object.Base.channel.2 { + name "fl" + reg 2 + shift 1 + } + Object.Base.channel.3 { + name "fr" + reg 2 + shift 2 + } + Object.Base.channel.4 { + name "frw" + reg 2 + shift 3 + } + + Object.Base.ops.1 { + name "ctl" + info "volsw" + ## get = 259 binds the mixer control to switch get/put handlers + get 259 + put 259 + } + + #max 1 indicates switch type control + max 1 + } } # Default attribute values for gain widget diff --git a/tools/topology/topology2/platform/intel/dmic-generic.conf b/tools/topology/topology2/platform/intel/dmic-generic.conf index 5ca0ec27c79b..11fede22cf63 100644 --- a/tools/topology/topology2/platform/intel/dmic-generic.conf +++ b/tools/topology/topology2/platform/intel/dmic-generic.conf @@ -140,7 +140,13 @@ IncludeByKey.PASSTHROUGH { } ] Object.Control.mixer.1 { - name '$DMIC0_PCM_NAME Capture Volume' + name 'Dmic0 Capture Volume' + } + Object.Control.mixer.2 { + name 'Dmic0 Capture Switch' + + mute_led_use 1 + mute_led_direction 1 } }