ASoC: dapm - add widget IO functions
Add widget IO in preparation to support platform driver DAPM widgets with IO.
This provides a generic widget IO operation wrapper in preparation for
decouplement of register IO from CODEC drivers.
Signed-off-by: Liam Girdwood <lrg@ti.com>
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index f369656..98cbbee 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -124,6 +124,49 @@
return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL);
}
+static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg)
+{
+ if (w->codec)
+ return snd_soc_read(w->codec, reg);
+ return 0;
+}
+
+static int soc_widget_write(struct snd_soc_dapm_widget *w,int reg, int val)
+{
+ if (w->codec)
+ return snd_soc_write(w->codec, reg, val);
+ return 0;
+}
+
+int soc_widget_update_bits(struct snd_soc_dapm_widget *w, unsigned short reg,
+ unsigned int mask, unsigned int value)
+{
+ int change;
+ unsigned int old, new;
+
+ old = soc_widget_read(w, reg);
+ new = (old & ~mask) | value;
+ change = old != new;
+ if (change)
+ soc_widget_write(w, reg, new);
+
+ return change;
+}
+
+int soc_widget_test_bits(struct snd_soc_dapm_widget *w, unsigned short reg,
+ unsigned int mask, unsigned int value)
+{
+ int change;
+ unsigned int old, new;
+
+ old = soc_widget_read(w, reg);
+ new = (old & ~mask) | value;
+ change = old != new;
+
+ return change;
+}
+
+
/**
* snd_soc_dapm_set_bias_level - set the bias level for the system
* @dapm: DAPM context
@@ -194,7 +237,7 @@
unsigned int mask = (1 << fls(max)) - 1;
unsigned int invert = mc->invert;
- val = snd_soc_read(w->codec, reg);
+ val = soc_widget_read(w, reg);
val = (val >> shift) & mask;
if ((invert && !val) || (!invert && val))
@@ -210,7 +253,7 @@
for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
;
- val = snd_soc_read(w->codec, e->reg);
+ val = soc_widget_read(w, e->reg);
item = (val >> e->shift_l) & (bitmask - 1);
p->connect = 0;
@@ -240,7 +283,7 @@
w->kcontrol_news[i].private_value;
int val, item;
- val = snd_soc_read(w->codec, e->reg);
+ val = soc_widget_read(w, e->reg);
val = (val >> e->shift_l) & e->mask;
for (item = 0; item < e->max; item++) {
if (val == e->values[item])
@@ -681,7 +724,7 @@
else
val = w->off_val;
- snd_soc_update_bits(w->codec, -(w->reg + 1),
+ soc_widget_update_bits(w, -(w->reg + 1),
w->mask << w->shift, val << w->shift);
return 0;
@@ -889,7 +932,7 @@
"pop test : Applying 0x%x/0x%x to %x in %dms\n",
value, mask, reg, card->pop_time);
pop_wait(card->pop_time);
- snd_soc_update_bits(dapm->codec, reg, mask, value);
+ soc_widget_update_bits(w, reg, mask, value);
}
list_for_each_entry(w, pending, power_list) {
@@ -1865,7 +1908,7 @@
/* Read the initial power state from the device */
if (w->reg >= 0) {
- val = snd_soc_read(w->codec, w->reg);
+ val = soc_widget_read(w, w->reg);
val &= 1 << w->shift;
if (w->invert)
val = !val;