]> asedeno.scripts.mit.edu Git - linux.git/blob - sound/soc/soc-io.c
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[linux.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->driver->read) {
36                 *val = component->driver->read(component, reg);
37                 ret = 0;
38         }
39         else
40                 ret = -EIO;
41
42         return ret;
43 }
44 EXPORT_SYMBOL_GPL(snd_soc_component_read);
45
46 unsigned int snd_soc_component_read32(struct snd_soc_component *component,
47                                       unsigned int reg)
48 {
49         unsigned int val;
50         int ret;
51
52         ret = snd_soc_component_read(component, reg, &val);
53         if (ret < 0)
54                 return -1;
55
56         return val;
57 }
58 EXPORT_SYMBOL_GPL(snd_soc_component_read32);
59
60 /**
61  * snd_soc_component_write() - Write register value
62  * @component: Component to write to
63  * @reg: Register to write
64  * @val: Value to write to the register
65  *
66  * Return: 0 on success, a negative error code otherwise.
67  */
68 int snd_soc_component_write(struct snd_soc_component *component,
69         unsigned int reg, unsigned int val)
70 {
71         if (component->regmap)
72                 return regmap_write(component->regmap, reg, val);
73         else if (component->driver->write)
74                 return component->driver->write(component, reg, val);
75         else
76                 return -EIO;
77 }
78 EXPORT_SYMBOL_GPL(snd_soc_component_write);
79
80 static int snd_soc_component_update_bits_legacy(
81         struct snd_soc_component *component, unsigned int reg,
82         unsigned int mask, unsigned int val, bool *change)
83 {
84         unsigned int old, new;
85         int ret;
86
87         mutex_lock(&component->io_mutex);
88
89         ret = snd_soc_component_read(component, reg, &old);
90         if (ret < 0)
91                 goto out_unlock;
92
93         new = (old & ~mask) | (val & mask);
94         *change = old != new;
95         if (*change)
96                 ret = snd_soc_component_write(component, reg, new);
97 out_unlock:
98         mutex_unlock(&component->io_mutex);
99
100         return ret;
101 }
102
103 /**
104  * snd_soc_component_update_bits() - Perform read/modify/write cycle
105  * @component: Component to update
106  * @reg: Register to update
107  * @mask: Mask that specifies which bits to update
108  * @val: New value for the bits specified by mask
109  *
110  * Return: 1 if the operation was successful and the value of the register
111  * changed, 0 if the operation was successful, but the value did not change.
112  * Returns a negative error code otherwise.
113  */
114 int snd_soc_component_update_bits(struct snd_soc_component *component,
115         unsigned int reg, unsigned int mask, unsigned int val)
116 {
117         bool change;
118         int ret;
119
120         if (component->regmap)
121                 ret = regmap_update_bits_check(component->regmap, reg, mask,
122                         val, &change);
123         else
124                 ret = snd_soc_component_update_bits_legacy(component, reg,
125                         mask, val, &change);
126
127         if (ret < 0)
128                 return ret;
129         return change;
130 }
131 EXPORT_SYMBOL_GPL(snd_soc_component_update_bits);
132
133 /**
134  * snd_soc_component_update_bits_async() - Perform asynchronous
135  *  read/modify/write cycle
136  * @component: Component to update
137  * @reg: Register to update
138  * @mask: Mask that specifies which bits to update
139  * @val: New value for the bits specified by mask
140  *
141  * This function is similar to snd_soc_component_update_bits(), but the update
142  * operation is scheduled asynchronously. This means it may not be completed
143  * when the function returns. To make sure that all scheduled updates have been
144  * completed snd_soc_component_async_complete() must be called.
145  *
146  * Return: 1 if the operation was successful and the value of the register
147  * changed, 0 if the operation was successful, but the value did not change.
148  * Returns a negative error code otherwise.
149  */
150 int snd_soc_component_update_bits_async(struct snd_soc_component *component,
151         unsigned int reg, unsigned int mask, unsigned int val)
152 {
153         bool change;
154         int ret;
155
156         if (component->regmap)
157                 ret = regmap_update_bits_check_async(component->regmap, reg,
158                         mask, val, &change);
159         else
160                 ret = snd_soc_component_update_bits_legacy(component, reg,
161                         mask, val, &change);
162
163         if (ret < 0)
164                 return ret;
165         return change;
166 }
167 EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async);
168
169 /**
170  * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed
171  * @component: Component for which to wait
172  *
173  * This function blocks until all asynchronous I/O which has previously been
174  * scheduled using snd_soc_component_update_bits_async() has completed.
175  */
176 void snd_soc_component_async_complete(struct snd_soc_component *component)
177 {
178         if (component->regmap)
179                 regmap_async_complete(component->regmap);
180 }
181 EXPORT_SYMBOL_GPL(snd_soc_component_async_complete);
182
183 /**
184  * snd_soc_component_test_bits - Test register for change
185  * @component: component
186  * @reg: Register to test
187  * @mask: Mask that specifies which bits to test
188  * @value: Value to test against
189  *
190  * Tests a register with a new value and checks if the new value is
191  * different from the old value.
192  *
193  * Return: 1 for change, otherwise 0.
194  */
195 int snd_soc_component_test_bits(struct snd_soc_component *component,
196         unsigned int reg, unsigned int mask, unsigned int value)
197 {
198         unsigned int old, new;
199         int ret;
200
201         ret = snd_soc_component_read(component, reg, &old);
202         if (ret < 0)
203                 return ret;
204         new = (old & ~mask) | value;
205         return old != new;
206 }
207 EXPORT_SYMBOL_GPL(snd_soc_component_test_bits);