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