soc-cache.c revision 68d44ee0bc70be30ea1ee936e6e21082193386cf
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 21static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, 22 unsigned int reg) 23{ 24 int ret; 25 unsigned int val; 26 27 if (reg >= codec->driver->reg_cache_size || 28 snd_soc_codec_volatile_register(codec, reg)) { 29 if (codec->cache_only) 30 return -1; 31 32 BUG_ON(!codec->hw_read); 33 return codec->hw_read(codec, reg); 34 } 35 36 ret = snd_soc_cache_read(codec, reg, &val); 37 if (ret < 0) 38 return -1; 39 return val; 40} 41 42static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, 43 unsigned int value) 44{ 45 u8 data[2]; 46 int ret; 47 48 data[0] = (reg << 4) | ((value >> 8) & 0x000f); 49 data[1] = value & 0x00ff; 50 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; 56 } 57 58 if (codec->cache_only) { 59 codec->cache_sync = 1; 60 return 0; 61 } 62 63 ret = codec->hw_write(codec->control_data, data, 2); 64 if (ret == 2) 65 return 0; 66 if (ret < 0) 67 return ret; 68 else 69 return -EIO; 70} 71 72#if defined(CONFIG_SPI_MASTER) 73static int snd_soc_4_12_spi_write(void *control_data, const char *data, 74 int len) 75{ 76 struct spi_device *spi = control_data; 77 struct spi_transfer t; 78 struct spi_message m; 79 u8 msg[2]; 80 81 if (len <= 0) 82 return 0; 83 84 msg[0] = data[1]; 85 msg[1] = data[0]; 86 87 spi_message_init(&m); 88 memset(&t, 0, sizeof t); 89 90 t.tx_buf = &msg[0]; 91 t.len = len; 92 93 spi_message_add_tail(&t, &m); 94 spi_sync(spi, &m); 95 96 return len; 97} 98#else 99#define snd_soc_4_12_spi_write NULL 100#endif 101 102static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, 103 unsigned int reg) 104{ 105 int ret; 106 unsigned int val; 107 108 if (reg >= codec->driver->reg_cache_size || 109 snd_soc_codec_volatile_register(codec, reg)) { 110 if (codec->cache_only) 111 return -1; 112 113 BUG_ON(!codec->hw_read); 114 return codec->hw_read(codec, reg); 115 } 116 117 ret = snd_soc_cache_read(codec, reg, &val); 118 if (ret < 0) 119 return -1; 120 return val; 121} 122 123static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, 124 unsigned int value) 125{ 126 u8 data[2]; 127 int ret; 128 129 data[0] = (reg << 1) | ((value >> 8) & 0x0001); 130 data[1] = value & 0x00ff; 131 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; 137 } 138 139 if (codec->cache_only) { 140 codec->cache_sync = 1; 141 return 0; 142 } 143 144 ret = codec->hw_write(codec->control_data, data, 2); 145 if (ret == 2) 146 return 0; 147 if (ret < 0) 148 return ret; 149 else 150 return -EIO; 151} 152 153#if defined(CONFIG_SPI_MASTER) 154static int snd_soc_7_9_spi_write(void *control_data, const char *data, 155 int len) 156{ 157 struct spi_device *spi = control_data; 158 struct spi_transfer t; 159 struct spi_message m; 160 u8 msg[2]; 161 162 if (len <= 0) 163 return 0; 164 165 msg[0] = data[0]; 166 msg[1] = data[1]; 167 168 spi_message_init(&m); 169 memset(&t, 0, sizeof t); 170 171 t.tx_buf = &msg[0]; 172 t.len = len; 173 174 spi_message_add_tail(&t, &m); 175 spi_sync(spi, &m); 176 177 return len; 178} 179#else 180#define snd_soc_7_9_spi_write NULL 181#endif 182 183static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, 184 unsigned int value) 185{ 186 u8 data[2]; 187 int ret; 188 189 reg &= 0xff; 190 data[0] = reg; 191 data[1] = value & 0xff; 192 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; 198 } 199 200 if (codec->cache_only) { 201 codec->cache_sync = 1; 202 return 0; 203 } 204 205 if (codec->hw_write(codec->control_data, data, 2) == 2) 206 return 0; 207 else 208 return -EIO; 209} 210 211static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, 212 unsigned int reg) 213{ 214 int ret; 215 unsigned int val; 216 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; 222 223 BUG_ON(!codec->hw_read); 224 return codec->hw_read(codec, reg); 225 } 226 227 ret = snd_soc_cache_read(codec, reg, &val); 228 if (ret < 0) 229 return -1; 230 return val; 231} 232 233#if defined(CONFIG_SPI_MASTER) 234static int snd_soc_8_8_spi_write(void *control_data, const char *data, 235 int len) 236{ 237 struct spi_device *spi = control_data; 238 struct spi_transfer t; 239 struct spi_message m; 240 u8 msg[2]; 241 242 if (len <= 0) 243 return 0; 244 245 msg[0] = data[0]; 246 msg[1] = data[1]; 247 248 spi_message_init(&m); 249 memset(&t, 0, sizeof t); 250 251 t.tx_buf = &msg[0]; 252 t.len = len; 253 254 spi_message_add_tail(&t, &m); 255 spi_sync(spi, &m); 256 257 return len; 258} 259#else 260#define snd_soc_8_8_spi_write NULL 261#endif 262 263static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, 264 unsigned int value) 265{ 266 u8 data[3]; 267 int ret; 268 269 data[0] = reg; 270 data[1] = (value >> 8) & 0xff; 271 data[2] = value & 0xff; 272 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; 278 } 279 280 if (codec->cache_only) { 281 codec->cache_sync = 1; 282 return 0; 283 } 284 285 if (codec->hw_write(codec->control_data, data, 3) == 3) 286 return 0; 287 else 288 return -EIO; 289} 290 291static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, 292 unsigned int reg) 293{ 294 int ret; 295 unsigned int val; 296 297 if (reg >= codec->driver->reg_cache_size || 298 snd_soc_codec_volatile_register(codec, reg)) { 299 if (codec->cache_only) 300 return -1; 301 302 BUG_ON(!codec->hw_read); 303 return codec->hw_read(codec, reg); 304 } 305 306 ret = snd_soc_cache_read(codec, reg, &val); 307 if (ret < 0) 308 return -1; 309 return val; 310} 311 312#if defined(CONFIG_SPI_MASTER) 313static int snd_soc_8_16_spi_write(void *control_data, const char *data, 314 int len) 315{ 316 struct spi_device *spi = control_data; 317 struct spi_transfer t; 318 struct spi_message m; 319 u8 msg[3]; 320 321 if (len <= 0) 322 return 0; 323 324 msg[0] = data[0]; 325 msg[1] = data[1]; 326 msg[2] = data[2]; 327 328 spi_message_init(&m); 329 memset(&t, 0, sizeof t); 330 331 t.tx_buf = &msg[0]; 332 t.len = len; 333 334 spi_message_add_tail(&t, &m); 335 spi_sync(spi, &m); 336 337 return len; 338} 339#else 340#define snd_soc_8_16_spi_write NULL 341#endif 342 343#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 344static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec, 345 unsigned int r) 346{ 347 struct i2c_msg xfer[2]; 348 u8 reg = r; 349 u8 data; 350 int ret; 351 struct i2c_client *client = codec->control_data; 352 353 /* Write register */ 354 xfer[0].addr = client->addr; 355 xfer[0].flags = 0; 356 xfer[0].len = 1; 357 xfer[0].buf = ® 358 359 /* Read data */ 360 xfer[1].addr = client->addr; 361 xfer[1].flags = I2C_M_RD; 362 xfer[1].len = 1; 363 xfer[1].buf = &data; 364 365 ret = i2c_transfer(client->adapter, xfer, 2); 366 if (ret != 2) { 367 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); 368 return 0; 369 } 370 371 return data; 372} 373#else 374#define snd_soc_8_8_read_i2c NULL 375#endif 376 377#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 378static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, 379 unsigned int r) 380{ 381 struct i2c_msg xfer[2]; 382 u8 reg = r; 383 u16 data; 384 int ret; 385 struct i2c_client *client = codec->control_data; 386 387 /* Write register */ 388 xfer[0].addr = client->addr; 389 xfer[0].flags = 0; 390 xfer[0].len = 1; 391 xfer[0].buf = ® 392 393 /* Read data */ 394 xfer[1].addr = client->addr; 395 xfer[1].flags = I2C_M_RD; 396 xfer[1].len = 2; 397 xfer[1].buf = (u8 *)&data; 398 399 ret = i2c_transfer(client->adapter, xfer, 2); 400 if (ret != 2) { 401 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); 402 return 0; 403 } 404 405 return (data >> 8) | ((data & 0xff) << 8); 406} 407#else 408#define snd_soc_8_16_read_i2c NULL 409#endif 410 411#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 412static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec, 413 unsigned int r) 414{ 415 struct i2c_msg xfer[2]; 416 u16 reg = r; 417 u8 data; 418 int ret; 419 struct i2c_client *client = codec->control_data; 420 421 /* Write register */ 422 xfer[0].addr = client->addr; 423 xfer[0].flags = 0; 424 xfer[0].len = 2; 425 xfer[0].buf = (u8 *)® 426 427 /* Read data */ 428 xfer[1].addr = client->addr; 429 xfer[1].flags = I2C_M_RD; 430 xfer[1].len = 1; 431 xfer[1].buf = &data; 432 433 ret = i2c_transfer(client->adapter, xfer, 2); 434 if (ret != 2) { 435 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); 436 return 0; 437 } 438 439 return data; 440} 441#else 442#define snd_soc_16_8_read_i2c NULL 443#endif 444 445static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec, 446 unsigned int reg) 447{ 448 int ret; 449 unsigned int val; 450 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; 456 457 BUG_ON(!codec->hw_read); 458 return codec->hw_read(codec, reg); 459 } 460 461 ret = snd_soc_cache_read(codec, reg, &val); 462 if (ret < 0) 463 return -1; 464 return val; 465} 466 467static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, 468 unsigned int value) 469{ 470 u8 data[3]; 471 int ret; 472 473 data[0] = (reg >> 8) & 0xff; 474 data[1] = reg & 0xff; 475 data[2] = value; 476 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; 483 } 484 485 if (codec->cache_only) { 486 codec->cache_sync = 1; 487 return 0; 488 } 489 490 ret = codec->hw_write(codec->control_data, data, 3); 491 if (ret == 3) 492 return 0; 493 if (ret < 0) 494 return ret; 495 else 496 return -EIO; 497} 498 499#if defined(CONFIG_SPI_MASTER) 500static int snd_soc_16_8_spi_write(void *control_data, const char *data, 501 int len) 502{ 503 struct spi_device *spi = control_data; 504 struct spi_transfer t; 505 struct spi_message m; 506 u8 msg[3]; 507 508 if (len <= 0) 509 return 0; 510 511 msg[0] = data[0]; 512 msg[1] = data[1]; 513 msg[2] = data[2]; 514 515 spi_message_init(&m); 516 memset(&t, 0, sizeof t); 517 518 t.tx_buf = &msg[0]; 519 t.len = len; 520 521 spi_message_add_tail(&t, &m); 522 spi_sync(spi, &m); 523 524 return len; 525} 526#else 527#define snd_soc_16_8_spi_write NULL 528#endif 529 530#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 531static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, 532 unsigned int r) 533{ 534 struct i2c_msg xfer[2]; 535 u16 reg = cpu_to_be16(r); 536 u16 data; 537 int ret; 538 struct i2c_client *client = codec->control_data; 539 540 /* Write register */ 541 xfer[0].addr = client->addr; 542 xfer[0].flags = 0; 543 xfer[0].len = 2; 544 xfer[0].buf = (u8 *)® 545 546 /* Read data */ 547 xfer[1].addr = client->addr; 548 xfer[1].flags = I2C_M_RD; 549 xfer[1].len = 2; 550 xfer[1].buf = (u8 *)&data; 551 552 ret = i2c_transfer(client->adapter, xfer, 2); 553 if (ret != 2) { 554 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); 555 return 0; 556 } 557 558 return be16_to_cpu(data); 559} 560#else 561#define snd_soc_16_16_read_i2c NULL 562#endif 563 564static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec, 565 unsigned int reg) 566{ 567 int ret; 568 unsigned int val; 569 570 if (reg >= codec->driver->reg_cache_size || 571 snd_soc_codec_volatile_register(codec, reg)) { 572 if (codec->cache_only) 573 return -1; 574 575 BUG_ON(!codec->hw_read); 576 return codec->hw_read(codec, reg); 577 } 578 579 ret = snd_soc_cache_read(codec, reg, &val); 580 if (ret < 0) 581 return -1; 582 583 return val; 584} 585 586static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, 587 unsigned int value) 588{ 589 u8 data[4]; 590 int ret; 591 592 data[0] = (reg >> 8) & 0xff; 593 data[1] = reg & 0xff; 594 data[2] = (value >> 8) & 0xff; 595 data[3] = value & 0xff; 596 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; 602 } 603 604 if (codec->cache_only) { 605 codec->cache_sync = 1; 606 return 0; 607 } 608 609 ret = codec->hw_write(codec->control_data, data, 4); 610 if (ret == 4) 611 return 0; 612 if (ret < 0) 613 return ret; 614 else 615 return -EIO; 616} 617 618#if defined(CONFIG_SPI_MASTER) 619static int snd_soc_16_16_spi_write(void *control_data, const char *data, 620 int len) 621{ 622 struct spi_device *spi = control_data; 623 struct spi_transfer t; 624 struct spi_message m; 625 u8 msg[4]; 626 627 if (len <= 0) 628 return 0; 629 630 msg[0] = data[0]; 631 msg[1] = data[1]; 632 msg[2] = data[2]; 633 msg[3] = data[3]; 634 635 spi_message_init(&m); 636 memset(&t, 0, sizeof t); 637 638 t.tx_buf = &msg[0]; 639 t.len = len; 640 641 spi_message_add_tail(&t, &m); 642 spi_sync(spi, &m); 643 644 return len; 645} 646#else 647#define snd_soc_16_16_spi_write NULL 648#endif 649 650static 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[] = { 658 { 659 .addr_bits = 4, .data_bits = 12, 660 .write = snd_soc_4_12_write, .read = snd_soc_4_12_read, 661 .spi_write = snd_soc_4_12_spi_write, 662 }, 663 { 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, 667 }, 668 { 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, 673 }, 674 { 675 .addr_bits = 8, .data_bits = 16, 676 .write = snd_soc_8_16_write, .read = snd_soc_8_16_read, 677 .i2c_read = snd_soc_8_16_read_i2c, 678 .spi_write = snd_soc_8_16_spi_write, 679 }, 680 { 681 .addr_bits = 16, .data_bits = 8, 682 .write = snd_soc_16_8_write, .read = snd_soc_16_8_read, 683 .i2c_read = snd_soc_16_8_read_i2c, 684 .spi_write = snd_soc_16_8_spi_write, 685 }, 686 { 687 .addr_bits = 16, .data_bits = 16, 688 .write = snd_soc_16_16_write, .read = snd_soc_16_16_read, 689 .i2c_read = snd_soc_16_16_read_i2c, 690 .spi_write = snd_soc_16_16_spi_write, 691 }, 692}; 693 694/** 695 * snd_soc_codec_set_cache_io: Set up standard I/O functions. 696 * 697 * @codec: CODEC to configure. 698 * @type: Type of cache. 699 * @addr_bits: Number of bits of register address data. 700 * @data_bits: Number of bits of data per register. 701 * @control: Control bus used. 702 * 703 * Register formats are frequently shared between many I2C and SPI 704 * devices. In order to promote code reuse the ASoC core provides 705 * some standard implementations of CODEC read and write operations 706 * which can be set up using this function. 707 * 708 * The caller is responsible for allocating and initialising the 709 * actual cache. 710 * 711 * Note that at present this code cannot be used by CODECs with 712 * volatile registers. 713 */ 714int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, 715 int addr_bits, int data_bits, 716 enum snd_soc_control_type control) 717{ 718 int i; 719 720 for (i = 0; i < ARRAY_SIZE(io_types); i++) 721 if (io_types[i].addr_bits == addr_bits && 722 io_types[i].data_bits == data_bits) 723 break; 724 if (i == ARRAY_SIZE(io_types)) { 725 printk(KERN_ERR 726 "No I/O functions for %d bit address %d bit data\n", 727 addr_bits, data_bits); 728 return -EINVAL; 729 } 730 731 codec->write = io_types[i].write; 732 codec->read = io_types[i].read; 733 734 switch (control) { 735 case SND_SOC_CUSTOM: 736 break; 737 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; 744 745 codec->control_data = container_of(codec->dev, 746 struct i2c_client, 747 dev); 748 break; 749 750 case SND_SOC_SPI: 751 if (io_types[i].spi_write) 752 codec->hw_write = io_types[i].spi_write; 753 754 codec->control_data = container_of(codec->dev, 755 struct spi_device, 756 dev); 757 break; 758 } 759 760 return 0; 761} 762EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); 763 764struct snd_soc_rbtree_node { 765 struct rb_node node; 766 unsigned int reg; 767 unsigned int value; 768 unsigned int defval; 769} __attribute__ ((packed)); 770 771struct snd_soc_rbtree_ctx { 772 struct rb_root root; 773}; 774 775static struct snd_soc_rbtree_node *snd_soc_rbtree_lookup( 776 struct rb_root *root, unsigned int reg) 777{ 778 struct rb_node *node; 779 struct snd_soc_rbtree_node *rbnode; 780 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; 790 } 791 792 return NULL; 793} 794 795static int snd_soc_rbtree_insert(struct rb_root *root, 796 struct snd_soc_rbtree_node *rbnode) 797{ 798 struct rb_node **new, *parent; 799 struct snd_soc_rbtree_node *rbnode_tmp; 800 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; 813 } 814 815 /* insert the node into the rbtree */ 816 rb_link_node(&rbnode->node, parent, new); 817 rb_insert_color(&rbnode->node, root); 818 819 return 1; 820} 821 822static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec) 823{ 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; 829 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); 843 } 844 845 return 0; 846} 847 848static int snd_soc_rbtree_cache_write(struct snd_soc_codec *codec, 849 unsigned int reg, unsigned int value) 850{ 851 struct snd_soc_rbtree_ctx *rbtree_ctx; 852 struct snd_soc_rbtree_node *rbnode; 853 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; 864 /* 865 * for uninitialized registers whose value is changed 866 * from the default zero, create an rbnode and insert 867 * it into the tree. 868 */ 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); 875 } 876 877 return 0; 878} 879 880static int snd_soc_rbtree_cache_read(struct snd_soc_codec *codec, 881 unsigned int reg, unsigned int *value) 882{ 883 struct snd_soc_rbtree_ctx *rbtree_ctx; 884 struct snd_soc_rbtree_node *rbnode; 885 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; 893 } 894 895 return 0; 896} 897 898static int snd_soc_rbtree_cache_exit(struct snd_soc_codec *codec) 899{ 900 struct rb_node *next; 901 struct snd_soc_rbtree_ctx *rbtree_ctx; 902 struct snd_soc_rbtree_node *rbtree_node; 903 904 /* if we've already been called then just return */ 905 rbtree_ctx = codec->reg_cache; 906 if (!rbtree_ctx) 907 return 0; 908 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); 916 } 917 918 /* release the resources */ 919 kfree(codec->reg_cache); 920 codec->reg_cache = NULL; 921 922 return 0; 923} 924 925static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec) 926{ 927 struct snd_soc_rbtree_ctx *rbtree_ctx; 928 929 codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL); 930 if (!codec->reg_cache) 931 return -ENOMEM; 932 933 rbtree_ctx = codec->reg_cache; 934 rbtree_ctx->root = RB_ROOT; 935 936 if (!codec->reg_def_copy) 937 return 0; 938 939/* 940 * populate the rbtree with the initialized registers. All other 941 * registers will be inserted into the tree when they are first written. 942 * 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. 947 */ 948#define snd_soc_rbtree_populate(cache) \ 949({ \ 950 int ret, i; \ 951 struct snd_soc_rbtree_node *rbtree_node; \ 952 \ 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; \ 963 } \ 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); \ 969 } \ 970 ret; \ 971}) 972 973 switch (codec->driver->reg_word_size) { 974 case 1: { 975 const u8 *cache; 976 977 return snd_soc_rbtree_populate(cache); 978 } 979 case 2: { 980 const u16 *cache; 981 982 return snd_soc_rbtree_populate(cache); 983 } 984 default: 985 BUG(); 986 } 987 988 return 0; 989} 990 991#ifdef CONFIG_SND_SOC_CACHE_LZO 992struct 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; 1001}; 1002 1003#define LZO_BLOCK_NUM 8 1004static int snd_soc_lzo_block_count(void) 1005{ 1006 return LZO_BLOCK_NUM; 1007} 1008 1009static int snd_soc_lzo_prepare(struct snd_soc_lzo_ctx *lzo_ctx) 1010{ 1011 lzo_ctx->wmem = kmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); 1012 if (!lzo_ctx->wmem) 1013 return -ENOMEM; 1014 return 0; 1015} 1016 1017static int snd_soc_lzo_compress(struct snd_soc_lzo_ctx *lzo_ctx) 1018{ 1019 size_t compress_size; 1020 int ret; 1021 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; 1028} 1029 1030static int snd_soc_lzo_decompress(struct snd_soc_lzo_ctx *lzo_ctx) 1031{ 1032 size_t dst_len; 1033 int ret; 1034 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; 1041} 1042 1043static int snd_soc_lzo_compress_cache_block(struct snd_soc_codec *codec, 1044 struct snd_soc_lzo_ctx *lzo_ctx) 1045{ 1046 int ret; 1047 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; 1053 } 1054 1055 ret = snd_soc_lzo_compress(lzo_ctx); 1056 if (ret < 0) 1057 return ret; 1058 return 0; 1059} 1060 1061static int snd_soc_lzo_decompress_cache_block(struct snd_soc_codec *codec, 1062 struct snd_soc_lzo_ctx *lzo_ctx) 1063{ 1064 int ret; 1065 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; 1071 } 1072 1073 ret = snd_soc_lzo_decompress(lzo_ctx); 1074 if (ret < 0) 1075 return ret; 1076 return 0; 1077} 1078 1079static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec, 1080 unsigned int reg) 1081{ 1082 const struct snd_soc_codec_driver *codec_drv; 1083 size_t reg_size; 1084 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()); 1089} 1090 1091static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec, 1092 unsigned int reg) 1093{ 1094 const struct snd_soc_codec_driver *codec_drv; 1095 size_t reg_size; 1096 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); 1101} 1102 1103static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec) 1104{ 1105 const struct snd_soc_codec_driver *codec_drv; 1106 size_t reg_size; 1107 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()); 1111} 1112 1113static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec) 1114{ 1115 struct snd_soc_lzo_ctx **lzo_blocks; 1116 unsigned int val; 1117 int i; 1118 int ret; 1119 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); 1130 } 1131 1132 return 0; 1133} 1134 1135static int snd_soc_lzo_cache_write(struct snd_soc_codec *codec, 1136 unsigned int reg, unsigned int value) 1137{ 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; 1142 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]; 1151 1152 /* save the pointer and length of the compressed block */ 1153 tmp_dst = lzo_block->dst; 1154 tmp_dst_len = lzo_block->dst_len; 1155 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; 1159 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; 1165 } 1166 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; 1175 } 1176 cache[blkpos] = value; 1177 } 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; 1185 } 1186 cache[blkpos] = value; 1187 } 1188 break; 1189 default: 1190 BUG(); 1191 } 1192 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; 1196 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; 1203 } 1204 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; 1210out: 1211 lzo_block->dst = tmp_dst; 1212 lzo_block->dst_len = tmp_dst_len; 1213 return ret; 1214} 1215 1216static int snd_soc_lzo_cache_read(struct snd_soc_codec *codec, 1217 unsigned int reg, unsigned int *value) 1218{ 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; 1223 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]; 1233 1234 /* save the pointer and length of the compressed block */ 1235 tmp_dst = lzo_block->dst; 1236 tmp_dst_len = lzo_block->dst_len; 1237 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; 1241 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]; 1251 } 1252 break; 1253 case 2: { 1254 u16 *cache; 1255 cache = lzo_block->dst; 1256 *value = cache[blkpos]; 1257 } 1258 break; 1259 default: 1260 BUG(); 1261 } 1262 } 1263 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; 1269} 1270 1271static int snd_soc_lzo_cache_exit(struct snd_soc_codec *codec) 1272{ 1273 struct snd_soc_lzo_ctx **lzo_blocks; 1274 int i, blkcount; 1275 1276 lzo_blocks = codec->reg_cache; 1277 if (!lzo_blocks) 1278 return 0; 1279 1280 blkcount = snd_soc_lzo_block_count(); 1281 /* 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. 1285 */ 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); 1292 } 1293 /* each lzo_block is a pointer returned by kmalloc or NULL */ 1294 kfree(lzo_blocks[i]); 1295 } 1296 kfree(lzo_blocks); 1297 codec->reg_cache = NULL; 1298 return 0; 1299} 1300 1301static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec) 1302{ 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; 1309 1310 ret = 0; 1311 codec_drv = codec->driver; 1312 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; 1313 1314 /* 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. 1318 */ 1319 tofree = 0; 1320 if (!codec->reg_def_copy) 1321 tofree = 1; 1322 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; 1328 } 1329 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; 1336 } 1337 lzo_blocks = codec->reg_cache; 1338 1339 /* 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. 1344 */ 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; 1351 } 1352 bitmap_zero(sync_bmp, bmp_size); 1353 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; 1362 } 1363 lzo_blocks[i]->sync_bmp = sync_bmp; 1364 lzo_blocks[i]->sync_bmp_nbits = reg_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; 1369 } 1370 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; 1387 } 1388 1389 if (tofree) { 1390 kfree(codec->reg_def_copy); 1391 codec->reg_def_copy = NULL; 1392 } 1393 return 0; 1394err: 1395 snd_soc_cache_exit(codec); 1396err_tofree: 1397 if (tofree) { 1398 kfree(codec->reg_def_copy); 1399 codec->reg_def_copy = NULL; 1400 } 1401 return ret; 1402} 1403#endif 1404 1405static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) 1406{ 1407 int i; 1408 int ret; 1409 const struct snd_soc_codec_driver *codec_drv; 1410 unsigned int val; 1411 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; 1421 1422 cache = codec_drv->reg_cache_default; 1423 if (cache[i] == val) 1424 continue; 1425 } 1426 break; 1427 case 2: { 1428 const u16 *cache; 1429 1430 cache = codec_drv->reg_cache_default; 1431 if (cache[i] == val) 1432 continue; 1433 } 1434 break; 1435 default: 1436 BUG(); 1437 } 1438 } 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); 1444 } 1445 return 0; 1446} 1447 1448static int snd_soc_flat_cache_write(struct snd_soc_codec *codec, 1449 unsigned int reg, unsigned int value) 1450{ 1451 switch (codec->driver->reg_word_size) { 1452 case 1: { 1453 u8 *cache; 1454 1455 cache = codec->reg_cache; 1456 cache[reg] = value; 1457 } 1458 break; 1459 case 2: { 1460 u16 *cache; 1461 1462 cache = codec->reg_cache; 1463 cache[reg] = value; 1464 } 1465 break; 1466 default: 1467 BUG(); 1468 } 1469 1470 return 0; 1471} 1472 1473static int snd_soc_flat_cache_read(struct snd_soc_codec *codec, 1474 unsigned int reg, unsigned int *value) 1475{ 1476 switch (codec->driver->reg_word_size) { 1477 case 1: { 1478 u8 *cache; 1479 1480 cache = codec->reg_cache; 1481 *value = cache[reg]; 1482 } 1483 break; 1484 case 2: { 1485 u16 *cache; 1486 1487 cache = codec->reg_cache; 1488 *value = cache[reg]; 1489 } 1490 break; 1491 default: 1492 BUG(); 1493 } 1494 1495 return 0; 1496} 1497 1498static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec) 1499{ 1500 if (!codec->reg_cache) 1501 return 0; 1502 kfree(codec->reg_cache); 1503 codec->reg_cache = NULL; 1504 return 0; 1505} 1506 1507static int snd_soc_flat_cache_init(struct snd_soc_codec *codec) 1508{ 1509 const struct snd_soc_codec_driver *codec_drv; 1510 size_t reg_size; 1511 1512 codec_drv = codec->driver; 1513 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; 1514 1515 /* 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 1519 */ 1520 kfree(codec->reg_def_copy); 1521 codec->reg_def_copy = NULL; 1522 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; 1530 1531 return 0; 1532} 1533 1534/* an array of all supported compression types */ 1535static const struct snd_soc_cache_ops cache_types[] = { 1536 /* Flat *must* be the first entry for fallback */ 1537 { 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 1545 }, 1546#ifdef CONFIG_SND_SOC_CACHE_LZO 1547 { 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 1555 }, 1556#endif 1557 { 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 1565 } 1566}; 1567 1568int snd_soc_cache_init(struct snd_soc_codec *codec) 1569{ 1570 int i; 1571 1572 for (i = 0; i < ARRAY_SIZE(cache_types); ++i) 1573 if (cache_types[i].id == codec->compress_type) 1574 break; 1575 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; 1581 } 1582 1583 mutex_init(&codec->cache_rw_mutex); 1584 codec->cache_ops = &cache_types[i]; 1585 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); 1591 } 1592 return -EINVAL; 1593} 1594 1595/* 1596 * NOTE: keep in mind that this function might be called 1597 * multiple times. 1598 */ 1599int snd_soc_cache_exit(struct snd_soc_codec *codec) 1600{ 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); 1606 } 1607 return -EINVAL; 1608} 1609 1610/** 1611 * snd_soc_cache_read: Fetch the value of a given register from the cache. 1612 * 1613 * @codec: CODEC to configure. 1614 * @reg: The register index. 1615 * @value: The value to be returned. 1616 */ 1617int snd_soc_cache_read(struct snd_soc_codec *codec, 1618 unsigned int reg, unsigned int *value) 1619{ 1620 int ret; 1621 1622 mutex_lock(&codec->cache_rw_mutex); 1623 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; 1628 } 1629 1630 mutex_unlock(&codec->cache_rw_mutex); 1631 return -EINVAL; 1632} 1633EXPORT_SYMBOL_GPL(snd_soc_cache_read); 1634 1635/** 1636 * snd_soc_cache_write: Set the value of a given register in the cache. 1637 * 1638 * @codec: CODEC to configure. 1639 * @reg: The register index. 1640 * @value: The new register value. 1641 */ 1642int snd_soc_cache_write(struct snd_soc_codec *codec, 1643 unsigned int reg, unsigned int value) 1644{ 1645 int ret; 1646 1647 mutex_lock(&codec->cache_rw_mutex); 1648 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; 1653 } 1654 1655 mutex_unlock(&codec->cache_rw_mutex); 1656 return -EINVAL; 1657} 1658EXPORT_SYMBOL_GPL(snd_soc_cache_write); 1659 1660/** 1661 * snd_soc_cache_sync: Sync the register cache with the hardware. 1662 * 1663 * @codec: CODEC to configure. 1664 * 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. 1668 */ 1669int snd_soc_cache_sync(struct snd_soc_codec *codec) 1670{ 1671 int ret; 1672 1673 if (!codec->cache_sync) { 1674 return 0; 1675 } 1676 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; 1685 } 1686 1687 return -EINVAL; 1688} 1689EXPORT_SYMBOL_GPL(snd_soc_cache_sync); 1690