ASoC: dapm: Consolidate MUXs and virtual MUXs
MUXs and virtual MUXs are almost identical, the only difference is that for
virtual MUX there is no hardware backing register in which setting is stored.
This patch adds code, which is similar to what we already do for DAPM mixer
controls to support virtual mixer controls, to DAPM enum controls. The new code
will check if the enum does a hardware backing register and skip over reading
and writing to the register if it has not. This allows us to use the same code
path for both MUXs and virtual MUXs and a lot of nearly identical code can be
removed.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index f23eeee..c07c7fb 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -70,7 +70,6 @@
[snd_soc_dapm_aif_out] = 4,
[snd_soc_dapm_mic] = 5,
[snd_soc_dapm_mux] = 6,
- [snd_soc_dapm_virt_mux] = 6,
[snd_soc_dapm_dac] = 7,
[snd_soc_dapm_switch] = 8,
[snd_soc_dapm_mixer] = 8,
@@ -101,7 +100,6 @@
[snd_soc_dapm_mic] = 7,
[snd_soc_dapm_micbias] = 8,
[snd_soc_dapm_mux] = 9,
- [snd_soc_dapm_virt_mux] = 9,
[snd_soc_dapm_aif_in] = 10,
[snd_soc_dapm_aif_out] = 10,
[snd_soc_dapm_dai_in] = 10,
@@ -531,9 +529,19 @@
w->kcontrol_news[i].private_value;
unsigned int val, item;
- soc_widget_read(w, e->reg, &val);
- val = (val >> e->shift_l) & e->mask;
- item = snd_soc_enum_val_to_item(e, val);
+ if (e->reg != SND_SOC_NOPM) {
+ soc_widget_read(w, e->reg, &val);
+ val = (val >> e->shift_l) & e->mask;
+ item = snd_soc_enum_val_to_item(e, val);
+ } else {
+ /* since a virtual mux has no backing registers to
+ * decide which path to connect, it will try to match
+ * with the first enumeration. This is to ensure
+ * that the default mux choice (the first) will be
+ * correctly powered up during initialization.
+ */
+ item = 0;
+ }
if (item < e->items && !strcmp(p->name, e->texts[item]))
p->connect = 1;
@@ -541,21 +549,6 @@
p->connect = 0;
}
break;
- case snd_soc_dapm_virt_mux: {
- struct soc_enum *e = (struct soc_enum *)
- w->kcontrol_news[i].private_value;
-
- p->connect = 0;
- /* since a virtual mux has no backing registers to
- * decide which path to connect, it will try to match
- * with the first enumeration. This is to ensure
- * that the default mux choice (the first) will be
- * correctly powered up during initialization.
- */
- if (!strcmp(p->name, e->texts[0]))
- p->connect = 1;
- }
- break;
/* does not affect routing - always connected */
case snd_soc_dapm_pga:
case snd_soc_dapm_out_drv:
@@ -705,7 +698,6 @@
kcname_in_long_name = true;
break;
case snd_soc_dapm_mux:
- case snd_soc_dapm_virt_mux:
wname_in_long_name = true;
kcname_in_long_name = false;
break;
@@ -2442,7 +2434,6 @@
path->connect = 1;
return 0;
case snd_soc_dapm_mux:
- case snd_soc_dapm_virt_mux:
ret = dapm_connect_mux(dapm, wsource, wsink, path, control,
&wsink->kcontrol_news[0]);
if (ret != 0)
@@ -2769,7 +2760,6 @@
dapm_new_mixer(w);
break;
case snd_soc_dapm_mux:
- case snd_soc_dapm_virt_mux:
dapm_new_mux(w);
break;
case snd_soc_dapm_pga:
@@ -2933,7 +2923,11 @@
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int reg_val, val;
- reg_val = snd_soc_read(codec, e->reg);
+ if (e->reg != SND_SOC_NOPM)
+ reg_val = snd_soc_read(codec, e->reg);
+ else
+ reg_val = dapm_kcontrol_get_value(kcontrol);
+
val = (reg_val >> e->shift_l) & e->mask;
ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val);
if (e->shift_l != e->shift_r) {
@@ -2981,13 +2975,19 @@
mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
- change = snd_soc_test_bits(codec, e->reg, mask, val);
+ if (e->reg != SND_SOC_NOPM)
+ change = snd_soc_test_bits(codec, e->reg, mask, val);
+ else
+ change = dapm_kcontrol_set_value(kcontrol, val);
+
if (change) {
- update.kcontrol = kcontrol;
- update.reg = e->reg;
- update.mask = mask;
- update.val = val;
- card->update = &update;
+ if (e->reg != SND_SOC_NOPM) {
+ update.kcontrol = kcontrol;
+ update.reg = e->reg;
+ update.mask = mask;
+ update.val = val;
+ card->update = &update;
+ }
ret = soc_dapm_mux_update_power(card, kcontrol, item[0], e);
@@ -3004,58 +3004,6 @@
EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
/**
- * snd_soc_dapm_get_enum_virt - Get virtual DAPM mux
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Returns 0 for success.
- */
-int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.enumerated.item[0] = dapm_kcontrol_get_value(kcontrol);
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_virt);
-
-/**
- * snd_soc_dapm_put_enum_virt - Set virtual DAPM mux
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Returns 0 for success.
- */
-int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
- struct snd_soc_card *card = codec->card;
- unsigned int value;
- struct soc_enum *e =
- (struct soc_enum *)kcontrol->private_value;
- int change;
- int ret = 0;
-
- if (ucontrol->value.enumerated.item[0] >= e->items)
- return -EINVAL;
-
- mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
-
- value = ucontrol->value.enumerated.item[0];
- change = dapm_kcontrol_set_value(kcontrol, value);
- if (change)
- ret = soc_dapm_mux_update_power(card, kcontrol, value, e);
-
- mutex_unlock(&card->dapm_mutex);
-
- if (ret > 0)
- soc_dpcm_runtime_update(card);
-
- return change;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt);
-
-/**
* snd_soc_dapm_info_pin_switch - Info for a pin switch
*
* @kcontrol: mixer control
@@ -3183,7 +3131,6 @@
w->power_check = dapm_generic_check_power;
break;
case snd_soc_dapm_mux:
- case snd_soc_dapm_virt_mux:
w->power_check = dapm_generic_check_power;
break;
case snd_soc_dapm_dai_out: