Merge remote-tracking branches 'asoc/topic/cs47l24', 'asoc/topic/cx20442', 'asoc...
[sfrench/cifs-2.6.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         if (!component->read || !component->write)
92                 return -EIO;
93
94         mutex_lock(&component->io_mutex);
95
96         ret = component->read(component, reg, &old);
97         if (ret < 0)
98                 goto out_unlock;
99
100         new = (old & ~mask) | (val & mask);
101         *change = old != new;
102         if (*change)
103                 ret = component->write(component, reg, new);
104 out_unlock:
105         mutex_unlock(&component->io_mutex);
106
107         return ret;
108 }
109
110 /**
111  * snd_soc_component_update_bits() - Perform read/modify/write cycle
112  * @component: Component to update
113  * @reg: Register to update
114  * @mask: Mask that specifies which bits to update
115  * @val: New value for the bits specified by mask
116  *
117  * Return: 1 if the operation was successful and the value of the register
118  * changed, 0 if the operation was successful, but the value did not change.
119  * Returns a negative error code otherwise.
120  */
121 int snd_soc_component_update_bits(struct snd_soc_component *component,
122         unsigned int reg, unsigned int mask, unsigned int val)
123 {
124         bool change;
125         int ret;
126
127         if (component->regmap)
128                 ret = regmap_update_bits_check(component->regmap, reg, mask,
129                         val, &change);
130         else
131                 ret = snd_soc_component_update_bits_legacy(component, reg,
132                         mask, val, &change);
133
134         if (ret < 0)
135                 return ret;
136         return change;
137 }
138 EXPORT_SYMBOL_GPL(snd_soc_component_update_bits);
139
140 /**
141  * snd_soc_component_update_bits_async() - Perform asynchronous
142  *  read/modify/write cycle
143  * @component: Component to update
144  * @reg: Register to update
145  * @mask: Mask that specifies which bits to update
146  * @val: New value for the bits specified by mask
147  *
148  * This function is similar to snd_soc_component_update_bits(), but the update
149  * operation is scheduled asynchronously. This means it may not be completed
150  * when the function returns. To make sure that all scheduled updates have been
151  * completed snd_soc_component_async_complete() must be called.
152  *
153  * Return: 1 if the operation was successful and the value of the register
154  * changed, 0 if the operation was successful, but the value did not change.
155  * Returns a negative error code otherwise.
156  */
157 int snd_soc_component_update_bits_async(struct snd_soc_component *component,
158         unsigned int reg, unsigned int mask, unsigned int val)
159 {
160         bool change;
161         int ret;
162
163         if (component->regmap)
164                 ret = regmap_update_bits_check_async(component->regmap, reg,
165                         mask, val, &change);
166         else
167                 ret = snd_soc_component_update_bits_legacy(component, reg,
168                         mask, val, &change);
169
170         if (ret < 0)
171                 return ret;
172         return change;
173 }
174 EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async);
175
176 /**
177  * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed
178  * @component: Component for which to wait
179  *
180  * This function blocks until all asynchronous I/O which has previously been
181  * scheduled using snd_soc_component_update_bits_async() has completed.
182  */
183 void snd_soc_component_async_complete(struct snd_soc_component *component)
184 {
185         if (component->regmap)
186                 regmap_async_complete(component->regmap);
187 }
188 EXPORT_SYMBOL_GPL(snd_soc_component_async_complete);
189
190 /**
191  * snd_soc_component_test_bits - Test register for change
192  * @component: component
193  * @reg: Register to test
194  * @mask: Mask that specifies which bits to test
195  * @value: Value to test against
196  *
197  * Tests a register with a new value and checks if the new value is
198  * different from the old value.
199  *
200  * Return: 1 for change, otherwise 0.
201  */
202 int snd_soc_component_test_bits(struct snd_soc_component *component,
203         unsigned int reg, unsigned int mask, unsigned int value)
204 {
205         unsigned int old, new;
206         int ret;
207
208         ret = snd_soc_component_read(component, reg, &old);
209         if (ret < 0)
210                 return ret;
211         new = (old & ~mask) | value;
212         return old != new;
213 }
214 EXPORT_SYMBOL_GPL(snd_soc_component_test_bits);
215
216 unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg)
217 {
218         unsigned int val;
219         int ret;
220
221         ret = snd_soc_component_read(&codec->component, reg, &val);
222         if (ret < 0)
223                 return -1;
224
225         return val;
226 }
227 EXPORT_SYMBOL_GPL(snd_soc_read);
228
229 int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg,
230         unsigned int val)
231 {
232         return snd_soc_component_write(&codec->component, reg, val);
233 }
234 EXPORT_SYMBOL_GPL(snd_soc_write);
235
236 /**
237  * snd_soc_update_bits - update codec register bits
238  * @codec: audio codec
239  * @reg: codec register
240  * @mask: register mask
241  * @value: new value
242  *
243  * Writes new register value.
244  *
245  * Returns 1 for change, 0 for no change, or negative error code.
246  */
247 int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg,
248                                 unsigned int mask, unsigned int value)
249 {
250         return snd_soc_component_update_bits(&codec->component, reg, mask,
251                 value);
252 }
253 EXPORT_SYMBOL_GPL(snd_soc_update_bits);
254
255 /**
256  * snd_soc_test_bits - test register for change
257  * @codec: audio codec
258  * @reg: codec register
259  * @mask: register mask
260  * @value: new value
261  *
262  * Tests a register with a new value and checks if the new value is
263  * different from the old value.
264  *
265  * Returns 1 for change else 0.
266  */
267 int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
268                                 unsigned int mask, unsigned int value)
269 {
270         return snd_soc_component_test_bits(&codec->component, reg, mask, value);
271 }
272 EXPORT_SYMBOL_GPL(snd_soc_test_bits);
273
274 int snd_soc_platform_read(struct snd_soc_platform *platform,
275                                         unsigned int reg)
276 {
277         unsigned int val;
278         int ret;
279
280         ret = snd_soc_component_read(&platform->component, reg, &val);
281         if (ret < 0)
282                 return -1;
283
284         return val;
285 }
286 EXPORT_SYMBOL_GPL(snd_soc_platform_read);
287
288 int snd_soc_platform_write(struct snd_soc_platform *platform,
289                                          unsigned int reg, unsigned int val)
290 {
291         return snd_soc_component_write(&platform->component, reg, val);
292 }
293 EXPORT_SYMBOL_GPL(snd_soc_platform_write);