Merge remote-tracking branch 'asoc/topic/pcm5102a' into asoc-next
[linux-2.6-block.git] / sound / soc / soc-io.c
CommitLineData
5bef44f9
MB
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>
be3ea3b9 16#include <linux/regmap.h>
d81a6d71 17#include <linux/export.h>
5bef44f9
MB
18#include <sound/soc.h>
19
e2c330b9
LPC
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 */
28int 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);
d0ff8ba5
KM
37 else if (component->driver->read) {
38 *val = component->driver->read(component, reg);
39 ret = 0;
40 }
e2c330b9
LPC
41 else
42 ret = -EIO;
43
e2c330b9
LPC
44 return ret;
45}
46EXPORT_SYMBOL_GPL(snd_soc_component_read);
47
738b49ef
KM
48unsigned 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}
60EXPORT_SYMBOL_GPL(snd_soc_component_read32);
61
e2c330b9
LPC
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 */
70int snd_soc_component_write(struct snd_soc_component *component,
71 unsigned int reg, unsigned int val)
96241c83 72{
e2c330b9
LPC
73 if (component->regmap)
74 return regmap_write(component->regmap, reg, val);
75 else if (component->write)
76 return component->write(component, reg, val);
d0ff8ba5
KM
77 else if (component->driver->write)
78 return component->driver->write(component, reg, val);
e2c330b9
LPC
79 else
80 return -EIO;
81}
82EXPORT_SYMBOL_GPL(snd_soc_component_write);
83
84static 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
e2c330b9
LPC
91 mutex_lock(&component->io_mutex);
92
dead99e8 93 ret = snd_soc_component_read(component, reg, &old);
e2c330b9
LPC
94 if (ret < 0)
95 goto out_unlock;
96
97 new = (old & ~mask) | (val & mask);
98 *change = old != new;
99 if (*change)
dead99e8 100 ret = snd_soc_component_write(component, reg, new);
e2c330b9
LPC
101out_unlock:
102 mutex_unlock(&component->io_mutex);
96241c83
LPC
103
104 return ret;
105}
e2c330b9
LPC
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 */
118int 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}
135EXPORT_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 */
154int 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}
171EXPORT_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 */
180void snd_soc_component_async_complete(struct snd_soc_component *component)
181{
182 if (component->regmap)
183 regmap_async_complete(component->regmap);
184}
185EXPORT_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 */
199int 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}
211EXPORT_SYMBOL_GPL(snd_soc_component_test_bits);
212
213unsigned 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;
e2c330b9
LPC
221
222 return val;
223}
96241c83
LPC
224EXPORT_SYMBOL_GPL(snd_soc_read);
225
ab2874a8
LPC
226int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg,
227 unsigned int val)
96241c83 228{
e2c330b9 229 return snd_soc_component_write(&codec->component, reg, val);
96241c83
LPC
230}
231EXPORT_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 */
aa0258ad 244int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg,
96241c83
LPC
245 unsigned int mask, unsigned int value)
246{
e2c330b9
LPC
247 return snd_soc_component_update_bits(&codec->component, reg, mask,
248 value);
96241c83
LPC
249}
250EXPORT_SYMBOL_GPL(snd_soc_update_bits);
251
96241c83
LPC
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 */
aa0258ad 264int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
96241c83
LPC
265 unsigned int mask, unsigned int value)
266{
e2c330b9 267 return snd_soc_component_test_bits(&codec->component, reg, mask, value);
96241c83
LPC
268}
269EXPORT_SYMBOL_GPL(snd_soc_test_bits);
270
271int snd_soc_platform_read(struct snd_soc_platform *platform,
272 unsigned int reg)
273{
e2c330b9
LPC
274 unsigned int val;
275 int ret;
96241c83 276
e2c330b9
LPC
277 ret = snd_soc_component_read(&platform->component, reg, &val);
278 if (ret < 0)
96241c83 279 return -1;
96241c83 280
e2c330b9 281 return val;
96241c83
LPC
282}
283EXPORT_SYMBOL_GPL(snd_soc_platform_read);
284
285int snd_soc_platform_write(struct snd_soc_platform *platform,
286 unsigned int reg, unsigned int val)
287{
e2c330b9 288 return snd_soc_component_write(&platform->component, reg, val);
96241c83
LPC
289}
290EXPORT_SYMBOL_GPL(snd_soc_platform_write);