Commit de9ba98b authored by Lars-Peter Clausen's avatar Lars-Peter Clausen Committed by Mark Brown

ASoC: dapm: Make widget power register settings more flexible

Currently the DAPM code is limited to only setting or clearing a single bit in a
register to power a widget up or down. This patch extends the DAPM code to be
more flexible in that regard and allow widgets to use arbitrary values to be
used to put a widget in either on or off state.

Since the snd_soc_dapm_widget struct already contains a on_val and off_val field
no additional fields need to be added and in fact the invert field can even be
removed. Also the generated code is slightly smaller.
Signed-off-by: default avatarLars-Peter Clausen <lars@metafoo.de>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent 5106b92f
This diff is collapsed.
...@@ -1122,7 +1122,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, ...@@ -1122,7 +1122,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
int ret; int ret;
if (SND_SOC_DAPM_EVENT_ON(event)) { if (SND_SOC_DAPM_EVENT_ON(event)) {
if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) { if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) {
ret = regulator_allow_bypass(w->regulator, false); ret = regulator_allow_bypass(w->regulator, false);
if (ret != 0) if (ret != 0)
dev_warn(w->dapm->dev, dev_warn(w->dapm->dev,
...@@ -1132,7 +1132,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, ...@@ -1132,7 +1132,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
return regulator_enable(w->regulator); return regulator_enable(w->regulator);
} else { } else {
if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) { if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) {
ret = regulator_allow_bypass(w->regulator, true); ret = regulator_allow_bypass(w->regulator, true);
if (ret != 0) if (ret != 0)
dev_warn(w->dapm->dev, dev_warn(w->dapm->dev,
...@@ -1360,26 +1360,21 @@ static void dapm_seq_run_coalesced(struct snd_soc_card *card, ...@@ -1360,26 +1360,21 @@ static void dapm_seq_run_coalesced(struct snd_soc_card *card,
struct list_head *pending) struct list_head *pending)
{ {
struct snd_soc_dapm_widget *w; struct snd_soc_dapm_widget *w;
int reg, power; int reg;
unsigned int value = 0; unsigned int value = 0;
unsigned int mask = 0; unsigned int mask = 0;
unsigned int cur_mask;
reg = list_first_entry(pending, struct snd_soc_dapm_widget, reg = list_first_entry(pending, struct snd_soc_dapm_widget,
power_list)->reg; power_list)->reg;
list_for_each_entry(w, pending, power_list) { list_for_each_entry(w, pending, power_list) {
cur_mask = 1 << w->shift;
BUG_ON(reg != w->reg); BUG_ON(reg != w->reg);
if (w->invert) mask |= w->mask << w->shift;
power = !w->power; if (w->power)
value |= w->on_val << w->shift;
else else
power = w->power; value |= w->off_val << w->shift;
mask |= cur_mask;
if (power)
value |= cur_mask;
pop_dbg(w->dapm->dev, card->pop_time, pop_dbg(w->dapm->dev, card->pop_time,
"pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n", "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n",
...@@ -1867,8 +1862,8 @@ static ssize_t dapm_widget_power_read_file(struct file *file, ...@@ -1867,8 +1862,8 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
if (w->reg >= 0) if (w->reg >= 0)
ret += snprintf(buf + ret, PAGE_SIZE - ret, ret += snprintf(buf + ret, PAGE_SIZE - ret,
" - R%d(0x%x) bit %d", " - R%d(0x%x) mask 0x%x",
w->reg, w->reg, w->shift); w->reg, w->reg, w->mask << w->shift);
ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
...@@ -2669,12 +2664,9 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) ...@@ -2669,12 +2664,9 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
/* Read the initial power state from the device */ /* Read the initial power state from the device */
if (w->reg >= 0) { if (w->reg >= 0) {
val = soc_widget_read(w, w->reg); val = soc_widget_read(w, w->reg) >> w->shift;
val &= 1 << w->shift; val &= w->mask;
if (w->invert) if (val == w->on_val)
val = !val;
if (val)
w->power = 1; w->power = 1;
} }
...@@ -3093,7 +3085,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, ...@@ -3093,7 +3085,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
return NULL; return NULL;
} }
if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) { if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) {
ret = regulator_allow_bypass(w->regulator, true); ret = regulator_allow_bypass(w->regulator, true);
if (ret != 0) if (ret != 0)
dev_warn(w->dapm->dev, dev_warn(w->dapm->dev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment