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