ASoC: soc-cache: Clean up the cache manipulation code
[deliverable/linux.git] / sound / soc / soc-cache.c
CommitLineData
17a52fd6
MB
1/*
2 * soc-cache.c -- ASoC register cache helpers
3 *
4 * Copyright 2009 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
7084a42b 14#include <linux/i2c.h>
27ded041 15#include <linux/spi/spi.h>
17a52fd6 16#include <sound/soc.h>
cc28fb8e
DP
17#include <linux/lzo.h>
18#include <linux/bitmap.h>
a7f387d5 19#include <linux/rbtree.h>
17a52fd6 20
63b62ab0
BS
21static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
22 unsigned int reg)
23{
7a30a3db
DP
24 int ret;
25 unsigned int val;
db49c146
DP
26
27 if (reg >= codec->driver->reg_cache_size ||
28 snd_soc_codec_volatile_register(codec, reg)) {
29 if (codec->cache_only)
30 return -1;
31
5aaa062c 32 BUG_ON(!codec->hw_read);
db49c146
DP
33 return codec->hw_read(codec, reg);
34 }
35
7a30a3db
DP
36 ret = snd_soc_cache_read(codec, reg, &val);
37 if (ret < 0)
38 return -1;
39 return val;
63b62ab0
BS
40}
41
42static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
43 unsigned int value)
44{
63b62ab0
BS
45 u8 data[2];
46 int ret;
47
63b62ab0
BS
48 data[0] = (reg << 4) | ((value >> 8) & 0x000f);
49 data[1] = value & 0x00ff;
50
db49c146 51 if (!snd_soc_codec_volatile_register(codec, reg) &&
7a30a3db
DP
52 reg < codec->driver->reg_cache_size) {
53 ret = snd_soc_cache_write(codec, reg, value);
54 if (ret < 0)
55 return -1;
56 }
8c961bcc 57
a3032b47
MB
58 if (codec->cache_only) {
59 codec->cache_sync = 1;
8c961bcc 60 return 0;
a3032b47 61 }
8c961bcc 62
63b62ab0
BS
63 ret = codec->hw_write(codec->control_data, data, 2);
64 if (ret == 2)
65 return 0;
66 if (ret < 0)
67 return ret;
68 else
69 return -EIO;
70}
71
72#if defined(CONFIG_SPI_MASTER)
73static int snd_soc_4_12_spi_write(void *control_data, const char *data,
74 int len)
75{
76 struct spi_device *spi = control_data;
77 struct spi_transfer t;
78 struct spi_message m;
79 u8 msg[2];
80
81 if (len <= 0)
82 return 0;
83
84 msg[0] = data[1];
85 msg[1] = data[0];
86
87 spi_message_init(&m);
465d7fcc 88 memset(&t, 0, sizeof t);
63b62ab0
BS
89
90 t.tx_buf = &msg[0];
91 t.len = len;
92
93 spi_message_add_tail(&t, &m);
94 spi_sync(spi, &m);
95
96 return len;
97}
98#else
99#define snd_soc_4_12_spi_write NULL
100#endif
101
17a52fd6
MB
102static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
103 unsigned int reg)
104{
7a30a3db
DP
105 int ret;
106 unsigned int val;
db49c146
DP
107
108 if (reg >= codec->driver->reg_cache_size ||
109 snd_soc_codec_volatile_register(codec, reg)) {
110 if (codec->cache_only)
111 return -1;
112
5aaa062c 113 BUG_ON(!codec->hw_read);
db49c146
DP
114 return codec->hw_read(codec, reg);
115 }
116
7a30a3db
DP
117 ret = snd_soc_cache_read(codec, reg, &val);
118 if (ret < 0)
119 return -1;
120 return val;
17a52fd6
MB
121}
122
123static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
124 unsigned int value)
125{
17a52fd6
MB
126 u8 data[2];
127 int ret;
128
17a52fd6
MB
129 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
130 data[1] = value & 0x00ff;
131
db49c146 132 if (!snd_soc_codec_volatile_register(codec, reg) &&
7a30a3db
DP
133 reg < codec->driver->reg_cache_size) {
134 ret = snd_soc_cache_write(codec, reg, value);
135 if (ret < 0)
136 return -1;
137 }
8c961bcc 138
a3032b47
MB
139 if (codec->cache_only) {
140 codec->cache_sync = 1;
8c961bcc 141 return 0;
a3032b47 142 }
8c961bcc 143
17a52fd6
MB
144 ret = codec->hw_write(codec->control_data, data, 2);
145 if (ret == 2)
146 return 0;
147 if (ret < 0)
148 return ret;
149 else
150 return -EIO;
151}
152
27ded041
MB
153#if defined(CONFIG_SPI_MASTER)
154static int snd_soc_7_9_spi_write(void *control_data, const char *data,
155 int len)
156{
157 struct spi_device *spi = control_data;
158 struct spi_transfer t;
159 struct spi_message m;
160 u8 msg[2];
161
162 if (len <= 0)
163 return 0;
164
165 msg[0] = data[0];
166 msg[1] = data[1];
167
168 spi_message_init(&m);
465d7fcc 169 memset(&t, 0, sizeof t);
27ded041
MB
170
171 t.tx_buf = &msg[0];
172 t.len = len;
173
174 spi_message_add_tail(&t, &m);
175 spi_sync(spi, &m);
176
177 return len;
178}
179#else
180#define snd_soc_7_9_spi_write NULL
181#endif
182
341c9b84
JS
183static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
184 unsigned int value)
185{
341c9b84 186 u8 data[2];
7a30a3db 187 int ret;
341c9b84 188
f4bee1bb
BS
189 reg &= 0xff;
190 data[0] = reg;
341c9b84
JS
191 data[1] = value & 0xff;
192
005d65fb 193 if (!snd_soc_codec_volatile_register(codec, reg) &&
7a30a3db
DP
194 reg < codec->driver->reg_cache_size) {
195 ret = snd_soc_cache_write(codec, reg, value);
196 if (ret < 0)
197 return -1;
198 }
341c9b84 199
a3032b47
MB
200 if (codec->cache_only) {
201 codec->cache_sync = 1;
8c961bcc 202 return 0;
a3032b47 203 }
8c961bcc 204
341c9b84
JS
205 if (codec->hw_write(codec->control_data, data, 2) == 2)
206 return 0;
207 else
208 return -EIO;
209}
210
211static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
212 unsigned int reg)
213{
7a30a3db
DP
214 int ret;
215 unsigned int val;
db49c146 216
f4bee1bb 217 reg &= 0xff;
db49c146
DP
218 if (reg >= codec->driver->reg_cache_size ||
219 snd_soc_codec_volatile_register(codec, reg)) {
220 if (codec->cache_only)
221 return -1;
222
5aaa062c 223 BUG_ON(!codec->hw_read);
db49c146
DP
224 return codec->hw_read(codec, reg);
225 }
226
7a30a3db
DP
227 ret = snd_soc_cache_read(codec, reg, &val);
228 if (ret < 0)
229 return -1;
230 return val;
341c9b84
JS
231}
232
f479fd93
DP
233#if defined(CONFIG_SPI_MASTER)
234static int snd_soc_8_8_spi_write(void *control_data, const char *data,
235 int len)
236{
237 struct spi_device *spi = control_data;
238 struct spi_transfer t;
239 struct spi_message m;
240 u8 msg[2];
241
242 if (len <= 0)
243 return 0;
244
245 msg[0] = data[0];
246 msg[1] = data[1];
247
248 spi_message_init(&m);
465d7fcc 249 memset(&t, 0, sizeof t);
f479fd93
DP
250
251 t.tx_buf = &msg[0];
252 t.len = len;
253
254 spi_message_add_tail(&t, &m);
255 spi_sync(spi, &m);
256
257 return len;
258}
259#else
260#define snd_soc_8_8_spi_write NULL
261#endif
262
afa2f106
MB
263static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
264 unsigned int value)
265{
afa2f106 266 u8 data[3];
7a30a3db 267 int ret;
afa2f106
MB
268
269 data[0] = reg;
270 data[1] = (value >> 8) & 0xff;
271 data[2] = value & 0xff;
272
3e13f65e 273 if (!snd_soc_codec_volatile_register(codec, reg) &&
7a30a3db
DP
274 reg < codec->driver->reg_cache_size) {
275 ret = snd_soc_cache_write(codec, reg, value);
276 if (ret < 0)
277 return -1;
278 }
afa2f106 279
a3032b47
MB
280 if (codec->cache_only) {
281 codec->cache_sync = 1;
8c961bcc 282 return 0;
a3032b47 283 }
8c961bcc 284
afa2f106
MB
285 if (codec->hw_write(codec->control_data, data, 3) == 3)
286 return 0;
287 else
288 return -EIO;
289}
290
291static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
292 unsigned int reg)
293{
7a30a3db
DP
294 int ret;
295 unsigned int val;
afa2f106 296
f0fba2ad 297 if (reg >= codec->driver->reg_cache_size ||
8c961bcc
MB
298 snd_soc_codec_volatile_register(codec, reg)) {
299 if (codec->cache_only)
391d8a04 300 return -1;
8c961bcc 301
5aaa062c 302 BUG_ON(!codec->hw_read);
afa2f106 303 return codec->hw_read(codec, reg);
8c961bcc 304 }
7a30a3db
DP
305
306 ret = snd_soc_cache_read(codec, reg, &val);
307 if (ret < 0)
308 return -1;
309 return val;
afa2f106
MB
310}
311
f479fd93
DP
312#if defined(CONFIG_SPI_MASTER)
313static int snd_soc_8_16_spi_write(void *control_data, const char *data,
314 int len)
315{
316 struct spi_device *spi = control_data;
317 struct spi_transfer t;
318 struct spi_message m;
319 u8 msg[3];
320
321 if (len <= 0)
322 return 0;
323
324 msg[0] = data[0];
325 msg[1] = data[1];
326 msg[2] = data[2];
327
328 spi_message_init(&m);
465d7fcc 329 memset(&t, 0, sizeof t);
f479fd93
DP
330
331 t.tx_buf = &msg[0];
332 t.len = len;
333
334 spi_message_add_tail(&t, &m);
335 spi_sync(spi, &m);
336
337 return len;
338}
339#else
340#define snd_soc_8_16_spi_write NULL
341#endif
342
85dfcdff
CC
343#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
344static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
345 unsigned int r)
346{
347 struct i2c_msg xfer[2];
348 u8 reg = r;
349 u8 data;
350 int ret;
351 struct i2c_client *client = codec->control_data;
352
353 /* Write register */
354 xfer[0].addr = client->addr;
355 xfer[0].flags = 0;
356 xfer[0].len = 1;
357 xfer[0].buf = &reg;
358
359 /* Read data */
360 xfer[1].addr = client->addr;
361 xfer[1].flags = I2C_M_RD;
362 xfer[1].len = 1;
363 xfer[1].buf = &data;
364
365 ret = i2c_transfer(client->adapter, xfer, 2);
366 if (ret != 2) {
367 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
368 return 0;
369 }
370
371 return data;
372}
373#else
374#define snd_soc_8_8_read_i2c NULL
375#endif
376
17244c24 377#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
afa2f106
MB
378static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
379 unsigned int r)
380{
381 struct i2c_msg xfer[2];
382 u8 reg = r;
383 u16 data;
384 int ret;
385 struct i2c_client *client = codec->control_data;
386
387 /* Write register */
388 xfer[0].addr = client->addr;
389 xfer[0].flags = 0;
390 xfer[0].len = 1;
391 xfer[0].buf = &reg;
392
393 /* Read data */
394 xfer[1].addr = client->addr;
395 xfer[1].flags = I2C_M_RD;
396 xfer[1].len = 2;
397 xfer[1].buf = (u8 *)&data;
398
399 ret = i2c_transfer(client->adapter, xfer, 2);
400 if (ret != 2) {
401 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
402 return 0;
403 }
404
405 return (data >> 8) | ((data & 0xff) << 8);
406}
407#else
408#define snd_soc_8_16_read_i2c NULL
409#endif
17a52fd6 410
994dc424
BS
411#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
412static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
413 unsigned int r)
414{
415 struct i2c_msg xfer[2];
416 u16 reg = r;
417 u8 data;
418 int ret;
419 struct i2c_client *client = codec->control_data;
420
421 /* Write register */
422 xfer[0].addr = client->addr;
423 xfer[0].flags = 0;
424 xfer[0].len = 2;
425 xfer[0].buf = (u8 *)&reg;
426
427 /* Read data */
428 xfer[1].addr = client->addr;
429 xfer[1].flags = I2C_M_RD;
430 xfer[1].len = 1;
431 xfer[1].buf = &data;
432
433 ret = i2c_transfer(client->adapter, xfer, 2);
434 if (ret != 2) {
435 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
436 return 0;
437 }
438
439 return data;
440}
441#else
442#define snd_soc_16_8_read_i2c NULL
443#endif
444
445static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
446 unsigned int reg)
447{
7a30a3db
DP
448 int ret;
449 unsigned int val;
994dc424
BS
450
451 reg &= 0xff;
db49c146
DP
452 if (reg >= codec->driver->reg_cache_size ||
453 snd_soc_codec_volatile_register(codec, reg)) {
454 if (codec->cache_only)
455 return -1;
456
5aaa062c 457 BUG_ON(!codec->hw_read);
db49c146
DP
458 return codec->hw_read(codec, reg);
459 }
460
7a30a3db
DP
461 ret = snd_soc_cache_read(codec, reg, &val);
462 if (ret < 0)
463 return -1;
464 return val;
994dc424
BS
465}
466
467static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
468 unsigned int value)
469{
994dc424
BS
470 u8 data[3];
471 int ret;
472
994dc424
BS
473 data[0] = (reg >> 8) & 0xff;
474 data[1] = reg & 0xff;
475 data[2] = value;
476
477 reg &= 0xff;
db49c146 478 if (!snd_soc_codec_volatile_register(codec, reg) &&
7a30a3db
DP
479 reg < codec->driver->reg_cache_size) {
480 ret = snd_soc_cache_write(codec, reg, value);
481 if (ret < 0)
482 return -1;
483 }
8c961bcc 484
a3032b47
MB
485 if (codec->cache_only) {
486 codec->cache_sync = 1;
8c961bcc 487 return 0;
a3032b47 488 }
8c961bcc 489
994dc424
BS
490 ret = codec->hw_write(codec->control_data, data, 3);
491 if (ret == 3)
492 return 0;
493 if (ret < 0)
494 return ret;
495 else
496 return -EIO;
497}
498
499#if defined(CONFIG_SPI_MASTER)
500static int snd_soc_16_8_spi_write(void *control_data, const char *data,
501 int len)
502{
503 struct spi_device *spi = control_data;
504 struct spi_transfer t;
505 struct spi_message m;
506 u8 msg[3];
507
508 if (len <= 0)
509 return 0;
510
511 msg[0] = data[0];
512 msg[1] = data[1];
513 msg[2] = data[2];
514
515 spi_message_init(&m);
465d7fcc 516 memset(&t, 0, sizeof t);
994dc424
BS
517
518 t.tx_buf = &msg[0];
519 t.len = len;
520
521 spi_message_add_tail(&t, &m);
522 spi_sync(spi, &m);
523
524 return len;
525}
526#else
527#define snd_soc_16_8_spi_write NULL
528#endif
529
bc6552f4
MB
530#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
531static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
532 unsigned int r)
533{
534 struct i2c_msg xfer[2];
535 u16 reg = cpu_to_be16(r);
536 u16 data;
537 int ret;
538 struct i2c_client *client = codec->control_data;
539
540 /* Write register */
541 xfer[0].addr = client->addr;
542 xfer[0].flags = 0;
543 xfer[0].len = 2;
544 xfer[0].buf = (u8 *)&reg;
545
546 /* Read data */
547 xfer[1].addr = client->addr;
548 xfer[1].flags = I2C_M_RD;
549 xfer[1].len = 2;
550 xfer[1].buf = (u8 *)&data;
551
552 ret = i2c_transfer(client->adapter, xfer, 2);
553 if (ret != 2) {
554 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
555 return 0;
556 }
557
558 return be16_to_cpu(data);
559}
560#else
561#define snd_soc_16_16_read_i2c NULL
562#endif
563
564static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
565 unsigned int reg)
566{
7a30a3db
DP
567 int ret;
568 unsigned int val;
bc6552f4 569
f0fba2ad 570 if (reg >= codec->driver->reg_cache_size ||
bc6552f4
MB
571 snd_soc_codec_volatile_register(codec, reg)) {
572 if (codec->cache_only)
391d8a04 573 return -1;
bc6552f4 574
5aaa062c 575 BUG_ON(!codec->hw_read);
bc6552f4
MB
576 return codec->hw_read(codec, reg);
577 }
578
7a30a3db
DP
579 ret = snd_soc_cache_read(codec, reg, &val);
580 if (ret < 0)
581 return -1;
582
583 return val;
bc6552f4
MB
584}
585
586static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
587 unsigned int value)
588{
bc6552f4
MB
589 u8 data[4];
590 int ret;
591
592 data[0] = (reg >> 8) & 0xff;
593 data[1] = reg & 0xff;
594 data[2] = (value >> 8) & 0xff;
595 data[3] = value & 0xff;
596
db49c146 597 if (!snd_soc_codec_volatile_register(codec, reg) &&
7a30a3db
DP
598 reg < codec->driver->reg_cache_size) {
599 ret = snd_soc_cache_write(codec, reg, value);
600 if (ret < 0)
601 return -1;
602 }
bc6552f4
MB
603
604 if (codec->cache_only) {
605 codec->cache_sync = 1;
606 return 0;
607 }
608
609 ret = codec->hw_write(codec->control_data, data, 4);
610 if (ret == 4)
611 return 0;
612 if (ret < 0)
613 return ret;
614 else
615 return -EIO;
616}
994dc424 617
f479fd93
DP
618#if defined(CONFIG_SPI_MASTER)
619static int snd_soc_16_16_spi_write(void *control_data, const char *data,
620 int len)
621{
622 struct spi_device *spi = control_data;
623 struct spi_transfer t;
624 struct spi_message m;
625 u8 msg[4];
626
627 if (len <= 0)
628 return 0;
629
630 msg[0] = data[0];
631 msg[1] = data[1];
632 msg[2] = data[2];
633 msg[3] = data[3];
634
635 spi_message_init(&m);
465d7fcc 636 memset(&t, 0, sizeof t);
f479fd93
DP
637
638 t.tx_buf = &msg[0];
639 t.len = len;
640
641 spi_message_add_tail(&t, &m);
642 spi_sync(spi, &m);
643
644 return len;
645}
646#else
647#define snd_soc_16_16_spi_write NULL
648#endif
649
17a52fd6
MB
650static struct {
651 int addr_bits;
652 int data_bits;
afa2f106 653 int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
27ded041 654 int (*spi_write)(void *, const char *, int);
17a52fd6 655 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
afa2f106 656 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
17a52fd6 657} io_types[] = {
63b62ab0
BS
658 {
659 .addr_bits = 4, .data_bits = 12,
660 .write = snd_soc_4_12_write, .read = snd_soc_4_12_read,
661 .spi_write = snd_soc_4_12_spi_write,
662 },
d62ab358
MB
663 {
664 .addr_bits = 7, .data_bits = 9,
665 .write = snd_soc_7_9_write, .read = snd_soc_7_9_read,
8998c899 666 .spi_write = snd_soc_7_9_spi_write,
d62ab358
MB
667 },
668 {
669 .addr_bits = 8, .data_bits = 8,
670 .write = snd_soc_8_8_write, .read = snd_soc_8_8_read,
85dfcdff 671 .i2c_read = snd_soc_8_8_read_i2c,
f479fd93 672 .spi_write = snd_soc_8_8_spi_write,
d62ab358
MB
673 },
674 {
675 .addr_bits = 8, .data_bits = 16,
676 .write = snd_soc_8_16_write, .read = snd_soc_8_16_read,
677 .i2c_read = snd_soc_8_16_read_i2c,
f479fd93 678 .spi_write = snd_soc_8_16_spi_write,
d62ab358 679 },
994dc424
BS
680 {
681 .addr_bits = 16, .data_bits = 8,
682 .write = snd_soc_16_8_write, .read = snd_soc_16_8_read,
683 .i2c_read = snd_soc_16_8_read_i2c,
684 .spi_write = snd_soc_16_8_spi_write,
685 },
bc6552f4
MB
686 {
687 .addr_bits = 16, .data_bits = 16,
688 .write = snd_soc_16_16_write, .read = snd_soc_16_16_read,
689 .i2c_read = snd_soc_16_16_read_i2c,
f479fd93 690 .spi_write = snd_soc_16_16_spi_write,
bc6552f4 691 },
17a52fd6
MB
692};
693
694/**
695 * snd_soc_codec_set_cache_io: Set up standard I/O functions.
696 *
697 * @codec: CODEC to configure.
698 * @type: Type of cache.
699 * @addr_bits: Number of bits of register address data.
700 * @data_bits: Number of bits of data per register.
7084a42b 701 * @control: Control bus used.
17a52fd6
MB
702 *
703 * Register formats are frequently shared between many I2C and SPI
704 * devices. In order to promote code reuse the ASoC core provides
705 * some standard implementations of CODEC read and write operations
706 * which can be set up using this function.
707 *
708 * The caller is responsible for allocating and initialising the
709 * actual cache.
710 *
711 * Note that at present this code cannot be used by CODECs with
712 * volatile registers.
713 */
714int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
7084a42b
MB
715 int addr_bits, int data_bits,
716 enum snd_soc_control_type control)
17a52fd6
MB
717{
718 int i;
719
17a52fd6
MB
720 for (i = 0; i < ARRAY_SIZE(io_types); i++)
721 if (io_types[i].addr_bits == addr_bits &&
722 io_types[i].data_bits == data_bits)
723 break;
724 if (i == ARRAY_SIZE(io_types)) {
725 printk(KERN_ERR
726 "No I/O functions for %d bit address %d bit data\n",
727 addr_bits, data_bits);
728 return -EINVAL;
729 }
730
c3acec26
MB
731 codec->write = io_types[i].write;
732 codec->read = io_types[i].read;
17a52fd6 733
7084a42b
MB
734 switch (control) {
735 case SND_SOC_CUSTOM:
736 break;
737
738 case SND_SOC_I2C:
17244c24 739#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
7084a42b
MB
740 codec->hw_write = (hw_write_t)i2c_master_send;
741#endif
afa2f106
MB
742 if (io_types[i].i2c_read)
743 codec->hw_read = io_types[i].i2c_read;
a6d14342
MB
744
745 codec->control_data = container_of(codec->dev,
746 struct i2c_client,
747 dev);
7084a42b
MB
748 break;
749
750 case SND_SOC_SPI:
27ded041
MB
751 if (io_types[i].spi_write)
752 codec->hw_write = io_types[i].spi_write;
a6d14342
MB
753
754 codec->control_data = container_of(codec->dev,
755 struct spi_device,
756 dev);
7084a42b
MB
757 break;
758 }
759
17a52fd6
MB
760 return 0;
761}
762EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
7a30a3db 763
1321e883
DP
764static bool snd_soc_set_cache_val(void *base, unsigned int idx,
765 unsigned int val, unsigned int word_size)
766{
767 switch (word_size) {
768 case 1: {
769 u8 *cache = base;
770 if (cache[idx] == val)
771 return true;
772 cache[idx] = val;
773 break;
774 }
775 case 2: {
776 u16 *cache = base;
777 if (cache[idx] == val)
778 return true;
779 cache[idx] = val;
780 break;
781 }
782 default:
783 BUG();
784 }
785 return false;
786}
787
788static unsigned int snd_soc_get_cache_val(const void *base, unsigned int idx,
789 unsigned int word_size)
790{
791 switch (word_size) {
792 case 1: {
793 const u8 *cache = base;
794 return cache[idx];
795 }
796 case 2: {
797 const u16 *cache = base;
798 return cache[idx];
799 }
800 default:
801 BUG();
802 }
803 /* unreachable */
804 return -1;
805}
806
a7f387d5
DP
807struct snd_soc_rbtree_node {
808 struct rb_node node;
809 unsigned int reg;
810 unsigned int value;
811 unsigned int defval;
812} __attribute__ ((packed));
813
814struct snd_soc_rbtree_ctx {
815 struct rb_root root;
816};
817
818static struct snd_soc_rbtree_node *snd_soc_rbtree_lookup(
819 struct rb_root *root, unsigned int reg)
820{
821 struct rb_node *node;
822 struct snd_soc_rbtree_node *rbnode;
823
824 node = root->rb_node;
825 while (node) {
826 rbnode = container_of(node, struct snd_soc_rbtree_node, node);
827 if (rbnode->reg < reg)
828 node = node->rb_left;
829 else if (rbnode->reg > reg)
830 node = node->rb_right;
831 else
832 return rbnode;
833 }
834
835 return NULL;
836}
837
a7f387d5
DP
838static int snd_soc_rbtree_insert(struct rb_root *root,
839 struct snd_soc_rbtree_node *rbnode)
840{
841 struct rb_node **new, *parent;
842 struct snd_soc_rbtree_node *rbnode_tmp;
843
844 parent = NULL;
845 new = &root->rb_node;
846 while (*new) {
847 rbnode_tmp = container_of(*new, struct snd_soc_rbtree_node,
848 node);
849 parent = *new;
850 if (rbnode_tmp->reg < rbnode->reg)
851 new = &((*new)->rb_left);
852 else if (rbnode_tmp->reg > rbnode->reg)
853 new = &((*new)->rb_right);
854 else
855 return 0;
856 }
857
858 /* insert the node into the rbtree */
859 rb_link_node(&rbnode->node, parent, new);
860 rb_insert_color(&rbnode->node, root);
861
862 return 1;
863}
864
865static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec)
866{
867 struct snd_soc_rbtree_ctx *rbtree_ctx;
868 struct rb_node *node;
869 struct snd_soc_rbtree_node *rbnode;
870 unsigned int val;
7a33d4ce 871 int ret;
a7f387d5
DP
872
873 rbtree_ctx = codec->reg_cache;
874 for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
875 rbnode = rb_entry(node, struct snd_soc_rbtree_node, node);
876 if (rbnode->value == rbnode->defval)
877 continue;
7a33d4ce
DP
878 ret = snd_soc_cache_read(codec, rbnode->reg, &val);
879 if (ret)
880 return ret;
881 ret = snd_soc_write(codec, rbnode->reg, val);
882 if (ret)
883 return ret;
a7f387d5
DP
884 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
885 rbnode->reg, val);
886 }
887
888 return 0;
889}
890
891static int snd_soc_rbtree_cache_write(struct snd_soc_codec *codec,
892 unsigned int reg, unsigned int value)
893{
894 struct snd_soc_rbtree_ctx *rbtree_ctx;
895 struct snd_soc_rbtree_node *rbnode;
896
897 rbtree_ctx = codec->reg_cache;
898 rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
899 if (rbnode) {
900 if (rbnode->value == value)
901 return 0;
902 rbnode->value = value;
903 } else {
904 /* bail out early, no need to create the rbnode yet */
905 if (!value)
906 return 0;
907 /*
908 * for uninitialized registers whose value is changed
909 * from the default zero, create an rbnode and insert
910 * it into the tree.
911 */
912 rbnode = kzalloc(sizeof *rbnode, GFP_KERNEL);
913 if (!rbnode)
914 return -ENOMEM;
915 rbnode->reg = reg;
916 rbnode->value = value;
917 snd_soc_rbtree_insert(&rbtree_ctx->root, rbnode);
918 }
919
920 return 0;
921}
922
923static int snd_soc_rbtree_cache_read(struct snd_soc_codec *codec,
924 unsigned int reg, unsigned int *value)
925{
926 struct snd_soc_rbtree_ctx *rbtree_ctx;
927 struct snd_soc_rbtree_node *rbnode;
928
929 rbtree_ctx = codec->reg_cache;
930 rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
931 if (rbnode) {
932 *value = rbnode->value;
933 } else {
934 /* uninitialized registers default to 0 */
935 *value = 0;
936 }
937
938 return 0;
939}
940
941static int snd_soc_rbtree_cache_exit(struct snd_soc_codec *codec)
942{
943 struct rb_node *next;
944 struct snd_soc_rbtree_ctx *rbtree_ctx;
945 struct snd_soc_rbtree_node *rbtree_node;
946
947 /* if we've already been called then just return */
948 rbtree_ctx = codec->reg_cache;
949 if (!rbtree_ctx)
950 return 0;
951
952 /* free up the rbtree */
953 next = rb_first(&rbtree_ctx->root);
954 while (next) {
955 rbtree_node = rb_entry(next, struct snd_soc_rbtree_node, node);
956 next = rb_next(&rbtree_node->node);
957 rb_erase(&rbtree_node->node, &rbtree_ctx->root);
958 kfree(rbtree_node);
959 }
960
961 /* release the resources */
962 kfree(codec->reg_cache);
963 codec->reg_cache = NULL;
964
965 return 0;
966}
967
968static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
969{
1321e883 970 struct snd_soc_rbtree_node *rbtree_node;
a7f387d5 971 struct snd_soc_rbtree_ctx *rbtree_ctx;
1321e883
DP
972 unsigned int val;
973 unsigned int word_size;
974 int i;
975 int ret;
a7f387d5
DP
976
977 codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL);
978 if (!codec->reg_cache)
979 return -ENOMEM;
980
981 rbtree_ctx = codec->reg_cache;
982 rbtree_ctx->root = RB_ROOT;
983
3335ddca 984 if (!codec->reg_def_copy)
a7f387d5
DP
985 return 0;
986
1321e883
DP
987 /*
988 * populate the rbtree with the initialized registers. All other
989 * registers will be inserted when they are first modified.
990 */
991 word_size = codec->driver->reg_word_size;
992 for (i = 0; i < codec->driver->reg_cache_size; ++i) {
993 val = snd_soc_get_cache_val(codec->reg_def_copy, i, word_size);
994 if (!val)
995 continue;
996 rbtree_node = kzalloc(sizeof *rbtree_node, GFP_KERNEL);
997 if (!rbtree_node) {
998 ret = -ENOMEM;
999 snd_soc_cache_exit(codec);
1000 break;
1001 }
1002 rbtree_node->reg = i;
1003 rbtree_node->value = val;
1004 rbtree_node->defval = val;
1005 snd_soc_rbtree_insert(&rbtree_ctx->root, rbtree_node);
a7f387d5
DP
1006 }
1007
1008 return 0;
1009}
1010
68d44ee0 1011#ifdef CONFIG_SND_SOC_CACHE_LZO
cc28fb8e
DP
1012struct snd_soc_lzo_ctx {
1013 void *wmem;
1014 void *dst;
1015 const void *src;
1016 size_t src_len;
1017 size_t dst_len;
1018 size_t decompressed_size;
1019 unsigned long *sync_bmp;
1020 int sync_bmp_nbits;
1021};
1022
1023#define LZO_BLOCK_NUM 8
1024static int snd_soc_lzo_block_count(void)
1025{
1026 return LZO_BLOCK_NUM;
1027}
1028
1029static int snd_soc_lzo_prepare(struct snd_soc_lzo_ctx *lzo_ctx)
1030{
1031 lzo_ctx->wmem = kmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
1032 if (!lzo_ctx->wmem)
1033 return -ENOMEM;
1034 return 0;
1035}
1036
1037static int snd_soc_lzo_compress(struct snd_soc_lzo_ctx *lzo_ctx)
1038{
1039 size_t compress_size;
1040 int ret;
1041
1042 ret = lzo1x_1_compress(lzo_ctx->src, lzo_ctx->src_len,
1043 lzo_ctx->dst, &compress_size, lzo_ctx->wmem);
1044 if (ret != LZO_E_OK || compress_size > lzo_ctx->dst_len)
1045 return -EINVAL;
1046 lzo_ctx->dst_len = compress_size;
1047 return 0;
1048}
1049
1050static int snd_soc_lzo_decompress(struct snd_soc_lzo_ctx *lzo_ctx)
1051{
1052 size_t dst_len;
1053 int ret;
1054
1055 dst_len = lzo_ctx->dst_len;
1056 ret = lzo1x_decompress_safe(lzo_ctx->src, lzo_ctx->src_len,
1057 lzo_ctx->dst, &dst_len);
1058 if (ret != LZO_E_OK || dst_len != lzo_ctx->dst_len)
1059 return -EINVAL;
1060 return 0;
1061}
1062
1063static int snd_soc_lzo_compress_cache_block(struct snd_soc_codec *codec,
1064 struct snd_soc_lzo_ctx *lzo_ctx)
1065{
1066 int ret;
1067
1068 lzo_ctx->dst_len = lzo1x_worst_compress(PAGE_SIZE);
1069 lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
1070 if (!lzo_ctx->dst) {
1071 lzo_ctx->dst_len = 0;
1072 return -ENOMEM;
1073 }
1074
1075 ret = snd_soc_lzo_compress(lzo_ctx);
1076 if (ret < 0)
1077 return ret;
1078 return 0;
1079}
1080
1081static int snd_soc_lzo_decompress_cache_block(struct snd_soc_codec *codec,
1082 struct snd_soc_lzo_ctx *lzo_ctx)
1083{
1084 int ret;
1085
1086 lzo_ctx->dst_len = lzo_ctx->decompressed_size;
1087 lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
1088 if (!lzo_ctx->dst) {
1089 lzo_ctx->dst_len = 0;
1090 return -ENOMEM;
1091 }
1092
1093 ret = snd_soc_lzo_decompress(lzo_ctx);
1094 if (ret < 0)
1095 return ret;
1096 return 0;
1097}
1098
1099static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec,
1100 unsigned int reg)
1101{
001ae4c0 1102 const struct snd_soc_codec_driver *codec_drv;
cc28fb8e
DP
1103 size_t reg_size;
1104
1105 codec_drv = codec->driver;
1106 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1107 return (reg * codec_drv->reg_word_size) /
1108 DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count());
1109}
1110
1111static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
1112 unsigned int reg)
1113{
001ae4c0 1114 const struct snd_soc_codec_driver *codec_drv;
cc28fb8e
DP
1115 size_t reg_size;
1116
1117 codec_drv = codec->driver;
1118 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1119 return reg % (DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count()) /
1120 codec_drv->reg_word_size);
1121}
1122
1123static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec)
1124{
001ae4c0 1125 const struct snd_soc_codec_driver *codec_drv;
cc28fb8e
DP
1126 size_t reg_size;
1127
1128 codec_drv = codec->driver;
1129 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1130 return DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count());
1131}
1132
1133static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
1134{
1135 struct snd_soc_lzo_ctx **lzo_blocks;
1136 unsigned int val;
1137 int i;
7a33d4ce 1138 int ret;
cc28fb8e
DP
1139
1140 lzo_blocks = codec->reg_cache;
1141 for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) {
7a33d4ce
DP
1142 ret = snd_soc_cache_read(codec, i, &val);
1143 if (ret)
1144 return ret;
1145 ret = snd_soc_write(codec, i, val);
1146 if (ret)
1147 return ret;
cc28fb8e
DP
1148 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
1149 i, val);
1150 }
1151
1152 return 0;
1153}
1154
1155static int snd_soc_lzo_cache_write(struct snd_soc_codec *codec,
1156 unsigned int reg, unsigned int value)
1157{
1158 struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
1159 int ret, blkindex, blkpos;
1160 size_t blksize, tmp_dst_len;
1161 void *tmp_dst;
1162
1163 /* index of the compressed lzo block */
1164 blkindex = snd_soc_lzo_get_blkindex(codec, reg);
1165 /* register index within the decompressed block */
1166 blkpos = snd_soc_lzo_get_blkpos(codec, reg);
1167 /* size of the compressed block */
1168 blksize = snd_soc_lzo_get_blksize(codec);
1169 lzo_blocks = codec->reg_cache;
1170 lzo_block = lzo_blocks[blkindex];
1171
1172 /* save the pointer and length of the compressed block */
1173 tmp_dst = lzo_block->dst;
1174 tmp_dst_len = lzo_block->dst_len;
1175
1176 /* prepare the source to be the compressed block */
1177 lzo_block->src = lzo_block->dst;
1178 lzo_block->src_len = lzo_block->dst_len;
1179
1180 /* decompress the block */
1181 ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
1182 if (ret < 0) {
1183 kfree(lzo_block->dst);
1184 goto out;
1185 }
1186
1187 /* write the new value to the cache */
1321e883
DP
1188 if (snd_soc_set_cache_val(lzo_block->dst, blkpos, value,
1189 codec->driver->reg_word_size)) {
1190 kfree(lzo_block->dst);
1191 goto out;
cc28fb8e
DP
1192 }
1193
1194 /* prepare the source to be the decompressed block */
1195 lzo_block->src = lzo_block->dst;
1196 lzo_block->src_len = lzo_block->dst_len;
1197
1198 /* compress the block */
1199 ret = snd_soc_lzo_compress_cache_block(codec, lzo_block);
1200 if (ret < 0) {
1201 kfree(lzo_block->dst);
1202 kfree(lzo_block->src);
1203 goto out;
1204 }
1205
1206 /* set the bit so we know we have to sync this register */
1207 set_bit(reg, lzo_block->sync_bmp);
1208 kfree(tmp_dst);
1209 kfree(lzo_block->src);
1210 return 0;
1211out:
1212 lzo_block->dst = tmp_dst;
1213 lzo_block->dst_len = tmp_dst_len;
1214 return ret;
1215}
1216
1217static int snd_soc_lzo_cache_read(struct snd_soc_codec *codec,
1218 unsigned int reg, unsigned int *value)
1219{
1220 struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
1221 int ret, blkindex, blkpos;
1222 size_t blksize, tmp_dst_len;
1223 void *tmp_dst;
1224
1225 *value = 0;
1226 /* index of the compressed lzo block */
1227 blkindex = snd_soc_lzo_get_blkindex(codec, reg);
1228 /* register index within the decompressed block */
1229 blkpos = snd_soc_lzo_get_blkpos(codec, reg);
1230 /* size of the compressed block */
1231 blksize = snd_soc_lzo_get_blksize(codec);
1232 lzo_blocks = codec->reg_cache;
1233 lzo_block = lzo_blocks[blkindex];
1234
1235 /* save the pointer and length of the compressed block */
1236 tmp_dst = lzo_block->dst;
1237 tmp_dst_len = lzo_block->dst_len;
1238
1239 /* prepare the source to be the compressed block */
1240 lzo_block->src = lzo_block->dst;
1241 lzo_block->src_len = lzo_block->dst_len;
1242
1243 /* decompress the block */
1244 ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
1321e883 1245 if (ret >= 0)
cc28fb8e 1246 /* fetch the value from the cache */
1321e883
DP
1247 *value = snd_soc_get_cache_val(lzo_block->dst, blkpos,
1248 codec->driver->reg_word_size);
cc28fb8e
DP
1249
1250 kfree(lzo_block->dst);
1251 /* restore the pointer and length of the compressed block */
1252 lzo_block->dst = tmp_dst;
1253 lzo_block->dst_len = tmp_dst_len;
1254 return 0;
1255}
1256
1257static int snd_soc_lzo_cache_exit(struct snd_soc_codec *codec)
1258{
1259 struct snd_soc_lzo_ctx **lzo_blocks;
1260 int i, blkcount;
1261
1262 lzo_blocks = codec->reg_cache;
1263 if (!lzo_blocks)
1264 return 0;
1265
1266 blkcount = snd_soc_lzo_block_count();
1267 /*
1268 * the pointer to the bitmap used for syncing the cache
1269 * is shared amongst all lzo_blocks. Ensure it is freed
1270 * only once.
1271 */
1272 if (lzo_blocks[0])
1273 kfree(lzo_blocks[0]->sync_bmp);
1274 for (i = 0; i < blkcount; ++i) {
1275 if (lzo_blocks[i]) {
1276 kfree(lzo_blocks[i]->wmem);
1277 kfree(lzo_blocks[i]->dst);
1278 }
1279 /* each lzo_block is a pointer returned by kmalloc or NULL */
1280 kfree(lzo_blocks[i]);
1281 }
1282 kfree(lzo_blocks);
1283 codec->reg_cache = NULL;
1284 return 0;
1285}
1286
1287static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
1288{
1289 struct snd_soc_lzo_ctx **lzo_blocks;
1290 size_t reg_size, bmp_size;
001ae4c0 1291 const struct snd_soc_codec_driver *codec_drv;
cc28fb8e
DP
1292 int ret, tofree, i, blksize, blkcount;
1293 const char *p, *end;
1294 unsigned long *sync_bmp;
1295
1296 ret = 0;
1297 codec_drv = codec->driver;
1298 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1299
1300 /*
1301 * If we have not been given a default register cache
1302 * then allocate a dummy zero-ed out region, compress it
1303 * and remember to free it afterwards.
1304 */
1305 tofree = 0;
3335ddca 1306 if (!codec->reg_def_copy)
cc28fb8e
DP
1307 tofree = 1;
1308
3335ddca
DP
1309 if (!codec->reg_def_copy) {
1310 codec->reg_def_copy = kzalloc(reg_size,
cc28fb8e 1311 GFP_KERNEL);
3335ddca 1312 if (!codec->reg_def_copy)
cc28fb8e
DP
1313 return -ENOMEM;
1314 }
1315
1316 blkcount = snd_soc_lzo_block_count();
1317 codec->reg_cache = kzalloc(blkcount * sizeof *lzo_blocks,
1318 GFP_KERNEL);
1319 if (!codec->reg_cache) {
1320 ret = -ENOMEM;
1321 goto err_tofree;
1322 }
1323 lzo_blocks = codec->reg_cache;
1324
1325 /*
1326 * allocate a bitmap to be used when syncing the cache with
1327 * the hardware. Each time a register is modified, the corresponding
1328 * bit is set in the bitmap, so we know that we have to sync
1329 * that register.
1330 */
1331 bmp_size = codec_drv->reg_cache_size;
465d7fcc 1332 sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof(long),
cc28fb8e
DP
1333 GFP_KERNEL);
1334 if (!sync_bmp) {
1335 ret = -ENOMEM;
1336 goto err;
1337 }
09c74a9d 1338 bitmap_zero(sync_bmp, bmp_size);
cc28fb8e
DP
1339
1340 /* allocate the lzo blocks and initialize them */
1341 for (i = 0; i < blkcount; ++i) {
1342 lzo_blocks[i] = kzalloc(sizeof **lzo_blocks,
1343 GFP_KERNEL);
1344 if (!lzo_blocks[i]) {
1345 kfree(sync_bmp);
1346 ret = -ENOMEM;
1347 goto err;
1348 }
1349 lzo_blocks[i]->sync_bmp = sync_bmp;
1350 lzo_blocks[i]->sync_bmp_nbits = reg_size;
1351 /* alloc the working space for the compressed block */
1352 ret = snd_soc_lzo_prepare(lzo_blocks[i]);
1353 if (ret < 0)
1354 goto err;
1355 }
1356
1357 blksize = snd_soc_lzo_get_blksize(codec);
3335ddca
DP
1358 p = codec->reg_def_copy;
1359 end = codec->reg_def_copy + reg_size;
cc28fb8e
DP
1360 /* compress the register map and fill the lzo blocks */
1361 for (i = 0; i < blkcount; ++i, p += blksize) {
1362 lzo_blocks[i]->src = p;
1363 if (p + blksize > end)
1364 lzo_blocks[i]->src_len = end - p;
1365 else
1366 lzo_blocks[i]->src_len = blksize;
1367 ret = snd_soc_lzo_compress_cache_block(codec,
1368 lzo_blocks[i]);
1369 if (ret < 0)
1370 goto err;
1371 lzo_blocks[i]->decompressed_size =
1372 lzo_blocks[i]->src_len;
1373 }
1374
3335ddca
DP
1375 if (tofree) {
1376 kfree(codec->reg_def_copy);
1377 codec->reg_def_copy = NULL;
1378 }
cc28fb8e
DP
1379 return 0;
1380err:
1381 snd_soc_cache_exit(codec);
1382err_tofree:
3335ddca
DP
1383 if (tofree) {
1384 kfree(codec->reg_def_copy);
1385 codec->reg_def_copy = NULL;
1386 }
cc28fb8e
DP
1387 return ret;
1388}
68d44ee0 1389#endif
cc28fb8e 1390
7a30a3db
DP
1391static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
1392{
1393 int i;
7a33d4ce 1394 int ret;
001ae4c0 1395 const struct snd_soc_codec_driver *codec_drv;
7a30a3db
DP
1396 unsigned int val;
1397
1398 codec_drv = codec->driver;
1399 for (i = 0; i < codec_drv->reg_cache_size; ++i) {
7a33d4ce
DP
1400 ret = snd_soc_cache_read(codec, i, &val);
1401 if (ret)
1402 return ret;
1321e883
DP
1403 if (codec_drv->reg_cache_default)
1404 if (snd_soc_get_cache_val(codec_drv->reg_cache_default,
1405 i, codec_drv->reg_word_size) == val)
1406 continue;
7a33d4ce
DP
1407 ret = snd_soc_write(codec, i, val);
1408 if (ret)
1409 return ret;
7a30a3db
DP
1410 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
1411 i, val);
1412 }
1413 return 0;
1414}
1415
1416static int snd_soc_flat_cache_write(struct snd_soc_codec *codec,
1417 unsigned int reg, unsigned int value)
1418{
1321e883
DP
1419 snd_soc_set_cache_val(codec->reg_cache, reg, value,
1420 codec->driver->reg_word_size);
7a30a3db
DP
1421 return 0;
1422}
1423
1424static int snd_soc_flat_cache_read(struct snd_soc_codec *codec,
1425 unsigned int reg, unsigned int *value)
1426{
1321e883
DP
1427 *value = snd_soc_get_cache_val(codec->reg_cache, reg,
1428 codec->driver->reg_word_size);
7a30a3db
DP
1429 return 0;
1430}
1431
1432static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec)
1433{
1434 if (!codec->reg_cache)
1435 return 0;
1436 kfree(codec->reg_cache);
1437 codec->reg_cache = NULL;
1438 return 0;
1439}
1440
1441static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
1442{
001ae4c0 1443 const struct snd_soc_codec_driver *codec_drv;
7a30a3db
DP
1444 size_t reg_size;
1445
1446 codec_drv = codec->driver;
1447 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1448
3335ddca
DP
1449 /*
1450 * for flat compression, we don't need to keep a copy of the
1451 * original defaults register cache as it will definitely not
1452 * be marked as __devinitconst
1453 */
1454 kfree(codec->reg_def_copy);
1455 codec->reg_def_copy = NULL;
1456
7a30a3db
DP
1457 if (codec_drv->reg_cache_default)
1458 codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
1459 reg_size, GFP_KERNEL);
1460 else
1461 codec->reg_cache = kzalloc(reg_size, GFP_KERNEL);
1462 if (!codec->reg_cache)
1463 return -ENOMEM;
1464
1465 return 0;
1466}
1467
1468/* an array of all supported compression types */
1469static const struct snd_soc_cache_ops cache_types[] = {
be4fcddd 1470 /* Flat *must* be the first entry for fallback */
7a30a3db 1471 {
df0701bb 1472 .id = SND_SOC_FLAT_COMPRESSION,
0d735eaa 1473 .name = "flat",
7a30a3db
DP
1474 .init = snd_soc_flat_cache_init,
1475 .exit = snd_soc_flat_cache_exit,
1476 .read = snd_soc_flat_cache_read,
1477 .write = snd_soc_flat_cache_write,
1478 .sync = snd_soc_flat_cache_sync
cc28fb8e 1479 },
68d44ee0 1480#ifdef CONFIG_SND_SOC_CACHE_LZO
cc28fb8e
DP
1481 {
1482 .id = SND_SOC_LZO_COMPRESSION,
0d735eaa 1483 .name = "LZO",
cc28fb8e
DP
1484 .init = snd_soc_lzo_cache_init,
1485 .exit = snd_soc_lzo_cache_exit,
1486 .read = snd_soc_lzo_cache_read,
1487 .write = snd_soc_lzo_cache_write,
1488 .sync = snd_soc_lzo_cache_sync
a7f387d5 1489 },
68d44ee0 1490#endif
a7f387d5
DP
1491 {
1492 .id = SND_SOC_RBTREE_COMPRESSION,
0d735eaa 1493 .name = "rbtree",
a7f387d5
DP
1494 .init = snd_soc_rbtree_cache_init,
1495 .exit = snd_soc_rbtree_cache_exit,
1496 .read = snd_soc_rbtree_cache_read,
1497 .write = snd_soc_rbtree_cache_write,
1498 .sync = snd_soc_rbtree_cache_sync
7a30a3db
DP
1499 }
1500};
1501
1502int snd_soc_cache_init(struct snd_soc_codec *codec)
1503{
1504 int i;
1505
1506 for (i = 0; i < ARRAY_SIZE(cache_types); ++i)
23bbce34 1507 if (cache_types[i].id == codec->compress_type)
7a30a3db 1508 break;
be4fcddd
MB
1509
1510 /* Fall back to flat compression */
7a30a3db 1511 if (i == ARRAY_SIZE(cache_types)) {
be4fcddd
MB
1512 dev_warn(codec->dev, "Could not match compress type: %d\n",
1513 codec->compress_type);
1514 i = 0;
7a30a3db
DP
1515 }
1516
1517 mutex_init(&codec->cache_rw_mutex);
1518 codec->cache_ops = &cache_types[i];
1519
0d735eaa
DP
1520 if (codec->cache_ops->init) {
1521 if (codec->cache_ops->name)
1522 dev_dbg(codec->dev, "Initializing %s cache for %s codec\n",
1523 codec->cache_ops->name, codec->name);
7a30a3db 1524 return codec->cache_ops->init(codec);
0d735eaa 1525 }
7a30a3db
DP
1526 return -EINVAL;
1527}
1528
1529/*
1530 * NOTE: keep in mind that this function might be called
1531 * multiple times.
1532 */
1533int snd_soc_cache_exit(struct snd_soc_codec *codec)
1534{
0d735eaa
DP
1535 if (codec->cache_ops && codec->cache_ops->exit) {
1536 if (codec->cache_ops->name)
1537 dev_dbg(codec->dev, "Destroying %s cache for %s codec\n",
1538 codec->cache_ops->name, codec->name);
7a30a3db 1539 return codec->cache_ops->exit(codec);
0d735eaa 1540 }
7a30a3db
DP
1541 return -EINVAL;
1542}
1543
1544/**
1545 * snd_soc_cache_read: Fetch the value of a given register from the cache.
1546 *
1547 * @codec: CODEC to configure.
1548 * @reg: The register index.
1549 * @value: The value to be returned.
1550 */
1551int snd_soc_cache_read(struct snd_soc_codec *codec,
1552 unsigned int reg, unsigned int *value)
1553{
1554 int ret;
1555
1556 mutex_lock(&codec->cache_rw_mutex);
1557
1558 if (value && codec->cache_ops && codec->cache_ops->read) {
1559 ret = codec->cache_ops->read(codec, reg, value);
1560 mutex_unlock(&codec->cache_rw_mutex);
1561 return ret;
1562 }
1563
1564 mutex_unlock(&codec->cache_rw_mutex);
1565 return -EINVAL;
1566}
1567EXPORT_SYMBOL_GPL(snd_soc_cache_read);
1568
1569/**
1570 * snd_soc_cache_write: Set the value of a given register in the cache.
1571 *
1572 * @codec: CODEC to configure.
1573 * @reg: The register index.
1574 * @value: The new register value.
1575 */
1576int snd_soc_cache_write(struct snd_soc_codec *codec,
1577 unsigned int reg, unsigned int value)
1578{
1579 int ret;
1580
1581 mutex_lock(&codec->cache_rw_mutex);
1582
1583 if (codec->cache_ops && codec->cache_ops->write) {
1584 ret = codec->cache_ops->write(codec, reg, value);
1585 mutex_unlock(&codec->cache_rw_mutex);
1586 return ret;
1587 }
1588
1589 mutex_unlock(&codec->cache_rw_mutex);
1590 return -EINVAL;
1591}
1592EXPORT_SYMBOL_GPL(snd_soc_cache_write);
1593
1594/**
1595 * snd_soc_cache_sync: Sync the register cache with the hardware.
1596 *
1597 * @codec: CODEC to configure.
1598 *
1599 * Any registers that should not be synced should be marked as
1600 * volatile. In general drivers can choose not to use the provided
1601 * syncing functionality if they so require.
1602 */
1603int snd_soc_cache_sync(struct snd_soc_codec *codec)
1604{
1605 int ret;
1606
1607 if (!codec->cache_sync) {
1608 return 0;
1609 }
1610
1611 if (codec->cache_ops && codec->cache_ops->sync) {
0d735eaa
DP
1612 if (codec->cache_ops->name)
1613 dev_dbg(codec->dev, "Syncing %s cache for %s codec\n",
1614 codec->cache_ops->name, codec->name);
7a30a3db
DP
1615 ret = codec->cache_ops->sync(codec);
1616 if (!ret)
1617 codec->cache_sync = 0;
1618 return ret;
1619 }
1620
1621 return -EINVAL;
1622}
1623EXPORT_SYMBOL_GPL(snd_soc_cache_sync);
This page took 0.137757 seconds and 5 git commands to generate.