Unverified Commit 4343af66 authored by Cezary Rojewski's avatar Cezary Rojewski Committed by Mark Brown
Browse files

ASoC: Intel: avs: Add WHM module support



WovHostModule (WHM) is used in wake-on-voice scenarios to optimize power
consumption. It combines capabilities of Copier, KeyPhraseBuffer,
WakeOnVoice and Muxer modules.

Signed-off-by: default avatarPiotr Maziarz <piotrx.maziarz@linux.intel.com>
Signed-off-by: default avatarCezary Rojewski <cezary.rojewski@intel.com>
Link: https://patch.msgid.link/20250203141051.2361323-11-cezary.rojewski@intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 320155a6
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -77,6 +77,13 @@ enum avs_tplg_token {
	AVS_TKN_MODCFG_UPDOWN_MIX_CHAN_MAP_U32		= 430,
	AVS_TKN_MODCFG_EXT_NUM_INPUT_PINS_U16		= 431,
	AVS_TKN_MODCFG_EXT_NUM_OUTPUT_PINS_U16		= 432,
	AVS_TKN_MODCFG_WHM_REF_AFMT_ID_U32		= 433,
	AVS_TKN_MODCFG_WHM_OUT_AFMT_ID_U32		= 434,
	AVS_TKN_MODCFG_WHM_WAKE_TICK_PERIOD_U32		= 435,
	AVS_TKN_MODCFG_WHM_VINDEX_U8			= 436,
	AVS_TKN_MODCFG_WHM_DMA_TYPE_U32			= 437,
	AVS_TKN_MODCFG_WHM_DMABUFF_SIZE_U32		= 438,
	AVS_TKN_MODCFG_WHM_BLOB_AFMT_ID_U32		= 439,

	/* struct avs_tplg_pplcfg */
	AVS_TKN_PPLCFG_ID_U32				= 1401,
+13 −0
Original line number Diff line number Diff line
@@ -652,6 +652,9 @@ int avs_ipc_set_system_time(struct avs_dev *adev);
#define AVS_INTELWOV_MOD_UUID \
	GUID_INIT(0xEC774FA9, 0x28D3, 0x424A, 0x90, 0xE4, 0x69, 0xF9, 0x84, 0xF1, 0xEE, 0xB7)

#define AVS_WOVHOSTM_MOD_UUID \
	GUID_INIT(0xF9ED62B7, 0x092E, 0x4A90, 0x8F, 0x4D, 0x82, 0xDA, 0xA8, 0xB3, 0x8F, 0x3B)

/* channel map */
enum avs_channel_index {
	AVS_CHANNEL_LEFT = 0,
@@ -881,6 +884,16 @@ struct avs_wov_cfg {
} __packed;
static_assert(sizeof(struct avs_wov_cfg) == 44);

struct avs_whm_cfg {
	struct avs_modcfg_base base;
	/* Audio format for output pin 0 */
	struct avs_audio_format ref_fmt;
	struct avs_audio_format out_fmt;
	u32 wake_tick_period;
	struct avs_copier_gtw_cfg gtw_cfg;
} __packed;
static_assert(sizeof(struct avs_whm_cfg) == 108);

/* Module runtime parameters */

enum avs_copier_runtime_param {
+36 −0
Original line number Diff line number Diff line
@@ -265,6 +265,41 @@ static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod)
	return ret;
}

static int avs_whm_create(struct avs_dev *adev, struct avs_path_module *mod)
{
	struct avs_tplg_module *t = mod->template;
	struct avs_tplg_modcfg_ext *te;
	struct avs_whm_cfg *cfg;
	size_t cfg_size;
	u32 dma_id;
	int ret;

	te = t->cfg_ext;
	cfg = adev->modcfg_buf;
	dma_id = mod->owner->owner->dma_id;
	cfg_size = offsetof(struct avs_whm_cfg, gtw_cfg.config);

	ret = avs_fill_gtw_config(adev, &cfg->gtw_cfg, t, &cfg_size);
	if (ret)
		return ret;

	cfg->base.cpc = t->cfg_base->cpc;
	cfg->base.ibs = t->cfg_base->ibs;
	cfg->base.obs = t->cfg_base->obs;
	cfg->base.is_pages = t->cfg_base->is_pages;
	cfg->base.audio_fmt = *t->in_fmt;
	cfg->ref_fmt = *te->whm.ref_fmt;
	cfg->out_fmt = *te->whm.out_fmt;
	cfg->wake_tick_period = te->whm.wake_tick_period;
	avs_init_node_id(&cfg->gtw_cfg.node_id, te, dma_id);
	cfg->gtw_cfg.dma_buffer_size = te->whm.dma_buffer_size;
	mod->gtw_attrs = cfg->gtw_cfg.config.attrs;

	ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, t->core_id,
				  t->domain, cfg, cfg_size, &mod->instance_id);
	return ret;
}

static struct avs_control_data *avs_get_module_control(struct avs_path_module *mod)
{
	struct avs_tplg_module *t = mod->template;
@@ -536,6 +571,7 @@ static struct avs_module_create avs_module_create[] = {
	{ &AVS_ASRC_MOD_UUID, avs_asrc_create },
	{ &AVS_INTELWOV_MOD_UUID, avs_wov_create },
	{ &AVS_PROBE_MOD_UUID, avs_probe_create },
	{ &AVS_WOVHOSTM_MOD_UUID, avs_whm_create },
};

static int avs_path_module_type_create(struct avs_dev *adev, struct avs_path_module *mod)
+42 −0
Original line number Diff line number Diff line
@@ -815,6 +815,48 @@ static const struct avs_tplg_token_parser modcfg_ext_parsers[] = {
		.offset = offsetof(struct avs_tplg_modcfg_ext, generic.num_output_pins),
		.parse = avs_parse_short_token,
	},
	{
		.token = AVS_TKN_MODCFG_WHM_REF_AFMT_ID_U32,
		.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
		.offset = offsetof(struct avs_tplg_modcfg_ext, whm.ref_fmt),
		.parse = avs_parse_audio_format_ptr,
	},
	{
		.token = AVS_TKN_MODCFG_WHM_OUT_AFMT_ID_U32,
		.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
		.offset = offsetof(struct avs_tplg_modcfg_ext, whm.out_fmt),
		.parse = avs_parse_audio_format_ptr,
	},
	{
		.token = AVS_TKN_MODCFG_WHM_WAKE_TICK_PERIOD_U32,
		.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
		.offset = offsetof(struct avs_tplg_modcfg_ext, whm.wake_tick_period),
		.parse = avs_parse_word_token,
	},
	{
		.token = AVS_TKN_MODCFG_WHM_VINDEX_U8,
		.type = SND_SOC_TPLG_TUPLE_TYPE_BYTE,
		.offset = offsetof(struct avs_tplg_modcfg_ext, whm.vindex),
		.parse = avs_parse_byte_token,
	},
	{
		.token = AVS_TKN_MODCFG_WHM_DMA_TYPE_U32,
		.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
		.offset = offsetof(struct avs_tplg_modcfg_ext, whm.dma_type),
		.parse = avs_parse_word_token,
	},
	{
		.token = AVS_TKN_MODCFG_WHM_DMABUFF_SIZE_U32,
		.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
		.offset = offsetof(struct avs_tplg_modcfg_ext, whm.dma_buffer_size),
		.parse = avs_parse_word_token,
	},
	{
		.token = AVS_TKN_MODCFG_WHM_BLOB_AFMT_ID_U32,
		.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
		.offset = offsetof(struct avs_tplg_modcfg_ext, whm.blob_fmt),
		.parse = avs_parse_audio_format_ptr,
	},
};

static const struct avs_tplg_token_parser pin_format_parsers[] = {
+9 −0
Original line number Diff line number Diff line
@@ -75,6 +75,15 @@ struct avs_tplg_modcfg_ext {
			u32 dma_type;
			u32 dma_buffer_size;
		} copier;
		struct {
			struct avs_audio_format *ref_fmt;
			struct avs_audio_format *out_fmt;
			u32 wake_tick_period;
			union avs_virtual_index vindex;
			u32 dma_type;
			u32 dma_buffer_size;
			struct avs_audio_format *blob_fmt; /* optional override */
		} whm;
		struct {
			u32 out_channel_config;
			u32 coefficients_select;