ASoC: dapm: fixup dapm kcontrol widget

snd_soc_dapm_kcontrol widget which is created by autodisable control
should contain correct on_val, mask and shift because it is set when the
widget is powered and changed value is applied on registers by following
code in dapm_seq_run_coalesced().

		mask |= w->mask << w->shift;
		if (w->power)
			value |= w->on_val << w->shift;
		else
			value |= w->off_val << w->shift;

Shift on the mask in dapm_kcontrol_data_alloc() is removed to prevent
double shift.
And, on_val in dapm_kcontrol_set_value() is modified to get correct
value in the dapm_seq_run_coalesced().

Signed-off-by: Gyeongtaek Lee <gt82.lee@samsung.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/000001d61537$b212f620$1638e260$@samsung.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Gyeongtaek Lee 2020-04-18 13:13:20 +09:00 committed by Mark Brown
parent 8c05246c0b
commit ebf1474745
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -423,7 +423,7 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,
memset(&template, 0, sizeof(template));
template.reg = e->reg;
template.mask = e->mask << e->shift_l;
template.mask = e->mask;
template.shift = e->shift_l;
template.off_val = snd_soc_enum_item_to_val(e, 0);
template.on_val = template.off_val;
@ -546,8 +546,22 @@ static bool dapm_kcontrol_set_value(const struct snd_kcontrol *kcontrol,
if (data->value == value)
return false;
if (data->widget)
data->widget->on_val = value;
if (data->widget) {
switch (dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->id) {
case snd_soc_dapm_switch:
case snd_soc_dapm_mixer:
case snd_soc_dapm_mixer_named_ctl:
data->widget->on_val = value & data->widget->mask;
break;
case snd_soc_dapm_demux:
case snd_soc_dapm_mux:
data->widget->on_val = value >> data->widget->shift;
break;
default:
data->widget->on_val = value;
break;
}
}
data->value = value;