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