// SPDX-License-Identifier: GPL-2.0
/*
 * Greybus audio driver
 * Copyright 2015-2016 Google Inc.
 * Copyright 2015-2016 Linaro Ltd.
 */

#include "audio_codec.h"
#include "greybus_protocols.h"

#define GBAUDIO_INVALID_ID	0xFF

/* mixer control */
struct gb_mixer_control {
	int min, max;
	unsigned int reg, rreg, shift, rshift, invert;
};

struct gbaudio_ctl_pvt {
	unsigned int ctl_id;
	unsigned int data_cport;
	unsigned int access;
	unsigned int vcount;
	struct gb_audio_ctl_elem_info *info;
};

static struct gbaudio_module_info *find_gb_module(
					struct gbaudio_codec_info *codec,
					char const *name)
{
	int dev_id, ret;
	char begin[NAME_SIZE];
	struct gbaudio_module_info *module;

	if (!name)
		return NULL;

	ret = sscanf(name, "%s %d", begin, &dev_id);
	dev_dbg(codec->dev, "%s:Find module#%d\n", __func__, dev_id);

	mutex_lock(&codec->lock);
	list_for_each_entry(module, &codec->module_list, list) {
		if (module->dev_id == dev_id) {
			mutex_unlock(&codec->lock);
			return module;
		}
	}
	mutex_unlock(&codec->lock);
	dev_warn(codec->dev, "%s: module#%d missing in codec list\n", name,
		 dev_id);
	return NULL;
}

static const char *gbaudio_map_controlid(struct gbaudio_module_info *module,
					 __u8 control_id, __u8 index)
{
	struct gbaudio_control *control;

	if (control_id == GBAUDIO_INVALID_ID)
		return NULL;

	list_for_each_entry(control, &module->ctl_list, list) {
		if (control->id == control_id) {
			if (index == GBAUDIO_INVALID_ID)
				return control->name;
			if (index >= control->items)
				return NULL;
			return control->texts[index];
		}
	}
	list_for_each_entry(control, &module->widget_ctl_list, list) {
		if (control->id == control_id) {
			if (index == GBAUDIO_INVALID_ID)
				return control->name;
			if (index >= control->items)
				return NULL;
			return control->texts[index];
		}
	}
	return NULL;
}

static int gbaudio_map_controlname(struct gbaudio_module_info *module,
				   const char *name)
{
	struct gbaudio_control *control;

	list_for_each_entry(control, &module->ctl_list, list) {
		if (!strncmp(control->name, name, NAME_SIZE))
			return control->id;
	}

	dev_warn(module->dev, "%s: missing in modules controls list\n", name);

	return -EINVAL;
}

static int gbaudio_map_wcontrolname(struct gbaudio_module_info *module,
				    const char *name)
{
	struct gbaudio_control *control;

	list_for_each_entry(control, &module->widget_ctl_list, list) {
		if (!strncmp(control->wname, name, NAME_SIZE))
			return control->id;
	}
	dev_warn(module->dev, "%s: missing in modules controls list\n", name);

	return -EINVAL;
}

static int gbaudio_map_widgetname(struct gbaudio_module_info *module,
				  const char *name)
{
	struct gbaudio_widget *widget;

	list_for_each_entry(widget, &module->widget_list, list) {
		if (!strncmp(widget->name, name, NAME_SIZE))
			return widget->id;
	}
	dev_warn(module->dev, "%s: missing in modules widgets list\n", name);

	return -EINVAL;
}

static const char *gbaudio_map_widgetid(struct gbaudio_module_info *module,
					__u8 widget_id)
{
	struct gbaudio_widget *widget;

	list_for_each_entry(widget, &module->widget_list, list) {
		if (widget->id == widget_id)
			return widget->name;
	}
	return NULL;
}

static const char **gb_generate_enum_strings(struct gbaudio_module_info *gb,
					     struct gb_audio_enumerated *gbenum)
{
	const char **strings;
	int i;
	unsigned int items;
	__u8 *data;

	items = le32_to_cpu(gbenum->items);
	strings = devm_kcalloc(gb->dev, items, sizeof(char *), GFP_KERNEL);
	if (!strings)
		return NULL;

	data = gbenum->names;

	for (i = 0; i < items; i++) {
		strings[i] = (const char *)data;
		while (*data != '\0')
			data++;
		data++;
	}

	return strings;
}

static int gbcodec_mixer_ctl_info(struct snd_kcontrol *kcontrol,
				  struct snd_ctl_elem_info *uinfo)
{
	unsigned int max;
	const char *name;
	struct gbaudio_ctl_pvt *data;
	struct gb_audio_ctl_elem_info *info;
	struct gbaudio_module_info *module;
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	struct gbaudio_codec_info *gbcodec = snd_soc_codec_get_drvdata(codec);

	dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
	data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
	info = (struct gb_audio_ctl_elem_info *)data->info;

	if (!info) {
		dev_err(codec->dev, "NULL info for %s\n", uinfo->id.name);
		return -EINVAL;
	}

	/* update uinfo */
	uinfo->access = data->access;
	uinfo->count = data->vcount;
	uinfo->type = (snd_ctl_elem_type_t)info->type;

	switch (info->type) {
	case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
	case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
		uinfo->value.integer.min = le32_to_cpu(info->value.integer.min);
		uinfo->value.integer.max = le32_to_cpu(info->value.integer.max);
		break;
	case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
		max = le32_to_cpu(info->value.enumerated.items);
		uinfo->value.enumerated.items = max;
		if (uinfo->value.enumerated.item > max - 1)
			uinfo->value.enumerated.item = max - 1;
		module = find_gb_module(gbcodec, kcontrol->id.name);
		if (!module)
			return -EINVAL;
		name = gbaudio_map_controlid(module, data->ctl_id,
					     uinfo->value.enumerated.item);
		strlcpy(uinfo->value.enumerated.name, name, NAME_SIZE);
		break;
	default:
		dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
			info->type, kcontrol->id.name);
		break;
	}
	return 0;
}

static int gbcodec_mixer_ctl_get(struct snd_kcontrol *kcontrol,
				 struct snd_ctl_elem_value *ucontrol)
{
	int ret;
	struct gb_audio_ctl_elem_info *info;
	struct gbaudio_ctl_pvt *data;
	struct gb_audio_ctl_elem_value gbvalue;
	struct gbaudio_module_info *module;
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
	struct gb_bundle *bundle;

	dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
	module = find_gb_module(gb, kcontrol->id.name);
	if (!module)
		return -EINVAL;

	data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
	info = (struct gb_audio_ctl_elem_info *)data->info;
	bundle = to_gb_bundle(module->dev);

	ret = gb_pm_runtime_get_sync(bundle);
	if (ret)
		return ret;

	ret = gb_audio_gb_get_control(module->mgmt_connection, data->ctl_id,
				      GB_AUDIO_INVALID_INDEX, &gbvalue);

	gb_pm_runtime_put_autosuspend(bundle);

	if (ret) {
		dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
				    __func__, kcontrol->id.name);
		return ret;
	}

	/* update ucontrol */
	switch (info->type) {
	case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
	case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
		ucontrol->value.integer.value[0] =
			le32_to_cpu(gbvalue.value.integer_value[0]);
		if (data->vcount == 2)
			ucontrol->value.integer.value[1] =
				le32_to_cpu(gbvalue.value.integer_value[1]);
		break;
	case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
		ucontrol->value.enumerated.item[0] =
			le32_to_cpu(gbvalue.value.enumerated_item[0]);
		if (data->vcount == 2)
			ucontrol->value.enumerated.item[1] =
				le32_to_cpu(gbvalue.value.enumerated_item[1]);
		break;
	default:
		dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
			info->type, kcontrol->id.name);
		ret = -EINVAL;
		break;
	}
	return ret;
}

static int gbcodec_mixer_ctl_put(struct snd_kcontrol *kcontrol,
				 struct snd_ctl_elem_value *ucontrol)
{
	int ret = 0;
	struct gb_audio_ctl_elem_info *info;
	struct gbaudio_ctl_pvt *data;
	struct gb_audio_ctl_elem_value gbvalue;
	struct gbaudio_module_info *module;
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
	struct gb_bundle *bundle;

	dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
	module = find_gb_module(gb, kcontrol->id.name);
	if (!module)
		return -EINVAL;

	data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
	info = (struct gb_audio_ctl_elem_info *)data->info;
	bundle = to_gb_bundle(module->dev);

	/* update ucontrol */
	switch (info->type) {
	case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
	case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
		gbvalue.value.integer_value[0] =
			cpu_to_le32(ucontrol->value.integer.value[0]);
		if (data->vcount == 2)
			gbvalue.value.integer_value[1] =
				cpu_to_le32(ucontrol->value.integer.value[1]);
		break;
	case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
		gbvalue.value.enumerated_item[0] =
			cpu_to_le32(ucontrol->value.enumerated.item[0]);
		if (data->vcount == 2)
			gbvalue.value.enumerated_item[1] =
				cpu_to_le32(ucontrol->value.enumerated.item[1]);
		break;
	default:
		dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
			info->type, kcontrol->id.name);
		ret = -EINVAL;
		break;
	}

	if (ret)
		return ret;

	ret = gb_pm_runtime_get_sync(bundle);
	if (ret)
		return ret;

	ret = gb_audio_gb_set_control(module->mgmt_connection, data->ctl_id,
				      GB_AUDIO_INVALID_INDEX, &gbvalue);

	gb_pm_runtime_put_autosuspend(bundle);

	if (ret) {
		dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
				    __func__, kcontrol->id.name);
	}

	return ret;
}

#define SOC_MIXER_GB(xname, kcount, data) \
{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
	.count = kcount, .info = gbcodec_mixer_ctl_info, \
	.get = gbcodec_mixer_ctl_get, .put = gbcodec_mixer_ctl_put, \
	.private_value = (unsigned long)data }

/*
 * although below callback functions seems redundant to above functions.
 * same are kept to allow provision for different handling in case
 * of DAPM related sequencing, etc.
 */
static int gbcodec_mixer_dapm_ctl_info(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_info *uinfo)
{
	int platform_max, platform_min;
	struct gbaudio_ctl_pvt *data;
	struct gb_audio_ctl_elem_info *info;
	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
	struct snd_soc_codec *codec = widget->codec;

	dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
	data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
	info = (struct gb_audio_ctl_elem_info *)data->info;

	/* update uinfo */
	platform_max = le32_to_cpu(info->value.integer.max);
	platform_min = le32_to_cpu(info->value.integer.min);

	if (platform_max == 1 &&
	    !strnstr(kcontrol->id.name, " Volume", NAME_SIZE))
		uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
	else
		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;

	uinfo->count = data->vcount;
	uinfo->value.integer.min = platform_min;
	uinfo->value.integer.max = platform_max;

	return 0;
}

static int gbcodec_mixer_dapm_ctl_get(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	int ret;
	struct gb_audio_ctl_elem_info *info;
	struct gbaudio_ctl_pvt *data;
	struct gb_audio_ctl_elem_value gbvalue;
	struct gbaudio_module_info *module;
	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
	struct snd_soc_codec *codec = widget->codec;
	struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
	struct gb_bundle *bundle;

	dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
	module = find_gb_module(gb, kcontrol->id.name);
	if (!module)
		return -EINVAL;

	data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
	info = (struct gb_audio_ctl_elem_info *)data->info;
	bundle = to_gb_bundle(module->dev);

	if (data->vcount == 2)
		dev_warn(widget->dapm->dev,
			 "GB: Control '%s' is stereo, which is not supported\n",
			 kcontrol->id.name);

	ret = gb_pm_runtime_get_sync(bundle);
	if (ret)
		return ret;

	ret = gb_audio_gb_get_control(module->mgmt_connection, data->ctl_id,
				      GB_AUDIO_INVALID_INDEX, &gbvalue);

	gb_pm_runtime_put_autosuspend(bundle);

	if (ret) {
		dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
				    __func__, kcontrol->id.name);
		return ret;
	}
	/* update ucontrol */
	ucontrol->value.integer.value[0] =
		le32_to_cpu(gbvalue.value.integer_value[0]);

	return ret;
}

static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	int ret, wi, max, connect;
	unsigned int mask, val;
	struct gb_audio_ctl_elem_info *info;
	struct gbaudio_ctl_pvt *data;
	struct gb_audio_ctl_elem_value gbvalue;
	struct gbaudio_module_info *module;
	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
	struct snd_soc_codec *codec = widget->codec;
	struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
	struct gb_bundle *bundle;

	dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
	module = find_gb_module(gb, kcontrol->id.name);
	if (!module)
		return -EINVAL;

	data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
	info = (struct gb_audio_ctl_elem_info *)data->info;
	bundle = to_gb_bundle(module->dev);

	if (data->vcount == 2)
		dev_warn(widget->dapm->dev,
			 "GB: Control '%s' is stereo, which is not supported\n",
			 kcontrol->id.name);

	max = le32_to_cpu(info->value.integer.max);
	mask = (1 << fls(max)) - 1;
	val = ucontrol->value.integer.value[0] & mask;
	connect = !!val;

	ret = gb_pm_runtime_get_sync(bundle);
	if (ret)
		return ret;

	ret = gb_audio_gb_get_control(module->mgmt_connection, data->ctl_id,
				      GB_AUDIO_INVALID_INDEX, &gbvalue);
	if (ret)
		goto exit;

	/* update ucontrol */
	if (gbvalue.value.integer_value[0] != val) {
		for (wi = 0; wi < wlist->num_widgets; wi++) {
			widget = wlist->widgets[wi];

			widget->value = val;
			widget->dapm->update = NULL;
			snd_soc_dapm_mixer_update_power(widget, kcontrol,
							connect);
		}
		gbvalue.value.integer_value[0] =
			cpu_to_le32(ucontrol->value.integer.value[0]);

		ret = gb_audio_gb_set_control(module->mgmt_connection,
					      data->ctl_id,
					      GB_AUDIO_INVALID_INDEX, &gbvalue);
	}

exit:
	gb_pm_runtime_put_autosuspend(bundle);
	if (ret)
		dev_err_ratelimited(codec_dev, "%d:Error in %s for %s\n", ret,
				    __func__, kcontrol->id.name);
	return ret;
}

#define SOC_DAPM_MIXER_GB(xname, kcount, data) \
{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
	.count = kcount, .info = gbcodec_mixer_dapm_ctl_info, \
	.get = gbcodec_mixer_dapm_ctl_get, .put = gbcodec_mixer_dapm_ctl_put, \
	.private_value = (unsigned long)data}

static int gbcodec_event_spk(struct snd_soc_dapm_widget *w,
			     struct snd_kcontrol *k, int event)
{
	/* Ensure GB speaker is connected */

	return 0;
}

static int gbcodec_event_hp(struct snd_soc_dapm_widget *w,
			    struct snd_kcontrol *k, int event)
{
	/* Ensure GB module supports jack slot */

	return 0;
}

static int gbcodec_event_int_mic(struct snd_soc_dapm_widget *w,
				 struct snd_kcontrol *k, int event)
{
	/* Ensure GB module supports jack slot */

	return 0;
}

static int gbaudio_validate_kcontrol_count(struct gb_audio_widget *w)
{
	int ret = 0;

	switch (w->type) {
	case snd_soc_dapm_spk:
	case snd_soc_dapm_hp:
	case snd_soc_dapm_mic:
	case snd_soc_dapm_output:
	case snd_soc_dapm_input:
		if (w->ncontrols)
			ret = -EINVAL;
		break;
	case snd_soc_dapm_switch:
	case snd_soc_dapm_mux:
		if (w->ncontrols != 1)
			ret = -EINVAL;
		break;
	default:
		break;
	}

	return ret;
}

static int gbcodec_enum_ctl_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	int ret, ctl_id;
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	struct gb_audio_ctl_elem_value gbvalue;
	struct gbaudio_module_info *module;
	struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
	struct gb_bundle *bundle;

	module = find_gb_module(gb, kcontrol->id.name);
	if (!module)
		return -EINVAL;

	ctl_id = gbaudio_map_controlname(module, kcontrol->id.name);
	if (ctl_id < 0)
		return -EINVAL;

	bundle = to_gb_bundle(module->dev);

	ret = gb_pm_runtime_get_sync(bundle);
	if (ret)
		return ret;

	ret = gb_audio_gb_get_control(module->mgmt_connection, ctl_id,
				      GB_AUDIO_INVALID_INDEX, &gbvalue);

	gb_pm_runtime_put_autosuspend(bundle);

	if (ret) {
		dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
				    __func__, kcontrol->id.name);
		return ret;
	}

	ucontrol->value.enumerated.item[0] =
		le32_to_cpu(gbvalue.value.enumerated_item[0]);
	if (e->shift_l != e->shift_r)
		ucontrol->value.enumerated.item[1] =
			le32_to_cpu(gbvalue.value.enumerated_item[1]);

	return 0;
}

static int gbcodec_enum_ctl_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	int ret, ctl_id;
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	struct gb_audio_ctl_elem_value gbvalue;
	struct gbaudio_module_info *module;
	struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
	struct gb_bundle *bundle;

	module = find_gb_module(gb, kcontrol->id.name);
	if (!module)
		return -EINVAL;

	ctl_id = gbaudio_map_controlname(module, kcontrol->id.name);
	if (ctl_id < 0)
		return -EINVAL;

	if (ucontrol->value.enumerated.item[0] > e->max - 1)
		return -EINVAL;
	gbvalue.value.enumerated_item[0] =
		cpu_to_le32(ucontrol->value.enumerated.item[0]);

	if (e->shift_l != e->shift_r) {
		if (ucontrol->value.enumerated.item[1] > e->max - 1)
			return -EINVAL;
		gbvalue.value.enumerated_item[1] =
			cpu_to_le32(ucontrol->value.enumerated.item[1]);
	}

	bundle = to_gb_bundle(module->dev);

	ret = gb_pm_runtime_get_sync(bundle);
	if (ret)
		return ret;

	ret = gb_audio_gb_set_control(module->mgmt_connection, ctl_id,
				      GB_AUDIO_INVALID_INDEX, &gbvalue);

	gb_pm_runtime_put_autosuspend(bundle);

	if (ret) {
		dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
				    __func__, kcontrol->id.name);
	}

	return ret;
}

static int gbaudio_tplg_create_enum_kctl(struct gbaudio_module_info *gb,
					 struct snd_kcontrol_new *kctl,
					 struct gb_audio_control *ctl)
{
	struct soc_enum *gbe;
	struct gb_audio_enumerated *gb_enum;
	int i;

	gbe = devm_kzalloc(gb->dev, sizeof(*gbe), GFP_KERNEL);
	if (!gbe)
		return -ENOMEM;

	gb_enum = &ctl->info.value.enumerated;

	/* since count=1, and reg is dummy */
	gbe->max = le32_to_cpu(gb_enum->items);
	gbe->texts = gb_generate_enum_strings(gb, gb_enum);
	if (!gbe->texts)
		return -ENOMEM;

	/* debug enum info */
	dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->max,
		le16_to_cpu(gb_enum->names_length));
	for (i = 0; i < gbe->max; i++)
		dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]);

	*kctl = (struct snd_kcontrol_new)
		SOC_ENUM_EXT(ctl->name, *gbe, gbcodec_enum_ctl_get,
			     gbcodec_enum_ctl_put);
	return 0;
}

static int gbaudio_tplg_create_kcontrol(struct gbaudio_module_info *gb,
					struct snd_kcontrol_new *kctl,
					struct gb_audio_control *ctl)
{
	int ret = 0;
	struct gbaudio_ctl_pvt *ctldata;

	switch (ctl->iface) {
	case SNDRV_CTL_ELEM_IFACE_MIXER:
		switch (ctl->info.type) {
		case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
			ret = gbaudio_tplg_create_enum_kctl(gb, kctl, ctl);
			break;
		default:
			ctldata = devm_kzalloc(gb->dev,
					       sizeof(struct gbaudio_ctl_pvt),
					       GFP_KERNEL);
			if (!ctldata)
				return -ENOMEM;
			ctldata->ctl_id = ctl->id;
			ctldata->data_cport = le16_to_cpu(ctl->data_cport);
			ctldata->access = ctl->access;
			ctldata->vcount = ctl->count_values;
			ctldata->info = &ctl->info;
			*kctl = (struct snd_kcontrol_new)
				SOC_MIXER_GB(ctl->name, ctl->count, ctldata);
			ctldata = NULL;
			break;
		}
		break;
	default:
		return -EINVAL;
	}

	dev_dbg(gb->dev, "%s:%d control created\n", ctl->name, ctl->id);
	return ret;
}

static int gbcodec_enum_dapm_ctl_get(struct snd_kcontrol *kcontrol,
				     struct snd_ctl_elem_value *ucontrol)
{
	int ret, ctl_id;
	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
	struct gbaudio_module_info *module;
	struct gb_audio_ctl_elem_value gbvalue;
	struct snd_soc_codec *codec = widget->codec;
	struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	struct gb_bundle *bundle;

	module = find_gb_module(gb, kcontrol->id.name);
	if (!module)
		return -EINVAL;

	ctl_id = gbaudio_map_wcontrolname(module, kcontrol->id.name);
	if (ctl_id < 0)
		return -EINVAL;

	bundle = to_gb_bundle(module->dev);

	ret = gb_pm_runtime_get_sync(bundle);
	if (ret)
		return ret;

	ret = gb_audio_gb_get_control(module->mgmt_connection, ctl_id,
				      GB_AUDIO_INVALID_INDEX, &gbvalue);

	gb_pm_runtime_put_autosuspend(bundle);

	if (ret) {
		dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
				    __func__, kcontrol->id.name);
		return ret;
	}

	ucontrol->value.enumerated.item[0] = gbvalue.value.enumerated_item[0];
	if (e->shift_l != e->shift_r)
		ucontrol->value.enumerated.item[1] =
			gbvalue.value.enumerated_item[1];

	return 0;
}

static int gbcodec_enum_dapm_ctl_put(struct snd_kcontrol *kcontrol,
				     struct snd_ctl_elem_value *ucontrol)
{
	int ret, wi, ctl_id;
	unsigned int val, mux, change;
	unsigned int mask;
	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
	struct gb_audio_ctl_elem_value gbvalue;
	struct gbaudio_module_info *module;
	struct snd_soc_codec *codec = widget->codec;
	struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	struct gb_bundle *bundle;

	if (ucontrol->value.enumerated.item[0] > e->max - 1)
		return -EINVAL;

	module = find_gb_module(gb, kcontrol->id.name);
	if (!module)
		return -EINVAL;

	ctl_id = gbaudio_map_wcontrolname(module, kcontrol->id.name);
	if (ctl_id < 0)
		return -EINVAL;

	change = 0;
	bundle = to_gb_bundle(module->dev);

	ret = gb_pm_runtime_get_sync(bundle);
	if (ret)
		return ret;

	ret = gb_audio_gb_get_control(module->mgmt_connection, ctl_id,
				      GB_AUDIO_INVALID_INDEX, &gbvalue);

	gb_pm_runtime_put_autosuspend(bundle);

	if (ret) {
		dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
				    __func__, kcontrol->id.name);
		return ret;
	}

	mux = ucontrol->value.enumerated.item[0];
	val = mux << e->shift_l;
	mask = e->mask << e->shift_l;

	if (gbvalue.value.enumerated_item[0] !=
	    ucontrol->value.enumerated.item[0]) {
		change = 1;
		gbvalue.value.enumerated_item[0] =
			ucontrol->value.enumerated.item[0];
	}

	if (e->shift_l != e->shift_r) {
		if (ucontrol->value.enumerated.item[1] > e->max - 1)
			return -EINVAL;
		val |= ucontrol->value.enumerated.item[1] << e->shift_r;
		mask |= e->mask << e->shift_r;
		if (gbvalue.value.enumerated_item[1] !=
		    ucontrol->value.enumerated.item[1]) {
			change = 1;
			gbvalue.value.enumerated_item[1] =
				ucontrol->value.enumerated.item[1];
		}
	}

	if (change) {
		ret = gb_pm_runtime_get_sync(bundle);
		if (ret)
			return ret;

		ret = gb_audio_gb_set_control(module->mgmt_connection, ctl_id,
					      GB_AUDIO_INVALID_INDEX, &gbvalue);

		gb_pm_runtime_put_autosuspend(bundle);

		if (ret) {
			dev_err_ratelimited(codec->dev,
					    "%d:Error in %s for %s\n", ret,
					    __func__, kcontrol->id.name);
		}
		for (wi = 0; wi < wlist->num_widgets; wi++) {
			widget = wlist->widgets[wi];

			widget->value = val;
			widget->dapm->update = NULL;
			snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e);
		}
	}

	return change;
}

static int gbaudio_tplg_create_enum_ctl(struct gbaudio_module_info *gb,
					struct snd_kcontrol_new *kctl,
					struct gb_audio_control *ctl)
{
	struct soc_enum *gbe;
	struct gb_audio_enumerated *gb_enum;
	int i;

	gbe = devm_kzalloc(gb->dev, sizeof(*gbe), GFP_KERNEL);
	if (!gbe)
		return -ENOMEM;

	gb_enum = &ctl->info.value.enumerated;

	/* since count=1, and reg is dummy */
	gbe->max = le32_to_cpu(gb_enum->items);
	gbe->texts = gb_generate_enum_strings(gb, gb_enum);
	if (!gbe->texts)
		return -ENOMEM;

	/* debug enum info */
	dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->max,
		le16_to_cpu(gb_enum->names_length));
	for (i = 0; i < gbe->max; i++)
		dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]);

	*kctl = (struct snd_kcontrol_new)
		SOC_DAPM_ENUM_EXT(ctl->name, *gbe, gbcodec_enum_dapm_ctl_get,
				  gbcodec_enum_dapm_ctl_put);
	return 0;
}

static int gbaudio_tplg_create_mixer_ctl(struct gbaudio_module_info *gb,
					 struct snd_kcontrol_new *kctl,
					 struct gb_audio_control *ctl)
{
	struct gbaudio_ctl_pvt *ctldata;

	ctldata = devm_kzalloc(gb->dev, sizeof(struct gbaudio_ctl_pvt),
			       GFP_KERNEL);
	if (!ctldata)
		return -ENOMEM;
	ctldata->ctl_id = ctl->id;
	ctldata->data_cport = le16_to_cpu(ctl->data_cport);
	ctldata->access = ctl->access;
	ctldata->vcount = ctl->count_values;
	ctldata->info = &ctl->info;
	*kctl = (struct snd_kcontrol_new)
		SOC_DAPM_MIXER_GB(ctl->name, ctl->count, ctldata);

	return 0;
}

static int gbaudio_tplg_create_wcontrol(struct gbaudio_module_info *gb,
					struct snd_kcontrol_new *kctl,
					struct gb_audio_control *ctl)
{
	int ret;

	switch (ctl->iface) {
	case SNDRV_CTL_ELEM_IFACE_MIXER:
		switch (ctl->info.type) {
		case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
			ret = gbaudio_tplg_create_enum_ctl(gb, kctl, ctl);
			break;
		default:
			ret = gbaudio_tplg_create_mixer_ctl(gb, kctl, ctl);
			break;
		}
		break;
	default:
		return -EINVAL;
	}

	dev_dbg(gb->dev, "%s:%d DAPM control created, ret:%d\n", ctl->name,
		ctl->id, ret);
	return ret;
}

static int gbaudio_widget_event(struct snd_soc_dapm_widget *w,
				struct snd_kcontrol *kcontrol, int event)
{
	int wid;
	int ret;
	struct snd_soc_codec *codec = w->codec;
	struct gbaudio_codec_info *gbcodec = snd_soc_codec_get_drvdata(codec);
	struct gbaudio_module_info *module;
	struct gb_bundle *bundle;

	dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);

	/* Find relevant module */
	module = find_gb_module(gbcodec, w->name);
	if (!module)
		return -EINVAL;

	/* map name to widget id */
	wid = gbaudio_map_widgetname(module, w->name);
	if (wid < 0) {
		dev_err(codec->dev, "Invalid widget name:%s\n", w->name);
		return -EINVAL;
	}

	bundle = to_gb_bundle(module->dev);

	ret = gb_pm_runtime_get_sync(bundle);
	if (ret)
		return ret;

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		ret = gb_audio_gb_enable_widget(module->mgmt_connection, wid);
		if (!ret)
			ret = gbaudio_module_update(gbcodec, w, module, 1);
		break;
	case SND_SOC_DAPM_POST_PMD:
		ret = gb_audio_gb_disable_widget(module->mgmt_connection, wid);
		if (!ret)
			ret = gbaudio_module_update(gbcodec, w, module, 0);
		break;
	}
	if (ret)
		dev_err_ratelimited(codec->dev,
				    "%d: widget, event:%d failed:%d\n", wid,
				    event, ret);

	gb_pm_runtime_put_autosuspend(bundle);

	return ret;
}

static const struct snd_soc_dapm_widget gbaudio_widgets[] = {
	[snd_soc_dapm_spk]	= SND_SOC_DAPM_SPK(NULL, gbcodec_event_spk),
	[snd_soc_dapm_hp]	= SND_SOC_DAPM_HP(NULL, gbcodec_event_hp),
	[snd_soc_dapm_mic]	= SND_SOC_DAPM_MIC(NULL, gbcodec_event_int_mic),
	[snd_soc_dapm_output]	= SND_SOC_DAPM_OUTPUT(NULL),
	[snd_soc_dapm_input]	= SND_SOC_DAPM_INPUT(NULL),
	[snd_soc_dapm_switch]	= SND_SOC_DAPM_SWITCH_E(NULL, SND_SOC_NOPM,
					0, 0, NULL,
					gbaudio_widget_event,
					SND_SOC_DAPM_PRE_PMU |
					SND_SOC_DAPM_POST_PMD),
	[snd_soc_dapm_pga]	= SND_SOC_DAPM_PGA_E(NULL, SND_SOC_NOPM,
					0, 0, NULL, 0,
					gbaudio_widget_event,
					SND_SOC_DAPM_PRE_PMU |
					SND_SOC_DAPM_POST_PMD),
	[snd_soc_dapm_mixer]	= SND_SOC_DAPM_MIXER_E(NULL, SND_SOC_NOPM,
					0, 0, NULL, 0,
					gbaudio_widget_event,
					SND_SOC_DAPM_PRE_PMU |
					SND_SOC_DAPM_POST_PMD),
	[snd_soc_dapm_mux]	= SND_SOC_DAPM_MUX_E(NULL, SND_SOC_NOPM,
					0, 0, NULL,
					gbaudio_widget_event,
					SND_SOC_DAPM_PRE_PMU |
					SND_SOC_DAPM_POST_PMD),
	[snd_soc_dapm_aif_in]	= SND_SOC_DAPM_AIF_IN_E(NULL, NULL, 0,
					SND_SOC_NOPM, 0, 0,
					gbaudio_widget_event,
					SND_SOC_DAPM_PRE_PMU |
					SND_SOC_DAPM_POST_PMD),
	[snd_soc_dapm_aif_out]	= SND_SOC_DAPM_AIF_OUT_E(NULL, NULL, 0,
					SND_SOC_NOPM, 0, 0,
					gbaudio_widget_event,
					SND_SOC_DAPM_PRE_PMU |
					SND_SOC_DAPM_POST_PMD),
};

static int gbaudio_tplg_create_widget(struct gbaudio_module_info *module,
				      struct snd_soc_dapm_widget *dw,
				      struct gb_audio_widget *w, int *w_size)
{
	int i, ret, csize;
	struct snd_kcontrol_new *widget_kctls;
	struct gb_audio_control *curr;
	struct gbaudio_control *control, *_control;
	size_t size;
	char temp_name[NAME_SIZE];

	ret = gbaudio_validate_kcontrol_count(w);
	if (ret) {
		dev_err(module->dev, "Invalid kcontrol count=%d for %s\n",
			w->ncontrols, w->name);
		return ret;
	}

	/* allocate memory for kcontrol */
	if (w->ncontrols) {
		size = sizeof(struct snd_kcontrol_new) * w->ncontrols;
		widget_kctls = devm_kzalloc(module->dev, size, GFP_KERNEL);
		if (!widget_kctls)
			return -ENOMEM;
	}

	*w_size = sizeof(struct gb_audio_widget);

	/* create relevant kcontrols */
	curr = w->ctl;
	for (i = 0; i < w->ncontrols; i++) {
		ret = gbaudio_tplg_create_wcontrol(module, &widget_kctls[i],
						   curr);
		if (ret) {
			dev_err(module->dev,
				"%s:%d type widget_ctl not supported\n",
				curr->name, curr->iface);
			goto error;
		}
		control = devm_kzalloc(module->dev,
				       sizeof(struct gbaudio_control),
				       GFP_KERNEL);
		if (!control) {
			ret = -ENOMEM;
			goto error;
		}
		control->id = curr->id;
		control->name = curr->name;
		control->wname = w->name;

		if (curr->info.type == GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED) {
			struct gb_audio_enumerated *gbenum =
				&curr->info.value.enumerated;

			csize = offsetof(struct gb_audio_control, info);
			csize += offsetof(struct gb_audio_ctl_elem_info, value);
			csize += offsetof(struct gb_audio_enumerated, names);
			csize += le16_to_cpu(gbenum->names_length);
			control->texts = (const char * const *)
				gb_generate_enum_strings(module, gbenum);
			if (!control->texts) {
				ret = -ENOMEM;
				goto error;
			}
			control->items = le32_to_cpu(gbenum->items);
		} else {
			csize = sizeof(struct gb_audio_control);
		}

		*w_size += csize;
		curr = (void *)curr + csize;
		list_add(&control->list, &module->widget_ctl_list);
		dev_dbg(module->dev, "%s: control of type %d created\n",
			widget_kctls[i].name, widget_kctls[i].iface);
	}

	/* Prefix dev_id to widget control_name */
	strlcpy(temp_name, w->name, NAME_SIZE);
	snprintf(w->name, NAME_SIZE, "GB %d %s", module->dev_id, temp_name);

	switch (w->type) {
	case snd_soc_dapm_spk:
		*dw = gbaudio_widgets[w->type];
		module->op_devices |= GBAUDIO_DEVICE_OUT_SPEAKER;
		break;
	case snd_soc_dapm_hp:
		*dw = gbaudio_widgets[w->type];
		module->op_devices |= (GBAUDIO_DEVICE_OUT_WIRED_HEADSET
					| GBAUDIO_DEVICE_OUT_WIRED_HEADPHONE);
		module->ip_devices |= GBAUDIO_DEVICE_IN_WIRED_HEADSET;
		break;
	case snd_soc_dapm_mic:
		*dw = gbaudio_widgets[w->type];
		module->ip_devices |= GBAUDIO_DEVICE_IN_BUILTIN_MIC;
		break;
	case snd_soc_dapm_output:
	case snd_soc_dapm_input:
	case snd_soc_dapm_switch:
	case snd_soc_dapm_pga:
	case snd_soc_dapm_mixer:
	case snd_soc_dapm_mux:
		*dw = gbaudio_widgets[w->type];
		break;
	case snd_soc_dapm_aif_in:
	case snd_soc_dapm_aif_out:
		*dw = gbaudio_widgets[w->type];
		dw->sname = w->sname;
		break;
	default:
		ret = -EINVAL;
		goto error;
	}
	dw->name = w->name;

	dev_dbg(module->dev, "%s: widget of type %d created\n", dw->name,
		dw->id);
	return 0;
error:
	list_for_each_entry_safe(control, _control, &module->widget_ctl_list,
				 list) {
		list_del(&control->list);
		devm_kfree(module->dev, control);
	}
	return ret;
}

static int gbaudio_tplg_process_kcontrols(struct gbaudio_module_info *module,
					  struct gb_audio_control *controls)
{
	int i, csize, ret;
	struct snd_kcontrol_new *dapm_kctls;
	struct gb_audio_control *curr;
	struct gbaudio_control *control, *_control;
	size_t size;
	char temp_name[NAME_SIZE];

	size = sizeof(struct snd_kcontrol_new) * module->num_controls;
	dapm_kctls = devm_kzalloc(module->dev, size, GFP_KERNEL);
	if (!dapm_kctls)
		return -ENOMEM;

	curr = controls;
	for (i = 0; i < module->num_controls; i++) {
		ret = gbaudio_tplg_create_kcontrol(module, &dapm_kctls[i],
						   curr);
		if (ret) {
			dev_err(module->dev, "%s:%d type not supported\n",
				curr->name, curr->iface);
			goto error;
		}
		control = devm_kzalloc(module->dev, sizeof(struct
							   gbaudio_control),
				      GFP_KERNEL);
		if (!control) {
			ret = -ENOMEM;
			goto error;
		}
		control->id = curr->id;
		/* Prefix dev_id to widget_name */
		strlcpy(temp_name, curr->name, NAME_SIZE);
		snprintf(curr->name, NAME_SIZE, "GB %d %s", module->dev_id,
			 temp_name);
		control->name = curr->name;
		if (curr->info.type == GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED) {
			struct gb_audio_enumerated *gbenum =
				&curr->info.value.enumerated;

			csize = offsetof(struct gb_audio_control, info);
			csize += offsetof(struct gb_audio_ctl_elem_info, value);
			csize += offsetof(struct gb_audio_enumerated, names);
			csize += le16_to_cpu(gbenum->names_length);
			control->texts = (const char * const *)
				gb_generate_enum_strings(module, gbenum);
			if (!control->texts) {
				ret = -ENOMEM;
				goto error;
			}
			control->items = le32_to_cpu(gbenum->items);
		} else {
			csize = sizeof(struct gb_audio_control);
		}

		list_add(&control->list, &module->ctl_list);
		dev_dbg(module->dev, "%d:%s created of type %d\n", curr->id,
			curr->name, curr->info.type);
		curr = (void *)curr + csize;
	}
	module->controls = dapm_kctls;

	return 0;
error:
	list_for_each_entry_safe(control, _control, &module->ctl_list,
				 list) {
		list_del(&control->list);
		devm_kfree(module->dev, control);
	}
	devm_kfree(module->dev, dapm_kctls);
	return ret;
}

static int gbaudio_tplg_process_widgets(struct gbaudio_module_info *module,
					struct gb_audio_widget *widgets)
{
	int i, ret, w_size;
	struct snd_soc_dapm_widget *dapm_widgets;
	struct gb_audio_widget *curr;
	struct gbaudio_widget *widget, *_widget;
	size_t size;

	size = sizeof(struct snd_soc_dapm_widget) * module->num_dapm_widgets;
	dapm_widgets = devm_kzalloc(module->dev, size, GFP_KERNEL);
	if (!dapm_widgets)
		return -ENOMEM;

	curr = widgets;
	for (i = 0; i < module->num_dapm_widgets; i++) {
		ret = gbaudio_tplg_create_widget(module, &dapm_widgets[i],
						 curr, &w_size);
		if (ret) {
			dev_err(module->dev, "%s:%d type not supported\n",
				curr->name, curr->type);
			goto error;
		}
		widget = devm_kzalloc(module->dev, sizeof(struct
							   gbaudio_widget),
				      GFP_KERNEL);
		if (!widget) {
			ret = -ENOMEM;
			goto error;
		}
		widget->id = curr->id;
		widget->name = curr->name;
		list_add(&widget->list, &module->widget_list);
		curr = (void *)curr + w_size;
	}
	module->dapm_widgets = dapm_widgets;

	return 0;

error:
	list_for_each_entry_safe(widget, _widget, &module->widget_list,
				 list) {
		list_del(&widget->list);
		devm_kfree(module->dev, widget);
	}
	devm_kfree(module->dev, dapm_widgets);
	return ret;
}

static int gbaudio_tplg_process_routes(struct gbaudio_module_info *module,
				       struct gb_audio_route *routes)
{
	int i, ret;
	struct snd_soc_dapm_route *dapm_routes;
	struct gb_audio_route *curr;
	size_t size;

	size = sizeof(struct snd_soc_dapm_route) * module->num_dapm_routes;
	dapm_routes = devm_kzalloc(module->dev, size, GFP_KERNEL);
	if (!dapm_routes)
		return -ENOMEM;

	module->dapm_routes = dapm_routes;
	curr = routes;

	for (i = 0; i < module->num_dapm_routes; i++) {
		dapm_routes->sink =
			gbaudio_map_widgetid(module, curr->destination_id);
		if (!dapm_routes->sink) {
			dev_err(module->dev, "%d:%d:%d:%d - Invalid sink\n",
				curr->source_id, curr->destination_id,
				curr->control_id, curr->index);
			ret = -EINVAL;
			goto error;
		}
		dapm_routes->source =
			gbaudio_map_widgetid(module, curr->source_id);
		if (!dapm_routes->source) {
			dev_err(module->dev, "%d:%d:%d:%d - Invalid source\n",
				curr->source_id, curr->destination_id,
				curr->control_id, curr->index);
			ret = -EINVAL;
			goto error;
		}
		dapm_routes->control =
			gbaudio_map_controlid(module,
					      curr->control_id,
					      curr->index);
		if ((curr->control_id !=  GBAUDIO_INVALID_ID) &&
		    !dapm_routes->control) {
			dev_err(module->dev, "%d:%d:%d:%d - Invalid control\n",
				curr->source_id, curr->destination_id,
				curr->control_id, curr->index);
			ret = -EINVAL;
			goto error;
		}
		dev_dbg(module->dev, "Route {%s, %s, %s}\n", dapm_routes->sink,
			(dapm_routes->control) ? dapm_routes->control : "NULL",
			dapm_routes->source);
		dapm_routes++;
		curr++;
	}

	return 0;

error:
	devm_kfree(module->dev, module->dapm_routes);
	return ret;
}

static int gbaudio_tplg_process_header(struct gbaudio_module_info *module,
				       struct gb_audio_topology *tplg_data)
{
	/* fetch no. of kcontrols, widgets & routes */
	module->num_controls = tplg_data->num_controls;
	module->num_dapm_widgets = tplg_data->num_widgets;
	module->num_dapm_routes = tplg_data->num_routes;

	/* update block offset */
	module->dai_offset = (unsigned long)&tplg_data->data;
	module->control_offset = module->dai_offset +
					le32_to_cpu(tplg_data->size_dais);
	module->widget_offset = module->control_offset +
					le32_to_cpu(tplg_data->size_controls);
	module->route_offset = module->widget_offset +
					le32_to_cpu(tplg_data->size_widgets);

	dev_dbg(module->dev, "DAI offset is 0x%lx\n", module->dai_offset);
	dev_dbg(module->dev, "control offset is %lx\n",
		module->control_offset);
	dev_dbg(module->dev, "widget offset is %lx\n", module->widget_offset);
	dev_dbg(module->dev, "route offset is %lx\n", module->route_offset);

	return 0;
}

int gbaudio_tplg_parse_data(struct gbaudio_module_info *module,
			    struct gb_audio_topology *tplg_data)
{
	int ret;
	struct gb_audio_control *controls;
	struct gb_audio_widget *widgets;
	struct gb_audio_route *routes;
	unsigned int jack_type;

	if (!tplg_data)
		return -EINVAL;

	ret = gbaudio_tplg_process_header(module, tplg_data);
	if (ret) {
		dev_err(module->dev, "%d: Error in parsing topology header\n",
			ret);
		return ret;
	}

	/* process control */
	controls = (struct gb_audio_control *)module->control_offset;
	ret = gbaudio_tplg_process_kcontrols(module, controls);
	if (ret) {
		dev_err(module->dev,
			"%d: Error in parsing controls data\n", ret);
		return ret;
	}
	dev_dbg(module->dev, "Control parsing finished\n");

	/* process widgets */
	widgets = (struct gb_audio_widget *)module->widget_offset;
	ret = gbaudio_tplg_process_widgets(module, widgets);
	if (ret) {
		dev_err(module->dev,
			"%d: Error in parsing widgets data\n", ret);
		return ret;
	}
	dev_dbg(module->dev, "Widget parsing finished\n");

	/* process route */
	routes = (struct gb_audio_route *)module->route_offset;
	ret = gbaudio_tplg_process_routes(module, routes);
	if (ret) {
		dev_err(module->dev,
			"%d: Error in parsing routes data\n", ret);
		return ret;
	}
	dev_dbg(module->dev, "Route parsing finished\n");

	/* parse jack capabilities */
	jack_type = le32_to_cpu(tplg_data->jack_type);
	if (jack_type) {
		module->jack_mask = jack_type & GBCODEC_JACK_MASK;
		module->button_mask = jack_type & GBCODEC_JACK_BUTTON_MASK;
	}

	return ret;
}

void gbaudio_tplg_release(struct gbaudio_module_info *module)
{
	struct gbaudio_control *control, *_control;
	struct gbaudio_widget *widget, *_widget;

	if (!module->topology)
		return;

	/* release kcontrols */
	list_for_each_entry_safe(control, _control, &module->ctl_list,
				 list) {
		list_del(&control->list);
		devm_kfree(module->dev, control);
	}
	if (module->controls)
		devm_kfree(module->dev, module->controls);

	/* release widget controls */
	list_for_each_entry_safe(control, _control, &module->widget_ctl_list,
				 list) {
		list_del(&control->list);
		devm_kfree(module->dev, control);
	}

	/* release widgets */
	list_for_each_entry_safe(widget, _widget, &module->widget_list,
				 list) {
		list_del(&widget->list);
		devm_kfree(module->dev, widget);
	}
	if (module->dapm_widgets)
		devm_kfree(module->dev, module->dapm_widgets);

	/* release routes */
	if (module->dapm_routes)
		devm_kfree(module->dev, module->dapm_routes);
}
