Merge branch 'lorenzo/pci/dwc-fixes'
[linux-2.6-microblaze.git] / sound / soc / soc-io.c
1 /*
2  * soc-io.c  --  ASoC register I/O helpers
3  *
4  * Copyright 2009-2011 Wolfson Microelectronics PLC.
5  *
6  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7  *
8  *  This program is free software; you can redistribute  it and/or modify it
9  *  under  the terms of  the GNU General  Public License as published by the
10  *  Free Software Foundation;  either version 2 of the  License, or (at your
11  *  option) any later version.
12  */
13
14 #include <linux/i2c.h>
15 #include <linux/spi/spi.h>
16 #include <linux/regmap.h>
17 #include <linux/export.h>
18 #include <sound/soc.h>
19
20 /**
21  * snd_soc_component_read() - Read register value
22  * @component: Component to read from
23  * @reg: Register to read
24  * @val: Pointer to where the read value is stored
25  *
26  * Return: 0 on success, a negative error code otherwise.
27  */
28 int snd_soc_component_read(struct snd_soc_component *component,
29         unsigned int reg, unsigned int *val)
30 {
31         int ret;
32
33         if (component->regmap)
34                 ret = regmap_read(component->regmap, reg, val);
35         else if (component->read)
36                 ret = component->read(component, reg, val);
37         else if (component->driver->read) {
38                 *val = component->driver->read(component, reg);
39                 ret = 0;
40         }
41         else
42                 ret = -EIO;
43
44         return ret;
45 }
46 EXPORT_SYMBOL_GPL(snd_soc_component_read);
47
48 unsigned int snd_soc_component_read32(struct snd_soc_component *component,
49                                       unsigned int reg)
50 {
51         unsigned int val;
52         int ret;
53
54         ret = snd_soc_component_read(component, reg, &val);
55         if (ret < 0)
56                 return -1;
57
58         return val;
59 }
60 EXPORT_SYMBOL_GPL(snd_soc_component_read32);
61
62 /**
63  * snd_soc_component_write() - Write register value
64  * @component: Component to write to
65  * @reg: Register to write
66  * @val: Value to write to the register
67  *
68  * Return: 0 on success, a negative error code otherwise.
69  */
70 int snd_soc_component_write(struct snd_soc_component *component,
71         unsigned int reg, unsigned int val)
72 {
73         if (component->regmap)
74                 return regmap_write(component->regmap, reg, val);
75         else if (component->write)
76                 return component->write(component, reg, val);
77         else if (component->driver->write)
78                 return component->driver->write(component, reg, val);
79         else
80                 return -EIO;
81 }
82 EXPORT_SYMBOL_GPL(snd_soc_component_write);
83
84 static int snd_soc_component_update_bits_legacy(
85         struct snd_soc_component *component, unsigned int reg,
86         unsigned int mask, unsigned int val, bool *change)
87 {
88         unsigned int old, new;
89         int ret;
90
91         mutex_lock(&component->io_mutex);
92
93         ret = snd_soc_component_read(component, reg, &old);
94         if (ret < 0)
95                 goto out_unlock;
96
97         new = (old & ~mask) | (val & mask);
98         *change = old != new;
99         if (*change)
100                 ret = snd_soc_component_write(component, reg, new);
101 out_unlock:
102         mutex_unlock(&component->io_mutex);
103
104         return ret;
105 }
106
107 /**
108  * snd_soc_component_update_bits() - Perform read/modify/write cycle
109  * @component: Component to update
110  * @reg: Register to update
111  * @mask: Mask that specifies which bits to update
112  * @val: New value for the bits specified by mask
113  *
114  * Return: 1 if the operation was successful and the value of the register
115  * changed, 0 if the operation was successful, but the value did not change.
116  * Returns a negative error code otherwise.
117  */
118 int snd_soc_component_update_bits(struct snd_soc_component *component,
119         unsigned int reg, unsigned int mask, unsigned int val)
120 {
121         bool change;
122         int ret;
123
124         if (component->regmap)
125                 ret = regmap_update_bits_check(component->regmap, reg, mask,
126                         val, &change);
127         else
128                 ret = snd_soc_component_update_bits_legacy(component, reg,
129                         mask, val, &change);
130
131         if (ret < 0)
132                 return ret;
133         return change;
134 }
135 EXPORT_SYMBOL_GPL(snd_soc_component_update_bits);
136
137 /**
138  * snd_soc_component_update_bits_async() - Perform asynchronous
139  *  read/modify/write cycle
140  * @component: Component to update
141  * @reg: Register to update
142  * @mask: Mask that specifies which bits to update
143  * @val: New value for the bits specified by mask
144  *
145  * This function is similar to snd_soc_component_update_bits(), but the update
146  * operation is scheduled asynchronously. This means it may not be completed
147  * when the function returns. To make sure that all scheduled updates have been
148  * completed snd_soc_component_async_complete() must be called.
149  *
150  * Return: 1 if the operation was successful and the value of the register
151  * changed, 0 if the operation was successful, but the value did not change.
152  * Returns a negative error code otherwise.
153  */
154 int snd_soc_component_update_bits_async(struct snd_soc_component *component,
155         unsigned int reg, unsigned int mask, unsigned int val)
156 {
157         bool change;
158         int ret;
159
160         if (component->regmap)
161                 ret = regmap_update_bits_check_async(component->regmap, reg,
162                         mask, val, &change);
163         else
164                 ret = snd_soc_component_update_bits_legacy(component, reg,
165                         mask, val, &change);
166
167         if (ret < 0)
168                 return ret;
169         return change;
170 }
171 EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async);
172
173 /**
174  * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed
175  * @component: Component for which to wait
176  *
177  * This function blocks until all asynchronous I/O which has previously been
178  * scheduled using snd_soc_component_update_bits_async() has completed.
179  */
180 void snd_soc_component_async_complete(struct snd_soc_component *component)
181 {
182         if (component->regmap)
183                 regmap_async_complete(component->regmap);
184 }
185 EXPORT_SYMBOL_GPL(snd_soc_component_async_complete);
186
187 /**
188  * snd_soc_component_test_bits - Test register for change
189  * @component: component
190  * @reg: Register to test
191  * @mask: Mask that specifies which bits to test
192  * @value: Value to test against
193  *
194  * Tests a register with a new value and checks if the new value is
195  * different from the old value.
196  *
197  * Return: 1 for change, otherwise 0.
198  */
199 int snd_soc_component_test_bits(struct snd_soc_component *component,
200         unsigned int reg, unsigned int mask, unsigned int value)
201 {
202         unsigned int old, new;
203         int ret;
204
205         ret = snd_soc_component_read(component, reg, &old);
206         if (ret < 0)
207                 return ret;
208         new = (old & ~mask) | value;
209         return old != new;
210 }
211 EXPORT_SYMBOL_GPL(snd_soc_component_test_bits);
212
213 unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg)
214 {
215         unsigned int val;
216         int ret;
217
218         ret = snd_soc_component_read(&codec->component, reg, &val);
219         if (ret < 0)
220                 return -1;
221
222         return val;
223 }
224 EXPORT_SYMBOL_GPL(snd_soc_read);
225
226 int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg,
227         unsigned int val)
228 {
229         return snd_soc_component_write(&codec->component, reg, val);
230 }
231 EXPORT_SYMBOL_GPL(snd_soc_write);
232
233 /**
234  * snd_soc_update_bits - update codec register bits
235  * @codec: audio codec
236  * @reg: codec register
237  * @mask: register mask
238  * @value: new value
239  *
240  * Writes new register value.
241  *
242  * Returns 1 for change, 0 for no change, or negative error code.
243  */
244 int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg,
245                                 unsigned int mask, unsigned int value)
246 {
247         return snd_soc_component_update_bits(&codec->component, reg, mask,
248                 value);
249 }
250 EXPORT_SYMBOL_GPL(snd_soc_update_bits);
251
252 /**
253  * snd_soc_test_bits - test register for change
254  * @codec: audio codec
255  * @reg: codec register
256  * @mask: register mask
257  * @value: new value
258  *
259  * Tests a register with a new value and checks if the new value is
260  * different from the old value.
261  *
262  * Returns 1 for change else 0.
263  */
264 int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
265                                 unsigned int mask, unsigned int value)
266 {
267         return snd_soc_component_test_bits(&codec->component, reg, mask, value);
268 }
269 EXPORT_SYMBOL_GPL(snd_soc_test_bits);
270
271 int snd_soc_platform_read(struct snd_soc_platform *platform,
272                                         unsigned int reg)
273 {
274         unsigned int val;
275         int ret;
276
277         ret = snd_soc_component_read(&platform->component, reg, &val);
278         if (ret < 0)
279                 return -1;
280
281         return val;
282 }
283 EXPORT_SYMBOL_GPL(snd_soc_platform_read);
284
285 int snd_soc_platform_write(struct snd_soc_platform *platform,
286                                          unsigned int reg, unsigned int val)
287 {
288         return snd_soc_component_write(&platform->component, reg, val);
289 }
290 EXPORT_SYMBOL_GPL(snd_soc_platform_write);