Merge branch 'media_fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
[cris-mirror.git] / sound / soc / soc-cache.c
blob8c2a21a978ac3551b2113b0640178f75ff8612ac
1 /*
2 * soc-cache.c -- ASoC register cache helpers
4 * Copyright 2009 Wolfson Microelectronics PLC.
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
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.
14 #include <linux/i2c.h>
15 #include <linux/spi/spi.h>
16 #include <sound/soc.h>
17 #include <linux/lzo.h>
18 #include <linux/bitmap.h>
19 #include <linux/rbtree.h>
21 static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
22 unsigned int reg)
24 int ret;
25 unsigned int val;
27 if (reg >= codec->driver->reg_cache_size ||
28 snd_soc_codec_volatile_register(codec, reg)) {
29 if (codec->cache_only)
30 return -1;
32 BUG_ON(!codec->hw_read);
33 return codec->hw_read(codec, reg);
36 ret = snd_soc_cache_read(codec, reg, &val);
37 if (ret < 0)
38 return -1;
39 return val;
42 static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
43 unsigned int value)
45 u8 data[2];
46 int ret;
48 data[0] = (reg << 4) | ((value >> 8) & 0x000f);
49 data[1] = value & 0x00ff;
51 if (!snd_soc_codec_volatile_register(codec, reg) &&
52 reg < codec->driver->reg_cache_size) {
53 ret = snd_soc_cache_write(codec, reg, value);
54 if (ret < 0)
55 return -1;
58 if (codec->cache_only) {
59 codec->cache_sync = 1;
60 return 0;
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;
72 #if defined(CONFIG_SPI_MASTER)
73 static int snd_soc_4_12_spi_write(void *control_data, const char *data,
74 int len)
76 struct spi_device *spi = control_data;
77 struct spi_transfer t;
78 struct spi_message m;
79 u8 msg[2];
81 if (len <= 0)
82 return 0;
84 msg[0] = data[1];
85 msg[1] = data[0];
87 spi_message_init(&m);
88 memset(&t, 0, sizeof t);
90 t.tx_buf = &msg[0];
91 t.len = len;
93 spi_message_add_tail(&t, &m);
94 spi_sync(spi, &m);
96 return len;
98 #else
99 #define snd_soc_4_12_spi_write NULL
100 #endif
102 static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
103 unsigned int reg)
105 int ret;
106 unsigned int val;
108 if (reg >= codec->driver->reg_cache_size ||
109 snd_soc_codec_volatile_register(codec, reg)) {
110 if (codec->cache_only)
111 return -1;
113 BUG_ON(!codec->hw_read);
114 return codec->hw_read(codec, reg);
117 ret = snd_soc_cache_read(codec, reg, &val);
118 if (ret < 0)
119 return -1;
120 return val;
123 static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
124 unsigned int value)
126 u8 data[2];
127 int ret;
129 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
130 data[1] = value & 0x00ff;
132 if (!snd_soc_codec_volatile_register(codec, reg) &&
133 reg < codec->driver->reg_cache_size) {
134 ret = snd_soc_cache_write(codec, reg, value);
135 if (ret < 0)
136 return -1;
139 if (codec->cache_only) {
140 codec->cache_sync = 1;
141 return 0;
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;
153 #if defined(CONFIG_SPI_MASTER)
154 static int snd_soc_7_9_spi_write(void *control_data, const char *data,
155 int len)
157 struct spi_device *spi = control_data;
158 struct spi_transfer t;
159 struct spi_message m;
160 u8 msg[2];
162 if (len <= 0)
163 return 0;
165 msg[0] = data[0];
166 msg[1] = data[1];
168 spi_message_init(&m);
169 memset(&t, 0, sizeof t);
171 t.tx_buf = &msg[0];
172 t.len = len;
174 spi_message_add_tail(&t, &m);
175 spi_sync(spi, &m);
177 return len;
179 #else
180 #define snd_soc_7_9_spi_write NULL
181 #endif
183 static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
184 unsigned int value)
186 u8 data[2];
187 int ret;
189 reg &= 0xff;
190 data[0] = reg;
191 data[1] = value & 0xff;
193 if (!snd_soc_codec_volatile_register(codec, reg) &&
194 reg < codec->driver->reg_cache_size) {
195 ret = snd_soc_cache_write(codec, reg, value);
196 if (ret < 0)
197 return -1;
200 if (codec->cache_only) {
201 codec->cache_sync = 1;
202 return 0;
205 if (codec->hw_write(codec->control_data, data, 2) == 2)
206 return 0;
207 else
208 return -EIO;
211 static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
212 unsigned int reg)
214 int ret;
215 unsigned int val;
217 reg &= 0xff;
218 if (reg >= codec->driver->reg_cache_size ||
219 snd_soc_codec_volatile_register(codec, reg)) {
220 if (codec->cache_only)
221 return -1;
223 BUG_ON(!codec->hw_read);
224 return codec->hw_read(codec, reg);
227 ret = snd_soc_cache_read(codec, reg, &val);
228 if (ret < 0)
229 return -1;
230 return val;
233 #if defined(CONFIG_SPI_MASTER)
234 static int snd_soc_8_8_spi_write(void *control_data, const char *data,
235 int len)
237 struct spi_device *spi = control_data;
238 struct spi_transfer t;
239 struct spi_message m;
240 u8 msg[2];
242 if (len <= 0)
243 return 0;
245 msg[0] = data[0];
246 msg[1] = data[1];
248 spi_message_init(&m);
249 memset(&t, 0, sizeof t);
251 t.tx_buf = &msg[0];
252 t.len = len;
254 spi_message_add_tail(&t, &m);
255 spi_sync(spi, &m);
257 return len;
259 #else
260 #define snd_soc_8_8_spi_write NULL
261 #endif
263 static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
264 unsigned int value)
266 u8 data[3];
267 int ret;
269 data[0] = reg;
270 data[1] = (value >> 8) & 0xff;
271 data[2] = value & 0xff;
273 if (!snd_soc_codec_volatile_register(codec, reg) &&
274 reg < codec->driver->reg_cache_size) {
275 ret = snd_soc_cache_write(codec, reg, value);
276 if (ret < 0)
277 return -1;
280 if (codec->cache_only) {
281 codec->cache_sync = 1;
282 return 0;
285 if (codec->hw_write(codec->control_data, data, 3) == 3)
286 return 0;
287 else
288 return -EIO;
291 static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
292 unsigned int reg)
294 int ret;
295 unsigned int val;
297 if (reg >= codec->driver->reg_cache_size ||
298 snd_soc_codec_volatile_register(codec, reg)) {
299 if (codec->cache_only)
300 return -1;
302 BUG_ON(!codec->hw_read);
303 return codec->hw_read(codec, reg);
306 ret = snd_soc_cache_read(codec, reg, &val);
307 if (ret < 0)
308 return -1;
309 return val;
312 #if defined(CONFIG_SPI_MASTER)
313 static int snd_soc_8_16_spi_write(void *control_data, const char *data,
314 int len)
316 struct spi_device *spi = control_data;
317 struct spi_transfer t;
318 struct spi_message m;
319 u8 msg[3];
321 if (len <= 0)
322 return 0;
324 msg[0] = data[0];
325 msg[1] = data[1];
326 msg[2] = data[2];
328 spi_message_init(&m);
329 memset(&t, 0, sizeof t);
331 t.tx_buf = &msg[0];
332 t.len = len;
334 spi_message_add_tail(&t, &m);
335 spi_sync(spi, &m);
337 return len;
339 #else
340 #define snd_soc_8_16_spi_write NULL
341 #endif
343 #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
344 static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
345 unsigned int r)
347 struct i2c_msg xfer[2];
348 u8 reg = r;
349 u8 data;
350 int ret;
351 struct i2c_client *client = codec->control_data;
353 /* Write register */
354 xfer[0].addr = client->addr;
355 xfer[0].flags = 0;
356 xfer[0].len = 1;
357 xfer[0].buf = &reg;
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;
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;
371 return data;
373 #else
374 #define snd_soc_8_8_read_i2c NULL
375 #endif
377 #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
378 static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
379 unsigned int r)
381 struct i2c_msg xfer[2];
382 u8 reg = r;
383 u16 data;
384 int ret;
385 struct i2c_client *client = codec->control_data;
387 /* Write register */
388 xfer[0].addr = client->addr;
389 xfer[0].flags = 0;
390 xfer[0].len = 1;
391 xfer[0].buf = &reg;
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;
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;
405 return (data >> 8) | ((data & 0xff) << 8);
407 #else
408 #define snd_soc_8_16_read_i2c NULL
409 #endif
411 #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
412 static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
413 unsigned int r)
415 struct i2c_msg xfer[2];
416 u16 reg = r;
417 u8 data;
418 int ret;
419 struct i2c_client *client = codec->control_data;
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;
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;
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;
439 return data;
441 #else
442 #define snd_soc_16_8_read_i2c NULL
443 #endif
445 static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
446 unsigned int reg)
448 int ret;
449 unsigned int val;
451 reg &= 0xff;
452 if (reg >= codec->driver->reg_cache_size ||
453 snd_soc_codec_volatile_register(codec, reg)) {
454 if (codec->cache_only)
455 return -1;
457 BUG_ON(!codec->hw_read);
458 return codec->hw_read(codec, reg);
461 ret = snd_soc_cache_read(codec, reg, &val);
462 if (ret < 0)
463 return -1;
464 return val;
467 static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
468 unsigned int value)
470 u8 data[3];
471 int ret;
473 data[0] = (reg >> 8) & 0xff;
474 data[1] = reg & 0xff;
475 data[2] = value;
477 reg &= 0xff;
478 if (!snd_soc_codec_volatile_register(codec, reg) &&
479 reg < codec->driver->reg_cache_size) {
480 ret = snd_soc_cache_write(codec, reg, value);
481 if (ret < 0)
482 return -1;
485 if (codec->cache_only) {
486 codec->cache_sync = 1;
487 return 0;
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;
499 #if defined(CONFIG_SPI_MASTER)
500 static int snd_soc_16_8_spi_write(void *control_data, const char *data,
501 int len)
503 struct spi_device *spi = control_data;
504 struct spi_transfer t;
505 struct spi_message m;
506 u8 msg[3];
508 if (len <= 0)
509 return 0;
511 msg[0] = data[0];
512 msg[1] = data[1];
513 msg[2] = data[2];
515 spi_message_init(&m);
516 memset(&t, 0, sizeof t);
518 t.tx_buf = &msg[0];
519 t.len = len;
521 spi_message_add_tail(&t, &m);
522 spi_sync(spi, &m);
524 return len;
526 #else
527 #define snd_soc_16_8_spi_write NULL
528 #endif
530 #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
531 static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
532 unsigned int r)
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;
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;
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;
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;
558 return be16_to_cpu(data);
560 #else
561 #define snd_soc_16_16_read_i2c NULL
562 #endif
564 static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
565 unsigned int reg)
567 int ret;
568 unsigned int val;
570 if (reg >= codec->driver->reg_cache_size ||
571 snd_soc_codec_volatile_register(codec, reg)) {
572 if (codec->cache_only)
573 return -1;
575 BUG_ON(!codec->hw_read);
576 return codec->hw_read(codec, reg);
579 ret = snd_soc_cache_read(codec, reg, &val);
580 if (ret < 0)
581 return -1;
583 return val;
586 static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
587 unsigned int value)
589 u8 data[4];
590 int ret;
592 data[0] = (reg >> 8) & 0xff;
593 data[1] = reg & 0xff;
594 data[2] = (value >> 8) & 0xff;
595 data[3] = value & 0xff;
597 if (!snd_soc_codec_volatile_register(codec, reg) &&
598 reg < codec->driver->reg_cache_size) {
599 ret = snd_soc_cache_write(codec, reg, value);
600 if (ret < 0)
601 return -1;
604 if (codec->cache_only) {
605 codec->cache_sync = 1;
606 return 0;
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;
618 #if defined(CONFIG_SPI_MASTER)
619 static int snd_soc_16_16_spi_write(void *control_data, const char *data,
620 int len)
622 struct spi_device *spi = control_data;
623 struct spi_transfer t;
624 struct spi_message m;
625 u8 msg[4];
627 if (len <= 0)
628 return 0;
630 msg[0] = data[0];
631 msg[1] = data[1];
632 msg[2] = data[2];
633 msg[3] = data[3];
635 spi_message_init(&m);
636 memset(&t, 0, sizeof t);
638 t.tx_buf = &msg[0];
639 t.len = len;
641 spi_message_add_tail(&t, &m);
642 spi_sync(spi, &m);
644 return len;
646 #else
647 #define snd_soc_16_16_spi_write NULL
648 #endif
650 static struct {
651 int addr_bits;
652 int data_bits;
653 int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
654 int (*spi_write)(void *, const char *, int);
655 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
656 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
657 } io_types[] = {
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,
664 .addr_bits = 7, .data_bits = 9,
665 .write = snd_soc_7_9_write, .read = snd_soc_7_9_read,
666 .spi_write = snd_soc_7_9_spi_write,
669 .addr_bits = 8, .data_bits = 8,
670 .write = snd_soc_8_8_write, .read = snd_soc_8_8_read,
671 .i2c_read = snd_soc_8_8_read_i2c,
672 .spi_write = snd_soc_8_8_spi_write,
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,
678 .spi_write = snd_soc_8_16_spi_write,
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,
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,
690 .spi_write = snd_soc_16_16_spi_write,
695 * snd_soc_codec_set_cache_io: Set up standard I/O functions.
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.
701 * @control: Control bus used.
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.
708 * The caller is responsible for allocating and initialising the
709 * actual cache.
711 * Note that at present this code cannot be used by CODECs with
712 * volatile registers.
714 int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
715 int addr_bits, int data_bits,
716 enum snd_soc_control_type control)
718 int i;
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;
731 codec->write = io_types[i].write;
732 codec->read = io_types[i].read;
734 switch (control) {
735 case SND_SOC_CUSTOM:
736 break;
738 case SND_SOC_I2C:
739 #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
740 codec->hw_write = (hw_write_t)i2c_master_send;
741 #endif
742 if (io_types[i].i2c_read)
743 codec->hw_read = io_types[i].i2c_read;
745 codec->control_data = container_of(codec->dev,
746 struct i2c_client,
747 dev);
748 break;
750 case SND_SOC_SPI:
751 if (io_types[i].spi_write)
752 codec->hw_write = io_types[i].spi_write;
754 codec->control_data = container_of(codec->dev,
755 struct spi_device,
756 dev);
757 break;
760 return 0;
762 EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
764 struct snd_soc_rbtree_node {
765 struct rb_node node;
766 unsigned int reg;
767 unsigned int value;
768 unsigned int defval;
769 } __attribute__ ((packed));
771 struct snd_soc_rbtree_ctx {
772 struct rb_root root;
775 static struct snd_soc_rbtree_node *snd_soc_rbtree_lookup(
776 struct rb_root *root, unsigned int reg)
778 struct rb_node *node;
779 struct snd_soc_rbtree_node *rbnode;
781 node = root->rb_node;
782 while (node) {
783 rbnode = container_of(node, struct snd_soc_rbtree_node, node);
784 if (rbnode->reg < reg)
785 node = node->rb_left;
786 else if (rbnode->reg > reg)
787 node = node->rb_right;
788 else
789 return rbnode;
792 return NULL;
795 static int snd_soc_rbtree_insert(struct rb_root *root,
796 struct snd_soc_rbtree_node *rbnode)
798 struct rb_node **new, *parent;
799 struct snd_soc_rbtree_node *rbnode_tmp;
801 parent = NULL;
802 new = &root->rb_node;
803 while (*new) {
804 rbnode_tmp = container_of(*new, struct snd_soc_rbtree_node,
805 node);
806 parent = *new;
807 if (rbnode_tmp->reg < rbnode->reg)
808 new = &((*new)->rb_left);
809 else if (rbnode_tmp->reg > rbnode->reg)
810 new = &((*new)->rb_right);
811 else
812 return 0;
815 /* insert the node into the rbtree */
816 rb_link_node(&rbnode->node, parent, new);
817 rb_insert_color(&rbnode->node, root);
819 return 1;
822 static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec)
824 struct snd_soc_rbtree_ctx *rbtree_ctx;
825 struct rb_node *node;
826 struct snd_soc_rbtree_node *rbnode;
827 unsigned int val;
828 int ret;
830 rbtree_ctx = codec->reg_cache;
831 for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
832 rbnode = rb_entry(node, struct snd_soc_rbtree_node, node);
833 if (rbnode->value == rbnode->defval)
834 continue;
835 ret = snd_soc_cache_read(codec, rbnode->reg, &val);
836 if (ret)
837 return ret;
838 ret = snd_soc_write(codec, rbnode->reg, val);
839 if (ret)
840 return ret;
841 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
842 rbnode->reg, val);
845 return 0;
848 static int snd_soc_rbtree_cache_write(struct snd_soc_codec *codec,
849 unsigned int reg, unsigned int value)
851 struct snd_soc_rbtree_ctx *rbtree_ctx;
852 struct snd_soc_rbtree_node *rbnode;
854 rbtree_ctx = codec->reg_cache;
855 rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
856 if (rbnode) {
857 if (rbnode->value == value)
858 return 0;
859 rbnode->value = value;
860 } else {
861 /* bail out early, no need to create the rbnode yet */
862 if (!value)
863 return 0;
865 * for uninitialized registers whose value is changed
866 * from the default zero, create an rbnode and insert
867 * it into the tree.
869 rbnode = kzalloc(sizeof *rbnode, GFP_KERNEL);
870 if (!rbnode)
871 return -ENOMEM;
872 rbnode->reg = reg;
873 rbnode->value = value;
874 snd_soc_rbtree_insert(&rbtree_ctx->root, rbnode);
877 return 0;
880 static int snd_soc_rbtree_cache_read(struct snd_soc_codec *codec,
881 unsigned int reg, unsigned int *value)
883 struct snd_soc_rbtree_ctx *rbtree_ctx;
884 struct snd_soc_rbtree_node *rbnode;
886 rbtree_ctx = codec->reg_cache;
887 rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
888 if (rbnode) {
889 *value = rbnode->value;
890 } else {
891 /* uninitialized registers default to 0 */
892 *value = 0;
895 return 0;
898 static int snd_soc_rbtree_cache_exit(struct snd_soc_codec *codec)
900 struct rb_node *next;
901 struct snd_soc_rbtree_ctx *rbtree_ctx;
902 struct snd_soc_rbtree_node *rbtree_node;
904 /* if we've already been called then just return */
905 rbtree_ctx = codec->reg_cache;
906 if (!rbtree_ctx)
907 return 0;
909 /* free up the rbtree */
910 next = rb_first(&rbtree_ctx->root);
911 while (next) {
912 rbtree_node = rb_entry(next, struct snd_soc_rbtree_node, node);
913 next = rb_next(&rbtree_node->node);
914 rb_erase(&rbtree_node->node, &rbtree_ctx->root);
915 kfree(rbtree_node);
918 /* release the resources */
919 kfree(codec->reg_cache);
920 codec->reg_cache = NULL;
922 return 0;
925 static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
927 struct snd_soc_rbtree_ctx *rbtree_ctx;
929 codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL);
930 if (!codec->reg_cache)
931 return -ENOMEM;
933 rbtree_ctx = codec->reg_cache;
934 rbtree_ctx->root = RB_ROOT;
936 if (!codec->reg_def_copy)
937 return 0;
940 * populate the rbtree with the initialized registers. All other
941 * registers will be inserted into the tree when they are first written.
943 * The reasoning behind this, is that we need to step through and
944 * dereference the cache in u8/u16 increments without sacrificing
945 * portability. This could also be done using memcpy() but that would
946 * be slightly more cryptic.
948 #define snd_soc_rbtree_populate(cache) \
949 ({ \
950 int ret, i; \
951 struct snd_soc_rbtree_node *rbtree_node; \
953 ret = 0; \
954 cache = codec->reg_def_copy; \
955 for (i = 0; i < codec->driver->reg_cache_size; ++i) { \
956 if (!cache[i]) \
957 continue; \
958 rbtree_node = kzalloc(sizeof *rbtree_node, GFP_KERNEL); \
959 if (!rbtree_node) { \
960 ret = -ENOMEM; \
961 snd_soc_cache_exit(codec); \
962 break; \
964 rbtree_node->reg = i; \
965 rbtree_node->value = cache[i]; \
966 rbtree_node->defval = cache[i]; \
967 snd_soc_rbtree_insert(&rbtree_ctx->root, \
968 rbtree_node); \
970 ret; \
973 switch (codec->driver->reg_word_size) {
974 case 1: {
975 const u8 *cache;
977 return snd_soc_rbtree_populate(cache);
979 case 2: {
980 const u16 *cache;
982 return snd_soc_rbtree_populate(cache);
984 default:
985 BUG();
988 return 0;
991 #ifdef CONFIG_SND_SOC_CACHE_LZO
992 struct snd_soc_lzo_ctx {
993 void *wmem;
994 void *dst;
995 const void *src;
996 size_t src_len;
997 size_t dst_len;
998 size_t decompressed_size;
999 unsigned long *sync_bmp;
1000 int sync_bmp_nbits;
1003 #define LZO_BLOCK_NUM 8
1004 static int snd_soc_lzo_block_count(void)
1006 return LZO_BLOCK_NUM;
1009 static int snd_soc_lzo_prepare(struct snd_soc_lzo_ctx *lzo_ctx)
1011 lzo_ctx->wmem = kmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
1012 if (!lzo_ctx->wmem)
1013 return -ENOMEM;
1014 return 0;
1017 static int snd_soc_lzo_compress(struct snd_soc_lzo_ctx *lzo_ctx)
1019 size_t compress_size;
1020 int ret;
1022 ret = lzo1x_1_compress(lzo_ctx->src, lzo_ctx->src_len,
1023 lzo_ctx->dst, &compress_size, lzo_ctx->wmem);
1024 if (ret != LZO_E_OK || compress_size > lzo_ctx->dst_len)
1025 return -EINVAL;
1026 lzo_ctx->dst_len = compress_size;
1027 return 0;
1030 static int snd_soc_lzo_decompress(struct snd_soc_lzo_ctx *lzo_ctx)
1032 size_t dst_len;
1033 int ret;
1035 dst_len = lzo_ctx->dst_len;
1036 ret = lzo1x_decompress_safe(lzo_ctx->src, lzo_ctx->src_len,
1037 lzo_ctx->dst, &dst_len);
1038 if (ret != LZO_E_OK || dst_len != lzo_ctx->dst_len)
1039 return -EINVAL;
1040 return 0;
1043 static int snd_soc_lzo_compress_cache_block(struct snd_soc_codec *codec,
1044 struct snd_soc_lzo_ctx *lzo_ctx)
1046 int ret;
1048 lzo_ctx->dst_len = lzo1x_worst_compress(PAGE_SIZE);
1049 lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
1050 if (!lzo_ctx->dst) {
1051 lzo_ctx->dst_len = 0;
1052 return -ENOMEM;
1055 ret = snd_soc_lzo_compress(lzo_ctx);
1056 if (ret < 0)
1057 return ret;
1058 return 0;
1061 static int snd_soc_lzo_decompress_cache_block(struct snd_soc_codec *codec,
1062 struct snd_soc_lzo_ctx *lzo_ctx)
1064 int ret;
1066 lzo_ctx->dst_len = lzo_ctx->decompressed_size;
1067 lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
1068 if (!lzo_ctx->dst) {
1069 lzo_ctx->dst_len = 0;
1070 return -ENOMEM;
1073 ret = snd_soc_lzo_decompress(lzo_ctx);
1074 if (ret < 0)
1075 return ret;
1076 return 0;
1079 static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec,
1080 unsigned int reg)
1082 const struct snd_soc_codec_driver *codec_drv;
1083 size_t reg_size;
1085 codec_drv = codec->driver;
1086 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1087 return (reg * codec_drv->reg_word_size) /
1088 DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count());
1091 static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
1092 unsigned int reg)
1094 const struct snd_soc_codec_driver *codec_drv;
1095 size_t reg_size;
1097 codec_drv = codec->driver;
1098 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1099 return reg % (DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count()) /
1100 codec_drv->reg_word_size);
1103 static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec)
1105 const struct snd_soc_codec_driver *codec_drv;
1106 size_t reg_size;
1108 codec_drv = codec->driver;
1109 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1110 return DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count());
1113 static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
1115 struct snd_soc_lzo_ctx **lzo_blocks;
1116 unsigned int val;
1117 int i;
1118 int ret;
1120 lzo_blocks = codec->reg_cache;
1121 for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) {
1122 ret = snd_soc_cache_read(codec, i, &val);
1123 if (ret)
1124 return ret;
1125 ret = snd_soc_write(codec, i, val);
1126 if (ret)
1127 return ret;
1128 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
1129 i, val);
1132 return 0;
1135 static int snd_soc_lzo_cache_write(struct snd_soc_codec *codec,
1136 unsigned int reg, unsigned int value)
1138 struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
1139 int ret, blkindex, blkpos;
1140 size_t blksize, tmp_dst_len;
1141 void *tmp_dst;
1143 /* index of the compressed lzo block */
1144 blkindex = snd_soc_lzo_get_blkindex(codec, reg);
1145 /* register index within the decompressed block */
1146 blkpos = snd_soc_lzo_get_blkpos(codec, reg);
1147 /* size of the compressed block */
1148 blksize = snd_soc_lzo_get_blksize(codec);
1149 lzo_blocks = codec->reg_cache;
1150 lzo_block = lzo_blocks[blkindex];
1152 /* save the pointer and length of the compressed block */
1153 tmp_dst = lzo_block->dst;
1154 tmp_dst_len = lzo_block->dst_len;
1156 /* prepare the source to be the compressed block */
1157 lzo_block->src = lzo_block->dst;
1158 lzo_block->src_len = lzo_block->dst_len;
1160 /* decompress the block */
1161 ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
1162 if (ret < 0) {
1163 kfree(lzo_block->dst);
1164 goto out;
1167 /* write the new value to the cache */
1168 switch (codec->driver->reg_word_size) {
1169 case 1: {
1170 u8 *cache;
1171 cache = lzo_block->dst;
1172 if (cache[blkpos] == value) {
1173 kfree(lzo_block->dst);
1174 goto out;
1176 cache[blkpos] = value;
1178 break;
1179 case 2: {
1180 u16 *cache;
1181 cache = lzo_block->dst;
1182 if (cache[blkpos] == value) {
1183 kfree(lzo_block->dst);
1184 goto out;
1186 cache[blkpos] = value;
1188 break;
1189 default:
1190 BUG();
1193 /* prepare the source to be the decompressed block */
1194 lzo_block->src = lzo_block->dst;
1195 lzo_block->src_len = lzo_block->dst_len;
1197 /* compress the block */
1198 ret = snd_soc_lzo_compress_cache_block(codec, lzo_block);
1199 if (ret < 0) {
1200 kfree(lzo_block->dst);
1201 kfree(lzo_block->src);
1202 goto out;
1205 /* set the bit so we know we have to sync this register */
1206 set_bit(reg, lzo_block->sync_bmp);
1207 kfree(tmp_dst);
1208 kfree(lzo_block->src);
1209 return 0;
1210 out:
1211 lzo_block->dst = tmp_dst;
1212 lzo_block->dst_len = tmp_dst_len;
1213 return ret;
1216 static int snd_soc_lzo_cache_read(struct snd_soc_codec *codec,
1217 unsigned int reg, unsigned int *value)
1219 struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
1220 int ret, blkindex, blkpos;
1221 size_t blksize, tmp_dst_len;
1222 void *tmp_dst;
1224 *value = 0;
1225 /* index of the compressed lzo block */
1226 blkindex = snd_soc_lzo_get_blkindex(codec, reg);
1227 /* register index within the decompressed block */
1228 blkpos = snd_soc_lzo_get_blkpos(codec, reg);
1229 /* size of the compressed block */
1230 blksize = snd_soc_lzo_get_blksize(codec);
1231 lzo_blocks = codec->reg_cache;
1232 lzo_block = lzo_blocks[blkindex];
1234 /* save the pointer and length of the compressed block */
1235 tmp_dst = lzo_block->dst;
1236 tmp_dst_len = lzo_block->dst_len;
1238 /* prepare the source to be the compressed block */
1239 lzo_block->src = lzo_block->dst;
1240 lzo_block->src_len = lzo_block->dst_len;
1242 /* decompress the block */
1243 ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
1244 if (ret >= 0) {
1245 /* fetch the value from the cache */
1246 switch (codec->driver->reg_word_size) {
1247 case 1: {
1248 u8 *cache;
1249 cache = lzo_block->dst;
1250 *value = cache[blkpos];
1252 break;
1253 case 2: {
1254 u16 *cache;
1255 cache = lzo_block->dst;
1256 *value = cache[blkpos];
1258 break;
1259 default:
1260 BUG();
1264 kfree(lzo_block->dst);
1265 /* restore the pointer and length of the compressed block */
1266 lzo_block->dst = tmp_dst;
1267 lzo_block->dst_len = tmp_dst_len;
1268 return 0;
1271 static int snd_soc_lzo_cache_exit(struct snd_soc_codec *codec)
1273 struct snd_soc_lzo_ctx **lzo_blocks;
1274 int i, blkcount;
1276 lzo_blocks = codec->reg_cache;
1277 if (!lzo_blocks)
1278 return 0;
1280 blkcount = snd_soc_lzo_block_count();
1282 * the pointer to the bitmap used for syncing the cache
1283 * is shared amongst all lzo_blocks. Ensure it is freed
1284 * only once.
1286 if (lzo_blocks[0])
1287 kfree(lzo_blocks[0]->sync_bmp);
1288 for (i = 0; i < blkcount; ++i) {
1289 if (lzo_blocks[i]) {
1290 kfree(lzo_blocks[i]->wmem);
1291 kfree(lzo_blocks[i]->dst);
1293 /* each lzo_block is a pointer returned by kmalloc or NULL */
1294 kfree(lzo_blocks[i]);
1296 kfree(lzo_blocks);
1297 codec->reg_cache = NULL;
1298 return 0;
1301 static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
1303 struct snd_soc_lzo_ctx **lzo_blocks;
1304 size_t reg_size, bmp_size;
1305 const struct snd_soc_codec_driver *codec_drv;
1306 int ret, tofree, i, blksize, blkcount;
1307 const char *p, *end;
1308 unsigned long *sync_bmp;
1310 ret = 0;
1311 codec_drv = codec->driver;
1312 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1315 * If we have not been given a default register cache
1316 * then allocate a dummy zero-ed out region, compress it
1317 * and remember to free it afterwards.
1319 tofree = 0;
1320 if (!codec->reg_def_copy)
1321 tofree = 1;
1323 if (!codec->reg_def_copy) {
1324 codec->reg_def_copy = kzalloc(reg_size,
1325 GFP_KERNEL);
1326 if (!codec->reg_def_copy)
1327 return -ENOMEM;
1330 blkcount = snd_soc_lzo_block_count();
1331 codec->reg_cache = kzalloc(blkcount * sizeof *lzo_blocks,
1332 GFP_KERNEL);
1333 if (!codec->reg_cache) {
1334 ret = -ENOMEM;
1335 goto err_tofree;
1337 lzo_blocks = codec->reg_cache;
1340 * allocate a bitmap to be used when syncing the cache with
1341 * the hardware. Each time a register is modified, the corresponding
1342 * bit is set in the bitmap, so we know that we have to sync
1343 * that register.
1345 bmp_size = codec_drv->reg_cache_size;
1346 sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof(long),
1347 GFP_KERNEL);
1348 if (!sync_bmp) {
1349 ret = -ENOMEM;
1350 goto err;
1352 bitmap_zero(sync_bmp, bmp_size);
1354 /* allocate the lzo blocks and initialize them */
1355 for (i = 0; i < blkcount; ++i) {
1356 lzo_blocks[i] = kzalloc(sizeof **lzo_blocks,
1357 GFP_KERNEL);
1358 if (!lzo_blocks[i]) {
1359 kfree(sync_bmp);
1360 ret = -ENOMEM;
1361 goto err;
1363 lzo_blocks[i]->sync_bmp = sync_bmp;
1364 lzo_blocks[i]->sync_bmp_nbits = bmp_size;
1365 /* alloc the working space for the compressed block */
1366 ret = snd_soc_lzo_prepare(lzo_blocks[i]);
1367 if (ret < 0)
1368 goto err;
1371 blksize = snd_soc_lzo_get_blksize(codec);
1372 p = codec->reg_def_copy;
1373 end = codec->reg_def_copy + reg_size;
1374 /* compress the register map and fill the lzo blocks */
1375 for (i = 0; i < blkcount; ++i, p += blksize) {
1376 lzo_blocks[i]->src = p;
1377 if (p + blksize > end)
1378 lzo_blocks[i]->src_len = end - p;
1379 else
1380 lzo_blocks[i]->src_len = blksize;
1381 ret = snd_soc_lzo_compress_cache_block(codec,
1382 lzo_blocks[i]);
1383 if (ret < 0)
1384 goto err;
1385 lzo_blocks[i]->decompressed_size =
1386 lzo_blocks[i]->src_len;
1389 if (tofree) {
1390 kfree(codec->reg_def_copy);
1391 codec->reg_def_copy = NULL;
1393 return 0;
1394 err:
1395 snd_soc_cache_exit(codec);
1396 err_tofree:
1397 if (tofree) {
1398 kfree(codec->reg_def_copy);
1399 codec->reg_def_copy = NULL;
1401 return ret;
1403 #endif
1405 static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
1407 int i;
1408 int ret;
1409 const struct snd_soc_codec_driver *codec_drv;
1410 unsigned int val;
1412 codec_drv = codec->driver;
1413 for (i = 0; i < codec_drv->reg_cache_size; ++i) {
1414 ret = snd_soc_cache_read(codec, i, &val);
1415 if (ret)
1416 return ret;
1417 if (codec_drv->reg_cache_default) {
1418 switch (codec_drv->reg_word_size) {
1419 case 1: {
1420 const u8 *cache;
1422 cache = codec_drv->reg_cache_default;
1423 if (cache[i] == val)
1424 continue;
1426 break;
1427 case 2: {
1428 const u16 *cache;
1430 cache = codec_drv->reg_cache_default;
1431 if (cache[i] == val)
1432 continue;
1434 break;
1435 default:
1436 BUG();
1439 ret = snd_soc_write(codec, i, val);
1440 if (ret)
1441 return ret;
1442 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
1443 i, val);
1445 return 0;
1448 static int snd_soc_flat_cache_write(struct snd_soc_codec *codec,
1449 unsigned int reg, unsigned int value)
1451 switch (codec->driver->reg_word_size) {
1452 case 1: {
1453 u8 *cache;
1455 cache = codec->reg_cache;
1456 cache[reg] = value;
1458 break;
1459 case 2: {
1460 u16 *cache;
1462 cache = codec->reg_cache;
1463 cache[reg] = value;
1465 break;
1466 default:
1467 BUG();
1470 return 0;
1473 static int snd_soc_flat_cache_read(struct snd_soc_codec *codec,
1474 unsigned int reg, unsigned int *value)
1476 switch (codec->driver->reg_word_size) {
1477 case 1: {
1478 u8 *cache;
1480 cache = codec->reg_cache;
1481 *value = cache[reg];
1483 break;
1484 case 2: {
1485 u16 *cache;
1487 cache = codec->reg_cache;
1488 *value = cache[reg];
1490 break;
1491 default:
1492 BUG();
1495 return 0;
1498 static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec)
1500 if (!codec->reg_cache)
1501 return 0;
1502 kfree(codec->reg_cache);
1503 codec->reg_cache = NULL;
1504 return 0;
1507 static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
1509 const struct snd_soc_codec_driver *codec_drv;
1510 size_t reg_size;
1512 codec_drv = codec->driver;
1513 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1516 * for flat compression, we don't need to keep a copy of the
1517 * original defaults register cache as it will definitely not
1518 * be marked as __devinitconst
1520 kfree(codec->reg_def_copy);
1521 codec->reg_def_copy = NULL;
1523 if (codec_drv->reg_cache_default)
1524 codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
1525 reg_size, GFP_KERNEL);
1526 else
1527 codec->reg_cache = kzalloc(reg_size, GFP_KERNEL);
1528 if (!codec->reg_cache)
1529 return -ENOMEM;
1531 return 0;
1534 /* an array of all supported compression types */
1535 static const struct snd_soc_cache_ops cache_types[] = {
1536 /* Flat *must* be the first entry for fallback */
1538 .id = SND_SOC_FLAT_COMPRESSION,
1539 .name = "flat",
1540 .init = snd_soc_flat_cache_init,
1541 .exit = snd_soc_flat_cache_exit,
1542 .read = snd_soc_flat_cache_read,
1543 .write = snd_soc_flat_cache_write,
1544 .sync = snd_soc_flat_cache_sync
1546 #ifdef CONFIG_SND_SOC_CACHE_LZO
1548 .id = SND_SOC_LZO_COMPRESSION,
1549 .name = "LZO",
1550 .init = snd_soc_lzo_cache_init,
1551 .exit = snd_soc_lzo_cache_exit,
1552 .read = snd_soc_lzo_cache_read,
1553 .write = snd_soc_lzo_cache_write,
1554 .sync = snd_soc_lzo_cache_sync
1556 #endif
1558 .id = SND_SOC_RBTREE_COMPRESSION,
1559 .name = "rbtree",
1560 .init = snd_soc_rbtree_cache_init,
1561 .exit = snd_soc_rbtree_cache_exit,
1562 .read = snd_soc_rbtree_cache_read,
1563 .write = snd_soc_rbtree_cache_write,
1564 .sync = snd_soc_rbtree_cache_sync
1568 int snd_soc_cache_init(struct snd_soc_codec *codec)
1570 int i;
1572 for (i = 0; i < ARRAY_SIZE(cache_types); ++i)
1573 if (cache_types[i].id == codec->compress_type)
1574 break;
1576 /* Fall back to flat compression */
1577 if (i == ARRAY_SIZE(cache_types)) {
1578 dev_warn(codec->dev, "Could not match compress type: %d\n",
1579 codec->compress_type);
1580 i = 0;
1583 mutex_init(&codec->cache_rw_mutex);
1584 codec->cache_ops = &cache_types[i];
1586 if (codec->cache_ops->init) {
1587 if (codec->cache_ops->name)
1588 dev_dbg(codec->dev, "Initializing %s cache for %s codec\n",
1589 codec->cache_ops->name, codec->name);
1590 return codec->cache_ops->init(codec);
1592 return -EINVAL;
1596 * NOTE: keep in mind that this function might be called
1597 * multiple times.
1599 int snd_soc_cache_exit(struct snd_soc_codec *codec)
1601 if (codec->cache_ops && codec->cache_ops->exit) {
1602 if (codec->cache_ops->name)
1603 dev_dbg(codec->dev, "Destroying %s cache for %s codec\n",
1604 codec->cache_ops->name, codec->name);
1605 return codec->cache_ops->exit(codec);
1607 return -EINVAL;
1611 * snd_soc_cache_read: Fetch the value of a given register from the cache.
1613 * @codec: CODEC to configure.
1614 * @reg: The register index.
1615 * @value: The value to be returned.
1617 int snd_soc_cache_read(struct snd_soc_codec *codec,
1618 unsigned int reg, unsigned int *value)
1620 int ret;
1622 mutex_lock(&codec->cache_rw_mutex);
1624 if (value && codec->cache_ops && codec->cache_ops->read) {
1625 ret = codec->cache_ops->read(codec, reg, value);
1626 mutex_unlock(&codec->cache_rw_mutex);
1627 return ret;
1630 mutex_unlock(&codec->cache_rw_mutex);
1631 return -EINVAL;
1633 EXPORT_SYMBOL_GPL(snd_soc_cache_read);
1636 * snd_soc_cache_write: Set the value of a given register in the cache.
1638 * @codec: CODEC to configure.
1639 * @reg: The register index.
1640 * @value: The new register value.
1642 int snd_soc_cache_write(struct snd_soc_codec *codec,
1643 unsigned int reg, unsigned int value)
1645 int ret;
1647 mutex_lock(&codec->cache_rw_mutex);
1649 if (codec->cache_ops && codec->cache_ops->write) {
1650 ret = codec->cache_ops->write(codec, reg, value);
1651 mutex_unlock(&codec->cache_rw_mutex);
1652 return ret;
1655 mutex_unlock(&codec->cache_rw_mutex);
1656 return -EINVAL;
1658 EXPORT_SYMBOL_GPL(snd_soc_cache_write);
1661 * snd_soc_cache_sync: Sync the register cache with the hardware.
1663 * @codec: CODEC to configure.
1665 * Any registers that should not be synced should be marked as
1666 * volatile. In general drivers can choose not to use the provided
1667 * syncing functionality if they so require.
1669 int snd_soc_cache_sync(struct snd_soc_codec *codec)
1671 int ret;
1673 if (!codec->cache_sync) {
1674 return 0;
1677 if (codec->cache_ops && codec->cache_ops->sync) {
1678 if (codec->cache_ops->name)
1679 dev_dbg(codec->dev, "Syncing %s cache for %s codec\n",
1680 codec->cache_ops->name, codec->name);
1681 ret = codec->cache_ops->sync(codec);
1682 if (!ret)
1683 codec->cache_sync = 0;
1684 return ret;
1687 return -EINVAL;
1689 EXPORT_SYMBOL_GPL(snd_soc_cache_sync);