Linux 4.16.11
[linux/fpc-iii.git] / sound / soc / soc-io.c
blob2bc1c4c17896d6c946baf584656f4fdca2bc25e8
1 /*
2 * soc-io.c -- ASoC register I/O helpers
4 * Copyright 2009-2011 Wolfson Microelectronics PLC.
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
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.
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>
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
26 * Return: 0 on success, a negative error code otherwise.
28 int snd_soc_component_read(struct snd_soc_component *component,
29 unsigned int reg, unsigned int *val)
31 int ret;
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;
41 else
42 ret = -EIO;
44 return ret;
46 EXPORT_SYMBOL_GPL(snd_soc_component_read);
48 unsigned int snd_soc_component_read32(struct snd_soc_component *component,
49 unsigned int reg)
51 unsigned int val;
52 int ret;
54 ret = snd_soc_component_read(component, reg, &val);
55 if (ret < 0)
56 return -1;
58 return val;
60 EXPORT_SYMBOL_GPL(snd_soc_component_read32);
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
68 * Return: 0 on success, a negative error code otherwise.
70 int snd_soc_component_write(struct snd_soc_component *component,
71 unsigned int reg, unsigned int val)
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;
82 EXPORT_SYMBOL_GPL(snd_soc_component_write);
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)
88 unsigned int old, new;
89 int ret;
91 if (!component->read || !component->write)
92 return -EIO;
94 mutex_lock(&component->io_mutex);
96 ret = component->read(component, reg, &old);
97 if (ret < 0)
98 goto out_unlock;
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);
107 return ret;
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
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.
121 int snd_soc_component_update_bits(struct snd_soc_component *component,
122 unsigned int reg, unsigned int mask, unsigned int val)
124 bool change;
125 int ret;
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);
134 if (ret < 0)
135 return ret;
136 return change;
138 EXPORT_SYMBOL_GPL(snd_soc_component_update_bits);
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
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.
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.
157 int snd_soc_component_update_bits_async(struct snd_soc_component *component,
158 unsigned int reg, unsigned int mask, unsigned int val)
160 bool change;
161 int ret;
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);
170 if (ret < 0)
171 return ret;
172 return change;
174 EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async);
177 * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed
178 * @component: Component for which to wait
180 * This function blocks until all asynchronous I/O which has previously been
181 * scheduled using snd_soc_component_update_bits_async() has completed.
183 void snd_soc_component_async_complete(struct snd_soc_component *component)
185 if (component->regmap)
186 regmap_async_complete(component->regmap);
188 EXPORT_SYMBOL_GPL(snd_soc_component_async_complete);
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
197 * Tests a register with a new value and checks if the new value is
198 * different from the old value.
200 * Return: 1 for change, otherwise 0.
202 int snd_soc_component_test_bits(struct snd_soc_component *component,
203 unsigned int reg, unsigned int mask, unsigned int value)
205 unsigned int old, new;
206 int ret;
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;
214 EXPORT_SYMBOL_GPL(snd_soc_component_test_bits);
216 unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg)
218 unsigned int val;
219 int ret;
221 ret = snd_soc_component_read(&codec->component, reg, &val);
222 if (ret < 0)
223 return -1;
225 return val;
227 EXPORT_SYMBOL_GPL(snd_soc_read);
229 int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg,
230 unsigned int val)
232 return snd_soc_component_write(&codec->component, reg, val);
234 EXPORT_SYMBOL_GPL(snd_soc_write);
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
243 * Writes new register value.
245 * Returns 1 for change, 0 for no change, or negative error code.
247 int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg,
248 unsigned int mask, unsigned int value)
250 return snd_soc_component_update_bits(&codec->component, reg, mask,
251 value);
253 EXPORT_SYMBOL_GPL(snd_soc_update_bits);
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
262 * Tests a register with a new value and checks if the new value is
263 * different from the old value.
265 * Returns 1 for change else 0.
267 int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
268 unsigned int mask, unsigned int value)
270 return snd_soc_component_test_bits(&codec->component, reg, mask, value);
272 EXPORT_SYMBOL_GPL(snd_soc_test_bits);
274 int snd_soc_platform_read(struct snd_soc_platform *platform,
275 unsigned int reg)
277 unsigned int val;
278 int ret;
280 ret = snd_soc_component_read(&platform->component, reg, &val);
281 if (ret < 0)
282 return -1;
284 return val;
286 EXPORT_SYMBOL_GPL(snd_soc_platform_read);
288 int snd_soc_platform_write(struct snd_soc_platform *platform,
289 unsigned int reg, unsigned int val)
291 return snd_soc_component_write(&platform->component, reg, val);
293 EXPORT_SYMBOL_GPL(snd_soc_platform_write);