summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGyeongtaek Lee <gt82.lee@samsung.com>2020-04-18 06:13:20 +0200
committerMark Brown <broonie@kernel.org>2020-04-20 15:35:06 +0200
commitebf1474745b4373fdde0fcf32d9d1f369b50b212 (patch)
treee9de3a209acc0c2c9e6234fe5ed0be2956e484fb
parentASoC: SOF: Intel: add min/max channels for SSP on Baytrail/Broadwell (diff)
downloadlinux-ebf1474745b4373fdde0fcf32d9d1f369b50b212.tar.xz
linux-ebf1474745b4373fdde0fcf32d9d1f369b50b212.zip
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>
-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 a4143ca190d0..e2632841b321 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -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;