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

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

Version: ~ [ linux-5.5-rc7 ] ~ [ linux-5.4.13 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.97 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.166 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.210 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.210 ] ~ [ 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.81 ] ~ [ 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 // SPDX-License-Identifier: GPL-2.0+
  2 //
  3 // soc-io.c  --  ASoC register I/O helpers
  4 //
  5 // Copyright 2009-2011 Wolfson Microelectronics PLC.
  6 //
  7 // Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
  8 
  9 #include <linux/i2c.h>
 10 #include <linux/spi/spi.h>
 11 #include <linux/regmap.h>
 12 #include <linux/export.h>
 13 #include <sound/soc.h>
 14 
 15 /**
 16  * snd_soc_component_read() - Read register value
 17  * @component: Component to read from
 18  * @reg: Register to read
 19  * @val: Pointer to where the read value is stored
 20  *
 21  * Return: 0 on success, a negative error code otherwise.
 22  */
 23 int snd_soc_component_read(struct snd_soc_component *component,
 24         unsigned int reg, unsigned int *val)
 25 {
 26         int ret;
 27 
 28         if (component->regmap)
 29                 ret = regmap_read(component->regmap, reg, val);
 30         else if (component->driver->read) {
 31                 *val = component->driver->read(component, reg);
 32                 ret = 0;
 33         }
 34         else
 35                 ret = -EIO;
 36 
 37         return ret;
 38 }
 39 EXPORT_SYMBOL_GPL(snd_soc_component_read);
 40 
 41 unsigned int snd_soc_component_read32(struct snd_soc_component *component,
 42                                       unsigned int reg)
 43 {
 44         unsigned int val;
 45         int ret;
 46 
 47         ret = snd_soc_component_read(component, reg, &val);
 48         if (ret < 0)
 49                 return -1;
 50 
 51         return val;
 52 }
 53 EXPORT_SYMBOL_GPL(snd_soc_component_read32);
 54 
 55 /**
 56  * snd_soc_component_write() - Write register value
 57  * @component: Component to write to
 58  * @reg: Register to write
 59  * @val: Value to write to the register
 60  *
 61  * Return: 0 on success, a negative error code otherwise.
 62  */
 63 int snd_soc_component_write(struct snd_soc_component *component,
 64         unsigned int reg, unsigned int val)
 65 {
 66         if (component->regmap)
 67                 return regmap_write(component->regmap, reg, val);
 68         else if (component->driver->write)
 69                 return component->driver->write(component, reg, val);
 70         else
 71                 return -EIO;
 72 }
 73 EXPORT_SYMBOL_GPL(snd_soc_component_write);
 74 
 75 static int snd_soc_component_update_bits_legacy(
 76         struct snd_soc_component *component, unsigned int reg,
 77         unsigned int mask, unsigned int val, bool *change)
 78 {
 79         unsigned int old, new;
 80         int ret;
 81 
 82         mutex_lock(&component->io_mutex);
 83 
 84         ret = snd_soc_component_read(component, reg, &old);
 85         if (ret < 0)
 86                 goto out_unlock;
 87 
 88         new = (old & ~mask) | (val & mask);
 89         *change = old != new;
 90         if (*change)
 91                 ret = snd_soc_component_write(component, reg, new);
 92 out_unlock:
 93         mutex_unlock(&component->io_mutex);
 94 
 95         return ret;
 96 }
 97 
 98 /**
 99  * snd_soc_component_update_bits() - Perform read/modify/write cycle
100  * @component: Component to update
101  * @reg: Register to update
102  * @mask: Mask that specifies which bits to update
103  * @val: New value for the bits specified by mask
104  *
105  * Return: 1 if the operation was successful and the value of the register
106  * changed, 0 if the operation was successful, but the value did not change.
107  * Returns a negative error code otherwise.
108  */
109 int snd_soc_component_update_bits(struct snd_soc_component *component,
110         unsigned int reg, unsigned int mask, unsigned int val)
111 {
112         bool change;
113         int ret;
114 
115         if (component->regmap)
116                 ret = regmap_update_bits_check(component->regmap, reg, mask,
117                         val, &change);
118         else
119                 ret = snd_soc_component_update_bits_legacy(component, reg,
120                         mask, val, &change);
121 
122         if (ret < 0)
123                 return ret;
124         return change;
125 }
126 EXPORT_SYMBOL_GPL(snd_soc_component_update_bits);
127 
128 /**
129  * snd_soc_component_update_bits_async() - Perform asynchronous
130  *  read/modify/write cycle
131  * @component: Component to update
132  * @reg: Register to update
133  * @mask: Mask that specifies which bits to update
134  * @val: New value for the bits specified by mask
135  *
136  * This function is similar to snd_soc_component_update_bits(), but the update
137  * operation is scheduled asynchronously. This means it may not be completed
138  * when the function returns. To make sure that all scheduled updates have been
139  * completed snd_soc_component_async_complete() must be called.
140  *
141  * Return: 1 if the operation was successful and the value of the register
142  * changed, 0 if the operation was successful, but the value did not change.
143  * Returns a negative error code otherwise.
144  */
145 int snd_soc_component_update_bits_async(struct snd_soc_component *component,
146         unsigned int reg, unsigned int mask, unsigned int val)
147 {
148         bool change;
149         int ret;
150 
151         if (component->regmap)
152                 ret = regmap_update_bits_check_async(component->regmap, reg,
153                         mask, val, &change);
154         else
155                 ret = snd_soc_component_update_bits_legacy(component, reg,
156                         mask, val, &change);
157 
158         if (ret < 0)
159                 return ret;
160         return change;
161 }
162 EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async);
163 
164 /**
165  * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed
166  * @component: Component for which to wait
167  *
168  * This function blocks until all asynchronous I/O which has previously been
169  * scheduled using snd_soc_component_update_bits_async() has completed.
170  */
171 void snd_soc_component_async_complete(struct snd_soc_component *component)
172 {
173         if (component->regmap)
174                 regmap_async_complete(component->regmap);
175 }
176 EXPORT_SYMBOL_GPL(snd_soc_component_async_complete);
177 
178 /**
179  * snd_soc_component_test_bits - Test register for change
180  * @component: component
181  * @reg: Register to test
182  * @mask: Mask that specifies which bits to test
183  * @value: Value to test against
184  *
185  * Tests a register with a new value and checks if the new value is
186  * different from the old value.
187  *
188  * Return: 1 for change, otherwise 0.
189  */
190 int snd_soc_component_test_bits(struct snd_soc_component *component,
191         unsigned int reg, unsigned int mask, unsigned int value)
192 {
193         unsigned int old, new;
194         int ret;
195 
196         ret = snd_soc_component_read(component, reg, &old);
197         if (ret < 0)
198                 return ret;
199         new = (old & ~mask) | value;
200         return old != new;
201 }
202 EXPORT_SYMBOL_GPL(snd_soc_component_test_bits);
203 

~ [ 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