// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
//
// This file is provided under a dual BSD/GPLv2 license.  When using or
// redistributing this file, you may do so under either license.
//
// Copyright(c) 2022 Intel Corporation. All rights reserved.
//
//
#include <uapi/sound/sof/tokens.h>
#include <sound/pcm_params.h>
#include <sound/sof/ext_manifest4.h>
#include <sound/intel-nhlt.h>
#include "sof-priv.h"
#include "sof-audio.h"
#include "ipc4-priv.h"
#include "ipc4-topology.h"
#include "ops.h"

#define SOF_IPC4_GAIN_PARAM_ID  0
#define SOF_IPC4_TPLG_ABI_SIZE 6

static DEFINE_IDA(alh_group_ida);
static DEFINE_IDA(pipeline_ida);

static const struct sof_topology_token ipc4_sched_tokens[] = {
	{SOF_TKN_SCHED_LP_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_pipeline, lp_mode)}
};

static const struct sof_topology_token pipeline_tokens[] = {
	{SOF_TKN_SCHED_DYNAMIC_PIPELINE, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16,
		offsetof(struct snd_sof_widget, dynamic_pipeline_widget)},
};

static const struct sof_topology_token ipc4_comp_tokens[] = {
	{SOF_TKN_COMP_CPC, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_base_module_cfg, cpc)},
	{SOF_TKN_COMP_IS_PAGES, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_base_module_cfg, is_pages)},
};

static const struct sof_topology_token ipc4_audio_format_buffer_size_tokens[] = {
	{SOF_TKN_CAVS_AUDIO_FORMAT_IBS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_base_module_cfg, ibs)},
	{SOF_TKN_CAVS_AUDIO_FORMAT_OBS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_base_module_cfg, obs)},
};

static const struct sof_topology_token ipc4_in_audio_format_tokens[] = {
	{SOF_TKN_CAVS_AUDIO_FORMAT_IN_RATE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_audio_format, sampling_frequency)},
	{SOF_TKN_CAVS_AUDIO_FORMAT_IN_BIT_DEPTH, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_audio_format, bit_depth)},
	{SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_MAP, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_audio_format, ch_map)},
	{SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_audio_format, ch_cfg)},
	{SOF_TKN_CAVS_AUDIO_FORMAT_IN_INTERLEAVING_STYLE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
		get_token_u32, offsetof(struct sof_ipc4_audio_format, interleaving_style)},
	{SOF_TKN_CAVS_AUDIO_FORMAT_IN_FMT_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_audio_format, fmt_cfg)},
};

static const struct sof_topology_token ipc4_out_audio_format_tokens[] = {
	{SOF_TKN_CAVS_AUDIO_FORMAT_OUT_RATE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_audio_format, sampling_frequency)},
	{SOF_TKN_CAVS_AUDIO_FORMAT_OUT_BIT_DEPTH, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_audio_format, bit_depth)},
	{SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_MAP, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_audio_format, ch_map)},
	{SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_audio_format, ch_cfg)},
	{SOF_TKN_CAVS_AUDIO_FORMAT_OUT_INTERLEAVING_STYLE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
		get_token_u32, offsetof(struct sof_ipc4_audio_format, interleaving_style)},
	{SOF_TKN_CAVS_AUDIO_FORMAT_OUT_FMT_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_audio_format, fmt_cfg)},
};

static const struct sof_topology_token ipc4_copier_gateway_cfg_tokens[] = {
	{SOF_TKN_CAVS_AUDIO_FORMAT_DMA_BUFFER_SIZE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 0},
};

static const struct sof_topology_token ipc4_copier_tokens[] = {
	{SOF_TKN_INTEL_COPIER_NODE_TYPE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 0},
};

static const struct sof_topology_token ipc4_audio_fmt_num_tokens[] = {
	{SOF_TKN_COMP_NUM_AUDIO_FORMATS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		0},
};

static const struct sof_topology_token dai_tokens[] = {
	{SOF_TKN_DAI_TYPE, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_dai_type,
		offsetof(struct sof_ipc4_copier, dai_type)},
	{SOF_TKN_DAI_INDEX, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_copier, dai_index)},
};

/* Component extended tokens */
static const struct sof_topology_token comp_ext_tokens[] = {
	{SOF_TKN_COMP_UUID, SND_SOC_TPLG_TUPLE_TYPE_UUID, get_token_uuid,
		offsetof(struct snd_sof_widget, uuid)},
};

static const struct sof_topology_token gain_tokens[] = {
	{SOF_TKN_GAIN_RAMP_TYPE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
		get_token_u32, offsetof(struct sof_ipc4_gain_data, curve_type)},
	{SOF_TKN_GAIN_RAMP_DURATION,
		SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_gain_data, curve_duration)},
	{SOF_TKN_GAIN_VAL, SND_SOC_TPLG_TUPLE_TYPE_WORD,
		get_token_u32, offsetof(struct sof_ipc4_gain_data, init_val)},
};

/* SRC */
static const struct sof_topology_token src_tokens[] = {
	{SOF_TKN_SRC_RATE_OUT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc4_src, sink_rate)},
};

static const struct sof_token_info ipc4_token_list[SOF_TOKEN_COUNT] = {
	[SOF_DAI_TOKENS] = {"DAI tokens", dai_tokens, ARRAY_SIZE(dai_tokens)},
	[SOF_PIPELINE_TOKENS] = {"Pipeline tokens", pipeline_tokens, ARRAY_SIZE(pipeline_tokens)},
	[SOF_SCHED_TOKENS] = {"Scheduler tokens", ipc4_sched_tokens,
		ARRAY_SIZE(ipc4_sched_tokens)},
	[SOF_COMP_EXT_TOKENS] = {"Comp extended tokens", comp_ext_tokens,
		ARRAY_SIZE(comp_ext_tokens)},
	[SOF_COMP_TOKENS] = {"IPC4 Component tokens",
		ipc4_comp_tokens, ARRAY_SIZE(ipc4_comp_tokens)},
	[SOF_IN_AUDIO_FORMAT_TOKENS] = {"IPC4 Input Audio format tokens",
		ipc4_in_audio_format_tokens, ARRAY_SIZE(ipc4_in_audio_format_tokens)},
	[SOF_OUT_AUDIO_FORMAT_TOKENS] = {"IPC4 Output Audio format tokens",
		ipc4_out_audio_format_tokens, ARRAY_SIZE(ipc4_out_audio_format_tokens)},
	[SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS] = {"IPC4 Audio format buffer size tokens",
		ipc4_audio_format_buffer_size_tokens,
		ARRAY_SIZE(ipc4_audio_format_buffer_size_tokens)},
	[SOF_COPIER_GATEWAY_CFG_TOKENS] = {"IPC4 Copier gateway config tokens",
		ipc4_copier_gateway_cfg_tokens, ARRAY_SIZE(ipc4_copier_gateway_cfg_tokens)},
	[SOF_COPIER_TOKENS] = {"IPC4 Copier tokens", ipc4_copier_tokens,
		ARRAY_SIZE(ipc4_copier_tokens)},
	[SOF_AUDIO_FMT_NUM_TOKENS] = {"IPC4 Audio format number tokens",
		ipc4_audio_fmt_num_tokens, ARRAY_SIZE(ipc4_audio_fmt_num_tokens)},
	[SOF_GAIN_TOKENS] = {"Gain tokens", gain_tokens, ARRAY_SIZE(gain_tokens)},
	[SOF_SRC_TOKENS] = {"SRC tokens", src_tokens, ARRAY_SIZE(src_tokens)},
};

static void sof_ipc4_dbg_audio_format(struct device *dev,
				      struct sof_ipc4_audio_format *format,
				      size_t object_size, int num_format)
{
	struct sof_ipc4_audio_format *fmt;
	void *ptr = format;
	int i;

	for (i = 0; i < num_format; i++, ptr = (u8 *)ptr + object_size) {
		fmt = ptr;
		dev_dbg(dev,
			" #%d: %uKHz, %ubit (ch_map %#x ch_cfg %u interleaving_style %u fmt_cfg %#x)\n",
			i, fmt->sampling_frequency, fmt->bit_depth, fmt->ch_map,
			fmt->ch_cfg, fmt->interleaving_style, fmt->fmt_cfg);
	}
}

/**
 * sof_ipc4_get_audio_fmt - get available audio formats from swidget->tuples
 * @scomp: pointer to pointer to SOC component
 * @swidget: pointer to struct snd_sof_widget containing tuples
 * @available_fmt: pointer to struct sof_ipc4_available_audio_format being filling in
 * @has_out_format: true if available_fmt contains output format
 *
 * Return: 0 if successful
 */
static int sof_ipc4_get_audio_fmt(struct snd_soc_component *scomp,
				  struct snd_sof_widget *swidget,
				  struct sof_ipc4_available_audio_format *available_fmt,
				  bool has_out_format)
{
	struct sof_ipc4_base_module_cfg *base_config;
	struct sof_ipc4_audio_format *out_format;
	int audio_fmt_num = 0;
	int ret, i;

	ret = sof_update_ipc_object(scomp, &audio_fmt_num,
				    SOF_AUDIO_FMT_NUM_TOKENS, swidget->tuples,
				    swidget->num_tuples, sizeof(audio_fmt_num), 1);
	if (ret || audio_fmt_num <= 0) {
		dev_err(scomp->dev, "Invalid number of audio formats: %d\n", audio_fmt_num);
		return -EINVAL;
	}
	available_fmt->audio_fmt_num = audio_fmt_num;

	dev_dbg(scomp->dev, "Number of audio formats: %d\n", available_fmt->audio_fmt_num);

	base_config = kcalloc(available_fmt->audio_fmt_num, sizeof(*base_config), GFP_KERNEL);
	if (!base_config)
		return -ENOMEM;

	/* set cpc and is_pages for all base_cfg */
	for (i = 0; i < available_fmt->audio_fmt_num; i++) {
		ret = sof_update_ipc_object(scomp, &base_config[i],
					    SOF_COMP_TOKENS, swidget->tuples,
					    swidget->num_tuples, sizeof(*base_config), 1);
		if (ret) {
			dev_err(scomp->dev, "parse comp tokens failed %d\n", ret);
			goto err_in;
		}
	}

	/* copy the ibs/obs for each base_cfg */
	ret = sof_update_ipc_object(scomp, base_config,
				    SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS, swidget->tuples,
				    swidget->num_tuples, sizeof(*base_config),
				    available_fmt->audio_fmt_num);
	if (ret) {
		dev_err(scomp->dev, "parse buffer size tokens failed %d\n", ret);
		goto err_in;
	}

	for (i = 0; i < available_fmt->audio_fmt_num; i++)
		dev_dbg(scomp->dev, "%d: ibs: %d obs: %d cpc: %d is_pages: %d\n", i,
			base_config[i].ibs, base_config[i].obs,
			base_config[i].cpc, base_config[i].is_pages);

	ret = sof_update_ipc_object(scomp, &base_config->audio_fmt,
				    SOF_IN_AUDIO_FORMAT_TOKENS, swidget->tuples,
				    swidget->num_tuples, sizeof(*base_config),
				    available_fmt->audio_fmt_num);
	if (ret) {
		dev_err(scomp->dev, "parse base_config audio_fmt tokens failed %d\n", ret);
		goto err_in;
	}

	dev_dbg(scomp->dev, "Get input audio formats for %s\n", swidget->widget->name);
	sof_ipc4_dbg_audio_format(scomp->dev, &base_config->audio_fmt,
				  sizeof(*base_config),
				  available_fmt->audio_fmt_num);

	available_fmt->base_config = base_config;

	if (!has_out_format)
		return 0;

	out_format = kcalloc(available_fmt->audio_fmt_num, sizeof(*out_format), GFP_KERNEL);
	if (!out_format) {
		ret = -ENOMEM;
		goto err_in;
	}

	ret = sof_update_ipc_object(scomp, out_format,
				    SOF_OUT_AUDIO_FORMAT_TOKENS, swidget->tuples,
				    swidget->num_tuples, sizeof(*out_format),
				    available_fmt->audio_fmt_num);

	if (ret) {
		dev_err(scomp->dev, "parse output audio_fmt tokens failed\n");
		goto err_out;
	}

	available_fmt->out_audio_fmt = out_format;
	dev_dbg(scomp->dev, "Get output audio formats for %s\n", swidget->widget->name);
	sof_ipc4_dbg_audio_format(scomp->dev, out_format, sizeof(*out_format),
				  available_fmt->audio_fmt_num);

	return 0;

err_out:
	kfree(out_format);
err_in:
	kfree(base_config);

	return ret;
}

/* release the memory allocated in sof_ipc4_get_audio_fmt */
static void sof_ipc4_free_audio_fmt(struct sof_ipc4_available_audio_format *available_fmt)

{
	kfree(available_fmt->base_config);
	available_fmt->base_config = NULL;
	kfree(available_fmt->out_audio_fmt);
	available_fmt->out_audio_fmt = NULL;
}

static void sof_ipc4_widget_free_comp_pipeline(struct snd_sof_widget *swidget)
{
	kfree(swidget->private);
}

static int sof_ipc4_widget_set_module_info(struct snd_sof_widget *swidget)
{
	struct snd_soc_component *scomp = swidget->scomp;
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);

	swidget->module_info = sof_ipc4_find_module_by_uuid(sdev, &swidget->uuid);

	if (swidget->module_info)
		return 0;

	dev_err(sdev->dev, "failed to find module info for widget %s with UUID %pUL\n",
		swidget->widget->name, &swidget->uuid);
	return -EINVAL;
}

static int sof_ipc4_widget_setup_msg(struct snd_sof_widget *swidget, struct sof_ipc4_msg *msg)
{
	struct sof_ipc4_fw_module *fw_module;
	uint32_t type;
	int ret;

	ret = sof_ipc4_widget_set_module_info(swidget);
	if (ret)
		return ret;

	fw_module = swidget->module_info;

	msg->primary = fw_module->man4_module_entry.id;
	msg->primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_INIT_INSTANCE);
	msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
	msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);

	msg->extension = SOF_IPC4_MOD_EXT_CORE_ID(swidget->core);

	type = (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_DP) ? 1 : 0;
	msg->extension |= SOF_IPC4_MOD_EXT_DOMAIN(type);

	return 0;
}

static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget)
{
	struct sof_ipc4_available_audio_format *available_fmt;
	struct snd_soc_component *scomp = swidget->scomp;
	struct sof_ipc4_copier *ipc4_copier;
	int node_type = 0;
	int ret, i;

	ipc4_copier = kzalloc(sizeof(*ipc4_copier), GFP_KERNEL);
	if (!ipc4_copier)
		return -ENOMEM;

	swidget->private = ipc4_copier;
	available_fmt = &ipc4_copier->available_fmt;

	dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name);

	ret = sof_ipc4_get_audio_fmt(scomp, swidget, available_fmt, true);
	if (ret)
		goto free_copier;

	available_fmt->dma_buffer_size = kcalloc(available_fmt->audio_fmt_num, sizeof(u32),
						 GFP_KERNEL);
	if (!available_fmt->dma_buffer_size) {
		ret = -ENOMEM;
		goto free_available_fmt;
	}

	/*
	 * This callback is used by host copier and module-to-module copier,
	 * and only host copier needs to set gtw_cfg.
	 */
	if (!WIDGET_IS_AIF(swidget->id))
		goto skip_gtw_cfg;

	ret = sof_update_ipc_object(scomp, available_fmt->dma_buffer_size,
				    SOF_COPIER_GATEWAY_CFG_TOKENS, swidget->tuples,
				    swidget->num_tuples, sizeof(u32),
				    available_fmt->audio_fmt_num);
	if (ret) {
		dev_err(scomp->dev, "Failed to parse dma buffer size in audio format for %s\n",
			swidget->widget->name);
		goto err;
	}

	dev_dbg(scomp->dev, "dma buffer size:\n");
	for (i = 0; i < available_fmt->audio_fmt_num; i++)
		dev_dbg(scomp->dev, "%d: %u\n", i,
			available_fmt->dma_buffer_size[i]);

	ret = sof_update_ipc_object(scomp, &node_type,
				    SOF_COPIER_TOKENS, swidget->tuples,
				    swidget->num_tuples, sizeof(node_type), 1);

	if (ret) {
		dev_err(scomp->dev, "parse host copier node type token failed %d\n",
			ret);
		goto err;
	}
	dev_dbg(scomp->dev, "host copier '%s' node_type %u\n", swidget->widget->name, node_type);

skip_gtw_cfg:
	ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL);
	if (!ipc4_copier->gtw_attr) {
		ret = -ENOMEM;
		goto err;
	}

	ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr;
	ipc4_copier->data.gtw_cfg.config_length =
		sizeof(struct sof_ipc4_gtw_attributes) >> 2;

	switch (swidget->id) {
	case snd_soc_dapm_aif_in:
	case snd_soc_dapm_aif_out:
		ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type);
		break;
	case snd_soc_dapm_buffer:
		ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_INVALID_NODE_ID;
		ipc4_copier->ipc_config_size = 0;
		break;
	default:
		dev_err(scomp->dev, "invalid widget type %d\n", swidget->id);
		ret = -EINVAL;
		goto free_gtw_attr;
	}

	/* set up module info and message header */
	ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg);
	if (ret)
		goto free_gtw_attr;

	return 0;

free_gtw_attr:
	kfree(ipc4_copier->gtw_attr);
err:
	kfree(available_fmt->dma_buffer_size);
free_available_fmt:
	sof_ipc4_free_audio_fmt(available_fmt);
free_copier:
	kfree(ipc4_copier);
	swidget->private = NULL;
	return ret;
}

static void sof_ipc4_widget_free_comp_pcm(struct snd_sof_widget *swidget)
{
	struct sof_ipc4_copier *ipc4_copier = swidget->private;
	struct sof_ipc4_available_audio_format *available_fmt;

	if (!ipc4_copier)
		return;

	available_fmt = &ipc4_copier->available_fmt;
	kfree(available_fmt->dma_buffer_size);
	kfree(available_fmt->base_config);
	kfree(available_fmt->out_audio_fmt);
	kfree(ipc4_copier->gtw_attr);
	kfree(ipc4_copier);
	swidget->private = NULL;
}

static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget)
{
	struct sof_ipc4_available_audio_format *available_fmt;
	struct snd_soc_component *scomp = swidget->scomp;
	struct snd_sof_dai *dai = swidget->private;
	struct sof_ipc4_copier *ipc4_copier;
	int node_type = 0;
	int ret, i;

	ipc4_copier = kzalloc(sizeof(*ipc4_copier), GFP_KERNEL);
	if (!ipc4_copier)
		return -ENOMEM;

	available_fmt = &ipc4_copier->available_fmt;

	dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name);

	ret = sof_ipc4_get_audio_fmt(scomp, swidget, available_fmt, true);
	if (ret)
		goto free_copier;

	available_fmt->dma_buffer_size = kcalloc(available_fmt->audio_fmt_num, sizeof(u32),
						 GFP_KERNEL);
	if (!available_fmt->dma_buffer_size) {
		ret = -ENOMEM;
		goto free_available_fmt;
	}

	ret = sof_update_ipc_object(scomp, available_fmt->dma_buffer_size,
				    SOF_COPIER_GATEWAY_CFG_TOKENS, swidget->tuples,
				    swidget->num_tuples, sizeof(u32),
				    available_fmt->audio_fmt_num);
	if (ret) {
		dev_err(scomp->dev, "Failed to parse dma buffer size in audio format for %s\n",
			swidget->widget->name);
		goto err;
	}

	for (i = 0; i < available_fmt->audio_fmt_num; i++)
		dev_dbg(scomp->dev, "%d: dma buffer size: %u\n", i,
			available_fmt->dma_buffer_size[i]);

	ret = sof_update_ipc_object(scomp, &node_type,
				    SOF_COPIER_TOKENS, swidget->tuples,
				    swidget->num_tuples, sizeof(node_type), 1);
	if (ret) {
		dev_err(scomp->dev, "parse dai node type failed %d\n", ret);
		goto err;
	}

	ret = sof_update_ipc_object(scomp, ipc4_copier,
				    SOF_DAI_TOKENS, swidget->tuples,
				    swidget->num_tuples, sizeof(u32), 1);
	if (ret) {
		dev_err(scomp->dev, "parse dai copier node token failed %d\n", ret);
		goto err;
	}

	dev_dbg(scomp->dev, "dai %s node_type %u dai_type %u dai_index %d\n", swidget->widget->name,
		node_type, ipc4_copier->dai_type, ipc4_copier->dai_index);

	ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type);

	switch (ipc4_copier->dai_type) {
	case SOF_DAI_INTEL_ALH:
	{
		struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
		struct sof_ipc4_alh_configuration_blob *blob;
		struct snd_sof_widget *w;

		blob = kzalloc(sizeof(*blob), GFP_KERNEL);
		if (!blob) {
			ret = -ENOMEM;
			goto err;
		}

		list_for_each_entry(w, &sdev->widget_list, list) {
			if (w->widget->sname &&
			    strcmp(w->widget->sname, swidget->widget->sname))
				continue;

			blob->alh_cfg.count++;
		}

		ipc4_copier->copier_config = (uint32_t *)blob;
		ipc4_copier->data.gtw_cfg.config_length = sizeof(*blob) >> 2;
		break;
	}
	case SOF_DAI_INTEL_SSP:
		/* set SSP DAI index as the node_id */
		ipc4_copier->data.gtw_cfg.node_id |=
			SOF_IPC4_NODE_INDEX_INTEL_SSP(ipc4_copier->dai_index);
		break;
	case SOF_DAI_INTEL_DMIC:
		/* set DMIC DAI index as the node_id */
		ipc4_copier->data.gtw_cfg.node_id |=
			SOF_IPC4_NODE_INDEX_INTEL_DMIC(ipc4_copier->dai_index);
		break;
	default:
		ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL);
		if (!ipc4_copier->gtw_attr) {
			ret = -ENOMEM;
			goto err;
		}

		ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr;
		ipc4_copier->data.gtw_cfg.config_length =
			sizeof(struct sof_ipc4_gtw_attributes) >> 2;
		break;
	}

	dai->scomp = scomp;
	dai->private = ipc4_copier;

	/* set up module info and message header */
	ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg);
	if (ret)
		goto free_copier_config;

	return 0;

free_copier_config:
	kfree(ipc4_copier->copier_config);
err:
	kfree(available_fmt->dma_buffer_size);
free_available_fmt:
	sof_ipc4_free_audio_fmt(available_fmt);
free_copier:
	kfree(ipc4_copier);
	dai->private = NULL;
	dai->scomp = NULL;
	return ret;
}

static void sof_ipc4_widget_free_comp_dai(struct snd_sof_widget *swidget)
{
	struct sof_ipc4_available_audio_format *available_fmt;
	struct snd_sof_dai *dai = swidget->private;
	struct sof_ipc4_copier *ipc4_copier;

	if (!dai)
		return;

	if (!dai->private) {
		kfree(dai);
		swidget->private = NULL;
		return;
	}

	ipc4_copier = dai->private;
	available_fmt = &ipc4_copier->available_fmt;

	kfree(available_fmt->dma_buffer_size);
	kfree(available_fmt->base_config);
	kfree(available_fmt->out_audio_fmt);
	if (ipc4_copier->dai_type != SOF_DAI_INTEL_SSP &&
	    ipc4_copier->dai_type != SOF_DAI_INTEL_DMIC)
		kfree(ipc4_copier->copier_config);
	kfree(dai->private);
	kfree(dai);
	swidget->private = NULL;
}

static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
{
	struct snd_soc_component *scomp = swidget->scomp;
	struct sof_ipc4_pipeline *pipeline;
	int ret;

	pipeline = kzalloc(sizeof(*pipeline), GFP_KERNEL);
	if (!pipeline)
		return -ENOMEM;

	ret = sof_update_ipc_object(scomp, pipeline, SOF_SCHED_TOKENS, swidget->tuples,
				    swidget->num_tuples, sizeof(*pipeline), 1);
	if (ret) {
		dev_err(scomp->dev, "parsing scheduler tokens failed\n");
		goto err;
	}

	/* parse one set of pipeline tokens */
	ret = sof_update_ipc_object(scomp, swidget, SOF_PIPELINE_TOKENS, swidget->tuples,
				    swidget->num_tuples, sizeof(*swidget), 1);
	if (ret) {
		dev_err(scomp->dev, "parsing pipeline tokens failed\n");
		goto err;
	}

	/* TODO: Get priority from topology */
	pipeline->priority = 0;

	dev_dbg(scomp->dev, "pipeline '%s': id %d pri %d lp mode %d\n",
		swidget->widget->name, swidget->pipeline_id,
		pipeline->priority, pipeline->lp_mode);

	swidget->private = pipeline;

	pipeline->msg.primary = SOF_IPC4_GLB_PIPE_PRIORITY(pipeline->priority);
	pipeline->msg.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_CREATE_PIPELINE);
	pipeline->msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
	pipeline->msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG);

	pipeline->msg.extension = pipeline->lp_mode;
	pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED;

	return 0;
err:
	kfree(pipeline);
	return ret;
}

static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget)
{
	struct snd_soc_component *scomp = swidget->scomp;
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
	struct sof_ipc4_fw_module *fw_module;
	struct snd_sof_control *scontrol;
	struct sof_ipc4_gain *gain;
	int ret;

	gain = kzalloc(sizeof(*gain), GFP_KERNEL);
	if (!gain)
		return -ENOMEM;

	swidget->private = gain;

	gain->data.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK;
	gain->data.init_val = SOF_IPC4_VOL_ZERO_DB;

	/* The out_audio_fmt in topology is ignored as it is not required to be sent to the FW */
	ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, false);
	if (ret)
		goto err;

	ret = sof_update_ipc_object(scomp, &gain->data, SOF_GAIN_TOKENS, swidget->tuples,
				    swidget->num_tuples, sizeof(gain->data), 1);
	if (ret) {
		dev_err(scomp->dev, "Parsing gain tokens failed\n");
		goto err;
	}

	dev_dbg(scomp->dev,
		"pga widget %s: ramp type: %d, ramp duration %d, initial gain value: %#x, cpc %d\n",
		swidget->widget->name, gain->data.curve_type, gain->data.curve_duration,
		gain->data.init_val, gain->base_config.cpc);

	ret = sof_ipc4_widget_setup_msg(swidget, &gain->msg);
	if (ret)
		goto err;

	fw_module = swidget->module_info;

	/* update module ID for all kcontrols for this widget */
	list_for_each_entry(scontrol, &sdev->kcontrol_list, list)
		if (scontrol->comp_id == swidget->comp_id) {
			struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data;
			struct sof_ipc4_msg *msg = &cdata->msg;

			msg->primary |= fw_module->man4_module_entry.id;
		}

	return 0;
err:
	sof_ipc4_free_audio_fmt(&gain->available_fmt);
	kfree(gain);
	swidget->private = NULL;
	return ret;
}

static void sof_ipc4_widget_free_comp_pga(struct snd_sof_widget *swidget)
{
	struct sof_ipc4_gain *gain = swidget->private;

	if (!gain)
		return;

	sof_ipc4_free_audio_fmt(&gain->available_fmt);
	kfree(swidget->private);
	swidget->private = NULL;
}

static int sof_ipc4_widget_setup_comp_mixer(struct snd_sof_widget *swidget)
{
	struct snd_soc_component *scomp = swidget->scomp;
	struct sof_ipc4_mixer *mixer;
	int ret;

	dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name);

	mixer = kzalloc(sizeof(*mixer), GFP_KERNEL);
	if (!mixer)
		return -ENOMEM;

	swidget->private = mixer;

	/* The out_audio_fmt in topology is ignored as it is not required to be sent to the FW */
	ret = sof_ipc4_get_audio_fmt(scomp, swidget, &mixer->available_fmt, false);
	if (ret)
		goto err;

	ret = sof_ipc4_widget_setup_msg(swidget, &mixer->msg);
	if (ret)
		goto err;

	return 0;
err:
	sof_ipc4_free_audio_fmt(&mixer->available_fmt);
	kfree(mixer);
	swidget->private = NULL;
	return ret;
}

static int sof_ipc4_widget_setup_comp_src(struct snd_sof_widget *swidget)
{
	struct snd_soc_component *scomp = swidget->scomp;
	struct sof_ipc4_src *src;
	int ret;

	dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name);

	src = kzalloc(sizeof(*src), GFP_KERNEL);
	if (!src)
		return -ENOMEM;

	swidget->private = src;

	/* The out_audio_fmt in topology is ignored as it is not required by SRC */
	ret = sof_ipc4_get_audio_fmt(scomp, swidget, &src->available_fmt, false);
	if (ret)
		goto err;

	ret = sof_update_ipc_object(scomp, src, SOF_SRC_TOKENS, swidget->tuples,
				    swidget->num_tuples, sizeof(*src), 1);
	if (ret) {
		dev_err(scomp->dev, "Parsing SRC tokens failed\n");
		goto err;
	}

	dev_dbg(scomp->dev, "SRC sink rate %d\n", src->sink_rate);

	ret = sof_ipc4_widget_setup_msg(swidget, &src->msg);
	if (ret)
		goto err;

	return 0;
err:
	sof_ipc4_free_audio_fmt(&src->available_fmt);
	kfree(src);
	swidget->private = NULL;
	return ret;
}

static void sof_ipc4_widget_free_comp_src(struct snd_sof_widget *swidget)
{
	struct sof_ipc4_src *src = swidget->private;

	if (!src)
		return;

	sof_ipc4_free_audio_fmt(&src->available_fmt);
	kfree(swidget->private);
	swidget->private = NULL;
}

static void sof_ipc4_widget_free_comp_mixer(struct snd_sof_widget *swidget)
{
	struct sof_ipc4_mixer *mixer = swidget->private;

	if (!mixer)
		return;

	sof_ipc4_free_audio_fmt(&mixer->available_fmt);
	kfree(swidget->private);
	swidget->private = NULL;
}

static void
sof_ipc4_update_pipeline_mem_usage(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget,
				   struct sof_ipc4_base_module_cfg *base_config)
{
	struct sof_ipc4_fw_module *fw_module = swidget->module_info;
	struct snd_sof_widget *pipe_widget;
	struct sof_ipc4_pipeline *pipeline;
	int task_mem, queue_mem;
	int ibs, bss, total;

	ibs = base_config->ibs;
	bss = base_config->is_pages;

	task_mem = SOF_IPC4_PIPELINE_OBJECT_SIZE;
	task_mem += SOF_IPC4_MODULE_INSTANCE_LIST_ITEM_SIZE + bss;

	if (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_LL) {
		task_mem += SOF_IPC4_FW_ROUNDUP(SOF_IPC4_LL_TASK_OBJECT_SIZE);
		task_mem += SOF_IPC4_FW_MAX_QUEUE_COUNT * SOF_IPC4_MODULE_INSTANCE_LIST_ITEM_SIZE;
		task_mem += SOF_IPC4_LL_TASK_LIST_ITEM_SIZE;
	} else {
		task_mem += SOF_IPC4_FW_ROUNDUP(SOF_IPC4_DP_TASK_OBJECT_SIZE);
		task_mem += SOF_IPC4_DP_TASK_LIST_SIZE;
	}

	ibs = SOF_IPC4_FW_ROUNDUP(ibs);
	queue_mem = SOF_IPC4_FW_MAX_QUEUE_COUNT * (SOF_IPC4_DATA_QUEUE_OBJECT_SIZE +  ibs);

	total = SOF_IPC4_FW_PAGE(task_mem + queue_mem);

	pipe_widget = swidget->spipe->pipe_widget;
	pipeline = pipe_widget->private;
	pipeline->mem_usage += total;
}

static int sof_ipc4_widget_assign_instance_id(struct snd_sof_dev *sdev,
					      struct snd_sof_widget *swidget)
{
	struct sof_ipc4_fw_module *fw_module = swidget->module_info;
	int max_instances = fw_module->man4_module_entry.instance_max_count;

	swidget->instance_id = ida_alloc_max(&fw_module->m_ida, max_instances, GFP_KERNEL);
	if (swidget->instance_id < 0) {
		dev_err(sdev->dev, "failed to assign instance id for widget %s",
			swidget->widget->name);
		return swidget->instance_id;
	}

	return 0;
}

static int sof_ipc4_init_audio_fmt(struct snd_sof_dev *sdev,
				   struct snd_sof_widget *swidget,
				   struct sof_ipc4_base_module_cfg *base_config,
				   struct sof_ipc4_audio_format *out_format,
				   struct snd_pcm_hw_params *params,
				   struct sof_ipc4_available_audio_format *available_fmt,
				   size_t object_offset)
{
	void *ptr = available_fmt->ref_audio_fmt;
	u32 valid_bits;
	u32 channels;
	u32 rate;
	int sample_valid_bits;
	int i;

	if (!ptr) {
		dev_err(sdev->dev, "no reference formats for %s\n", swidget->widget->name);
		return -EINVAL;
	}

	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		sample_valid_bits = 16;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		sample_valid_bits = 24;
		break;
	case SNDRV_PCM_FORMAT_S32_LE:
		sample_valid_bits = 32;
		break;
	default:
		dev_err(sdev->dev, "invalid pcm frame format %d\n", params_format(params));
		return -EINVAL;
	}

	if (!available_fmt->audio_fmt_num) {
		dev_err(sdev->dev, "no formats available for %s\n", swidget->widget->name);
		return -EINVAL;
	}

	/*
	 * Search supported audio formats to match rate, channels ,and
	 * sample_valid_bytes from runtime params
	 */
	for (i = 0; i < available_fmt->audio_fmt_num; i++, ptr = (u8 *)ptr + object_offset) {
		struct sof_ipc4_audio_format *fmt = ptr;

		rate = fmt->sampling_frequency;
		channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg);
		valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
		if (params_rate(params) == rate && params_channels(params) == channels &&
		    sample_valid_bits == valid_bits) {
			dev_dbg(sdev->dev, "matching audio format index for %uHz, %ubit, %u channels: %d\n",
				rate, valid_bits, channels, i);

			/* copy ibs/obs and input format */
			memcpy(base_config, &available_fmt->base_config[i],
			       sizeof(struct sof_ipc4_base_module_cfg));

			/* copy output format */
			if (out_format)
				memcpy(out_format, &available_fmt->out_audio_fmt[i],
				       sizeof(struct sof_ipc4_audio_format));
			break;
		}
	}

	if (i == available_fmt->audio_fmt_num) {
		dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n",
			__func__, params_rate(params), sample_valid_bits, params_channels(params));
		return -EINVAL;
	}

	dev_dbg(sdev->dev, "Init input audio formats for %s\n", swidget->widget->name);
	sof_ipc4_dbg_audio_format(sdev->dev, &base_config->audio_fmt,
				  sizeof(*base_config), 1);
	if (out_format) {
		dev_dbg(sdev->dev, "Init output audio formats for %s\n", swidget->widget->name);
		sof_ipc4_dbg_audio_format(sdev->dev, out_format,
					  sizeof(*out_format), 1);
	}

	/* Return the index of the matched format */
	return i;
}

static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget)
{
	struct sof_ipc4_copier *ipc4_copier = NULL;
	struct snd_sof_widget *pipe_widget;
	struct sof_ipc4_pipeline *pipeline;

	/* reset pipeline memory usage */
	pipe_widget = swidget->spipe->pipe_widget;
	pipeline = pipe_widget->private;
	pipeline->mem_usage = 0;

	if (WIDGET_IS_AIF(swidget->id) || swidget->id == snd_soc_dapm_buffer) {
		ipc4_copier = swidget->private;
	} else if (WIDGET_IS_DAI(swidget->id)) {
		struct snd_sof_dai *dai = swidget->private;

		ipc4_copier = dai->private;
		if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) {
			struct sof_ipc4_alh_configuration_blob *blob;
			unsigned int group_id;

			blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config;
			if (blob->alh_cfg.count > 1) {
				group_id = SOF_IPC4_NODE_INDEX(ipc4_copier->data.gtw_cfg.node_id) -
					   ALH_MULTI_GTW_BASE;
				ida_free(&alh_group_ida, group_id);
			}
		}
	}

	if (ipc4_copier) {
		kfree(ipc4_copier->ipc_config_data);
		ipc4_copier->ipc_config_data = NULL;
		ipc4_copier->ipc_config_size = 0;
	}
}

#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_INTEL_NHLT)
static int snd_sof_get_hw_config_params(struct snd_sof_dev *sdev, struct snd_sof_dai *dai,
					int *sample_rate, int *channel_count, int *bit_depth)
{
	struct snd_soc_tplg_hw_config *hw_config;
	struct snd_sof_dai_link *slink;
	bool dai_link_found = false;
	bool hw_cfg_found = false;
	int i;

	/* get current hw_config from link */
	list_for_each_entry(slink, &sdev->dai_link_list, list) {
		if (!strcmp(slink->link->name, dai->name)) {
			dai_link_found = true;
			break;
		}
	}

	if (!dai_link_found) {
		dev_err(sdev->dev, "%s: no DAI link found for DAI %s\n", __func__, dai->name);
		return -EINVAL;
	}

	for (i = 0; i < slink->num_hw_configs; i++) {
		hw_config = &slink->hw_configs[i];
		if (dai->current_config == le32_to_cpu(hw_config->id)) {
			hw_cfg_found = true;
			break;
		}
	}

	if (!hw_cfg_found) {
		dev_err(sdev->dev, "%s: no matching hw_config found for DAI %s\n", __func__,
			dai->name);
		return -EINVAL;
	}

	*bit_depth = le32_to_cpu(hw_config->tdm_slot_width);
	*channel_count = le32_to_cpu(hw_config->tdm_slots);
	*sample_rate = le32_to_cpu(hw_config->fsync_rate);

	dev_dbg(sdev->dev, "sample rate: %d sample width: %d channels: %d\n",
		*sample_rate, *bit_depth, *channel_count);

	return 0;
}

static int snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_sof_dai *dai,
					  struct snd_pcm_hw_params *params, u32 dai_index,
					  u32 linktype, u8 dir, u32 **dst, u32 *len)
{
	struct sof_ipc4_fw_data *ipc4_data = sdev->private;
	struct nhlt_specific_cfg *cfg;
	int sample_rate, channel_count;
	int bit_depth, ret;
	u32 nhlt_type;

	/* convert to NHLT type */
	switch (linktype) {
	case SOF_DAI_INTEL_DMIC:
		nhlt_type = NHLT_LINK_DMIC;
		bit_depth = params_width(params);
		channel_count = params_channels(params);
		sample_rate = params_rate(params);
		break;
	case SOF_DAI_INTEL_SSP:
		nhlt_type = NHLT_LINK_SSP;
		ret = snd_sof_get_hw_config_params(sdev, dai, &sample_rate, &channel_count,
						   &bit_depth);
		if (ret < 0)
			return ret;
		break;
	default:
		return 0;
	}

	dev_dbg(sdev->dev, "dai index %d nhlt type %d direction %d\n",
		dai_index, nhlt_type, dir);

	/* find NHLT blob with matching params */
	cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, dai_index, nhlt_type,
					   bit_depth, bit_depth, channel_count, sample_rate,
					   dir, 0);

	if (!cfg) {
		dev_err(sdev->dev,
			"no matching blob for sample rate: %d sample width: %d channels: %d\n",
			sample_rate, bit_depth, channel_count);
		return -EINVAL;
	}

	/* config length should be in dwords */
	*len = cfg->size >> 2;
	*dst = (u32 *)cfg->caps;

	return 0;
}
#else
static int snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_sof_dai *dai,
					  struct snd_pcm_hw_params *params, u32 dai_index,
					  u32 linktype, u8 dir, u32 **dst, u32 *len)
{
	return 0;
}
#endif

static int
sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
			       struct snd_pcm_hw_params *fe_params,
			       struct snd_sof_platform_stream_params *platform_params,
			       struct snd_pcm_hw_params *pipeline_params, int dir)
{
	struct sof_ipc4_available_audio_format *available_fmt;
	struct snd_soc_component *scomp = swidget->scomp;
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
	struct sof_ipc4_copier_data *copier_data;
	struct snd_pcm_hw_params *ref_params;
	struct sof_ipc4_copier *ipc4_copier;
	struct snd_sof_dai *dai;
	struct snd_mask *fmt;
	int out_sample_valid_bits;
	size_t ref_audio_fmt_size;
	void **ipc_config_data;
	int *ipc_config_size;
	u32 **data;
	int ipc_size, ret;

	dev_dbg(sdev->dev, "copier %s, type %d", swidget->widget->name, swidget->id);

	switch (swidget->id) {
	case snd_soc_dapm_aif_in:
	case snd_soc_dapm_aif_out:
	{
		struct sof_ipc4_gtw_attributes *gtw_attr;
		struct snd_sof_widget *pipe_widget;
		struct sof_ipc4_pipeline *pipeline;

		pipe_widget = swidget->spipe->pipe_widget;
		pipeline = pipe_widget->private;
		ipc4_copier = (struct sof_ipc4_copier *)swidget->private;
		gtw_attr = ipc4_copier->gtw_attr;
		copier_data = &ipc4_copier->data;
		available_fmt = &ipc4_copier->available_fmt;

		/*
		 * base_config->audio_fmt and out_audio_fmt represent the input and output audio
		 * formats. Use the input format as the reference to match pcm params for playback
		 * and the output format as reference for capture.
		 */
		if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
			available_fmt->ref_audio_fmt = &available_fmt->base_config->audio_fmt;
			ref_audio_fmt_size = sizeof(struct sof_ipc4_base_module_cfg);
		} else {
			available_fmt->ref_audio_fmt = available_fmt->out_audio_fmt;
			ref_audio_fmt_size = sizeof(struct sof_ipc4_audio_format);
		}
		copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
		copier_data->gtw_cfg.node_id |=
			SOF_IPC4_NODE_INDEX(platform_params->stream_tag - 1);

		/* set gateway attributes */
		gtw_attr->lp_buffer_alloc = pipeline->lp_mode;
		ref_params = fe_params;
		break;
	}
	case snd_soc_dapm_dai_in:
	case snd_soc_dapm_dai_out:
	{
		dai = swidget->private;

		ipc4_copier = (struct sof_ipc4_copier *)dai->private;
		copier_data = &ipc4_copier->data;
		available_fmt = &ipc4_copier->available_fmt;
		if (dir == SNDRV_PCM_STREAM_CAPTURE) {
			available_fmt->ref_audio_fmt = available_fmt->out_audio_fmt;
			ref_audio_fmt_size = sizeof(struct sof_ipc4_audio_format);

			/*
			 * modify the input params for the dai copier as it only supports
			 * 32-bit always
			 */
			fmt = hw_param_mask(pipeline_params, SNDRV_PCM_HW_PARAM_FORMAT);
			snd_mask_none(fmt);
			snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S32_LE);
		} else {
			available_fmt->ref_audio_fmt = &available_fmt->base_config->audio_fmt;
			ref_audio_fmt_size = sizeof(struct sof_ipc4_base_module_cfg);
		}

		ref_params = pipeline_params;

		ret = snd_sof_get_nhlt_endpoint_data(sdev, dai, fe_params, ipc4_copier->dai_index,
						     ipc4_copier->dai_type, dir,
						     &ipc4_copier->copier_config,
						     &copier_data->gtw_cfg.config_length);
		if (ret < 0)
			return ret;

		break;
	}
	case snd_soc_dapm_buffer:
	{
		ipc4_copier = (struct sof_ipc4_copier *)swidget->private;
		copier_data = &ipc4_copier->data;
		available_fmt = &ipc4_copier->available_fmt;

		/*
		 * base_config->audio_fmt represent the input audio formats. Use
		 * the input format as the reference to match pcm params
		 */
		available_fmt->ref_audio_fmt = &available_fmt->base_config->audio_fmt;
		ref_audio_fmt_size = sizeof(struct sof_ipc4_base_module_cfg);
		ref_params = pipeline_params;

		break;
	}
	default:
		dev_err(sdev->dev, "unsupported type %d for copier %s",
			swidget->id, swidget->widget->name);
		return -EINVAL;
	}

	/* set input and output audio formats */
	ret = sof_ipc4_init_audio_fmt(sdev, swidget, &copier_data->base_config,
				      &copier_data->out_format, ref_params,
				      available_fmt, ref_audio_fmt_size);
	if (ret < 0)
		return ret;

	switch (swidget->id) {
	case snd_soc_dapm_dai_in:
	case snd_soc_dapm_dai_out:
	{
		/*
		 * Only SOF_DAI_INTEL_ALH needs copier_data to set blob.
		 * That's why only ALH dai's blob is set after sof_ipc4_init_audio_fmt
		 */
		if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) {
			struct sof_ipc4_alh_configuration_blob *blob;
			struct sof_ipc4_copier_data *alh_data;
			struct sof_ipc4_copier *alh_copier;
			struct snd_sof_widget *w;
			u32 ch_count = 0;
			u32 ch_mask = 0;
			u32 ch_map;
			u32 step;
			u32 mask;
			int i;

			blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config;

			blob->gw_attr.lp_buffer_alloc = 0;

			/* Get channel_mask from ch_map */
			ch_map = copier_data->base_config.audio_fmt.ch_map;
			for (i = 0; ch_map; i++) {
				if ((ch_map & 0xf) != 0xf) {
					ch_mask |= BIT(i);
					ch_count++;
				}
				ch_map >>= 4;
			}

			step = ch_count / blob->alh_cfg.count;
			mask =  GENMASK(step - 1, 0);
			/*
			 * Set each gtw_cfg.node_id to blob->alh_cfg.mapping[]
			 * for all widgets with the same stream name
			 */
			i = 0;
			list_for_each_entry(w, &sdev->widget_list, list) {
				if (w->widget->sname &&
				    strcmp(w->widget->sname, swidget->widget->sname))
					continue;

				dai = w->private;
				alh_copier = (struct sof_ipc4_copier *)dai->private;
				alh_data = &alh_copier->data;
				blob->alh_cfg.mapping[i].alh_id = alh_data->gtw_cfg.node_id;
				/*
				 * Set the same channel mask for playback as the audio data is
				 * duplicated for all speakers. For capture, split the channels
				 * among the aggregated DAIs. For example, with 4 channels on 2
				 * aggregated DAIs, the channel_mask should be 0x3 and 0xc for the
				 * two DAI's.
				 * The channel masks used depend on the cpu_dais used in the
				 * dailink at the machine driver level, which actually comes from
				 * the tables in soc_acpi files depending on the _ADR and devID
				 * registers for each codec.
				 */
				if (w->id == snd_soc_dapm_dai_in)
					blob->alh_cfg.mapping[i].channel_mask = ch_mask;
				else
					blob->alh_cfg.mapping[i].channel_mask = mask << (step * i);

				i++;
			}
			if (blob->alh_cfg.count > 1) {
				int group_id;

				group_id = ida_alloc_max(&alh_group_ida, ALH_MULTI_GTW_COUNT - 1,
							 GFP_KERNEL);

				if (group_id < 0)
					return group_id;

				/* add multi-gateway base */
				group_id += ALH_MULTI_GTW_BASE;
				copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
				copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(group_id);
			}
		}
	}
	}

	/* modify the input params for the next widget */
	fmt = hw_param_mask(pipeline_params, SNDRV_PCM_HW_PARAM_FORMAT);
	out_sample_valid_bits =
		SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(copier_data->out_format.fmt_cfg);
	snd_mask_none(fmt);
	switch (out_sample_valid_bits) {
	case 16:
		snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
		break;
	case 24:
		snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
		break;
	case 32:
		snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S32_LE);
		break;
	default:
		dev_err(sdev->dev, "invalid sample frame format %d\n",
			params_format(pipeline_params));
		return -EINVAL;
	}

	/* set the gateway dma_buffer_size using the matched ID returned above */
	copier_data->gtw_cfg.dma_buffer_size = available_fmt->dma_buffer_size[ret];

	data = &ipc4_copier->copier_config;
	ipc_config_size = &ipc4_copier->ipc_config_size;
	ipc_config_data = &ipc4_copier->ipc_config_data;

	/* config_length is DWORD based */
	ipc_size = sizeof(*copier_data) + copier_data->gtw_cfg.config_length * 4;

	dev_dbg(sdev->dev, "copier %s, IPC size is %d", swidget->widget->name, ipc_size);

	*ipc_config_data = kzalloc(ipc_size, GFP_KERNEL);
	if (!*ipc_config_data)
		return -ENOMEM;

	*ipc_config_size = ipc_size;

	/* copy IPC data */
	memcpy(*ipc_config_data, (void *)copier_data, sizeof(*copier_data));
	if (copier_data->gtw_cfg.config_length)
		memcpy(*ipc_config_data + sizeof(*copier_data),
		       *data, copier_data->gtw_cfg.config_length * 4);

	/* update pipeline memory usage */
	sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &copier_data->base_config);

	return 0;
}

static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
					struct snd_pcm_hw_params *fe_params,
					struct snd_sof_platform_stream_params *platform_params,
					struct snd_pcm_hw_params *pipeline_params, int dir)
{
	struct snd_soc_component *scomp = swidget->scomp;
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
	struct sof_ipc4_gain *gain = swidget->private;
	int ret;

	gain->available_fmt.ref_audio_fmt = &gain->available_fmt.base_config->audio_fmt;

	/* output format is not required to be sent to the FW for gain */
	ret = sof_ipc4_init_audio_fmt(sdev, swidget, &gain->base_config,
				      NULL, pipeline_params, &gain->available_fmt,
				      sizeof(gain->base_config));
	if (ret < 0)
		return ret;

	/* update pipeline memory usage */
	sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &gain->base_config);

	return 0;
}

static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
					 struct snd_pcm_hw_params *fe_params,
					 struct snd_sof_platform_stream_params *platform_params,
					 struct snd_pcm_hw_params *pipeline_params, int dir)
{
	struct snd_soc_component *scomp = swidget->scomp;
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
	struct sof_ipc4_mixer *mixer = swidget->private;
	int ret;

	/* only 32bit is supported by mixer */
	mixer->available_fmt.ref_audio_fmt = &mixer->available_fmt.base_config->audio_fmt;

	/* output format is not required to be sent to the FW for mixer */
	ret = sof_ipc4_init_audio_fmt(sdev, swidget, &mixer->base_config,
				      NULL, pipeline_params, &mixer->available_fmt,
				      sizeof(mixer->base_config));
	if (ret < 0)
		return ret;

	/* update pipeline memory usage */
	sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &mixer->base_config);

	return 0;
}

static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
				       struct snd_pcm_hw_params *fe_params,
				       struct snd_sof_platform_stream_params *platform_params,
				       struct snd_pcm_hw_params *pipeline_params, int dir)
{
	struct snd_soc_component *scomp = swidget->scomp;
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
	struct sof_ipc4_src *src = swidget->private;
	struct snd_interval *rate;
	int ret;

	src->available_fmt.ref_audio_fmt = &src->available_fmt.base_config->audio_fmt;

	/* output format is not required to be sent to the FW for SRC */
	ret = sof_ipc4_init_audio_fmt(sdev, swidget, &src->base_config,
				      NULL, pipeline_params, &src->available_fmt,
				      sizeof(src->base_config));
	if (ret < 0)
		return ret;

	/* update pipeline memory usage */
	sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &src->base_config);

	/* update pipeline_params for sink widgets */
	rate = hw_param_interval(pipeline_params, SNDRV_PCM_HW_PARAM_RATE);
	rate->min = src->sink_rate;
	rate->max = rate->min;

	return 0;
}

static int sof_ipc4_control_load_volume(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol)
{
	struct sof_ipc4_control_data *control_data;
	struct sof_ipc4_msg *msg;
	int i;

	scontrol->size = struct_size(control_data, chanv, scontrol->num_channels);

	/* scontrol->ipc_control_data will be freed in sof_control_unload */
	scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL);
	if (!scontrol->ipc_control_data)
		return -ENOMEM;

	control_data = scontrol->ipc_control_data;
	control_data->index = scontrol->index;

	msg = &control_data->msg;
	msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET);
	msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
	msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);

	msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_GAIN_PARAM_ID);

	/* set default volume values to 0dB in control */
	for (i = 0; i < scontrol->num_channels; i++) {
		control_data->chanv[i].channel = i;
		control_data->chanv[i].value = SOF_IPC4_VOL_ZERO_DB;
	}

	return 0;
}

static int sof_ipc4_control_setup(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol)
{
	switch (scontrol->info_type) {
	case SND_SOC_TPLG_CTL_VOLSW:
	case SND_SOC_TPLG_CTL_VOLSW_SX:
	case SND_SOC_TPLG_CTL_VOLSW_XR_SX:
		return sof_ipc4_control_load_volume(sdev, scontrol);
	default:
		break;
	}

	return 0;
}

static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
{
	struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
	struct sof_ipc4_fw_data *ipc4_data = sdev->private;
	struct sof_ipc4_pipeline *pipeline;
	struct sof_ipc4_msg *msg;
	void *ipc_data = NULL;
	u32 ipc_size = 0;
	int ret;

	switch (swidget->id) {
	case snd_soc_dapm_scheduler:
		pipeline = swidget->private;

		dev_dbg(sdev->dev, "pipeline: %d memory pages: %d\n", swidget->pipeline_id,
			pipeline->mem_usage);

		msg = &pipeline->msg;
		msg->primary |= pipeline->mem_usage;

		swidget->instance_id = ida_alloc_max(&pipeline_ida, ipc4_data->max_num_pipelines,
						     GFP_KERNEL);
		if (swidget->instance_id < 0) {
			dev_err(sdev->dev, "failed to assign pipeline id for %s: %d\n",
				swidget->widget->name, swidget->instance_id);
			return swidget->instance_id;
		}
		msg->primary &= ~SOF_IPC4_GLB_PIPE_INSTANCE_MASK;
		msg->primary |= SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id);
		break;
	case snd_soc_dapm_aif_in:
	case snd_soc_dapm_aif_out:
	case snd_soc_dapm_buffer:
	{
		struct sof_ipc4_copier *ipc4_copier = swidget->private;

		ipc_size = ipc4_copier->ipc_config_size;
		ipc_data = ipc4_copier->ipc_config_data;

		msg = &ipc4_copier->msg;
		break;
	}
	case snd_soc_dapm_dai_in:
	case snd_soc_dapm_dai_out:
	{
		struct snd_sof_dai *dai = swidget->private;
		struct sof_ipc4_copier *ipc4_copier = dai->private;

		ipc_size = ipc4_copier->ipc_config_size;
		ipc_data = ipc4_copier->ipc_config_data;

		msg = &ipc4_copier->msg;
		break;
	}
	case snd_soc_dapm_pga:
	{
		struct sof_ipc4_gain *gain = swidget->private;

		ipc_size = sizeof(struct sof_ipc4_base_module_cfg) +
			   sizeof(struct sof_ipc4_gain_data);
		ipc_data = gain;

		msg = &gain->msg;
		break;
	}
	case snd_soc_dapm_mixer:
	{
		struct sof_ipc4_mixer *mixer = swidget->private;

		ipc_size = sizeof(mixer->base_config);
		ipc_data = &mixer->base_config;

		msg = &mixer->msg;
		break;
	}
	case snd_soc_dapm_src:
	{
		struct sof_ipc4_src *src = swidget->private;

		ipc_size = sizeof(struct sof_ipc4_base_module_cfg) + sizeof(src->sink_rate);
		ipc_data = src;

		msg = &src->msg;
		break;
	}
	default:
		dev_err(sdev->dev, "widget type %d not supported", swidget->id);
		return -EINVAL;
	}

	if (swidget->id != snd_soc_dapm_scheduler) {
		ret = sof_ipc4_widget_assign_instance_id(sdev, swidget);
		if (ret < 0) {
			dev_err(sdev->dev, "failed to assign instance id for %s\n",
				swidget->widget->name);
			return ret;
		}

		msg->primary &= ~SOF_IPC4_MOD_INSTANCE_MASK;
		msg->primary |= SOF_IPC4_MOD_INSTANCE(swidget->instance_id);

		msg->extension &= ~SOF_IPC4_MOD_EXT_PARAM_SIZE_MASK;
		msg->extension |= ipc_size >> 2;

		msg->extension &= ~SOF_IPC4_MOD_EXT_PPL_ID_MASK;
		msg->extension |= SOF_IPC4_MOD_EXT_PPL_ID(pipe_widget->instance_id);
	}
	dev_dbg(sdev->dev, "Create widget %s instance %d - pipe %d - core %d\n",
		swidget->widget->name, swidget->instance_id, swidget->pipeline_id, swidget->core);

	msg->data_size = ipc_size;
	msg->data_ptr = ipc_data;

	ret = sof_ipc_tx_message(sdev->ipc, msg, ipc_size, NULL, 0);
	if (ret < 0) {
		dev_err(sdev->dev, "failed to create module %s\n", swidget->widget->name);

		if (swidget->id != snd_soc_dapm_scheduler) {
			struct sof_ipc4_fw_module *fw_module = swidget->module_info;

			ida_free(&fw_module->m_ida, swidget->instance_id);
		} else {
			ida_free(&pipeline_ida, swidget->instance_id);
		}
	}

	return ret;
}

static int sof_ipc4_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
{
	struct sof_ipc4_fw_module *fw_module = swidget->module_info;
	struct sof_ipc4_fw_data *ipc4_data = sdev->private;
	int ret = 0;

	mutex_lock(&ipc4_data->pipeline_state_mutex);

	/* freeing a pipeline frees all the widgets associated with it */
	if (swidget->id == snd_soc_dapm_scheduler) {
		struct sof_ipc4_pipeline *pipeline = swidget->private;
		struct sof_ipc4_msg msg = {{ 0 }};
		u32 header;

		header = SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id);
		header |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_DELETE_PIPELINE);
		header |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
		header |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG);

		msg.primary = header;

		ret = sof_ipc_tx_message(sdev->ipc, &msg, 0, NULL, 0);
		if (ret < 0)
			dev_err(sdev->dev, "failed to free pipeline widget %s\n",
				swidget->widget->name);

		pipeline->mem_usage = 0;
		pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED;
		ida_free(&pipeline_ida, swidget->instance_id);
	} else {
		ida_free(&fw_module->m_ida, swidget->instance_id);
	}

	mutex_unlock(&ipc4_data->pipeline_state_mutex);

	return ret;
}

static int sof_ipc4_get_queue_id(struct snd_sof_widget *src_widget,
				 struct snd_sof_widget *sink_widget, bool pin_type)
{
	struct snd_sof_widget *current_swidget;
	struct snd_soc_component *scomp;
	struct ida *queue_ida;
	const char *buddy_name;
	char **pin_binding;
	u32 num_pins;
	int i;

	if (pin_type == SOF_PIN_TYPE_SOURCE) {
		current_swidget = src_widget;
		pin_binding = src_widget->src_pin_binding;
		queue_ida = &src_widget->src_queue_ida;
		num_pins = src_widget->num_source_pins;
		buddy_name = sink_widget->widget->name;
	} else {
		current_swidget = sink_widget;
		pin_binding = sink_widget->sink_pin_binding;
		queue_ida = &sink_widget->sink_queue_ida;
		num_pins = sink_widget->num_sink_pins;
		buddy_name = src_widget->widget->name;
	}

	scomp = current_swidget->scomp;

	if (num_pins < 1) {
		dev_err(scomp->dev, "invalid %s num_pins: %d for queue allocation for %s\n",
			(pin_type == SOF_PIN_TYPE_SOURCE ? "source" : "sink"),
			num_pins, current_swidget->widget->name);
		return -EINVAL;
	}

	/* If there is only one sink/source pin, queue id must be 0 */
	if (num_pins == 1)
		return 0;

	/* Allocate queue ID from pin binding array if it is defined in topology. */
	if (pin_binding) {
		for (i = 0; i < num_pins; i++) {
			if (!strcmp(pin_binding[i], buddy_name))
				return i;
		}
		/*
		 * Fail if no queue ID found from pin binding array, so that we don't
		 * mixed use pin binding array and ida for queue ID allocation.
		 */
		dev_err(scomp->dev, "no %s queue id found from pin binding array for %s\n",
			(pin_type == SOF_PIN_TYPE_SOURCE ? "source" : "sink"),
			current_swidget->widget->name);
		return -EINVAL;
	}

	/* If no pin binding array specified in topology, use ida to allocate one */
	return ida_alloc_max(queue_ida, num_pins, GFP_KERNEL);
}

static void sof_ipc4_put_queue_id(struct snd_sof_widget *swidget, int queue_id,
				  bool pin_type)
{
	struct ida *queue_ida;
	char **pin_binding;
	int num_pins;

	if (pin_type == SOF_PIN_TYPE_SOURCE) {
		pin_binding = swidget->src_pin_binding;
		queue_ida = &swidget->src_queue_ida;
		num_pins = swidget->num_source_pins;
	} else {
		pin_binding = swidget->sink_pin_binding;
		queue_ida = &swidget->sink_queue_ida;
		num_pins = swidget->num_sink_pins;
	}

	/* Nothing to free if queue ID is not allocated with ida. */
	if (num_pins == 1 || pin_binding)
		return;

	ida_free(queue_ida, queue_id);
}

static int sof_ipc4_route_setup(struct snd_sof_dev *sdev, struct snd_sof_route *sroute)
{
	struct snd_sof_widget *src_widget = sroute->src_widget;
	struct snd_sof_widget *sink_widget = sroute->sink_widget;
	struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info;
	struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info;
	struct sof_ipc4_msg msg = {{ 0 }};
	u32 header, extension;
	int ret;

	sroute->src_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget,
						     SOF_PIN_TYPE_SOURCE);
	if (sroute->src_queue_id < 0) {
		dev_err(sdev->dev, "failed to get queue ID for source widget: %s\n",
			src_widget->widget->name);
		return sroute->src_queue_id;
	}

	sroute->dst_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget,
						     SOF_PIN_TYPE_SINK);
	if (sroute->dst_queue_id < 0) {
		dev_err(sdev->dev, "failed to get queue ID for sink widget: %s\n",
			sink_widget->widget->name);
		sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id,
				      SOF_PIN_TYPE_SOURCE);
		return sroute->dst_queue_id;
	}

	dev_dbg(sdev->dev, "bind %s:%d -> %s:%d\n",
		src_widget->widget->name, sroute->src_queue_id,
		sink_widget->widget->name, sroute->dst_queue_id);

	header = src_fw_module->man4_module_entry.id;
	header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id);
	header |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_BIND);
	header |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
	header |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);

	extension = sink_fw_module->man4_module_entry.id;
	extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id);
	extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id);
	extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id);

	msg.primary = header;
	msg.extension = extension;

	ret = sof_ipc_tx_message(sdev->ipc, &msg, 0, NULL, 0);
	if (ret < 0) {
		dev_err(sdev->dev, "failed to bind modules %s:%d -> %s:%d\n",
			src_widget->widget->name, sroute->src_queue_id,
			sink_widget->widget->name, sroute->dst_queue_id);

		sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id,
				      SOF_PIN_TYPE_SOURCE);
		sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id,
				      SOF_PIN_TYPE_SINK);
	}

	return ret;
}

static int sof_ipc4_route_free(struct snd_sof_dev *sdev, struct snd_sof_route *sroute)
{
	struct snd_sof_widget *src_widget = sroute->src_widget;
	struct snd_sof_widget *sink_widget = sroute->sink_widget;
	struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info;
	struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info;
	struct sof_ipc4_msg msg = {{ 0 }};
	u32 header, extension;
	int ret = 0;

	dev_dbg(sdev->dev, "unbind modules %s:%d -> %s:%d\n",
		src_widget->widget->name, sroute->src_queue_id,
		sink_widget->widget->name, sroute->dst_queue_id);

	/*
	 * routes belonging to the same pipeline will be disconnected by the FW when the pipeline
	 * is freed. So avoid sending this IPC which will be ignored by the FW anyway.
	 */
	if (src_widget->spipe->pipe_widget == sink_widget->spipe->pipe_widget)
		goto out;

	header = src_fw_module->man4_module_entry.id;
	header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id);
	header |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_UNBIND);
	header |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
	header |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);

	extension = sink_fw_module->man4_module_entry.id;
	extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id);
	extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id);
	extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id);

	msg.primary = header;
	msg.extension = extension;

	ret = sof_ipc_tx_message(sdev->ipc, &msg, 0, NULL, 0);
	if (ret < 0)
		dev_err(sdev->dev, "failed to unbind modules %s:%d -> %s:%d\n",
			src_widget->widget->name, sroute->src_queue_id,
			sink_widget->widget->name, sroute->dst_queue_id);
out:
	sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_SINK);
	sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_SOURCE);

	return ret;
}

static int sof_ipc4_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget,
			       unsigned int flags, struct snd_sof_dai_config_data *data)
{
	struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
	struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
	struct snd_sof_dai *dai = swidget->private;
	struct sof_ipc4_gtw_attributes *gtw_attr;
	struct sof_ipc4_copier_data *copier_data;
	struct sof_ipc4_copier *ipc4_copier;

	if (!dai || !dai->private) {
		dev_err(sdev->dev, "Invalid DAI or DAI private data for %s\n",
			swidget->widget->name);
		return -EINVAL;
	}

	ipc4_copier = (struct sof_ipc4_copier *)dai->private;
	copier_data = &ipc4_copier->data;

	if (!data)
		return 0;

	switch (ipc4_copier->dai_type) {
	case SOF_DAI_INTEL_HDA:
		gtw_attr = ipc4_copier->gtw_attr;
		gtw_attr->lp_buffer_alloc = pipeline->lp_mode;
		pipeline->skip_during_fe_trigger = true;
		fallthrough;
	case SOF_DAI_INTEL_ALH:
		copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
		copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(data->dai_data);
		break;
	case SOF_DAI_INTEL_DMIC:
	case SOF_DAI_INTEL_SSP:
		/* nothing to do for SSP/DMIC */
		break;
	default:
		dev_err(sdev->dev, "%s: unsupported dai type %d\n", __func__,
			ipc4_copier->dai_type);
		return -EINVAL;
	}

	return 0;
}

static int sof_ipc4_parse_manifest(struct snd_soc_component *scomp, int index,
				   struct snd_soc_tplg_manifest *man)
{
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
	struct sof_ipc4_fw_data *ipc4_data = sdev->private;
	struct sof_manifest_tlv *manifest_tlv;
	struct sof_manifest *manifest;
	u32 size = le32_to_cpu(man->priv.size);
	u8 *man_ptr = man->priv.data;
	u32 len_check;
	int i;

	if (!size || size < SOF_IPC4_TPLG_ABI_SIZE) {
		dev_err(scomp->dev, "%s: Invalid topology ABI size: %u\n",
			__func__, size);
		return -EINVAL;
	}

	manifest = (struct sof_manifest *)man_ptr;

	dev_info(scomp->dev,
		 "Topology: ABI %d:%d:%d Kernel ABI %u:%u:%u\n",
		  le16_to_cpu(manifest->abi_major), le16_to_cpu(manifest->abi_minor),
		  le16_to_cpu(manifest->abi_patch),
		  SOF_ABI_MAJOR, SOF_ABI_MINOR, SOF_ABI_PATCH);

	/* TODO: Add ABI compatibility check */

	/* no more data after the ABI version */
	if (size <= SOF_IPC4_TPLG_ABI_SIZE)
		return 0;

	manifest_tlv = manifest->items;
	len_check = sizeof(struct sof_manifest);
	for (i = 0; i < le16_to_cpu(manifest->count); i++) {
		len_check += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size);
		if (len_check > size)
			return -EINVAL;

		switch (le32_to_cpu(manifest_tlv->type)) {
		case SOF_MANIFEST_DATA_TYPE_NHLT:
			/* no NHLT in BIOS, so use the one from topology manifest */
			if (ipc4_data->nhlt)
				break;
			ipc4_data->nhlt = devm_kmemdup(sdev->dev, manifest_tlv->data,
						       le32_to_cpu(manifest_tlv->size), GFP_KERNEL);
			if (!ipc4_data->nhlt)
				return -ENOMEM;
			break;
		default:
			dev_warn(scomp->dev, "Skipping unknown manifest data type %d\n",
				 manifest_tlv->type);
			break;
		}
		man_ptr += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size);
		manifest_tlv = (struct sof_manifest_tlv *)man_ptr;
	}

	return 0;
}

static int sof_ipc4_dai_get_clk(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, int clk_type)
{
	struct sof_ipc4_copier *ipc4_copier = dai->private;
	struct snd_soc_tplg_hw_config *hw_config;
	struct snd_sof_dai_link *slink;
	bool dai_link_found = false;
	bool hw_cfg_found = false;
	int i;

	if (!ipc4_copier)
		return 0;

	list_for_each_entry(slink, &sdev->dai_link_list, list) {
		if (!strcmp(slink->link->name, dai->name)) {
			dai_link_found = true;
			break;
		}
	}

	if (!dai_link_found) {
		dev_err(sdev->dev, "no DAI link found for DAI %s\n", dai->name);
		return -EINVAL;
	}

	for (i = 0; i < slink->num_hw_configs; i++) {
		hw_config = &slink->hw_configs[i];
		if (dai->current_config == le32_to_cpu(hw_config->id)) {
			hw_cfg_found = true;
			break;
		}
	}

	if (!hw_cfg_found) {
		dev_err(sdev->dev, "no matching hw_config found for DAI %s\n", dai->name);
		return -EINVAL;
	}

	switch (ipc4_copier->dai_type) {
	case SOF_DAI_INTEL_SSP:
		switch (clk_type) {
		case SOF_DAI_CLK_INTEL_SSP_MCLK:
			return le32_to_cpu(hw_config->mclk_rate);
		case SOF_DAI_CLK_INTEL_SSP_BCLK:
			return le32_to_cpu(hw_config->bclk_rate);
		default:
			dev_err(sdev->dev, "Invalid clk type for SSP %d\n", clk_type);
			break;
		}
		break;
	default:
		dev_err(sdev->dev, "DAI type %d not supported yet!\n", ipc4_copier->dai_type);
		break;
	}

	return -EINVAL;
}

static int sof_ipc4_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verify)
{
	struct snd_sof_pcm *spcm;
	int dir, ret;

	/*
	 * This function is called during system suspend, we need to make sure
	 * that all streams have been freed up.
	 * Freeing might have been skipped when xrun happened just at the start
	 * of the suspend and it sent a SNDRV_PCM_TRIGGER_STOP to the active
	 * stream. This will call sof_pcm_stream_free() with
	 * free_widget_list = false which will leave the kernel and firmware out
	 * of sync during suspend/resume.
	 *
	 * This will also make sure that paused streams handled correctly.
	 */
	list_for_each_entry(spcm, &sdev->pcm_list, list) {
		for_each_pcm_streams(dir) {
			struct snd_pcm_substream *substream = spcm->stream[dir].substream;

			if (!substream || !substream->runtime || spcm->stream[dir].suspend_ignored)
				continue;

			if (spcm->stream[dir].list) {
				ret = sof_pcm_stream_free(sdev, substream, spcm, dir, true);
				if (ret < 0)
					return ret;
			}
		}
	}
	return 0;
}

static int sof_ipc4_link_setup(struct snd_sof_dev *sdev, struct snd_soc_dai_link *link)
{
	if (link->no_pcm)
		return 0;

	/*
	 * set default trigger order for all links. Exceptions to
	 * the rule will be handled in sof_pcm_dai_link_fixup()
	 * For playback, the sequence is the following: start BE,
	 * start FE, stop FE, stop BE; for Capture the sequence is
	 * inverted start FE, start BE, stop BE, stop FE
	 */
	link->trigger[SNDRV_PCM_STREAM_PLAYBACK] = SND_SOC_DPCM_TRIGGER_POST;
	link->trigger[SNDRV_PCM_STREAM_CAPTURE] = SND_SOC_DPCM_TRIGGER_PRE;

	return 0;
}

static enum sof_tokens common_copier_token_list[] = {
	SOF_COMP_TOKENS,
	SOF_AUDIO_FMT_NUM_TOKENS,
	SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS,
	SOF_IN_AUDIO_FORMAT_TOKENS,
	SOF_OUT_AUDIO_FORMAT_TOKENS,
	SOF_COPIER_GATEWAY_CFG_TOKENS,
	SOF_COPIER_TOKENS,
	SOF_COMP_EXT_TOKENS,
};

static enum sof_tokens pipeline_token_list[] = {
	SOF_SCHED_TOKENS,
	SOF_PIPELINE_TOKENS,
};

static enum sof_tokens dai_token_list[] = {
	SOF_COMP_TOKENS,
	SOF_AUDIO_FMT_NUM_TOKENS,
	SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS,
	SOF_IN_AUDIO_FORMAT_TOKENS,
	SOF_OUT_AUDIO_FORMAT_TOKENS,
	SOF_COPIER_GATEWAY_CFG_TOKENS,
	SOF_COPIER_TOKENS,
	SOF_DAI_TOKENS,
	SOF_COMP_EXT_TOKENS,
};

static enum sof_tokens pga_token_list[] = {
	SOF_COMP_TOKENS,
	SOF_GAIN_TOKENS,
	SOF_AUDIO_FMT_NUM_TOKENS,
	SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS,
	SOF_IN_AUDIO_FORMAT_TOKENS,
	SOF_COMP_EXT_TOKENS,
};

static enum sof_tokens mixer_token_list[] = {
	SOF_COMP_TOKENS,
	SOF_AUDIO_FMT_NUM_TOKENS,
	SOF_IN_AUDIO_FORMAT_TOKENS,
	SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS,
	SOF_COMP_EXT_TOKENS,
};

static enum sof_tokens src_token_list[] = {
	SOF_COMP_TOKENS,
	SOF_SRC_TOKENS,
	SOF_AUDIO_FMT_NUM_TOKENS,
	SOF_IN_AUDIO_FORMAT_TOKENS,
	SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS,
	SOF_COMP_EXT_TOKENS,
};

static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TYPE_COUNT] = {
	[snd_soc_dapm_aif_in] =  {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm,
				  common_copier_token_list, ARRAY_SIZE(common_copier_token_list),
				  NULL, sof_ipc4_prepare_copier_module,
				  sof_ipc4_unprepare_copier_module},
	[snd_soc_dapm_aif_out] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm,
				  common_copier_token_list, ARRAY_SIZE(common_copier_token_list),
				  NULL, sof_ipc4_prepare_copier_module,
				  sof_ipc4_unprepare_copier_module},
	[snd_soc_dapm_dai_in] = {sof_ipc4_widget_setup_comp_dai, sof_ipc4_widget_free_comp_dai,
				 dai_token_list, ARRAY_SIZE(dai_token_list), NULL,
				 sof_ipc4_prepare_copier_module,
				 sof_ipc4_unprepare_copier_module},
	[snd_soc_dapm_dai_out] = {sof_ipc4_widget_setup_comp_dai, sof_ipc4_widget_free_comp_dai,
				  dai_token_list, ARRAY_SIZE(dai_token_list), NULL,
				  sof_ipc4_prepare_copier_module,
				  sof_ipc4_unprepare_copier_module},
	[snd_soc_dapm_buffer] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm,
				 common_copier_token_list, ARRAY_SIZE(common_copier_token_list),
				 NULL, sof_ipc4_prepare_copier_module,
				 sof_ipc4_unprepare_copier_module},
	[snd_soc_dapm_scheduler] = {sof_ipc4_widget_setup_comp_pipeline,
				    sof_ipc4_widget_free_comp_pipeline,
				    pipeline_token_list, ARRAY_SIZE(pipeline_token_list), NULL,
				    NULL, NULL},
	[snd_soc_dapm_pga] = {sof_ipc4_widget_setup_comp_pga, sof_ipc4_widget_free_comp_pga,
			      pga_token_list, ARRAY_SIZE(pga_token_list), NULL,
			      sof_ipc4_prepare_gain_module,
			      NULL},
	[snd_soc_dapm_mixer] = {sof_ipc4_widget_setup_comp_mixer, sof_ipc4_widget_free_comp_mixer,
				mixer_token_list, ARRAY_SIZE(mixer_token_list),
				NULL, sof_ipc4_prepare_mixer_module,
				NULL},
	[snd_soc_dapm_src] = {sof_ipc4_widget_setup_comp_src, sof_ipc4_widget_free_comp_src,
				src_token_list, ARRAY_SIZE(src_token_list),
				NULL, sof_ipc4_prepare_src_module,
				NULL},
};

const struct sof_ipc_tplg_ops ipc4_tplg_ops = {
	.widget = tplg_ipc4_widget_ops,
	.token_list = ipc4_token_list,
	.control_setup = sof_ipc4_control_setup,
	.control = &tplg_ipc4_control_ops,
	.widget_setup = sof_ipc4_widget_setup,
	.widget_free = sof_ipc4_widget_free,
	.route_setup = sof_ipc4_route_setup,
	.route_free = sof_ipc4_route_free,
	.dai_config = sof_ipc4_dai_config,
	.parse_manifest = sof_ipc4_parse_manifest,
	.dai_get_clk = sof_ipc4_dai_get_clk,
	.tear_down_all_pipelines = sof_ipc4_tear_down_all_pipelines,
	.link_setup = sof_ipc4_link_setup,
};
