/*
 * Greybus audio driver
 * Copyright 2015-2016 Google Inc.
 * Copyright 2015-2016 Linaro Ltd.
 *
 * Released under the GPLv2 only.
 */

#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;
	__u8 *data;

	strings = devm_kzalloc(gb->dev, sizeof(char *) * gbenum->items,
			       GFP_KERNEL);
	data = gbenum->names;

	for (i = 0; i < gbenum->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 = info->value.integer.min;
		uinfo->value.integer.max = info->value.integer.max;
		break;
	case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
		max = 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] =
			gbvalue.value.integer_value[0];
		if (data->vcount == 2)
			ucontrol->value.integer.value[1] =
				gbvalue.value.integer_value[1];
		break;
	case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
		ucontrol->value.enumerated.item[0] =
			gbvalue.value.enumerated_item[0];
		if (data->vcount == 2)
			ucontrol->value.enumerated.item[1] =
				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] =
			ucontrol->value.integer.value[0];
		if (data->vcount == 2)
			gbvalue.value.integer_value[1] =
				ucontrol->value.integer.value[1];
		break;
	case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
		gbvalue.value.enumerated_item[0] =
			ucontrol->value.enumerated.item[0];
		if (data->vcount == 2)
			gbvalue.value.enumerated_item[1] =
				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 = info->value.integer.max;
	platform_min = 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 = 0;
	if (info->value.integer.min < 0 &&
	    (uinfo->type == SNDRV_CTL_ELEM_TYPE_INTEGER))
		uinfo->value.integer.max = platform_max - platform_min;
	else
		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] = 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 = info->value.integer.max;
	mask = (1 << fls(max)) - 1;
	val = ucontrol->value.integer.value[0] & mask;
	connect = !!val;

	/* 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] =
			ucontrol->value.integer.value[0];

		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;
		}
	}

	return 0;
}

#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] = 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_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] = 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] =
			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 = gb_enum->items;
	gbe->texts = gb_generate_enum_strings(gb, gb_enum);

	/* debug enum info */
	dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items,
		 gb_enum->names_length);
	for (i = 0; i < gb_enum->items; 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 = 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 = gb_enum->items;
	gbe->texts = gb_generate_enum_strings(gb, gb_enum);

	/* debug enum info */
	dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items,
		 gb_enum->names_length);
	for (i = 0; i < gb_enum->items; 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 = 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 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, "Inavlid 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 += gbenum->names_length;
			control->texts = (const char * const *)
				gb_generate_enum_strings(module, gbenum);
			control->items = 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 = (struct snd_soc_dapm_widget)
			SND_SOC_DAPM_SPK(w->name, gbcodec_event_spk);
		module->op_devices |= GBAUDIO_DEVICE_OUT_SPEAKER;
		break;
	case snd_soc_dapm_hp:
		*dw = (struct snd_soc_dapm_widget)
			SND_SOC_DAPM_HP(w->name, gbcodec_event_hp);
		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 = (struct snd_soc_dapm_widget)
			SND_SOC_DAPM_MIC(w->name, gbcodec_event_int_mic);
		module->ip_devices |= GBAUDIO_DEVICE_IN_BUILTIN_MIC;
		break;
	case snd_soc_dapm_output:
		*dw = (struct snd_soc_dapm_widget)SND_SOC_DAPM_OUTPUT(w->name);
		break;
	case snd_soc_dapm_input:
		*dw = (struct snd_soc_dapm_widget)SND_SOC_DAPM_INPUT(w->name);
		break;
	case snd_soc_dapm_switch:
		*dw = (struct snd_soc_dapm_widget)
			SND_SOC_DAPM_SWITCH_E(w->name, SND_SOC_NOPM, 0, 0,
					    widget_kctls, gbaudio_widget_event,
					    SND_SOC_DAPM_PRE_PMU |
					    SND_SOC_DAPM_POST_PMD);
		break;
	case snd_soc_dapm_pga:
		*dw = (struct snd_soc_dapm_widget)
			SND_SOC_DAPM_PGA_E(w->name, SND_SOC_NOPM, 0, 0, NULL, 0,
					   gbaudio_widget_event,
					   SND_SOC_DAPM_PRE_PMU |
					   SND_SOC_DAPM_POST_PMD);
		break;
	case snd_soc_dapm_mixer:
		*dw = (struct snd_soc_dapm_widget)
			SND_SOC_DAPM_MIXER_E(w->name, SND_SOC_NOPM, 0, 0, NULL,
					   0, gbaudio_widget_event,
					   SND_SOC_DAPM_PRE_PMU |
					   SND_SOC_DAPM_POST_PMD);
		break;
	case snd_soc_dapm_mux:
		*dw = (struct snd_soc_dapm_widget)
			SND_SOC_DAPM_MUX_E(w->name, SND_SOC_NOPM, 0, 0,
					 widget_kctls, gbaudio_widget_event,
					 SND_SOC_DAPM_PRE_PMU |
					 SND_SOC_DAPM_POST_PMD);
		break;
	case snd_soc_dapm_aif_in:
		*dw = (struct snd_soc_dapm_widget)
			SND_SOC_DAPM_AIF_IN_E(w->name, w->sname, 0,
					      SND_SOC_NOPM,
					      0, 0, gbaudio_widget_event,
					      SND_SOC_DAPM_PRE_PMU |
					      SND_SOC_DAPM_POST_PMD);
		break;
	case snd_soc_dapm_aif_out:
		*dw = (struct snd_soc_dapm_widget)
			SND_SOC_DAPM_AIF_OUT_E(w->name, w->sname, 0,
					       SND_SOC_NOPM,
					       0, 0, gbaudio_widget_event,
					       SND_SOC_DAPM_PRE_PMU |
					       SND_SOC_DAPM_POST_PMD);
		break;
	default:
		ret = -EINVAL;
		goto error;
	}

	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 += gbenum->names_length;
			control->texts = (const char * const *)
				gb_generate_enum_strings(module, gbenum);
			control->items = 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 + tplg_data->size_dais;
	module->widget_offset = module->control_offset +
		tplg_data->size_controls;
	module->route_offset = module->widget_offset +
		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;

	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 */
	if (tplg_data->jack_type) {
		module->jack_mask = tplg_data->jack_type & GBCODEC_JACK_MASK;
		module->button_mask = tplg_data->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);
}
