diff options
author | Liam Girdwood <lrg@ti.com> | 2011-06-13 14:37:36 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-06-14 09:25:32 -0400 |
commit | 0445bdf4ae2a1a3f4ac71ba6c298f3517b9ed238 (patch) | |
tree | 7a2e6df827a9104927dc0e286a64eea750e38d12 /sound/soc/soc-dapm.c | |
parent | 169d5a83f687c37104d51cbaa639bdffca8a1cd3 (diff) |
ASoC: dapm - Refactor widget IO functions in preparation for platform widgets.
This time with soc_widget_update_bits reflecting recent soc_update_bits changes.
Currently widget IO is tightly coupled to the CODEC drivers. Future platform DSP
devices have mixer components that can alter power usage and hence require full
DAPM support.
This provides a generic widget IO operation wrapper in preparation for
future patches that implement platform driver DAPM.
Signed-off-by: Liam Girdwood <lrg@ti.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r-- | sound/soc/soc-dapm.c | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 746349faf2db..605c225c709a 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -124,6 +124,43 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget( | |||
124 | return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL); | 124 | return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL); |
125 | } | 125 | } |
126 | 126 | ||
127 | static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg) | ||
128 | { | ||
129 | if (w->codec) | ||
130 | return snd_soc_read(w->codec, reg); | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val) | ||
135 | { | ||
136 | if (w->codec) | ||
137 | return snd_soc_write(w->codec, reg, val); | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static int soc_widget_update_bits(struct snd_soc_dapm_widget *w, | ||
142 | unsigned short reg, unsigned int mask, unsigned int value) | ||
143 | { | ||
144 | int change; | ||
145 | unsigned int old, new; | ||
146 | int ret; | ||
147 | |||
148 | ret = soc_widget_read(w, reg); | ||
149 | if (ret < 0) | ||
150 | return ret; | ||
151 | |||
152 | old = ret; | ||
153 | new = (old & ~mask) | (value & mask); | ||
154 | change = old != new; | ||
155 | if (change) { | ||
156 | ret = soc_widget_write(w, reg, new); | ||
157 | if (ret < 0) | ||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | return change; | ||
162 | } | ||
163 | |||
127 | /** | 164 | /** |
128 | * snd_soc_dapm_set_bias_level - set the bias level for the system | 165 | * snd_soc_dapm_set_bias_level - set the bias level for the system |
129 | * @dapm: DAPM context | 166 | * @dapm: DAPM context |
@@ -181,7 +218,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, | |||
181 | unsigned int mask = (1 << fls(max)) - 1; | 218 | unsigned int mask = (1 << fls(max)) - 1; |
182 | unsigned int invert = mc->invert; | 219 | unsigned int invert = mc->invert; |
183 | 220 | ||
184 | val = snd_soc_read(w->codec, reg); | 221 | val = soc_widget_read(w, reg); |
185 | val = (val >> shift) & mask; | 222 | val = (val >> shift) & mask; |
186 | 223 | ||
187 | if ((invert && !val) || (!invert && val)) | 224 | if ((invert && !val) || (!invert && val)) |
@@ -197,7 +234,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, | |||
197 | 234 | ||
198 | for (bitmask = 1; bitmask < e->max; bitmask <<= 1) | 235 | for (bitmask = 1; bitmask < e->max; bitmask <<= 1) |
199 | ; | 236 | ; |
200 | val = snd_soc_read(w->codec, e->reg); | 237 | val = soc_widget_read(w, e->reg); |
201 | item = (val >> e->shift_l) & (bitmask - 1); | 238 | item = (val >> e->shift_l) & (bitmask - 1); |
202 | 239 | ||
203 | p->connect = 0; | 240 | p->connect = 0; |
@@ -227,7 +264,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, | |||
227 | w->kcontrol_news[i].private_value; | 264 | w->kcontrol_news[i].private_value; |
228 | int val, item; | 265 | int val, item; |
229 | 266 | ||
230 | val = snd_soc_read(w->codec, e->reg); | 267 | val = soc_widget_read(w, e->reg); |
231 | val = (val >> e->shift_l) & e->mask; | 268 | val = (val >> e->shift_l) & e->mask; |
232 | for (item = 0; item < e->max; item++) { | 269 | for (item = 0; item < e->max; item++) { |
233 | if (val == e->values[item]) | 270 | if (val == e->values[item]) |
@@ -674,7 +711,7 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w, | |||
674 | else | 711 | else |
675 | val = w->off_val; | 712 | val = w->off_val; |
676 | 713 | ||
677 | snd_soc_update_bits(w->codec, -(w->reg + 1), | 714 | soc_widget_update_bits(w, -(w->reg + 1), |
678 | w->mask << w->shift, val << w->shift); | 715 | w->mask << w->shift, val << w->shift); |
679 | 716 | ||
680 | return 0; | 717 | return 0; |
@@ -885,7 +922,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, | |||
885 | "pop test : Applying 0x%x/0x%x to %x in %dms\n", | 922 | "pop test : Applying 0x%x/0x%x to %x in %dms\n", |
886 | value, mask, reg, card->pop_time); | 923 | value, mask, reg, card->pop_time); |
887 | pop_wait(card->pop_time); | 924 | pop_wait(card->pop_time); |
888 | snd_soc_update_bits(dapm->codec, reg, mask, value); | 925 | soc_widget_update_bits(w, reg, mask, value); |
889 | } | 926 | } |
890 | 927 | ||
891 | list_for_each_entry(w, pending, power_list) { | 928 | list_for_each_entry(w, pending, power_list) { |
@@ -1964,7 +2001,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) | |||
1964 | 2001 | ||
1965 | /* Read the initial power state from the device */ | 2002 | /* Read the initial power state from the device */ |
1966 | if (w->reg >= 0) { | 2003 | if (w->reg >= 0) { |
1967 | val = snd_soc_read(w->codec, w->reg); | 2004 | val = soc_widget_read(w, w->reg); |
1968 | val &= 1 << w->shift; | 2005 | val &= 1 << w->shift; |
1969 | if (w->invert) | 2006 | if (w->invert) |
1970 | val = !val; | 2007 | val = !val; |