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