ASoC: Use cpu_to_be16() in 8x16 write
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / sound / soc / soc-cache.c
blob9c688b8a1f916105dc8785a58d4ab77cc284cb5b
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 #include <trace/events/asoc.h>
23 #if defined(CONFIG_SPI_MASTER)
24 static int do_spi_write(void *control_data, const void *msg,
25 int len)
27 struct spi_device *spi = control_data;
28 struct spi_transfer t;
29 struct spi_message m;
31 if (len <= 0)
32 return 0;
34 spi_message_init(&m);
35 memset(&t, 0, sizeof t);
37 t.tx_buf = msg;
38 t.len = len;
40 spi_message_add_tail(&t, &m);
41 spi_sync(spi, &m);
43 return len;
45 #endif
47 static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
48 unsigned int value, const void *data, int len)
50 int ret;
52 if (!snd_soc_codec_volatile_register(codec, reg) &&
53 reg < codec->driver->reg_cache_size &&
54 !codec->cache_bypass) {
55 ret = snd_soc_cache_write(codec, reg, value);
56 if (ret < 0)
57 return -1;
60 if (codec->cache_only) {
61 codec->cache_sync = 1;
62 return 0;
65 ret = codec->hw_write(codec->control_data, data, len);
66 if (ret == len)
67 return 0;
68 if (ret < 0)
69 return ret;
70 else
71 return -EIO;
74 static unsigned int do_hw_read(struct snd_soc_codec *codec, unsigned int reg)
76 int ret;
77 unsigned int val;
79 if (reg >= codec->driver->reg_cache_size ||
80 snd_soc_codec_volatile_register(codec, reg) ||
81 codec->cache_bypass) {
82 if (codec->cache_only)
83 return -1;
85 BUG_ON(!codec->hw_read);
86 return codec->hw_read(codec, reg);
89 ret = snd_soc_cache_read(codec, reg, &val);
90 if (ret < 0)
91 return -1;
92 return val;
95 static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
96 unsigned int reg)
98 return do_hw_read(codec, reg);
101 static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
102 unsigned int value)
104 u8 data[2];
106 data[0] = (reg << 4) | ((value >> 8) & 0x000f);
107 data[1] = value & 0x00ff;
109 return do_hw_write(codec, reg, value, data, 2);
112 #if defined(CONFIG_SPI_MASTER)
113 static int snd_soc_4_12_spi_write(void *control_data, const char *data,
114 int len)
116 u8 msg[2];
118 msg[0] = data[1];
119 msg[1] = data[0];
121 return do_spi_write(control_data, msg, len);
123 #else
124 #define snd_soc_4_12_spi_write NULL
125 #endif
127 static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
128 unsigned int reg)
130 return do_hw_read(codec, reg);
133 static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
134 unsigned int value)
136 u16 data;
138 data = cpu_to_be16((reg << 9) | (value & 0x1ff));
140 return do_hw_write(codec, reg, value, &data, 2);
143 #if defined(CONFIG_SPI_MASTER)
144 static int snd_soc_7_9_spi_write(void *control_data, const char *data,
145 int len)
147 u8 msg[2];
149 msg[0] = data[0];
150 msg[1] = data[1];
152 return do_spi_write(control_data, msg, len);
154 #else
155 #define snd_soc_7_9_spi_write NULL
156 #endif
158 static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
159 unsigned int value)
161 u8 data[2];
163 reg &= 0xff;
164 data[0] = reg;
165 data[1] = value & 0xff;
167 return do_hw_write(codec, reg, value, data, 2);
170 static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
171 unsigned int reg)
173 return do_hw_read(codec, reg);
176 #if defined(CONFIG_SPI_MASTER)
177 static int snd_soc_8_8_spi_write(void *control_data, const char *data,
178 int len)
180 u8 msg[2];
182 msg[0] = data[0];
183 msg[1] = data[1];
185 return do_spi_write(control_data, msg, len);
187 #else
188 #define snd_soc_8_8_spi_write NULL
189 #endif
191 static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
192 unsigned int value)
194 u8 data[3];
195 u16 val = cpu_to_be16(value);
197 data[0] = reg;
198 memcpy(&data[1], &val, sizeof(val));
200 return do_hw_write(codec, reg, value, data, 3);
203 static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
204 unsigned int reg)
206 return do_hw_read(codec, reg);
209 #if defined(CONFIG_SPI_MASTER)
210 static int snd_soc_8_16_spi_write(void *control_data, const char *data,
211 int len)
213 u8 msg[3];
215 msg[0] = data[0];
216 msg[1] = data[1];
217 msg[2] = data[2];
219 return do_spi_write(control_data, msg, len);
221 #else
222 #define snd_soc_8_16_spi_write NULL
223 #endif
225 #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
226 static unsigned int do_i2c_read(struct snd_soc_codec *codec,
227 void *reg, int reglen,
228 void *data, int datalen)
230 struct i2c_msg xfer[2];
231 int ret;
232 struct i2c_client *client = codec->control_data;
234 /* Write register */
235 xfer[0].addr = client->addr;
236 xfer[0].flags = 0;
237 xfer[0].len = reglen;
238 xfer[0].buf = reg;
240 /* Read data */
241 xfer[1].addr = client->addr;
242 xfer[1].flags = I2C_M_RD;
243 xfer[1].len = datalen;
244 xfer[1].buf = data;
246 ret = i2c_transfer(client->adapter, xfer, 2);
247 if (ret == 2)
248 return 0;
249 else if (ret < 0)
250 return ret;
251 else
252 return -EIO;
254 #endif
256 #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
257 static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
258 unsigned int r)
260 u8 reg = r;
261 u8 data;
262 int ret;
264 ret = do_i2c_read(codec, &reg, 1, &data, 1);
265 if (ret < 0)
266 return 0;
267 return data;
269 #else
270 #define snd_soc_8_8_read_i2c NULL
271 #endif
273 #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
274 static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
275 unsigned int r)
277 u8 reg = r;
278 u16 data;
279 int ret;
281 ret = do_i2c_read(codec, &reg, 1, &data, 2);
282 if (ret < 0)
283 return 0;
284 return (data >> 8) | ((data & 0xff) << 8);
286 #else
287 #define snd_soc_8_16_read_i2c NULL
288 #endif
290 #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
291 static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
292 unsigned int r)
294 u16 reg = r;
295 u8 data;
296 int ret;
298 ret = do_i2c_read(codec, &reg, 2, &data, 1);
299 if (ret < 0)
300 return 0;
301 return data;
303 #else
304 #define snd_soc_16_8_read_i2c NULL
305 #endif
307 static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
308 unsigned int reg)
310 return do_hw_read(codec, reg);
313 static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
314 unsigned int value)
316 u8 data[3];
318 data[0] = (reg >> 8) & 0xff;
319 data[1] = reg & 0xff;
320 data[2] = value;
321 reg &= 0xff;
323 return do_hw_write(codec, reg, value, data, 3);
326 #if defined(CONFIG_SPI_MASTER)
327 static int snd_soc_16_8_spi_write(void *control_data, const char *data,
328 int len)
330 u8 msg[3];
332 msg[0] = data[0];
333 msg[1] = data[1];
334 msg[2] = data[2];
336 return do_spi_write(control_data, msg, len);
338 #else
339 #define snd_soc_16_8_spi_write NULL
340 #endif
342 #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
343 static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
344 unsigned int r)
346 u16 reg = cpu_to_be16(r);
347 u16 data;
348 int ret;
350 ret = do_i2c_read(codec, &reg, 2, &data, 2);
351 if (ret < 0)
352 return 0;
353 return be16_to_cpu(data);
355 #else
356 #define snd_soc_16_16_read_i2c NULL
357 #endif
359 static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
360 unsigned int reg)
362 return do_hw_read(codec, reg);
365 static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
366 unsigned int value)
368 u16 data[2];
370 data[0] = cpu_to_be16(reg);
371 data[1] = cpu_to_be16(value);
373 return do_hw_write(codec, reg, value, data, sizeof(data));
376 #if defined(CONFIG_SPI_MASTER)
377 static int snd_soc_16_16_spi_write(void *control_data, const char *data,
378 int len)
380 u8 msg[4];
382 msg[0] = data[0];
383 msg[1] = data[1];
384 msg[2] = data[2];
385 msg[3] = data[3];
387 return do_spi_write(control_data, msg, len);
389 #else
390 #define snd_soc_16_16_spi_write NULL
391 #endif
393 /* Primitive bulk write support for soc-cache. The data pointed to by
394 * `data' needs to already be in the form the hardware expects
395 * including any leading register specific data. Any data written
396 * through this function will not go through the cache as it only
397 * handles writing to volatile or out of bounds registers.
399 static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int reg,
400 const void *data, size_t len)
402 int ret;
404 /* To ensure that we don't get out of sync with the cache, check
405 * whether the base register is volatile or if we've directly asked
406 * to bypass the cache. Out of bounds registers are considered
407 * volatile.
409 if (!codec->cache_bypass
410 && !snd_soc_codec_volatile_register(codec, reg)
411 && reg < codec->driver->reg_cache_size)
412 return -EINVAL;
414 switch (codec->control_type) {
415 #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
416 case SND_SOC_I2C:
417 ret = i2c_master_send(codec->control_data, data, len);
418 break;
419 #endif
420 #if defined(CONFIG_SPI_MASTER)
421 case SND_SOC_SPI:
422 ret = do_spi_write(codec->control_data, data, len);
423 break;
424 #endif
425 default:
426 BUG();
429 if (ret == len)
430 return 0;
431 if (ret < 0)
432 return ret;
433 else
434 return -EIO;
437 static struct {
438 int addr_bits;
439 int data_bits;
440 int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
441 int (*spi_write)(void *, const char *, int);
442 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
443 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
444 } io_types[] = {
446 .addr_bits = 4, .data_bits = 12,
447 .write = snd_soc_4_12_write, .read = snd_soc_4_12_read,
448 .spi_write = snd_soc_4_12_spi_write,
451 .addr_bits = 7, .data_bits = 9,
452 .write = snd_soc_7_9_write, .read = snd_soc_7_9_read,
453 .spi_write = snd_soc_7_9_spi_write,
456 .addr_bits = 8, .data_bits = 8,
457 .write = snd_soc_8_8_write, .read = snd_soc_8_8_read,
458 .i2c_read = snd_soc_8_8_read_i2c,
459 .spi_write = snd_soc_8_8_spi_write,
462 .addr_bits = 8, .data_bits = 16,
463 .write = snd_soc_8_16_write, .read = snd_soc_8_16_read,
464 .i2c_read = snd_soc_8_16_read_i2c,
465 .spi_write = snd_soc_8_16_spi_write,
468 .addr_bits = 16, .data_bits = 8,
469 .write = snd_soc_16_8_write, .read = snd_soc_16_8_read,
470 .i2c_read = snd_soc_16_8_read_i2c,
471 .spi_write = snd_soc_16_8_spi_write,
474 .addr_bits = 16, .data_bits = 16,
475 .write = snd_soc_16_16_write, .read = snd_soc_16_16_read,
476 .i2c_read = snd_soc_16_16_read_i2c,
477 .spi_write = snd_soc_16_16_spi_write,
482 * snd_soc_codec_set_cache_io: Set up standard I/O functions.
484 * @codec: CODEC to configure.
485 * @addr_bits: Number of bits of register address data.
486 * @data_bits: Number of bits of data per register.
487 * @control: Control bus used.
489 * Register formats are frequently shared between many I2C and SPI
490 * devices. In order to promote code reuse the ASoC core provides
491 * some standard implementations of CODEC read and write operations
492 * which can be set up using this function.
494 * The caller is responsible for allocating and initialising the
495 * actual cache.
497 * Note that at present this code cannot be used by CODECs with
498 * volatile registers.
500 int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
501 int addr_bits, int data_bits,
502 enum snd_soc_control_type control)
504 int i;
506 for (i = 0; i < ARRAY_SIZE(io_types); i++)
507 if (io_types[i].addr_bits == addr_bits &&
508 io_types[i].data_bits == data_bits)
509 break;
510 if (i == ARRAY_SIZE(io_types)) {
511 printk(KERN_ERR
512 "No I/O functions for %d bit address %d bit data\n",
513 addr_bits, data_bits);
514 return -EINVAL;
517 codec->write = io_types[i].write;
518 codec->read = io_types[i].read;
519 codec->bulk_write_raw = snd_soc_hw_bulk_write_raw;
521 switch (control) {
522 case SND_SOC_CUSTOM:
523 break;
525 case SND_SOC_I2C:
526 #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
527 codec->hw_write = (hw_write_t)i2c_master_send;
528 #endif
529 if (io_types[i].i2c_read)
530 codec->hw_read = io_types[i].i2c_read;
532 codec->control_data = container_of(codec->dev,
533 struct i2c_client,
534 dev);
535 break;
537 case SND_SOC_SPI:
538 if (io_types[i].spi_write)
539 codec->hw_write = io_types[i].spi_write;
541 codec->control_data = container_of(codec->dev,
542 struct spi_device,
543 dev);
544 break;
547 return 0;
549 EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
551 static bool snd_soc_set_cache_val(void *base, unsigned int idx,
552 unsigned int val, unsigned int word_size)
554 switch (word_size) {
555 case 1: {
556 u8 *cache = base;
557 if (cache[idx] == val)
558 return true;
559 cache[idx] = val;
560 break;
562 case 2: {
563 u16 *cache = base;
564 if (cache[idx] == val)
565 return true;
566 cache[idx] = val;
567 break;
569 default:
570 BUG();
572 return false;
575 static unsigned int snd_soc_get_cache_val(const void *base, unsigned int idx,
576 unsigned int word_size)
578 switch (word_size) {
579 case 1: {
580 const u8 *cache = base;
581 return cache[idx];
583 case 2: {
584 const u16 *cache = base;
585 return cache[idx];
587 default:
588 BUG();
590 /* unreachable */
591 return -1;
594 struct snd_soc_rbtree_node {
595 struct rb_node node; /* the actual rbtree node holding this block */
596 unsigned int base_reg; /* base register handled by this block */
597 unsigned int word_size; /* number of bytes needed to represent the register index */
598 void *block; /* block of adjacent registers */
599 unsigned int blklen; /* number of registers available in the block */
600 } __attribute__ ((packed));
602 struct snd_soc_rbtree_ctx {
603 struct rb_root root;
604 struct snd_soc_rbtree_node *cached_rbnode;
607 static inline void snd_soc_rbtree_get_base_top_reg(
608 struct snd_soc_rbtree_node *rbnode,
609 unsigned int *base, unsigned int *top)
611 *base = rbnode->base_reg;
612 *top = rbnode->base_reg + rbnode->blklen - 1;
615 static unsigned int snd_soc_rbtree_get_register(
616 struct snd_soc_rbtree_node *rbnode, unsigned int idx)
618 unsigned int val;
620 switch (rbnode->word_size) {
621 case 1: {
622 u8 *p = rbnode->block;
623 val = p[idx];
624 return val;
626 case 2: {
627 u16 *p = rbnode->block;
628 val = p[idx];
629 return val;
631 default:
632 BUG();
633 break;
635 return -1;
638 static void snd_soc_rbtree_set_register(struct snd_soc_rbtree_node *rbnode,
639 unsigned int idx, unsigned int val)
641 switch (rbnode->word_size) {
642 case 1: {
643 u8 *p = rbnode->block;
644 p[idx] = val;
645 break;
647 case 2: {
648 u16 *p = rbnode->block;
649 p[idx] = val;
650 break;
652 default:
653 BUG();
654 break;
658 static struct snd_soc_rbtree_node *snd_soc_rbtree_lookup(
659 struct rb_root *root, unsigned int reg)
661 struct rb_node *node;
662 struct snd_soc_rbtree_node *rbnode;
663 unsigned int base_reg, top_reg;
665 node = root->rb_node;
666 while (node) {
667 rbnode = container_of(node, struct snd_soc_rbtree_node, node);
668 snd_soc_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg);
669 if (reg >= base_reg && reg <= top_reg)
670 return rbnode;
671 else if (reg > top_reg)
672 node = node->rb_right;
673 else if (reg < base_reg)
674 node = node->rb_left;
677 return NULL;
680 static int snd_soc_rbtree_insert(struct rb_root *root,
681 struct snd_soc_rbtree_node *rbnode)
683 struct rb_node **new, *parent;
684 struct snd_soc_rbtree_node *rbnode_tmp;
685 unsigned int base_reg_tmp, top_reg_tmp;
686 unsigned int base_reg;
688 parent = NULL;
689 new = &root->rb_node;
690 while (*new) {
691 rbnode_tmp = container_of(*new, struct snd_soc_rbtree_node,
692 node);
693 /* base and top registers of the current rbnode */
694 snd_soc_rbtree_get_base_top_reg(rbnode_tmp, &base_reg_tmp,
695 &top_reg_tmp);
696 /* base register of the rbnode to be added */
697 base_reg = rbnode->base_reg;
698 parent = *new;
699 /* if this register has already been inserted, just return */
700 if (base_reg >= base_reg_tmp &&
701 base_reg <= top_reg_tmp)
702 return 0;
703 else if (base_reg > top_reg_tmp)
704 new = &((*new)->rb_right);
705 else if (base_reg < base_reg_tmp)
706 new = &((*new)->rb_left);
709 /* insert the node into the rbtree */
710 rb_link_node(&rbnode->node, parent, new);
711 rb_insert_color(&rbnode->node, root);
713 return 1;
716 static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec)
718 struct snd_soc_rbtree_ctx *rbtree_ctx;
719 struct rb_node *node;
720 struct snd_soc_rbtree_node *rbnode;
721 unsigned int regtmp;
722 unsigned int val;
723 int ret;
724 int i;
726 rbtree_ctx = codec->reg_cache;
727 for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
728 rbnode = rb_entry(node, struct snd_soc_rbtree_node, node);
729 for (i = 0; i < rbnode->blklen; ++i) {
730 regtmp = rbnode->base_reg + i;
731 WARN_ON(codec->writable_register &&
732 codec->writable_register(codec, regtmp));
733 val = snd_soc_rbtree_get_register(rbnode, i);
734 codec->cache_bypass = 1;
735 ret = snd_soc_write(codec, regtmp, val);
736 codec->cache_bypass = 0;
737 if (ret)
738 return ret;
739 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
740 regtmp, val);
744 return 0;
747 static int snd_soc_rbtree_insert_to_block(struct snd_soc_rbtree_node *rbnode,
748 unsigned int pos, unsigned int reg,
749 unsigned int value)
751 u8 *blk;
753 blk = krealloc(rbnode->block,
754 (rbnode->blklen + 1) * rbnode->word_size, GFP_KERNEL);
755 if (!blk)
756 return -ENOMEM;
758 /* insert the register value in the correct place in the rbnode block */
759 memmove(blk + (pos + 1) * rbnode->word_size,
760 blk + pos * rbnode->word_size,
761 (rbnode->blklen - pos) * rbnode->word_size);
763 /* update the rbnode block, its size and the base register */
764 rbnode->block = blk;
765 rbnode->blklen++;
766 if (!pos)
767 rbnode->base_reg = reg;
769 snd_soc_rbtree_set_register(rbnode, pos, value);
770 return 0;
773 static int snd_soc_rbtree_cache_write(struct snd_soc_codec *codec,
774 unsigned int reg, unsigned int value)
776 struct snd_soc_rbtree_ctx *rbtree_ctx;
777 struct snd_soc_rbtree_node *rbnode, *rbnode_tmp;
778 struct rb_node *node;
779 unsigned int val;
780 unsigned int reg_tmp;
781 unsigned int base_reg, top_reg;
782 unsigned int pos;
783 int i;
784 int ret;
786 rbtree_ctx = codec->reg_cache;
787 /* look up the required register in the cached rbnode */
788 rbnode = rbtree_ctx->cached_rbnode;
789 if (rbnode) {
790 snd_soc_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg);
791 if (reg >= base_reg && reg <= top_reg) {
792 reg_tmp = reg - base_reg;
793 val = snd_soc_rbtree_get_register(rbnode, reg_tmp);
794 if (val == value)
795 return 0;
796 snd_soc_rbtree_set_register(rbnode, reg_tmp, value);
797 return 0;
800 /* if we can't locate it in the cached rbnode we'll have
801 * to traverse the rbtree looking for it.
803 rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
804 if (rbnode) {
805 reg_tmp = reg - rbnode->base_reg;
806 val = snd_soc_rbtree_get_register(rbnode, reg_tmp);
807 if (val == value)
808 return 0;
809 snd_soc_rbtree_set_register(rbnode, reg_tmp, value);
810 rbtree_ctx->cached_rbnode = rbnode;
811 } else {
812 /* bail out early, no need to create the rbnode yet */
813 if (!value)
814 return 0;
815 /* look for an adjacent register to the one we are about to add */
816 for (node = rb_first(&rbtree_ctx->root); node;
817 node = rb_next(node)) {
818 rbnode_tmp = rb_entry(node, struct snd_soc_rbtree_node, node);
819 for (i = 0; i < rbnode_tmp->blklen; ++i) {
820 reg_tmp = rbnode_tmp->base_reg + i;
821 if (abs(reg_tmp - reg) != 1)
822 continue;
823 /* decide where in the block to place our register */
824 if (reg_tmp + 1 == reg)
825 pos = i + 1;
826 else
827 pos = i;
828 ret = snd_soc_rbtree_insert_to_block(rbnode_tmp, pos,
829 reg, value);
830 if (ret)
831 return ret;
832 rbtree_ctx->cached_rbnode = rbnode_tmp;
833 return 0;
836 /* we did not manage to find a place to insert it in an existing
837 * block so create a new rbnode with a single register in its block.
838 * This block will get populated further if any other adjacent
839 * registers get modified in the future.
841 rbnode = kzalloc(sizeof *rbnode, GFP_KERNEL);
842 if (!rbnode)
843 return -ENOMEM;
844 rbnode->blklen = 1;
845 rbnode->base_reg = reg;
846 rbnode->word_size = codec->driver->reg_word_size;
847 rbnode->block = kmalloc(rbnode->blklen * rbnode->word_size,
848 GFP_KERNEL);
849 if (!rbnode->block) {
850 kfree(rbnode);
851 return -ENOMEM;
853 snd_soc_rbtree_set_register(rbnode, 0, value);
854 snd_soc_rbtree_insert(&rbtree_ctx->root, rbnode);
855 rbtree_ctx->cached_rbnode = rbnode;
858 return 0;
861 static int snd_soc_rbtree_cache_read(struct snd_soc_codec *codec,
862 unsigned int reg, unsigned int *value)
864 struct snd_soc_rbtree_ctx *rbtree_ctx;
865 struct snd_soc_rbtree_node *rbnode;
866 unsigned int base_reg, top_reg;
867 unsigned int reg_tmp;
869 rbtree_ctx = codec->reg_cache;
870 /* look up the required register in the cached rbnode */
871 rbnode = rbtree_ctx->cached_rbnode;
872 if (rbnode) {
873 snd_soc_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg);
874 if (reg >= base_reg && reg <= top_reg) {
875 reg_tmp = reg - base_reg;
876 *value = snd_soc_rbtree_get_register(rbnode, reg_tmp);
877 return 0;
880 /* if we can't locate it in the cached rbnode we'll have
881 * to traverse the rbtree looking for it.
883 rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
884 if (rbnode) {
885 reg_tmp = reg - rbnode->base_reg;
886 *value = snd_soc_rbtree_get_register(rbnode, reg_tmp);
887 rbtree_ctx->cached_rbnode = rbnode;
888 } else {
889 /* uninitialized registers default to 0 */
890 *value = 0;
893 return 0;
896 static int snd_soc_rbtree_cache_exit(struct snd_soc_codec *codec)
898 struct rb_node *next;
899 struct snd_soc_rbtree_ctx *rbtree_ctx;
900 struct snd_soc_rbtree_node *rbtree_node;
902 /* if we've already been called then just return */
903 rbtree_ctx = codec->reg_cache;
904 if (!rbtree_ctx)
905 return 0;
907 /* free up the rbtree */
908 next = rb_first(&rbtree_ctx->root);
909 while (next) {
910 rbtree_node = rb_entry(next, struct snd_soc_rbtree_node, node);
911 next = rb_next(&rbtree_node->node);
912 rb_erase(&rbtree_node->node, &rbtree_ctx->root);
913 kfree(rbtree_node->block);
914 kfree(rbtree_node);
917 /* release the resources */
918 kfree(codec->reg_cache);
919 codec->reg_cache = NULL;
921 return 0;
924 static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
926 struct snd_soc_rbtree_ctx *rbtree_ctx;
927 unsigned int word_size;
928 unsigned int val;
929 int i;
930 int ret;
932 codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL);
933 if (!codec->reg_cache)
934 return -ENOMEM;
936 rbtree_ctx = codec->reg_cache;
937 rbtree_ctx->root = RB_ROOT;
938 rbtree_ctx->cached_rbnode = NULL;
940 if (!codec->reg_def_copy)
941 return 0;
943 word_size = codec->driver->reg_word_size;
944 for (i = 0; i < codec->driver->reg_cache_size; ++i) {
945 val = snd_soc_get_cache_val(codec->reg_def_copy, i,
946 word_size);
947 if (!val)
948 continue;
949 ret = snd_soc_rbtree_cache_write(codec, i, val);
950 if (ret)
951 goto err;
954 return 0;
956 err:
957 snd_soc_cache_exit(codec);
958 return ret;
961 #ifdef CONFIG_SND_SOC_CACHE_LZO
962 struct snd_soc_lzo_ctx {
963 void *wmem;
964 void *dst;
965 const void *src;
966 size_t src_len;
967 size_t dst_len;
968 size_t decompressed_size;
969 unsigned long *sync_bmp;
970 int sync_bmp_nbits;
973 #define LZO_BLOCK_NUM 8
974 static int snd_soc_lzo_block_count(void)
976 return LZO_BLOCK_NUM;
979 static int snd_soc_lzo_prepare(struct snd_soc_lzo_ctx *lzo_ctx)
981 lzo_ctx->wmem = kmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
982 if (!lzo_ctx->wmem)
983 return -ENOMEM;
984 return 0;
987 static int snd_soc_lzo_compress(struct snd_soc_lzo_ctx *lzo_ctx)
989 size_t compress_size;
990 int ret;
992 ret = lzo1x_1_compress(lzo_ctx->src, lzo_ctx->src_len,
993 lzo_ctx->dst, &compress_size, lzo_ctx->wmem);
994 if (ret != LZO_E_OK || compress_size > lzo_ctx->dst_len)
995 return -EINVAL;
996 lzo_ctx->dst_len = compress_size;
997 return 0;
1000 static int snd_soc_lzo_decompress(struct snd_soc_lzo_ctx *lzo_ctx)
1002 size_t dst_len;
1003 int ret;
1005 dst_len = lzo_ctx->dst_len;
1006 ret = lzo1x_decompress_safe(lzo_ctx->src, lzo_ctx->src_len,
1007 lzo_ctx->dst, &dst_len);
1008 if (ret != LZO_E_OK || dst_len != lzo_ctx->dst_len)
1009 return -EINVAL;
1010 return 0;
1013 static int snd_soc_lzo_compress_cache_block(struct snd_soc_codec *codec,
1014 struct snd_soc_lzo_ctx *lzo_ctx)
1016 int ret;
1018 lzo_ctx->dst_len = lzo1x_worst_compress(PAGE_SIZE);
1019 lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
1020 if (!lzo_ctx->dst) {
1021 lzo_ctx->dst_len = 0;
1022 return -ENOMEM;
1025 ret = snd_soc_lzo_compress(lzo_ctx);
1026 if (ret < 0)
1027 return ret;
1028 return 0;
1031 static int snd_soc_lzo_decompress_cache_block(struct snd_soc_codec *codec,
1032 struct snd_soc_lzo_ctx *lzo_ctx)
1034 int ret;
1036 lzo_ctx->dst_len = lzo_ctx->decompressed_size;
1037 lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
1038 if (!lzo_ctx->dst) {
1039 lzo_ctx->dst_len = 0;
1040 return -ENOMEM;
1043 ret = snd_soc_lzo_decompress(lzo_ctx);
1044 if (ret < 0)
1045 return ret;
1046 return 0;
1049 static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec,
1050 unsigned int reg)
1052 const struct snd_soc_codec_driver *codec_drv;
1054 codec_drv = codec->driver;
1055 return (reg * codec_drv->reg_word_size) /
1056 DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count());
1059 static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
1060 unsigned int reg)
1062 const struct snd_soc_codec_driver *codec_drv;
1064 codec_drv = codec->driver;
1065 return reg % (DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count()) /
1066 codec_drv->reg_word_size);
1069 static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec)
1071 const struct snd_soc_codec_driver *codec_drv;
1073 codec_drv = codec->driver;
1074 return DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count());
1077 static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
1079 struct snd_soc_lzo_ctx **lzo_blocks;
1080 unsigned int val;
1081 int i;
1082 int ret;
1084 lzo_blocks = codec->reg_cache;
1085 for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) {
1086 WARN_ON(codec->writable_register &&
1087 codec->writable_register(codec, i));
1088 ret = snd_soc_cache_read(codec, i, &val);
1089 if (ret)
1090 return ret;
1091 codec->cache_bypass = 1;
1092 ret = snd_soc_write(codec, i, val);
1093 codec->cache_bypass = 0;
1094 if (ret)
1095 return ret;
1096 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
1097 i, val);
1100 return 0;
1103 static int snd_soc_lzo_cache_write(struct snd_soc_codec *codec,
1104 unsigned int reg, unsigned int value)
1106 struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
1107 int ret, blkindex, blkpos;
1108 size_t blksize, tmp_dst_len;
1109 void *tmp_dst;
1111 /* index of the compressed lzo block */
1112 blkindex = snd_soc_lzo_get_blkindex(codec, reg);
1113 /* register index within the decompressed block */
1114 blkpos = snd_soc_lzo_get_blkpos(codec, reg);
1115 /* size of the compressed block */
1116 blksize = snd_soc_lzo_get_blksize(codec);
1117 lzo_blocks = codec->reg_cache;
1118 lzo_block = lzo_blocks[blkindex];
1120 /* save the pointer and length of the compressed block */
1121 tmp_dst = lzo_block->dst;
1122 tmp_dst_len = lzo_block->dst_len;
1124 /* prepare the source to be the compressed block */
1125 lzo_block->src = lzo_block->dst;
1126 lzo_block->src_len = lzo_block->dst_len;
1128 /* decompress the block */
1129 ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
1130 if (ret < 0) {
1131 kfree(lzo_block->dst);
1132 goto out;
1135 /* write the new value to the cache */
1136 if (snd_soc_set_cache_val(lzo_block->dst, blkpos, value,
1137 codec->driver->reg_word_size)) {
1138 kfree(lzo_block->dst);
1139 goto out;
1142 /* prepare the source to be the decompressed block */
1143 lzo_block->src = lzo_block->dst;
1144 lzo_block->src_len = lzo_block->dst_len;
1146 /* compress the block */
1147 ret = snd_soc_lzo_compress_cache_block(codec, lzo_block);
1148 if (ret < 0) {
1149 kfree(lzo_block->dst);
1150 kfree(lzo_block->src);
1151 goto out;
1154 /* set the bit so we know we have to sync this register */
1155 set_bit(reg, lzo_block->sync_bmp);
1156 kfree(tmp_dst);
1157 kfree(lzo_block->src);
1158 return 0;
1159 out:
1160 lzo_block->dst = tmp_dst;
1161 lzo_block->dst_len = tmp_dst_len;
1162 return ret;
1165 static int snd_soc_lzo_cache_read(struct snd_soc_codec *codec,
1166 unsigned int reg, unsigned int *value)
1168 struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
1169 int ret, blkindex, blkpos;
1170 size_t blksize, tmp_dst_len;
1171 void *tmp_dst;
1173 *value = 0;
1174 /* index of the compressed lzo block */
1175 blkindex = snd_soc_lzo_get_blkindex(codec, reg);
1176 /* register index within the decompressed block */
1177 blkpos = snd_soc_lzo_get_blkpos(codec, reg);
1178 /* size of the compressed block */
1179 blksize = snd_soc_lzo_get_blksize(codec);
1180 lzo_blocks = codec->reg_cache;
1181 lzo_block = lzo_blocks[blkindex];
1183 /* save the pointer and length of the compressed block */
1184 tmp_dst = lzo_block->dst;
1185 tmp_dst_len = lzo_block->dst_len;
1187 /* prepare the source to be the compressed block */
1188 lzo_block->src = lzo_block->dst;
1189 lzo_block->src_len = lzo_block->dst_len;
1191 /* decompress the block */
1192 ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
1193 if (ret >= 0)
1194 /* fetch the value from the cache */
1195 *value = snd_soc_get_cache_val(lzo_block->dst, blkpos,
1196 codec->driver->reg_word_size);
1198 kfree(lzo_block->dst);
1199 /* restore the pointer and length of the compressed block */
1200 lzo_block->dst = tmp_dst;
1201 lzo_block->dst_len = tmp_dst_len;
1202 return 0;
1205 static int snd_soc_lzo_cache_exit(struct snd_soc_codec *codec)
1207 struct snd_soc_lzo_ctx **lzo_blocks;
1208 int i, blkcount;
1210 lzo_blocks = codec->reg_cache;
1211 if (!lzo_blocks)
1212 return 0;
1214 blkcount = snd_soc_lzo_block_count();
1216 * the pointer to the bitmap used for syncing the cache
1217 * is shared amongst all lzo_blocks. Ensure it is freed
1218 * only once.
1220 if (lzo_blocks[0])
1221 kfree(lzo_blocks[0]->sync_bmp);
1222 for (i = 0; i < blkcount; ++i) {
1223 if (lzo_blocks[i]) {
1224 kfree(lzo_blocks[i]->wmem);
1225 kfree(lzo_blocks[i]->dst);
1227 /* each lzo_block is a pointer returned by kmalloc or NULL */
1228 kfree(lzo_blocks[i]);
1230 kfree(lzo_blocks);
1231 codec->reg_cache = NULL;
1232 return 0;
1235 static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
1237 struct snd_soc_lzo_ctx **lzo_blocks;
1238 size_t bmp_size;
1239 const struct snd_soc_codec_driver *codec_drv;
1240 int ret, tofree, i, blksize, blkcount;
1241 const char *p, *end;
1242 unsigned long *sync_bmp;
1244 ret = 0;
1245 codec_drv = codec->driver;
1248 * If we have not been given a default register cache
1249 * then allocate a dummy zero-ed out region, compress it
1250 * and remember to free it afterwards.
1252 tofree = 0;
1253 if (!codec->reg_def_copy)
1254 tofree = 1;
1256 if (!codec->reg_def_copy) {
1257 codec->reg_def_copy = kzalloc(codec->reg_size, GFP_KERNEL);
1258 if (!codec->reg_def_copy)
1259 return -ENOMEM;
1262 blkcount = snd_soc_lzo_block_count();
1263 codec->reg_cache = kzalloc(blkcount * sizeof *lzo_blocks,
1264 GFP_KERNEL);
1265 if (!codec->reg_cache) {
1266 ret = -ENOMEM;
1267 goto err_tofree;
1269 lzo_blocks = codec->reg_cache;
1272 * allocate a bitmap to be used when syncing the cache with
1273 * the hardware. Each time a register is modified, the corresponding
1274 * bit is set in the bitmap, so we know that we have to sync
1275 * that register.
1277 bmp_size = codec_drv->reg_cache_size;
1278 sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof(long),
1279 GFP_KERNEL);
1280 if (!sync_bmp) {
1281 ret = -ENOMEM;
1282 goto err;
1284 bitmap_zero(sync_bmp, bmp_size);
1286 /* allocate the lzo blocks and initialize them */
1287 for (i = 0; i < blkcount; ++i) {
1288 lzo_blocks[i] = kzalloc(sizeof **lzo_blocks,
1289 GFP_KERNEL);
1290 if (!lzo_blocks[i]) {
1291 kfree(sync_bmp);
1292 ret = -ENOMEM;
1293 goto err;
1295 lzo_blocks[i]->sync_bmp = sync_bmp;
1296 lzo_blocks[i]->sync_bmp_nbits = bmp_size;
1297 /* alloc the working space for the compressed block */
1298 ret = snd_soc_lzo_prepare(lzo_blocks[i]);
1299 if (ret < 0)
1300 goto err;
1303 blksize = snd_soc_lzo_get_blksize(codec);
1304 p = codec->reg_def_copy;
1305 end = codec->reg_def_copy + codec->reg_size;
1306 /* compress the register map and fill the lzo blocks */
1307 for (i = 0; i < blkcount; ++i, p += blksize) {
1308 lzo_blocks[i]->src = p;
1309 if (p + blksize > end)
1310 lzo_blocks[i]->src_len = end - p;
1311 else
1312 lzo_blocks[i]->src_len = blksize;
1313 ret = snd_soc_lzo_compress_cache_block(codec,
1314 lzo_blocks[i]);
1315 if (ret < 0)
1316 goto err;
1317 lzo_blocks[i]->decompressed_size =
1318 lzo_blocks[i]->src_len;
1321 if (tofree) {
1322 kfree(codec->reg_def_copy);
1323 codec->reg_def_copy = NULL;
1325 return 0;
1326 err:
1327 snd_soc_cache_exit(codec);
1328 err_tofree:
1329 if (tofree) {
1330 kfree(codec->reg_def_copy);
1331 codec->reg_def_copy = NULL;
1333 return ret;
1335 #endif
1337 static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
1339 int i;
1340 int ret;
1341 const struct snd_soc_codec_driver *codec_drv;
1342 unsigned int val;
1344 codec_drv = codec->driver;
1345 for (i = 0; i < codec_drv->reg_cache_size; ++i) {
1346 WARN_ON(codec->writable_register &&
1347 codec->writable_register(codec, i));
1348 ret = snd_soc_cache_read(codec, i, &val);
1349 if (ret)
1350 return ret;
1351 if (codec->reg_def_copy)
1352 if (snd_soc_get_cache_val(codec->reg_def_copy,
1353 i, codec_drv->reg_word_size) == val)
1354 continue;
1355 ret = snd_soc_write(codec, i, val);
1356 if (ret)
1357 return ret;
1358 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
1359 i, val);
1361 return 0;
1364 static int snd_soc_flat_cache_write(struct snd_soc_codec *codec,
1365 unsigned int reg, unsigned int value)
1367 snd_soc_set_cache_val(codec->reg_cache, reg, value,
1368 codec->driver->reg_word_size);
1369 return 0;
1372 static int snd_soc_flat_cache_read(struct snd_soc_codec *codec,
1373 unsigned int reg, unsigned int *value)
1375 *value = snd_soc_get_cache_val(codec->reg_cache, reg,
1376 codec->driver->reg_word_size);
1377 return 0;
1380 static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec)
1382 if (!codec->reg_cache)
1383 return 0;
1384 kfree(codec->reg_cache);
1385 codec->reg_cache = NULL;
1386 return 0;
1389 static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
1391 const struct snd_soc_codec_driver *codec_drv;
1393 codec_drv = codec->driver;
1395 if (codec->reg_def_copy)
1396 codec->reg_cache = kmemdup(codec->reg_def_copy,
1397 codec->reg_size, GFP_KERNEL);
1398 else
1399 codec->reg_cache = kzalloc(codec->reg_size, GFP_KERNEL);
1400 if (!codec->reg_cache)
1401 return -ENOMEM;
1403 return 0;
1406 /* an array of all supported compression types */
1407 static const struct snd_soc_cache_ops cache_types[] = {
1408 /* Flat *must* be the first entry for fallback */
1410 .id = SND_SOC_FLAT_COMPRESSION,
1411 .name = "flat",
1412 .init = snd_soc_flat_cache_init,
1413 .exit = snd_soc_flat_cache_exit,
1414 .read = snd_soc_flat_cache_read,
1415 .write = snd_soc_flat_cache_write,
1416 .sync = snd_soc_flat_cache_sync
1418 #ifdef CONFIG_SND_SOC_CACHE_LZO
1420 .id = SND_SOC_LZO_COMPRESSION,
1421 .name = "LZO",
1422 .init = snd_soc_lzo_cache_init,
1423 .exit = snd_soc_lzo_cache_exit,
1424 .read = snd_soc_lzo_cache_read,
1425 .write = snd_soc_lzo_cache_write,
1426 .sync = snd_soc_lzo_cache_sync
1428 #endif
1430 .id = SND_SOC_RBTREE_COMPRESSION,
1431 .name = "rbtree",
1432 .init = snd_soc_rbtree_cache_init,
1433 .exit = snd_soc_rbtree_cache_exit,
1434 .read = snd_soc_rbtree_cache_read,
1435 .write = snd_soc_rbtree_cache_write,
1436 .sync = snd_soc_rbtree_cache_sync
1440 int snd_soc_cache_init(struct snd_soc_codec *codec)
1442 int i;
1444 for (i = 0; i < ARRAY_SIZE(cache_types); ++i)
1445 if (cache_types[i].id == codec->compress_type)
1446 break;
1448 /* Fall back to flat compression */
1449 if (i == ARRAY_SIZE(cache_types)) {
1450 dev_warn(codec->dev, "Could not match compress type: %d\n",
1451 codec->compress_type);
1452 i = 0;
1455 mutex_init(&codec->cache_rw_mutex);
1456 codec->cache_ops = &cache_types[i];
1458 if (codec->cache_ops->init) {
1459 if (codec->cache_ops->name)
1460 dev_dbg(codec->dev, "Initializing %s cache for %s codec\n",
1461 codec->cache_ops->name, codec->name);
1462 return codec->cache_ops->init(codec);
1464 return -ENOSYS;
1468 * NOTE: keep in mind that this function might be called
1469 * multiple times.
1471 int snd_soc_cache_exit(struct snd_soc_codec *codec)
1473 if (codec->cache_ops && codec->cache_ops->exit) {
1474 if (codec->cache_ops->name)
1475 dev_dbg(codec->dev, "Destroying %s cache for %s codec\n",
1476 codec->cache_ops->name, codec->name);
1477 return codec->cache_ops->exit(codec);
1479 return -ENOSYS;
1483 * snd_soc_cache_read: Fetch the value of a given register from the cache.
1485 * @codec: CODEC to configure.
1486 * @reg: The register index.
1487 * @value: The value to be returned.
1489 int snd_soc_cache_read(struct snd_soc_codec *codec,
1490 unsigned int reg, unsigned int *value)
1492 int ret;
1494 mutex_lock(&codec->cache_rw_mutex);
1496 if (value && codec->cache_ops && codec->cache_ops->read) {
1497 ret = codec->cache_ops->read(codec, reg, value);
1498 mutex_unlock(&codec->cache_rw_mutex);
1499 return ret;
1502 mutex_unlock(&codec->cache_rw_mutex);
1503 return -ENOSYS;
1505 EXPORT_SYMBOL_GPL(snd_soc_cache_read);
1508 * snd_soc_cache_write: Set the value of a given register in the cache.
1510 * @codec: CODEC to configure.
1511 * @reg: The register index.
1512 * @value: The new register value.
1514 int snd_soc_cache_write(struct snd_soc_codec *codec,
1515 unsigned int reg, unsigned int value)
1517 int ret;
1519 mutex_lock(&codec->cache_rw_mutex);
1521 if (codec->cache_ops && codec->cache_ops->write) {
1522 ret = codec->cache_ops->write(codec, reg, value);
1523 mutex_unlock(&codec->cache_rw_mutex);
1524 return ret;
1527 mutex_unlock(&codec->cache_rw_mutex);
1528 return -ENOSYS;
1530 EXPORT_SYMBOL_GPL(snd_soc_cache_write);
1533 * snd_soc_cache_sync: Sync the register cache with the hardware.
1535 * @codec: CODEC to configure.
1537 * Any registers that should not be synced should be marked as
1538 * volatile. In general drivers can choose not to use the provided
1539 * syncing functionality if they so require.
1541 int snd_soc_cache_sync(struct snd_soc_codec *codec)
1543 int ret;
1544 const char *name;
1546 if (!codec->cache_sync) {
1547 return 0;
1550 if (!codec->cache_ops || !codec->cache_ops->sync)
1551 return -ENOSYS;
1553 if (codec->cache_ops->name)
1554 name = codec->cache_ops->name;
1555 else
1556 name = "unknown";
1558 if (codec->cache_ops->name)
1559 dev_dbg(codec->dev, "Syncing %s cache for %s codec\n",
1560 codec->cache_ops->name, codec->name);
1561 trace_snd_soc_cache_sync(codec, name, "start");
1562 ret = codec->cache_ops->sync(codec);
1563 if (!ret)
1564 codec->cache_sync = 0;
1565 trace_snd_soc_cache_sync(codec, name, "end");
1566 return ret;
1568 EXPORT_SYMBOL_GPL(snd_soc_cache_sync);
1570 static int snd_soc_get_reg_access_index(struct snd_soc_codec *codec,
1571 unsigned int reg)
1573 const struct snd_soc_codec_driver *codec_drv;
1574 unsigned int min, max, index;
1576 codec_drv = codec->driver;
1577 min = 0;
1578 max = codec_drv->reg_access_size - 1;
1579 do {
1580 index = (min + max) / 2;
1581 if (codec_drv->reg_access_default[index].reg == reg)
1582 return index;
1583 if (codec_drv->reg_access_default[index].reg < reg)
1584 min = index + 1;
1585 else
1586 max = index;
1587 } while (min <= max);
1588 return -1;
1591 int snd_soc_default_volatile_register(struct snd_soc_codec *codec,
1592 unsigned int reg)
1594 int index;
1596 if (reg >= codec->driver->reg_cache_size)
1597 return 1;
1598 index = snd_soc_get_reg_access_index(codec, reg);
1599 if (index < 0)
1600 return 0;
1601 return codec->driver->reg_access_default[index].vol;
1603 EXPORT_SYMBOL_GPL(snd_soc_default_volatile_register);
1605 int snd_soc_default_readable_register(struct snd_soc_codec *codec,
1606 unsigned int reg)
1608 int index;
1610 if (reg >= codec->driver->reg_cache_size)
1611 return 1;
1612 index = snd_soc_get_reg_access_index(codec, reg);
1613 if (index < 0)
1614 return 0;
1615 return codec->driver->reg_access_default[index].read;
1617 EXPORT_SYMBOL_GPL(snd_soc_default_readable_register);
1619 int snd_soc_default_writable_register(struct snd_soc_codec *codec,
1620 unsigned int reg)
1622 int index;
1624 if (reg >= codec->driver->reg_cache_size)
1625 return 1;
1626 index = snd_soc_get_reg_access_index(codec, reg);
1627 if (index < 0)
1628 return 0;
1629 return codec->driver->reg_access_default[index].write;
1631 EXPORT_SYMBOL_GPL(snd_soc_default_writable_register);