~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/soc-io.c

Version: ~ [ linux-5.5-rc1 ] ~ [ linux-5.4.2 ] ~ [ linux-5.3.15 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.88 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.158 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.206 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.206 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.78 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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);
274 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp