summaryrefslogtreecommitdiff
path: root/sound/soc/soc-dapm.c
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2013-07-29 17:14:01 +0200
committerMark Brown <broonie@linaro.org>2013-07-29 18:41:00 +0100
commitde9ba98b6d2629f53fd271a973176c2fa9736d9c (patch)
treef3dd7477dfcf63ca2effa74fa1a5a5d998df853e /sound/soc/soc-dapm.c
parent5106b92f80a2cd37c52cffed80b4f5acfb77ccfd (diff)
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: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r--sound/soc/soc-dapm.c34
1 files changed, 13 insertions, 21 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index b779d36d5b3a..59bcc66358ca 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1122,7 +1122,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
int ret;
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);
if (ret != 0)
dev_warn(w->dapm->dev,
@@ -1132,7 +1132,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
return regulator_enable(w->regulator);
} 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);
if (ret != 0)
dev_warn(w->dapm->dev,
@@ -1360,26 +1360,21 @@ static void dapm_seq_run_coalesced(struct snd_soc_card *card,
struct list_head *pending)
{
struct snd_soc_dapm_widget *w;
- int reg, power;
+ int reg;
unsigned int value = 0;
unsigned int mask = 0;
- unsigned int cur_mask;
reg = list_first_entry(pending, struct snd_soc_dapm_widget,
power_list)->reg;
list_for_each_entry(w, pending, power_list) {
- cur_mask = 1 << w->shift;
BUG_ON(reg != w->reg);
- if (w->invert)
- power = !w->power;
+ mask |= w->mask << w->shift;
+ if (w->power)
+ value |= w->on_val << w->shift;
else
- power = w->power;
-
- mask |= cur_mask;
- if (power)
- value |= cur_mask;
+ value |= w->off_val << w->shift;
pop_dbg(w->dapm->dev, card->pop_time,
"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,
if (w->reg >= 0)
ret += snprintf(buf + ret, PAGE_SIZE - ret,
- " - R%d(0x%x) bit %d",
- w->reg, w->reg, w->shift);
+ " - R%d(0x%x) mask 0x%x",
+ w->reg, w->reg, w->mask << w->shift);
ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
@@ -2669,12 +2664,9 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
/* Read the initial power state from the device */
if (w->reg >= 0) {
- val = soc_widget_read(w, w->reg);
- val &= 1 << w->shift;
- if (w->invert)
- val = !val;
-
- if (val)
+ val = soc_widget_read(w, w->reg) >> w->shift;
+ val &= w->mask;
+ if (val == w->on_val)
w->power = 1;
}
@@ -3093,7 +3085,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
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);
if (ret != 0)
dev_warn(w->dapm->dev,