summaryrefslogtreecommitdiff
path: root/sound/soc/soc-dapm.c
diff options
context:
space:
mode:
authorGyeongtaek Lee <gt82.lee@samsung.com>2020-04-18 13:13:20 +0900
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-05-02 17:20:49 +0200
commit4f04d30031dbf6684afcc20a0ee520808ac038fa (patch)
tree35e9cec2b97613942d58d34e75ab5d05c09ca76f /sound/soc/soc-dapm.c
parent1a8abec91244735f760b21f0a4ba93f62cab3483 (diff)
ASoC: dapm: fixup dapm kcontrol widget
commit ebf1474745b4373fdde0fcf32d9d1f369b50b212 upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r--sound/soc/soc-dapm.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 2798f4bb7fe4..e7714c030a2e 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -384,7 +384,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;
@@ -510,8 +510,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;