soc-cache.c revision 3e13f65e3aa51fc7009afc554683a0b182c057f5
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 18static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, 19 unsigned int reg) 20{ 21 u16 *cache = codec->reg_cache; 22 if (reg >= codec->driver->reg_cache_size) 23 return -1; 24 return cache[reg]; 25} 26 27static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, 28 unsigned int value) 29{ 30 u16 *cache = codec->reg_cache; 31 u8 data[2]; 32 int ret; 33 34 BUG_ON(codec->driver->volatile_register); 35 36 data[0] = (reg << 4) | ((value >> 8) & 0x000f); 37 data[1] = value & 0x00ff; 38 39 if (reg < codec->driver->reg_cache_size) 40 cache[reg] = value; 41 42 if (codec->cache_only) { 43 codec->cache_sync = 1; 44 return 0; 45 } 46 47 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); 48 49 ret = codec->hw_write(codec->control_data, data, 2); 50 if (ret == 2) 51 return 0; 52 if (ret < 0) 53 return ret; 54 else 55 return -EIO; 56} 57 58#if defined(CONFIG_SPI_MASTER) 59static int snd_soc_4_12_spi_write(void *control_data, const char *data, 60 int len) 61{ 62 struct spi_device *spi = control_data; 63 struct spi_transfer t; 64 struct spi_message m; 65 u8 msg[2]; 66 67 if (len <= 0) 68 return 0; 69 70 msg[0] = data[1]; 71 msg[1] = data[0]; 72 73 spi_message_init(&m); 74 memset(&t, 0, (sizeof t)); 75 76 t.tx_buf = &msg[0]; 77 t.len = len; 78 79 spi_message_add_tail(&t, &m); 80 spi_sync(spi, &m); 81 82 return len; 83} 84#else 85#define snd_soc_4_12_spi_write NULL 86#endif 87 88static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, 89 unsigned int reg) 90{ 91 u16 *cache = codec->reg_cache; 92 if (reg >= codec->driver->reg_cache_size) 93 return -1; 94 return cache[reg]; 95} 96 97static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, 98 unsigned int value) 99{ 100 u16 *cache = codec->reg_cache; 101 u8 data[2]; 102 int ret; 103 104 BUG_ON(codec->driver->volatile_register); 105 106 data[0] = (reg << 1) | ((value >> 8) & 0x0001); 107 data[1] = value & 0x00ff; 108 109 if (reg < codec->driver->reg_cache_size) 110 cache[reg] = value; 111 112 if (codec->cache_only) { 113 codec->cache_sync = 1; 114 return 0; 115 } 116 117 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); 118 119 ret = codec->hw_write(codec->control_data, data, 2); 120 if (ret == 2) 121 return 0; 122 if (ret < 0) 123 return ret; 124 else 125 return -EIO; 126} 127 128#if defined(CONFIG_SPI_MASTER) 129static int snd_soc_7_9_spi_write(void *control_data, const char *data, 130 int len) 131{ 132 struct spi_device *spi = control_data; 133 struct spi_transfer t; 134 struct spi_message m; 135 u8 msg[2]; 136 137 if (len <= 0) 138 return 0; 139 140 msg[0] = data[0]; 141 msg[1] = data[1]; 142 143 spi_message_init(&m); 144 memset(&t, 0, (sizeof t)); 145 146 t.tx_buf = &msg[0]; 147 t.len = len; 148 149 spi_message_add_tail(&t, &m); 150 spi_sync(spi, &m); 151 152 return len; 153} 154#else 155#define snd_soc_7_9_spi_write NULL 156#endif 157 158static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, 159 unsigned int value) 160{ 161 u8 *cache = codec->reg_cache; 162 u8 data[2]; 163 164 BUG_ON(codec->driver->volatile_register); 165 166 reg &= 0xff; 167 data[0] = reg; 168 data[1] = value & 0xff; 169 170 if (reg < codec->driver->reg_cache_size) 171 cache[reg] = value; 172 173 if (codec->cache_only) { 174 codec->cache_sync = 1; 175 return 0; 176 } 177 178 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); 179 180 if (codec->hw_write(codec->control_data, data, 2) == 2) 181 return 0; 182 else 183 return -EIO; 184} 185 186static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, 187 unsigned int reg) 188{ 189 u8 *cache = codec->reg_cache; 190 reg &= 0xff; 191 if (reg >= codec->driver->reg_cache_size) 192 return -1; 193 return cache[reg]; 194} 195 196static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, 197 unsigned int value) 198{ 199 u16 *reg_cache = codec->reg_cache; 200 u8 data[3]; 201 202 data[0] = reg; 203 data[1] = (value >> 8) & 0xff; 204 data[2] = value & 0xff; 205 206 if (!snd_soc_codec_volatile_register(codec, reg) && 207 reg < codec->driver->reg_cache_size) 208 reg_cache[reg] = value; 209 210 if (codec->cache_only) { 211 codec->cache_sync = 1; 212 return 0; 213 } 214 215 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); 216 217 if (codec->hw_write(codec->control_data, data, 3) == 3) 218 return 0; 219 else 220 return -EIO; 221} 222 223static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, 224 unsigned int reg) 225{ 226 u16 *cache = codec->reg_cache; 227 228 if (reg >= codec->driver->reg_cache_size || 229 snd_soc_codec_volatile_register(codec, reg)) { 230 if (codec->cache_only) 231 return -1; 232 233 return codec->hw_read(codec, reg); 234 } else { 235 return cache[reg]; 236 } 237} 238 239#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 240static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec, 241 unsigned int r) 242{ 243 struct i2c_msg xfer[2]; 244 u8 reg = r; 245 u8 data; 246 int ret; 247 struct i2c_client *client = codec->control_data; 248 249 /* Write register */ 250 xfer[0].addr = client->addr; 251 xfer[0].flags = 0; 252 xfer[0].len = 1; 253 xfer[0].buf = ® 254 255 /* Read data */ 256 xfer[1].addr = client->addr; 257 xfer[1].flags = I2C_M_RD; 258 xfer[1].len = 1; 259 xfer[1].buf = &data; 260 261 ret = i2c_transfer(client->adapter, xfer, 2); 262 if (ret != 2) { 263 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); 264 return 0; 265 } 266 267 return data; 268} 269#else 270#define snd_soc_8_8_read_i2c NULL 271#endif 272 273#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 274static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, 275 unsigned int r) 276{ 277 struct i2c_msg xfer[2]; 278 u8 reg = r; 279 u16 data; 280 int ret; 281 struct i2c_client *client = codec->control_data; 282 283 /* Write register */ 284 xfer[0].addr = client->addr; 285 xfer[0].flags = 0; 286 xfer[0].len = 1; 287 xfer[0].buf = ® 288 289 /* Read data */ 290 xfer[1].addr = client->addr; 291 xfer[1].flags = I2C_M_RD; 292 xfer[1].len = 2; 293 xfer[1].buf = (u8 *)&data; 294 295 ret = i2c_transfer(client->adapter, xfer, 2); 296 if (ret != 2) { 297 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); 298 return 0; 299 } 300 301 return (data >> 8) | ((data & 0xff) << 8); 302} 303#else 304#define snd_soc_8_16_read_i2c NULL 305#endif 306 307#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 308static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec, 309 unsigned int r) 310{ 311 struct i2c_msg xfer[2]; 312 u16 reg = r; 313 u8 data; 314 int ret; 315 struct i2c_client *client = codec->control_data; 316 317 /* Write register */ 318 xfer[0].addr = client->addr; 319 xfer[0].flags = 0; 320 xfer[0].len = 2; 321 xfer[0].buf = (u8 *)® 322 323 /* Read data */ 324 xfer[1].addr = client->addr; 325 xfer[1].flags = I2C_M_RD; 326 xfer[1].len = 1; 327 xfer[1].buf = &data; 328 329 ret = i2c_transfer(client->adapter, xfer, 2); 330 if (ret != 2) { 331 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); 332 return 0; 333 } 334 335 return data; 336} 337#else 338#define snd_soc_16_8_read_i2c NULL 339#endif 340 341static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec, 342 unsigned int reg) 343{ 344 u8 *cache = codec->reg_cache; 345 346 reg &= 0xff; 347 if (reg >= codec->driver->reg_cache_size) 348 return -1; 349 return cache[reg]; 350} 351 352static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, 353 unsigned int value) 354{ 355 u8 *cache = codec->reg_cache; 356 u8 data[3]; 357 int ret; 358 359 BUG_ON(codec->driver->volatile_register); 360 361 data[0] = (reg >> 8) & 0xff; 362 data[1] = reg & 0xff; 363 data[2] = value; 364 365 reg &= 0xff; 366 if (reg < codec->driver->reg_cache_size) 367 cache[reg] = value; 368 369 if (codec->cache_only) { 370 codec->cache_sync = 1; 371 return 0; 372 } 373 374 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); 375 376 ret = codec->hw_write(codec->control_data, data, 3); 377 if (ret == 3) 378 return 0; 379 if (ret < 0) 380 return ret; 381 else 382 return -EIO; 383} 384 385#if defined(CONFIG_SPI_MASTER) 386static int snd_soc_16_8_spi_write(void *control_data, const char *data, 387 int len) 388{ 389 struct spi_device *spi = control_data; 390 struct spi_transfer t; 391 struct spi_message m; 392 u8 msg[3]; 393 394 if (len <= 0) 395 return 0; 396 397 msg[0] = data[0]; 398 msg[1] = data[1]; 399 msg[2] = data[2]; 400 401 spi_message_init(&m); 402 memset(&t, 0, (sizeof t)); 403 404 t.tx_buf = &msg[0]; 405 t.len = len; 406 407 spi_message_add_tail(&t, &m); 408 spi_sync(spi, &m); 409 410 return len; 411} 412#else 413#define snd_soc_16_8_spi_write NULL 414#endif 415 416#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 417static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, 418 unsigned int r) 419{ 420 struct i2c_msg xfer[2]; 421 u16 reg = cpu_to_be16(r); 422 u16 data; 423 int ret; 424 struct i2c_client *client = codec->control_data; 425 426 /* Write register */ 427 xfer[0].addr = client->addr; 428 xfer[0].flags = 0; 429 xfer[0].len = 2; 430 xfer[0].buf = (u8 *)® 431 432 /* Read data */ 433 xfer[1].addr = client->addr; 434 xfer[1].flags = I2C_M_RD; 435 xfer[1].len = 2; 436 xfer[1].buf = (u8 *)&data; 437 438 ret = i2c_transfer(client->adapter, xfer, 2); 439 if (ret != 2) { 440 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); 441 return 0; 442 } 443 444 return be16_to_cpu(data); 445} 446#else 447#define snd_soc_16_16_read_i2c NULL 448#endif 449 450static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec, 451 unsigned int reg) 452{ 453 u16 *cache = codec->reg_cache; 454 455 if (reg >= codec->driver->reg_cache_size || 456 snd_soc_codec_volatile_register(codec, reg)) { 457 if (codec->cache_only) 458 return -1; 459 460 return codec->hw_read(codec, reg); 461 } 462 463 return cache[reg]; 464} 465 466static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, 467 unsigned int value) 468{ 469 u16 *cache = codec->reg_cache; 470 u8 data[4]; 471 int ret; 472 473 data[0] = (reg >> 8) & 0xff; 474 data[1] = reg & 0xff; 475 data[2] = (value >> 8) & 0xff; 476 data[3] = value & 0xff; 477 478 if (reg < codec->driver->reg_cache_size) 479 cache[reg] = value; 480 481 if (codec->cache_only) { 482 codec->cache_sync = 1; 483 return 0; 484 } 485 486 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); 487 488 ret = codec->hw_write(codec->control_data, data, 4); 489 if (ret == 4) 490 return 0; 491 if (ret < 0) 492 return ret; 493 else 494 return -EIO; 495} 496 497static struct { 498 int addr_bits; 499 int data_bits; 500 int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int); 501 int (*spi_write)(void *, const char *, int); 502 unsigned int (*read)(struct snd_soc_codec *, unsigned int); 503 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int); 504} io_types[] = { 505 { 506 .addr_bits = 4, .data_bits = 12, 507 .write = snd_soc_4_12_write, .read = snd_soc_4_12_read, 508 .spi_write = snd_soc_4_12_spi_write, 509 }, 510 { 511 .addr_bits = 7, .data_bits = 9, 512 .write = snd_soc_7_9_write, .read = snd_soc_7_9_read, 513 .spi_write = snd_soc_7_9_spi_write, 514 }, 515 { 516 .addr_bits = 8, .data_bits = 8, 517 .write = snd_soc_8_8_write, .read = snd_soc_8_8_read, 518 .i2c_read = snd_soc_8_8_read_i2c, 519 }, 520 { 521 .addr_bits = 8, .data_bits = 16, 522 .write = snd_soc_8_16_write, .read = snd_soc_8_16_read, 523 .i2c_read = snd_soc_8_16_read_i2c, 524 }, 525 { 526 .addr_bits = 16, .data_bits = 8, 527 .write = snd_soc_16_8_write, .read = snd_soc_16_8_read, 528 .i2c_read = snd_soc_16_8_read_i2c, 529 .spi_write = snd_soc_16_8_spi_write, 530 }, 531 { 532 .addr_bits = 16, .data_bits = 16, 533 .write = snd_soc_16_16_write, .read = snd_soc_16_16_read, 534 .i2c_read = snd_soc_16_16_read_i2c, 535 }, 536}; 537 538/** 539 * snd_soc_codec_set_cache_io: Set up standard I/O functions. 540 * 541 * @codec: CODEC to configure. 542 * @type: Type of cache. 543 * @addr_bits: Number of bits of register address data. 544 * @data_bits: Number of bits of data per register. 545 * @control: Control bus used. 546 * 547 * Register formats are frequently shared between many I2C and SPI 548 * devices. In order to promote code reuse the ASoC core provides 549 * some standard implementations of CODEC read and write operations 550 * which can be set up using this function. 551 * 552 * The caller is responsible for allocating and initialising the 553 * actual cache. 554 * 555 * Note that at present this code cannot be used by CODECs with 556 * volatile registers. 557 */ 558int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, 559 int addr_bits, int data_bits, 560 enum snd_soc_control_type control) 561{ 562 int i; 563 564 for (i = 0; i < ARRAY_SIZE(io_types); i++) 565 if (io_types[i].addr_bits == addr_bits && 566 io_types[i].data_bits == data_bits) 567 break; 568 if (i == ARRAY_SIZE(io_types)) { 569 printk(KERN_ERR 570 "No I/O functions for %d bit address %d bit data\n", 571 addr_bits, data_bits); 572 return -EINVAL; 573 } 574 575 codec->driver->write = io_types[i].write; 576 codec->driver->read = io_types[i].read; 577 578 switch (control) { 579 case SND_SOC_CUSTOM: 580 break; 581 582 case SND_SOC_I2C: 583#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 584 codec->hw_write = (hw_write_t)i2c_master_send; 585#endif 586 if (io_types[i].i2c_read) 587 codec->hw_read = io_types[i].i2c_read; 588 589 codec->control_data = container_of(codec->dev, 590 struct i2c_client, 591 dev); 592 break; 593 594 case SND_SOC_SPI: 595 if (io_types[i].spi_write) 596 codec->hw_write = io_types[i].spi_write; 597 598 codec->control_data = container_of(codec->dev, 599 struct spi_device, 600 dev); 601 break; 602 } 603 604 return 0; 605} 606EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); 607