Commit eea3dd4f authored by Mengdong Lin's avatar Mengdong Lin Committed by Mark Brown

ASoC: topology: Only free TLV for volume mixers of a widget

This patch will check the type of embedded controls for a widget, and
only free the TLV of volume mixers. Bytes controls don't have TLV.

Just free the private value which is used as struct soc_mixer_control
for volume mixers or soc_bytes_ext for bytes controls. No need to cast
to these types before freeing it.
Signed-off-by: default avatarMengdong Lin <mengdong.lin@linux.intel.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 1a7dd6e2
...@@ -53,7 +53,7 @@ struct snd_soc_dobj_control { ...@@ -53,7 +53,7 @@ struct snd_soc_dobj_control {
/* dynamic widget object */ /* dynamic widget object */
struct snd_soc_dobj_widget { struct snd_soc_dobj_widget {
unsigned int kcontrol_enum:1; /* this widget is an enum kcontrol */ unsigned int kcontrol_type; /* kcontrol type: mixer, enum, bytes */
}; };
/* generic dynamic object - all dynamic objects belong to this struct */ /* generic dynamic object - all dynamic objects belong to this struct */
......
...@@ -489,7 +489,7 @@ static void remove_widget(struct snd_soc_component *comp, ...@@ -489,7 +489,7 @@ static void remove_widget(struct snd_soc_component *comp,
* Dynamic Widgets either have 1..N enum kcontrols or mixers. * Dynamic Widgets either have 1..N enum kcontrols or mixers.
* The enum may either have an array of values or strings. * The enum may either have an array of values or strings.
*/ */
if (dobj->widget.kcontrol_enum) { if (dobj->widget.kcontrol_type == SND_SOC_TPLG_TYPE_ENUM) {
/* enumerated widget mixer */ /* enumerated widget mixer */
for (i = 0; i < w->num_kcontrols; i++) { for (i = 0; i < w->num_kcontrols; i++) {
struct snd_kcontrol *kcontrol = w->kcontrols[i]; struct snd_kcontrol *kcontrol = w->kcontrols[i];
...@@ -506,16 +506,21 @@ static void remove_widget(struct snd_soc_component *comp, ...@@ -506,16 +506,21 @@ static void remove_widget(struct snd_soc_component *comp,
} }
kfree(w->kcontrol_news); kfree(w->kcontrol_news);
} else { } else {
/* non enumerated widget mixer */ /* volume mixer or bytes controls */
for (i = 0; i < w->num_kcontrols; i++) { for (i = 0; i < w->num_kcontrols; i++) {
struct snd_kcontrol *kcontrol = w->kcontrols[i]; struct snd_kcontrol *kcontrol = w->kcontrols[i];
struct soc_mixer_control *sm =
(struct soc_mixer_control *) kcontrol->private_value;
kfree(w->kcontrols[i]->tlv.p); if (dobj->widget.kcontrol_type
== SND_SOC_TPLG_TYPE_MIXER)
kfree(kcontrol->tlv.p);
snd_ctl_remove(card, w->kcontrols[i]); snd_ctl_remove(card, kcontrol);
kfree(sm);
/* Private value is used as struct soc_mixer_control
* for volume mixers or soc_bytes_ext for bytes
* controls.
*/
kfree((void *)kcontrol->private_value);
} }
kfree(w->kcontrol_news); kfree(w->kcontrol_news);
} }
...@@ -1439,6 +1444,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, ...@@ -1439,6 +1444,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,
struct snd_soc_dapm_widget template, *widget; struct snd_soc_dapm_widget template, *widget;
struct snd_soc_tplg_ctl_hdr *control_hdr; struct snd_soc_tplg_ctl_hdr *control_hdr;
struct snd_soc_card *card = tplg->comp->card; struct snd_soc_card *card = tplg->comp->card;
unsigned int kcontrol_type;
int ret = 0; int ret = 0;
if (strnlen(w->name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == if (strnlen(w->name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) ==
...@@ -1494,6 +1500,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, ...@@ -1494,6 +1500,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,
case SND_SOC_TPLG_CTL_VOLSW_XR_SX: case SND_SOC_TPLG_CTL_VOLSW_XR_SX:
case SND_SOC_TPLG_CTL_RANGE: case SND_SOC_TPLG_CTL_RANGE:
case SND_SOC_TPLG_DAPM_CTL_VOLSW: case SND_SOC_TPLG_DAPM_CTL_VOLSW:
kcontrol_type = SND_SOC_TPLG_TYPE_MIXER; /* volume mixer */
template.num_kcontrols = w->num_kcontrols; template.num_kcontrols = w->num_kcontrols;
template.kcontrol_news = template.kcontrol_news =
soc_tplg_dapm_widget_dmixer_create(tplg, soc_tplg_dapm_widget_dmixer_create(tplg,
...@@ -1508,7 +1515,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, ...@@ -1508,7 +1515,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,
case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE: case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT: case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT:
case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE: case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE:
template.dobj.widget.kcontrol_enum = 1; kcontrol_type = SND_SOC_TPLG_TYPE_ENUM; /* enumerated mixer */
template.num_kcontrols = w->num_kcontrols; template.num_kcontrols = w->num_kcontrols;
template.kcontrol_news = template.kcontrol_news =
soc_tplg_dapm_widget_denum_create(tplg, soc_tplg_dapm_widget_denum_create(tplg,
...@@ -1519,6 +1526,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, ...@@ -1519,6 +1526,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,
} }
break; break;
case SND_SOC_TPLG_CTL_BYTES: case SND_SOC_TPLG_CTL_BYTES:
kcontrol_type = SND_SOC_TPLG_TYPE_BYTES; /* bytes control */
template.num_kcontrols = w->num_kcontrols; template.num_kcontrols = w->num_kcontrols;
template.kcontrol_news = template.kcontrol_news =
soc_tplg_dapm_widget_dbytes_create(tplg, soc_tplg_dapm_widget_dbytes_create(tplg,
...@@ -1555,6 +1563,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, ...@@ -1555,6 +1563,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,
} }
widget->dobj.type = SND_SOC_DOBJ_WIDGET; widget->dobj.type = SND_SOC_DOBJ_WIDGET;
widget->dobj.widget.kcontrol_type = kcontrol_type;
widget->dobj.ops = tplg->ops; widget->dobj.ops = tplg->ops;
widget->dobj.index = tplg->index; widget->dobj.index = tplg->index;
kfree(template.sname); kfree(template.sname);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment