summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc-dapm.h7
-rw-r--r--sound/soc/soc-dapm.c162
2 files changed, 71 insertions, 98 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 3e479f4e15f5..3717ad089486 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -391,10 +391,10 @@ void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
void snd_soc_dapm_shutdown(struct snd_soc_card *card);
/* external DAPM widget events */
-int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
+int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_context *dapm,
struct snd_kcontrol *kcontrol, int connect);
-int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
- struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e);
+int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_context *dapm,
+ struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e);
/* dapm sys fs - used by the core */
int snd_soc_dapm_sys_add(struct device *dev);
@@ -559,7 +559,6 @@ struct snd_soc_dapm_widget {
};
struct snd_soc_dapm_update {
- struct snd_soc_dapm_widget *widget;
struct snd_kcontrol *kcontrol;
int reg;
int mask;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 8d9c09b266fd..6f8a01bf6ca8 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1456,34 +1456,45 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
static void dapm_widget_update(struct snd_soc_dapm_context *dapm)
{
struct snd_soc_dapm_update *update = dapm->update;
- struct snd_soc_dapm_widget *w;
+ struct snd_soc_dapm_widget_list *wlist;
+ struct snd_soc_dapm_widget *w = NULL;
+ unsigned int wi;
int ret;
if (!update)
return;
- w = update->widget;
+ wlist = snd_kcontrol_chip(update->kcontrol);
- if (w->event &&
- (w->event_flags & SND_SOC_DAPM_PRE_REG)) {
- ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG);
- if (ret != 0)
- dev_err(dapm->dev, "ASoC: %s DAPM pre-event failed: %d\n",
- w->name, ret);
+ for (wi = 0; wi < wlist->num_widgets; wi++) {
+ w = wlist->widgets[wi];
+
+ if (w->event && (w->event_flags & SND_SOC_DAPM_PRE_REG)) {
+ ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG);
+ if (ret != 0)
+ dev_err(dapm->dev, "ASoC: %s DAPM pre-event failed: %d\n",
+ w->name, ret);
+ }
}
+ if (!w)
+ return;
+
ret = soc_widget_update_bits_locked(w, update->reg, update->mask,
update->val);
if (ret < 0)
dev_err(dapm->dev, "ASoC: %s DAPM update failed: %d\n",
w->name, ret);
- if (w->event &&
- (w->event_flags & SND_SOC_DAPM_POST_REG)) {
- ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG);
- if (ret != 0)
- dev_err(dapm->dev, "ASoC: %s DAPM post-event failed: %d\n",
- w->name, ret);
+ for (wi = 0; wi < wlist->num_widgets; wi++) {
+ w = wlist->widgets[wi];
+
+ if (w->event && (w->event_flags & SND_SOC_DAPM_POST_REG)) {
+ ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG);
+ if (ret != 0)
+ dev_err(dapm->dev, "ASoC: %s DAPM post-event failed: %d\n",
+ w->name, ret);
+ }
}
}
@@ -1936,19 +1947,14 @@ static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
#endif
/* test and update the power status of a mux widget */
-static int soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
+static int soc_dapm_mux_update_power(struct snd_soc_dapm_context *dapm,
struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e)
{
struct snd_soc_dapm_path *path;
int found = 0;
- if (widget->id != snd_soc_dapm_mux &&
- widget->id != snd_soc_dapm_virt_mux &&
- widget->id != snd_soc_dapm_value_mux)
- return -ENODEV;
-
/* find dapm widget path assoc with kcontrol */
- list_for_each_entry(path, &widget->dapm->card->paths, list) {
+ list_for_each_entry(path, &dapm->card->paths, list) {
if (path->kcontrol != kcontrol)
continue;
@@ -1966,24 +1972,23 @@ static int soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
"mux disconnection");
path->connect = 0; /* old connection must be powered down */
}
+ dapm_mark_dirty(path->sink, "mux change");
}
- if (found) {
- dapm_mark_dirty(widget, "mux change");
- dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
- }
+ if (found)
+ dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
return found;
}
-int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
- struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e)
+int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_context *dapm,
+ struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e)
{
- struct snd_soc_card *card = widget->dapm->card;
+ struct snd_soc_card *card = dapm->card;
int ret;
mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
- ret = soc_dapm_mux_update_power(widget, kcontrol, mux, e);
+ ret = soc_dapm_mux_update_power(dapm, kcontrol, mux, e);
mutex_unlock(&card->dapm_mutex);
if (ret > 0)
soc_dpcm_runtime_update(card);
@@ -1992,19 +1997,14 @@ int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power);
/* test and update the power status of a mixer or switch widget */
-static int soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
+static int soc_dapm_mixer_update_power(struct snd_soc_dapm_context *dapm,
struct snd_kcontrol *kcontrol, int connect)
{
struct snd_soc_dapm_path *path;
int found = 0;
- if (widget->id != snd_soc_dapm_mixer &&
- widget->id != snd_soc_dapm_mixer_named_ctl &&
- widget->id != snd_soc_dapm_switch)
- return -ENODEV;
-
/* find dapm widget path assoc with kcontrol */
- list_for_each_entry(path, &widget->dapm->card->paths, list) {
+ list_for_each_entry(path, &dapm->card->paths, list) {
if (path->kcontrol != kcontrol)
continue;
@@ -2012,24 +2012,23 @@ static int soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
found = 1;
path->connect = connect;
dapm_mark_dirty(path->source, "mixer connection");
+ dapm_mark_dirty(path->sink, "mixer update");
}
- if (found) {
- dapm_mark_dirty(widget, "mixer update");
- dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
- }
+ if (found)
+ dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
return found;
}
-int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
- struct snd_kcontrol *kcontrol, int connect)
+int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_context *dapm,
+ struct snd_kcontrol *kcontrol, int connect)
{
- struct snd_soc_card *card = widget->dapm->card;
+ struct snd_soc_card *card = dapm->card;
int ret;
mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
- ret = soc_dapm_mixer_update_power(widget, kcontrol, connect);
+ ret = soc_dapm_mixer_update_power(dapm, kcontrol, connect);
mutex_unlock(&card->dapm_mutex);
if (ret > 0)
soc_dpcm_runtime_update(card);
@@ -2695,7 +2694,6 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
unsigned int val;
int connect, change;
struct snd_soc_dapm_update update;
- int wi;
if (snd_soc_volsw_is_stereo(mc))
dev_warn(widget->dapm->dev,
@@ -2714,22 +2712,16 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
change = snd_soc_test_bits(widget->codec, reg, mask, val);
if (change) {
- for (wi = 0; wi < wlist->num_widgets; wi++) {
- widget = wlist->widgets[wi];
-
- widget->value = val;
+ update.kcontrol = kcontrol;
+ update.reg = reg;
+ update.mask = mask;
+ update.val = val;
- update.kcontrol = kcontrol;
- update.widget = widget;
- update.reg = reg;
- update.mask = mask;
- update.val = val;
- widget->dapm->update = &update;
+ widget->dapm->update = &update;
- soc_dapm_mixer_update_power(widget, kcontrol, connect);
+ soc_dapm_mixer_update_power(widget->dapm, kcontrol, connect);
- widget->dapm->update = NULL;
- }
+ widget->dapm->update = NULL;
}
mutex_unlock(&card->dapm_mutex);
@@ -2784,7 +2776,6 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
unsigned int val, mux, change;
unsigned int mask;
struct snd_soc_dapm_update update;
- int wi;
if (ucontrol->value.enumerated.item[0] > e->max - 1)
return -EINVAL;
@@ -2802,22 +2793,17 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
if (change) {
- for (wi = 0; wi < wlist->num_widgets; wi++) {
- widget = wlist->widgets[wi];
+ widget->value = val;
- widget->value = val;
+ update.kcontrol = kcontrol;
+ update.reg = e->reg;
+ update.mask = mask;
+ update.val = val;
+ widget->dapm->update = &update;
- update.kcontrol = kcontrol;
- update.widget = widget;
- update.reg = e->reg;
- update.mask = mask;
- update.val = val;
- widget->dapm->update = &update;
+ soc_dapm_mux_update_power(widget->dapm, kcontrol, mux, e);
- soc_dapm_mux_update_power(widget, kcontrol, mux, e);
-
- widget->dapm->update = NULL;
- }
+ widget->dapm->update = NULL;
}
mutex_unlock(&card->dapm_mutex);
@@ -2861,7 +2847,6 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
struct soc_enum *e =
(struct soc_enum *)kcontrol->private_value;
int change;
- int wi;
if (ucontrol->value.enumerated.item[0] >= e->max)
return -EINVAL;
@@ -2870,13 +2855,8 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
change = widget->value != ucontrol->value.enumerated.item[0];
if (change) {
- for (wi = 0; wi < wlist->num_widgets; wi++) {
- widget = wlist->widgets[wi];
-
- widget->value = ucontrol->value.enumerated.item[0];
-
- soc_dapm_mux_update_power(widget, kcontrol, widget->value, e);
- }
+ widget->value = ucontrol->value.enumerated.item[0];
+ soc_dapm_mux_update_power(widget->dapm, kcontrol, widget->value, e);
}
mutex_unlock(&card->dapm_mutex);
@@ -2949,7 +2929,6 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
unsigned int val, mux, change;
unsigned int mask;
struct snd_soc_dapm_update update;
- int wi;
if (ucontrol->value.enumerated.item[0] > e->max - 1)
return -EINVAL;
@@ -2967,22 +2946,17 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
if (change) {
- for (wi = 0; wi < wlist->num_widgets; wi++) {
- widget = wlist->widgets[wi];
-
- widget->value = val;
+ widget->value = val;
- update.kcontrol = kcontrol;
- update.widget = widget;
- update.reg = e->reg;
- update.mask = mask;
- update.val = val;
- widget->dapm->update = &update;
+ update.kcontrol = kcontrol;
+ update.reg = e->reg;
+ update.mask = mask;
+ update.val = val;
+ widget->dapm->update = &update;
- soc_dapm_mux_update_power(widget, kcontrol, mux, e);
+ soc_dapm_mux_update_power(widget->dapm, kcontrol, mux, e);
- widget->dapm->update = NULL;
- }
+ widget->dapm->update = NULL;
}
mutex_unlock(&card->dapm_mutex);