diff options
Diffstat (limited to 'sound/soc/soc-cache.c')
-rw-r--r-- | sound/soc/soc-cache.c | 612 |
1 files changed, 148 insertions, 464 deletions
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 5d76da43b14c..06b7b81a1601 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c | |||
@@ -20,40 +20,28 @@ | |||
20 | 20 | ||
21 | #include <trace/events/asoc.h> | 21 | #include <trace/events/asoc.h> |
22 | 22 | ||
23 | static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, | 23 | #ifdef CONFIG_SPI_MASTER |
24 | unsigned int reg) | 24 | static int do_spi_write(void *control, const char *data, int len) |
25 | { | 25 | { |
26 | struct spi_device *spi = control; | ||
26 | int ret; | 27 | int ret; |
27 | unsigned int val; | ||
28 | |||
29 | if (reg >= codec->driver->reg_cache_size || | ||
30 | snd_soc_codec_volatile_register(codec, reg) || | ||
31 | codec->cache_bypass) { | ||
32 | if (codec->cache_only) | ||
33 | return -1; | ||
34 | |||
35 | BUG_ON(!codec->hw_read); | ||
36 | return codec->hw_read(codec, reg); | ||
37 | } | ||
38 | 28 | ||
39 | ret = snd_soc_cache_read(codec, reg, &val); | 29 | ret = spi_write(spi, data, len); |
40 | if (ret < 0) | 30 | if (ret < 0) |
41 | return -1; | 31 | return ret; |
42 | return val; | 32 | |
33 | return len; | ||
43 | } | 34 | } |
35 | #endif | ||
44 | 36 | ||
45 | static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, | 37 | static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg, |
46 | unsigned int value) | 38 | unsigned int value, const void *data, int len) |
47 | { | 39 | { |
48 | u8 data[2]; | ||
49 | int ret; | 40 | int ret; |
50 | 41 | ||
51 | data[0] = (reg << 4) | ((value >> 8) & 0x000f); | ||
52 | data[1] = value & 0x00ff; | ||
53 | |||
54 | if (!snd_soc_codec_volatile_register(codec, reg) && | 42 | if (!snd_soc_codec_volatile_register(codec, reg) && |
55 | reg < codec->driver->reg_cache_size && | 43 | reg < codec->driver->reg_cache_size && |
56 | !codec->cache_bypass) { | 44 | !codec->cache_bypass) { |
57 | ret = snd_soc_cache_write(codec, reg, value); | 45 | ret = snd_soc_cache_write(codec, reg, value); |
58 | if (ret < 0) | 46 | if (ret < 0) |
59 | return -1; | 47 | return -1; |
@@ -64,8 +52,8 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, | |||
64 | return 0; | 52 | return 0; |
65 | } | 53 | } |
66 | 54 | ||
67 | ret = codec->hw_write(codec->control_data, data, 2); | 55 | ret = codec->hw_write(codec->control_data, data, len); |
68 | if (ret == 2) | 56 | if (ret == len) |
69 | return 0; | 57 | return 0; |
70 | if (ret < 0) | 58 | if (ret < 0) |
71 | return ret; | 59 | return ret; |
@@ -73,50 +61,19 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, | |||
73 | return -EIO; | 61 | return -EIO; |
74 | } | 62 | } |
75 | 63 | ||
76 | #if defined(CONFIG_SPI_MASTER) | 64 | static unsigned int do_hw_read(struct snd_soc_codec *codec, unsigned int reg) |
77 | static int snd_soc_4_12_spi_write(void *control_data, const char *data, | ||
78 | int len) | ||
79 | { | ||
80 | struct spi_device *spi = control_data; | ||
81 | struct spi_transfer t; | ||
82 | struct spi_message m; | ||
83 | u8 msg[2]; | ||
84 | |||
85 | if (len <= 0) | ||
86 | return 0; | ||
87 | |||
88 | msg[0] = data[1]; | ||
89 | msg[1] = data[0]; | ||
90 | |||
91 | spi_message_init(&m); | ||
92 | memset(&t, 0, sizeof t); | ||
93 | |||
94 | t.tx_buf = &msg[0]; | ||
95 | t.len = len; | ||
96 | |||
97 | spi_message_add_tail(&t, &m); | ||
98 | spi_sync(spi, &m); | ||
99 | |||
100 | return len; | ||
101 | } | ||
102 | #else | ||
103 | #define snd_soc_4_12_spi_write NULL | ||
104 | #endif | ||
105 | |||
106 | static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, | ||
107 | unsigned int reg) | ||
108 | { | 65 | { |
109 | int ret; | 66 | int ret; |
110 | unsigned int val; | 67 | unsigned int val; |
111 | 68 | ||
112 | if (reg >= codec->driver->reg_cache_size || | 69 | if (reg >= codec->driver->reg_cache_size || |
113 | snd_soc_codec_volatile_register(codec, reg) || | 70 | snd_soc_codec_volatile_register(codec, reg) || |
114 | codec->cache_bypass) { | 71 | codec->cache_bypass) { |
115 | if (codec->cache_only) | 72 | if (codec->cache_only) |
116 | return -1; | 73 | return -1; |
117 | 74 | ||
118 | BUG_ON(!codec->hw_read); | 75 | BUG_ON(!codec->hw_read); |
119 | return codec->hw_read(codec, reg); | 76 | return codec->hw_read(codec, reg); |
120 | } | 77 | } |
121 | 78 | ||
122 | ret = snd_soc_cache_read(codec, reg, &val); | 79 | ret = snd_soc_cache_read(codec, reg, &val); |
@@ -125,259 +82,117 @@ static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, | |||
125 | return val; | 82 | return val; |
126 | } | 83 | } |
127 | 84 | ||
128 | static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, | 85 | static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, |
129 | unsigned int value) | 86 | unsigned int reg) |
130 | { | 87 | { |
131 | u8 data[2]; | 88 | return do_hw_read(codec, reg); |
132 | int ret; | ||
133 | |||
134 | data[0] = (reg << 1) | ((value >> 8) & 0x0001); | ||
135 | data[1] = value & 0x00ff; | ||
136 | |||
137 | if (!snd_soc_codec_volatile_register(codec, reg) && | ||
138 | reg < codec->driver->reg_cache_size && | ||
139 | !codec->cache_bypass) { | ||
140 | ret = snd_soc_cache_write(codec, reg, value); | ||
141 | if (ret < 0) | ||
142 | return -1; | ||
143 | } | ||
144 | |||
145 | if (codec->cache_only) { | ||
146 | codec->cache_sync = 1; | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | ret = codec->hw_write(codec->control_data, data, 2); | ||
151 | if (ret == 2) | ||
152 | return 0; | ||
153 | if (ret < 0) | ||
154 | return ret; | ||
155 | else | ||
156 | return -EIO; | ||
157 | } | 89 | } |
158 | 90 | ||
159 | #if defined(CONFIG_SPI_MASTER) | 91 | static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, |
160 | static int snd_soc_7_9_spi_write(void *control_data, const char *data, | 92 | unsigned int value) |
161 | int len) | ||
162 | { | 93 | { |
163 | struct spi_device *spi = control_data; | 94 | u16 data; |
164 | struct spi_transfer t; | ||
165 | struct spi_message m; | ||
166 | u8 msg[2]; | ||
167 | 95 | ||
168 | if (len <= 0) | 96 | data = cpu_to_be16((reg << 12) | (value & 0xffffff)); |
169 | return 0; | ||
170 | 97 | ||
171 | msg[0] = data[0]; | 98 | return do_hw_write(codec, reg, value, &data, 2); |
172 | msg[1] = data[1]; | 99 | } |
173 | 100 | ||
174 | spi_message_init(&m); | 101 | static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, |
175 | memset(&t, 0, sizeof t); | 102 | unsigned int reg) |
103 | { | ||
104 | return do_hw_read(codec, reg); | ||
105 | } | ||
176 | 106 | ||
177 | t.tx_buf = &msg[0]; | 107 | static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, |
178 | t.len = len; | 108 | unsigned int value) |
109 | { | ||
110 | u8 data[2]; | ||
179 | 111 | ||
180 | spi_message_add_tail(&t, &m); | 112 | data[0] = (reg << 1) | ((value >> 8) & 0x0001); |
181 | spi_sync(spi, &m); | 113 | data[1] = value & 0x00ff; |
182 | 114 | ||
183 | return len; | 115 | return do_hw_write(codec, reg, value, data, 2); |
184 | } | 116 | } |
185 | #else | ||
186 | #define snd_soc_7_9_spi_write NULL | ||
187 | #endif | ||
188 | 117 | ||
189 | static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, | 118 | static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, |
190 | unsigned int value) | 119 | unsigned int value) |
191 | { | 120 | { |
192 | u8 data[2]; | 121 | u8 data[2]; |
193 | int ret; | ||
194 | 122 | ||
195 | reg &= 0xff; | 123 | reg &= 0xff; |
196 | data[0] = reg; | 124 | data[0] = reg; |
197 | data[1] = value & 0xff; | 125 | data[1] = value & 0xff; |
198 | 126 | ||
199 | if (!snd_soc_codec_volatile_register(codec, reg) && | 127 | return do_hw_write(codec, reg, value, data, 2); |
200 | reg < codec->driver->reg_cache_size && | ||
201 | !codec->cache_bypass) { | ||
202 | ret = snd_soc_cache_write(codec, reg, value); | ||
203 | if (ret < 0) | ||
204 | return -1; | ||
205 | } | ||
206 | |||
207 | if (codec->cache_only) { | ||
208 | codec->cache_sync = 1; | ||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | if (codec->hw_write(codec->control_data, data, 2) == 2) | ||
213 | return 0; | ||
214 | else | ||
215 | return -EIO; | ||
216 | } | 128 | } |
217 | 129 | ||
218 | static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, | 130 | static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, |
219 | unsigned int reg) | 131 | unsigned int reg) |
220 | { | 132 | { |
221 | int ret; | 133 | return do_hw_read(codec, reg); |
222 | unsigned int val; | ||
223 | |||
224 | reg &= 0xff; | ||
225 | if (reg >= codec->driver->reg_cache_size || | ||
226 | snd_soc_codec_volatile_register(codec, reg) || | ||
227 | codec->cache_bypass) { | ||
228 | if (codec->cache_only) | ||
229 | return -1; | ||
230 | |||
231 | BUG_ON(!codec->hw_read); | ||
232 | return codec->hw_read(codec, reg); | ||
233 | } | ||
234 | |||
235 | ret = snd_soc_cache_read(codec, reg, &val); | ||
236 | if (ret < 0) | ||
237 | return -1; | ||
238 | return val; | ||
239 | } | ||
240 | |||
241 | #if defined(CONFIG_SPI_MASTER) | ||
242 | static int snd_soc_8_8_spi_write(void *control_data, const char *data, | ||
243 | int len) | ||
244 | { | ||
245 | struct spi_device *spi = control_data; | ||
246 | struct spi_transfer t; | ||
247 | struct spi_message m; | ||
248 | u8 msg[2]; | ||
249 | |||
250 | if (len <= 0) | ||
251 | return 0; | ||
252 | |||
253 | msg[0] = data[0]; | ||
254 | msg[1] = data[1]; | ||
255 | |||
256 | spi_message_init(&m); | ||
257 | memset(&t, 0, sizeof t); | ||
258 | |||
259 | t.tx_buf = &msg[0]; | ||
260 | t.len = len; | ||
261 | |||
262 | spi_message_add_tail(&t, &m); | ||
263 | spi_sync(spi, &m); | ||
264 | |||
265 | return len; | ||
266 | } | 134 | } |
267 | #else | ||
268 | #define snd_soc_8_8_spi_write NULL | ||
269 | #endif | ||
270 | 135 | ||
271 | static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, | 136 | static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, |
272 | unsigned int value) | 137 | unsigned int value) |
273 | { | 138 | { |
274 | u8 data[3]; | 139 | u8 data[3]; |
275 | int ret; | ||
276 | 140 | ||
277 | data[0] = reg; | 141 | data[0] = reg; |
278 | data[1] = (value >> 8) & 0xff; | 142 | data[1] = (value >> 8) & 0xff; |
279 | data[2] = value & 0xff; | 143 | data[2] = value & 0xff; |
280 | 144 | ||
281 | if (!snd_soc_codec_volatile_register(codec, reg) && | 145 | return do_hw_write(codec, reg, value, data, 3); |
282 | reg < codec->driver->reg_cache_size && | ||
283 | !codec->cache_bypass) { | ||
284 | ret = snd_soc_cache_write(codec, reg, value); | ||
285 | if (ret < 0) | ||
286 | return -1; | ||
287 | } | ||
288 | |||
289 | if (codec->cache_only) { | ||
290 | codec->cache_sync = 1; | ||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | if (codec->hw_write(codec->control_data, data, 3) == 3) | ||
295 | return 0; | ||
296 | else | ||
297 | return -EIO; | ||
298 | } | 146 | } |
299 | 147 | ||
300 | static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, | 148 | static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, |
301 | unsigned int reg) | 149 | unsigned int reg) |
302 | { | 150 | { |
303 | int ret; | 151 | return do_hw_read(codec, reg); |
304 | unsigned int val; | ||
305 | |||
306 | if (reg >= codec->driver->reg_cache_size || | ||
307 | snd_soc_codec_volatile_register(codec, reg) || | ||
308 | codec->cache_bypass) { | ||
309 | if (codec->cache_only) | ||
310 | return -1; | ||
311 | |||
312 | BUG_ON(!codec->hw_read); | ||
313 | return codec->hw_read(codec, reg); | ||
314 | } | ||
315 | |||
316 | ret = snd_soc_cache_read(codec, reg, &val); | ||
317 | if (ret < 0) | ||
318 | return -1; | ||
319 | return val; | ||
320 | } | ||
321 | |||
322 | #if defined(CONFIG_SPI_MASTER) | ||
323 | static int snd_soc_8_16_spi_write(void *control_data, const char *data, | ||
324 | int len) | ||
325 | { | ||
326 | struct spi_device *spi = control_data; | ||
327 | struct spi_transfer t; | ||
328 | struct spi_message m; | ||
329 | u8 msg[3]; | ||
330 | |||
331 | if (len <= 0) | ||
332 | return 0; | ||
333 | |||
334 | msg[0] = data[0]; | ||
335 | msg[1] = data[1]; | ||
336 | msg[2] = data[2]; | ||
337 | |||
338 | spi_message_init(&m); | ||
339 | memset(&t, 0, sizeof t); | ||
340 | |||
341 | t.tx_buf = &msg[0]; | ||
342 | t.len = len; | ||
343 | |||
344 | spi_message_add_tail(&t, &m); | ||
345 | spi_sync(spi, &m); | ||
346 | |||
347 | return len; | ||
348 | } | 152 | } |
349 | #else | ||
350 | #define snd_soc_8_16_spi_write NULL | ||
351 | #endif | ||
352 | 153 | ||
353 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | 154 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) |
354 | static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec, | 155 | static unsigned int do_i2c_read(struct snd_soc_codec *codec, |
355 | unsigned int r) | 156 | void *reg, int reglen, |
157 | void *data, int datalen) | ||
356 | { | 158 | { |
357 | struct i2c_msg xfer[2]; | 159 | struct i2c_msg xfer[2]; |
358 | u8 reg = r; | ||
359 | u8 data; | ||
360 | int ret; | 160 | int ret; |
361 | struct i2c_client *client = codec->control_data; | 161 | struct i2c_client *client = codec->control_data; |
362 | 162 | ||
363 | /* Write register */ | 163 | /* Write register */ |
364 | xfer[0].addr = client->addr; | 164 | xfer[0].addr = client->addr; |
365 | xfer[0].flags = 0; | 165 | xfer[0].flags = 0; |
366 | xfer[0].len = 1; | 166 | xfer[0].len = reglen; |
367 | xfer[0].buf = ® | 167 | xfer[0].buf = reg; |
368 | 168 | ||
369 | /* Read data */ | 169 | /* Read data */ |
370 | xfer[1].addr = client->addr; | 170 | xfer[1].addr = client->addr; |
371 | xfer[1].flags = I2C_M_RD; | 171 | xfer[1].flags = I2C_M_RD; |
372 | xfer[1].len = 1; | 172 | xfer[1].len = datalen; |
373 | xfer[1].buf = &data; | 173 | xfer[1].buf = data; |
374 | 174 | ||
375 | ret = i2c_transfer(client->adapter, xfer, 2); | 175 | ret = i2c_transfer(client->adapter, xfer, 2); |
376 | if (ret != 2) { | 176 | if (ret == 2) |
377 | dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); | ||
378 | return 0; | 177 | return 0; |
379 | } | 178 | else if (ret < 0) |
179 | return ret; | ||
180 | else | ||
181 | return -EIO; | ||
182 | } | ||
183 | #endif | ||
380 | 184 | ||
185 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | ||
186 | static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec, | ||
187 | unsigned int r) | ||
188 | { | ||
189 | u8 reg = r; | ||
190 | u8 data; | ||
191 | int ret; | ||
192 | |||
193 | ret = do_i2c_read(codec, ®, 1, &data, 1); | ||
194 | if (ret < 0) | ||
195 | return 0; | ||
381 | return data; | 196 | return data; |
382 | } | 197 | } |
383 | #else | 198 | #else |
@@ -388,30 +203,13 @@ static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec, | |||
388 | static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, | 203 | static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, |
389 | unsigned int r) | 204 | unsigned int r) |
390 | { | 205 | { |
391 | struct i2c_msg xfer[2]; | ||
392 | u8 reg = r; | 206 | u8 reg = r; |
393 | u16 data; | 207 | u16 data; |
394 | int ret; | 208 | int ret; |
395 | struct i2c_client *client = codec->control_data; | ||
396 | 209 | ||
397 | /* Write register */ | 210 | ret = do_i2c_read(codec, ®, 1, &data, 2); |
398 | xfer[0].addr = client->addr; | 211 | if (ret < 0) |
399 | xfer[0].flags = 0; | ||
400 | xfer[0].len = 1; | ||
401 | xfer[0].buf = ® | ||
402 | |||
403 | /* Read data */ | ||
404 | xfer[1].addr = client->addr; | ||
405 | xfer[1].flags = I2C_M_RD; | ||
406 | xfer[1].len = 2; | ||
407 | xfer[1].buf = (u8 *)&data; | ||
408 | |||
409 | ret = i2c_transfer(client->adapter, xfer, 2); | ||
410 | if (ret != 2) { | ||
411 | dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); | ||
412 | return 0; | 212 | return 0; |
413 | } | ||
414 | |||
415 | return (data >> 8) | ((data & 0xff) << 8); | 213 | return (data >> 8) | ((data & 0xff) << 8); |
416 | } | 214 | } |
417 | #else | 215 | #else |
@@ -422,30 +220,13 @@ static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, | |||
422 | static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec, | 220 | static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec, |
423 | unsigned int r) | 221 | unsigned int r) |
424 | { | 222 | { |
425 | struct i2c_msg xfer[2]; | ||
426 | u16 reg = r; | 223 | u16 reg = r; |
427 | u8 data; | 224 | u8 data; |
428 | int ret; | 225 | int ret; |
429 | struct i2c_client *client = codec->control_data; | ||
430 | |||
431 | /* Write register */ | ||
432 | xfer[0].addr = client->addr; | ||
433 | xfer[0].flags = 0; | ||
434 | xfer[0].len = 2; | ||
435 | xfer[0].buf = (u8 *)® | ||
436 | |||
437 | /* Read data */ | ||
438 | xfer[1].addr = client->addr; | ||
439 | xfer[1].flags = I2C_M_RD; | ||
440 | xfer[1].len = 1; | ||
441 | xfer[1].buf = &data; | ||
442 | 226 | ||
443 | ret = i2c_transfer(client->adapter, xfer, 2); | 227 | ret = do_i2c_read(codec, ®, 2, &data, 1); |
444 | if (ret != 2) { | 228 | if (ret < 0) |
445 | dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); | ||
446 | return 0; | 229 | return 0; |
447 | } | ||
448 | |||
449 | return data; | 230 | return data; |
450 | } | 231 | } |
451 | #else | 232 | #else |
@@ -453,120 +234,34 @@ static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec, | |||
453 | #endif | 234 | #endif |
454 | 235 | ||
455 | static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec, | 236 | static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec, |
456 | unsigned int reg) | 237 | unsigned int reg) |
457 | { | 238 | { |
458 | int ret; | 239 | return do_hw_read(codec, reg); |
459 | unsigned int val; | ||
460 | |||
461 | reg &= 0xff; | ||
462 | if (reg >= codec->driver->reg_cache_size || | ||
463 | snd_soc_codec_volatile_register(codec, reg) || | ||
464 | codec->cache_bypass) { | ||
465 | if (codec->cache_only) | ||
466 | return -1; | ||
467 | |||
468 | BUG_ON(!codec->hw_read); | ||
469 | return codec->hw_read(codec, reg); | ||
470 | } | ||
471 | |||
472 | ret = snd_soc_cache_read(codec, reg, &val); | ||
473 | if (ret < 0) | ||
474 | return -1; | ||
475 | return val; | ||
476 | } | 240 | } |
477 | 241 | ||
478 | static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, | 242 | static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, |
479 | unsigned int value) | 243 | unsigned int value) |
480 | { | 244 | { |
481 | u8 data[3]; | 245 | u8 data[3]; |
482 | int ret; | ||
483 | 246 | ||
484 | data[0] = (reg >> 8) & 0xff; | 247 | data[0] = (reg >> 8) & 0xff; |
485 | data[1] = reg & 0xff; | 248 | data[1] = reg & 0xff; |
486 | data[2] = value; | 249 | data[2] = value; |
487 | 250 | ||
488 | reg &= 0xff; | 251 | return do_hw_write(codec, reg, value, data, 3); |
489 | if (!snd_soc_codec_volatile_register(codec, reg) && | ||
490 | reg < codec->driver->reg_cache_size && | ||
491 | !codec->cache_bypass) { | ||
492 | ret = snd_soc_cache_write(codec, reg, value); | ||
493 | if (ret < 0) | ||
494 | return -1; | ||
495 | } | ||
496 | |||
497 | if (codec->cache_only) { | ||
498 | codec->cache_sync = 1; | ||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | ret = codec->hw_write(codec->control_data, data, 3); | ||
503 | if (ret == 3) | ||
504 | return 0; | ||
505 | if (ret < 0) | ||
506 | return ret; | ||
507 | else | ||
508 | return -EIO; | ||
509 | } | ||
510 | |||
511 | #if defined(CONFIG_SPI_MASTER) | ||
512 | static int snd_soc_16_8_spi_write(void *control_data, const char *data, | ||
513 | int len) | ||
514 | { | ||
515 | struct spi_device *spi = control_data; | ||
516 | struct spi_transfer t; | ||
517 | struct spi_message m; | ||
518 | u8 msg[3]; | ||
519 | |||
520 | if (len <= 0) | ||
521 | return 0; | ||
522 | |||
523 | msg[0] = data[0]; | ||
524 | msg[1] = data[1]; | ||
525 | msg[2] = data[2]; | ||
526 | |||
527 | spi_message_init(&m); | ||
528 | memset(&t, 0, sizeof t); | ||
529 | |||
530 | t.tx_buf = &msg[0]; | ||
531 | t.len = len; | ||
532 | |||
533 | spi_message_add_tail(&t, &m); | ||
534 | spi_sync(spi, &m); | ||
535 | |||
536 | return len; | ||
537 | } | 252 | } |
538 | #else | ||
539 | #define snd_soc_16_8_spi_write NULL | ||
540 | #endif | ||
541 | 253 | ||
542 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | 254 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) |
543 | static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, | 255 | static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, |
544 | unsigned int r) | 256 | unsigned int r) |
545 | { | 257 | { |
546 | struct i2c_msg xfer[2]; | ||
547 | u16 reg = cpu_to_be16(r); | 258 | u16 reg = cpu_to_be16(r); |
548 | u16 data; | 259 | u16 data; |
549 | int ret; | 260 | int ret; |
550 | struct i2c_client *client = codec->control_data; | ||
551 | |||
552 | /* Write register */ | ||
553 | xfer[0].addr = client->addr; | ||
554 | xfer[0].flags = 0; | ||
555 | xfer[0].len = 2; | ||
556 | xfer[0].buf = (u8 *)® | ||
557 | 261 | ||
558 | /* Read data */ | 262 | ret = do_i2c_read(codec, ®, 2, &data, 2); |
559 | xfer[1].addr = client->addr; | 263 | if (ret < 0) |
560 | xfer[1].flags = I2C_M_RD; | ||
561 | xfer[1].len = 2; | ||
562 | xfer[1].buf = (u8 *)&data; | ||
563 | |||
564 | ret = i2c_transfer(client->adapter, xfer, 2); | ||
565 | if (ret != 2) { | ||
566 | dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); | ||
567 | return 0; | 264 | return 0; |
568 | } | ||
569 | |||
570 | return be16_to_cpu(data); | 265 | return be16_to_cpu(data); |
571 | } | 266 | } |
572 | #else | 267 | #else |
@@ -576,52 +271,59 @@ static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, | |||
576 | static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec, | 271 | static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec, |
577 | unsigned int reg) | 272 | unsigned int reg) |
578 | { | 273 | { |
579 | int ret; | 274 | return do_hw_read(codec, reg); |
580 | unsigned int val; | ||
581 | |||
582 | if (reg >= codec->driver->reg_cache_size || | ||
583 | snd_soc_codec_volatile_register(codec, reg) || | ||
584 | codec->cache_bypass) { | ||
585 | if (codec->cache_only) | ||
586 | return -1; | ||
587 | |||
588 | BUG_ON(!codec->hw_read); | ||
589 | return codec->hw_read(codec, reg); | ||
590 | } | ||
591 | |||
592 | ret = snd_soc_cache_read(codec, reg, &val); | ||
593 | if (ret < 0) | ||
594 | return -1; | ||
595 | |||
596 | return val; | ||
597 | } | 275 | } |
598 | 276 | ||
599 | static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, | 277 | static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, |
600 | unsigned int value) | 278 | unsigned int value) |
601 | { | 279 | { |
602 | u8 data[4]; | 280 | u8 data[4]; |
603 | int ret; | ||
604 | 281 | ||
605 | data[0] = (reg >> 8) & 0xff; | 282 | data[0] = (reg >> 8) & 0xff; |
606 | data[1] = reg & 0xff; | 283 | data[1] = reg & 0xff; |
607 | data[2] = (value >> 8) & 0xff; | 284 | data[2] = (value >> 8) & 0xff; |
608 | data[3] = value & 0xff; | 285 | data[3] = value & 0xff; |
609 | 286 | ||
610 | if (!snd_soc_codec_volatile_register(codec, reg) && | 287 | return do_hw_write(codec, reg, value, data, 4); |
611 | reg < codec->driver->reg_cache_size && | 288 | } |
612 | !codec->cache_bypass) { | ||
613 | ret = snd_soc_cache_write(codec, reg, value); | ||
614 | if (ret < 0) | ||
615 | return -1; | ||
616 | } | ||
617 | 289 | ||
618 | if (codec->cache_only) { | 290 | /* Primitive bulk write support for soc-cache. The data pointed to by |
619 | codec->cache_sync = 1; | 291 | * `data' needs to already be in the form the hardware expects |
620 | return 0; | 292 | * including any leading register specific data. Any data written |
293 | * through this function will not go through the cache as it only | ||
294 | * handles writing to volatile or out of bounds registers. | ||
295 | */ | ||
296 | static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int reg, | ||
297 | const void *data, size_t len) | ||
298 | { | ||
299 | int ret; | ||
300 | |||
301 | /* To ensure that we don't get out of sync with the cache, check | ||
302 | * whether the base register is volatile or if we've directly asked | ||
303 | * to bypass the cache. Out of bounds registers are considered | ||
304 | * volatile. | ||
305 | */ | ||
306 | if (!codec->cache_bypass | ||
307 | && !snd_soc_codec_volatile_register(codec, reg) | ||
308 | && reg < codec->driver->reg_cache_size) | ||
309 | return -EINVAL; | ||
310 | |||
311 | switch (codec->control_type) { | ||
312 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | ||
313 | case SND_SOC_I2C: | ||
314 | ret = i2c_master_send(codec->control_data, data, len); | ||
315 | break; | ||
316 | #endif | ||
317 | #if defined(CONFIG_SPI_MASTER) | ||
318 | case SND_SOC_SPI: | ||
319 | ret = spi_write(codec->control_data, data, len); | ||
320 | break; | ||
321 | #endif | ||
322 | default: | ||
323 | BUG(); | ||
621 | } | 324 | } |
622 | 325 | ||
623 | ret = codec->hw_write(codec->control_data, data, 4); | 326 | if (ret == len) |
624 | if (ret == 4) | ||
625 | return 0; | 327 | return 0; |
626 | if (ret < 0) | 328 | if (ret < 0) |
627 | return ret; | 329 | return ret; |
@@ -629,79 +331,40 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, | |||
629 | return -EIO; | 331 | return -EIO; |
630 | } | 332 | } |
631 | 333 | ||
632 | #if defined(CONFIG_SPI_MASTER) | ||
633 | static int snd_soc_16_16_spi_write(void *control_data, const char *data, | ||
634 | int len) | ||
635 | { | ||
636 | struct spi_device *spi = control_data; | ||
637 | struct spi_transfer t; | ||
638 | struct spi_message m; | ||
639 | u8 msg[4]; | ||
640 | |||
641 | if (len <= 0) | ||
642 | return 0; | ||
643 | |||
644 | msg[0] = data[0]; | ||
645 | msg[1] = data[1]; | ||
646 | msg[2] = data[2]; | ||
647 | msg[3] = data[3]; | ||
648 | |||
649 | spi_message_init(&m); | ||
650 | memset(&t, 0, sizeof t); | ||
651 | |||
652 | t.tx_buf = &msg[0]; | ||
653 | t.len = len; | ||
654 | |||
655 | spi_message_add_tail(&t, &m); | ||
656 | spi_sync(spi, &m); | ||
657 | |||
658 | return len; | ||
659 | } | ||
660 | #else | ||
661 | #define snd_soc_16_16_spi_write NULL | ||
662 | #endif | ||
663 | |||
664 | static struct { | 334 | static struct { |
665 | int addr_bits; | 335 | int addr_bits; |
666 | int data_bits; | 336 | int data_bits; |
667 | int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int); | 337 | int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int); |
668 | int (*spi_write)(void *, const char *, int); | ||
669 | unsigned int (*read)(struct snd_soc_codec *, unsigned int); | 338 | unsigned int (*read)(struct snd_soc_codec *, unsigned int); |
670 | unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int); | 339 | unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int); |
671 | } io_types[] = { | 340 | } io_types[] = { |
672 | { | 341 | { |
673 | .addr_bits = 4, .data_bits = 12, | 342 | .addr_bits = 4, .data_bits = 12, |
674 | .write = snd_soc_4_12_write, .read = snd_soc_4_12_read, | 343 | .write = snd_soc_4_12_write, .read = snd_soc_4_12_read, |
675 | .spi_write = snd_soc_4_12_spi_write, | ||
676 | }, | 344 | }, |
677 | { | 345 | { |
678 | .addr_bits = 7, .data_bits = 9, | 346 | .addr_bits = 7, .data_bits = 9, |
679 | .write = snd_soc_7_9_write, .read = snd_soc_7_9_read, | 347 | .write = snd_soc_7_9_write, .read = snd_soc_7_9_read, |
680 | .spi_write = snd_soc_7_9_spi_write, | ||
681 | }, | 348 | }, |
682 | { | 349 | { |
683 | .addr_bits = 8, .data_bits = 8, | 350 | .addr_bits = 8, .data_bits = 8, |
684 | .write = snd_soc_8_8_write, .read = snd_soc_8_8_read, | 351 | .write = snd_soc_8_8_write, .read = snd_soc_8_8_read, |
685 | .i2c_read = snd_soc_8_8_read_i2c, | 352 | .i2c_read = snd_soc_8_8_read_i2c, |
686 | .spi_write = snd_soc_8_8_spi_write, | ||
687 | }, | 353 | }, |
688 | { | 354 | { |
689 | .addr_bits = 8, .data_bits = 16, | 355 | .addr_bits = 8, .data_bits = 16, |
690 | .write = snd_soc_8_16_write, .read = snd_soc_8_16_read, | 356 | .write = snd_soc_8_16_write, .read = snd_soc_8_16_read, |
691 | .i2c_read = snd_soc_8_16_read_i2c, | 357 | .i2c_read = snd_soc_8_16_read_i2c, |
692 | .spi_write = snd_soc_8_16_spi_write, | ||
693 | }, | 358 | }, |
694 | { | 359 | { |
695 | .addr_bits = 16, .data_bits = 8, | 360 | .addr_bits = 16, .data_bits = 8, |
696 | .write = snd_soc_16_8_write, .read = snd_soc_16_8_read, | 361 | .write = snd_soc_16_8_write, .read = snd_soc_16_8_read, |
697 | .i2c_read = snd_soc_16_8_read_i2c, | 362 | .i2c_read = snd_soc_16_8_read_i2c, |
698 | .spi_write = snd_soc_16_8_spi_write, | ||
699 | }, | 363 | }, |
700 | { | 364 | { |
701 | .addr_bits = 16, .data_bits = 16, | 365 | .addr_bits = 16, .data_bits = 16, |
702 | .write = snd_soc_16_16_write, .read = snd_soc_16_16_read, | 366 | .write = snd_soc_16_16_write, .read = snd_soc_16_16_read, |
703 | .i2c_read = snd_soc_16_16_read_i2c, | 367 | .i2c_read = snd_soc_16_16_read_i2c, |
704 | .spi_write = snd_soc_16_16_spi_write, | ||
705 | }, | 368 | }, |
706 | }; | 369 | }; |
707 | 370 | ||
@@ -709,7 +372,6 @@ static struct { | |||
709 | * snd_soc_codec_set_cache_io: Set up standard I/O functions. | 372 | * snd_soc_codec_set_cache_io: Set up standard I/O functions. |
710 | * | 373 | * |
711 | * @codec: CODEC to configure. | 374 | * @codec: CODEC to configure. |
712 | * @type: Type of cache. | ||
713 | * @addr_bits: Number of bits of register address data. | 375 | * @addr_bits: Number of bits of register address data. |
714 | * @data_bits: Number of bits of data per register. | 376 | * @data_bits: Number of bits of data per register. |
715 | * @control: Control bus used. | 377 | * @control: Control bus used. |
@@ -744,6 +406,7 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, | |||
744 | 406 | ||
745 | codec->write = io_types[i].write; | 407 | codec->write = io_types[i].write; |
746 | codec->read = io_types[i].read; | 408 | codec->read = io_types[i].read; |
409 | codec->bulk_write_raw = snd_soc_hw_bulk_write_raw; | ||
747 | 410 | ||
748 | switch (control) { | 411 | switch (control) { |
749 | case SND_SOC_CUSTOM: | 412 | case SND_SOC_CUSTOM: |
@@ -762,8 +425,9 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, | |||
762 | break; | 425 | break; |
763 | 426 | ||
764 | case SND_SOC_SPI: | 427 | case SND_SOC_SPI: |
765 | if (io_types[i].spi_write) | 428 | #ifdef CONFIG_SPI_MASTER |
766 | codec->hw_write = io_types[i].spi_write; | 429 | codec->hw_write = do_spi_write; |
430 | #endif | ||
767 | 431 | ||
768 | codec->control_data = container_of(codec->dev, | 432 | codec->control_data = container_of(codec->dev, |
769 | struct spi_device, | 433 | struct spi_device, |
@@ -889,6 +553,8 @@ static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec) | |||
889 | rbnode = rb_entry(node, struct snd_soc_rbtree_node, node); | 553 | rbnode = rb_entry(node, struct snd_soc_rbtree_node, node); |
890 | if (rbnode->value == rbnode->defval) | 554 | if (rbnode->value == rbnode->defval) |
891 | continue; | 555 | continue; |
556 | WARN_ON(codec->writable_register && | ||
557 | codec->writable_register(codec, rbnode->reg)); | ||
892 | ret = snd_soc_cache_read(codec, rbnode->reg, &val); | 558 | ret = snd_soc_cache_read(codec, rbnode->reg, &val); |
893 | if (ret) | 559 | if (ret) |
894 | return ret; | 560 | return ret; |
@@ -1149,6 +815,8 @@ static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec) | |||
1149 | 815 | ||
1150 | lzo_blocks = codec->reg_cache; | 816 | lzo_blocks = codec->reg_cache; |
1151 | for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) { | 817 | for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) { |
818 | WARN_ON(codec->writable_register && | ||
819 | codec->writable_register(codec, i)); | ||
1152 | ret = snd_soc_cache_read(codec, i, &val); | 820 | ret = snd_soc_cache_read(codec, i, &val); |
1153 | if (ret) | 821 | if (ret) |
1154 | return ret; | 822 | return ret; |
@@ -1407,6 +1075,8 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) | |||
1407 | 1075 | ||
1408 | codec_drv = codec->driver; | 1076 | codec_drv = codec->driver; |
1409 | for (i = 0; i < codec_drv->reg_cache_size; ++i) { | 1077 | for (i = 0; i < codec_drv->reg_cache_size; ++i) { |
1078 | WARN_ON(codec->writable_register && | ||
1079 | codec->writable_register(codec, i)); | ||
1410 | ret = snd_soc_cache_read(codec, i, &val); | 1080 | ret = snd_soc_cache_read(codec, i, &val); |
1411 | if (ret) | 1081 | if (ret) |
1412 | return ret; | 1082 | return ret; |
@@ -1523,7 +1193,7 @@ int snd_soc_cache_init(struct snd_soc_codec *codec) | |||
1523 | codec->cache_ops->name, codec->name); | 1193 | codec->cache_ops->name, codec->name); |
1524 | return codec->cache_ops->init(codec); | 1194 | return codec->cache_ops->init(codec); |
1525 | } | 1195 | } |
1526 | return -EINVAL; | 1196 | return -ENOSYS; |
1527 | } | 1197 | } |
1528 | 1198 | ||
1529 | /* | 1199 | /* |
@@ -1538,7 +1208,7 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec) | |||
1538 | codec->cache_ops->name, codec->name); | 1208 | codec->cache_ops->name, codec->name); |
1539 | return codec->cache_ops->exit(codec); | 1209 | return codec->cache_ops->exit(codec); |
1540 | } | 1210 | } |
1541 | return -EINVAL; | 1211 | return -ENOSYS; |
1542 | } | 1212 | } |
1543 | 1213 | ||
1544 | /** | 1214 | /** |
@@ -1562,7 +1232,7 @@ int snd_soc_cache_read(struct snd_soc_codec *codec, | |||
1562 | } | 1232 | } |
1563 | 1233 | ||
1564 | mutex_unlock(&codec->cache_rw_mutex); | 1234 | mutex_unlock(&codec->cache_rw_mutex); |
1565 | return -EINVAL; | 1235 | return -ENOSYS; |
1566 | } | 1236 | } |
1567 | EXPORT_SYMBOL_GPL(snd_soc_cache_read); | 1237 | EXPORT_SYMBOL_GPL(snd_soc_cache_read); |
1568 | 1238 | ||
@@ -1587,7 +1257,7 @@ int snd_soc_cache_write(struct snd_soc_codec *codec, | |||
1587 | } | 1257 | } |
1588 | 1258 | ||
1589 | mutex_unlock(&codec->cache_rw_mutex); | 1259 | mutex_unlock(&codec->cache_rw_mutex); |
1590 | return -EINVAL; | 1260 | return -ENOSYS; |
1591 | } | 1261 | } |
1592 | EXPORT_SYMBOL_GPL(snd_soc_cache_write); | 1262 | EXPORT_SYMBOL_GPL(snd_soc_cache_write); |
1593 | 1263 | ||
@@ -1610,7 +1280,7 @@ int snd_soc_cache_sync(struct snd_soc_codec *codec) | |||
1610 | } | 1280 | } |
1611 | 1281 | ||
1612 | if (!codec->cache_ops || !codec->cache_ops->sync) | 1282 | if (!codec->cache_ops || !codec->cache_ops->sync) |
1613 | return -EINVAL; | 1283 | return -ENOSYS; |
1614 | 1284 | ||
1615 | if (codec->cache_ops->name) | 1285 | if (codec->cache_ops->name) |
1616 | name = codec->cache_ops->name; | 1286 | name = codec->cache_ops->name; |
@@ -1677,3 +1347,17 @@ int snd_soc_default_readable_register(struct snd_soc_codec *codec, | |||
1677 | return codec->driver->reg_access_default[index].read; | 1347 | return codec->driver->reg_access_default[index].read; |
1678 | } | 1348 | } |
1679 | EXPORT_SYMBOL_GPL(snd_soc_default_readable_register); | 1349 | EXPORT_SYMBOL_GPL(snd_soc_default_readable_register); |
1350 | |||
1351 | int snd_soc_default_writable_register(struct snd_soc_codec *codec, | ||
1352 | unsigned int reg) | ||
1353 | { | ||
1354 | int index; | ||
1355 | |||
1356 | if (reg >= codec->driver->reg_cache_size) | ||
1357 | return 1; | ||
1358 | index = snd_soc_get_reg_access_index(codec, reg); | ||
1359 | if (index < 0) | ||
1360 | return 0; | ||
1361 | return codec->driver->reg_access_default[index].write; | ||
1362 | } | ||
1363 | EXPORT_SYMBOL_GPL(snd_soc_default_writable_register); | ||