Unverified Commit ebf14747 authored by Gyeongtaek Lee's avatar Gyeongtaek Lee Committed by Mark Brown
Browse files

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: default avatarGyeongtaek Lee <gt82.lee@samsung.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/000001d61537$b212f620$1638e260$@samsung.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 8c05246c
Loading
Loading
Loading
Loading
+17 −3
Original line number Diff line number Diff line
@@ -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)
	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;