diff options
Diffstat (limited to 'sound/soc/soc-cache.c')
| -rw-r--r-- | sound/soc/soc-cache.c | 134 |
1 files changed, 133 insertions, 1 deletions
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 5869dc3be781..472af38188c1 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c | |||
| @@ -44,6 +44,8 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, | |||
| 44 | return 0; | 44 | return 0; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); | ||
| 48 | |||
| 47 | ret = codec->hw_write(codec->control_data, data, 2); | 49 | ret = codec->hw_write(codec->control_data, data, 2); |
| 48 | if (ret == 2) | 50 | if (ret == 2) |
| 49 | return 0; | 51 | return 0; |
| @@ -112,6 +114,8 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, | |||
| 112 | return 0; | 114 | return 0; |
| 113 | } | 115 | } |
| 114 | 116 | ||
| 117 | dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); | ||
| 118 | |||
| 115 | ret = codec->hw_write(codec->control_data, data, 2); | 119 | ret = codec->hw_write(codec->control_data, data, 2); |
| 116 | if (ret == 2) | 120 | if (ret == 2) |
| 117 | return 0; | 121 | return 0; |
| @@ -159,7 +163,8 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, | |||
| 159 | 163 | ||
| 160 | BUG_ON(codec->volatile_register); | 164 | BUG_ON(codec->volatile_register); |
| 161 | 165 | ||
| 162 | data[0] = reg & 0xff; | 166 | reg &= 0xff; |
| 167 | data[0] = reg; | ||
| 163 | data[1] = value & 0xff; | 168 | data[1] = value & 0xff; |
| 164 | 169 | ||
| 165 | if (reg < codec->reg_cache_size) | 170 | if (reg < codec->reg_cache_size) |
| @@ -170,6 +175,8 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, | |||
| 170 | return 0; | 175 | return 0; |
| 171 | } | 176 | } |
| 172 | 177 | ||
| 178 | dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); | ||
| 179 | |||
| 173 | if (codec->hw_write(codec->control_data, data, 2) == 2) | 180 | if (codec->hw_write(codec->control_data, data, 2) == 2) |
| 174 | return 0; | 181 | return 0; |
| 175 | else | 182 | else |
| @@ -180,6 +187,7 @@ static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, | |||
| 180 | unsigned int reg) | 187 | unsigned int reg) |
| 181 | { | 188 | { |
| 182 | u8 *cache = codec->reg_cache; | 189 | u8 *cache = codec->reg_cache; |
| 190 | reg &= 0xff; | ||
| 183 | if (reg >= codec->reg_cache_size) | 191 | if (reg >= codec->reg_cache_size) |
| 184 | return -1; | 192 | return -1; |
| 185 | return cache[reg]; | 193 | return cache[reg]; |
| @@ -203,6 +211,8 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, | |||
| 203 | return 0; | 211 | return 0; |
| 204 | } | 212 | } |
| 205 | 213 | ||
| 214 | dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); | ||
| 215 | |||
| 206 | if (codec->hw_write(codec->control_data, data, 3) == 3) | 216 | if (codec->hw_write(codec->control_data, data, 3) == 3) |
| 207 | return 0; | 217 | return 0; |
| 208 | else | 218 | else |
| @@ -226,6 +236,40 @@ static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, | |||
| 226 | } | 236 | } |
| 227 | 237 | ||
| 228 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | 238 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) |
| 239 | static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec, | ||
| 240 | unsigned int r) | ||
| 241 | { | ||
| 242 | struct i2c_msg xfer[2]; | ||
| 243 | u8 reg = r; | ||
| 244 | u8 data; | ||
| 245 | int ret; | ||
| 246 | struct i2c_client *client = codec->control_data; | ||
| 247 | |||
| 248 | /* Write register */ | ||
| 249 | xfer[0].addr = client->addr; | ||
| 250 | xfer[0].flags = 0; | ||
| 251 | xfer[0].len = 1; | ||
| 252 | xfer[0].buf = ® | ||
| 253 | |||
| 254 | /* Read data */ | ||
| 255 | xfer[1].addr = client->addr; | ||
| 256 | xfer[1].flags = I2C_M_RD; | ||
| 257 | xfer[1].len = 1; | ||
| 258 | xfer[1].buf = &data; | ||
| 259 | |||
| 260 | ret = i2c_transfer(client->adapter, xfer, 2); | ||
| 261 | if (ret != 2) { | ||
| 262 | dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); | ||
| 263 | return 0; | ||
| 264 | } | ||
| 265 | |||
| 266 | return data; | ||
| 267 | } | ||
| 268 | #else | ||
| 269 | #define snd_soc_8_8_read_i2c NULL | ||
| 270 | #endif | ||
| 271 | |||
| 272 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | ||
| 229 | static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, | 273 | static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, |
| 230 | unsigned int r) | 274 | unsigned int r) |
| 231 | { | 275 | { |
| @@ -326,6 +370,8 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, | |||
| 326 | return 0; | 370 | return 0; |
| 327 | } | 371 | } |
| 328 | 372 | ||
| 373 | dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); | ||
| 374 | |||
| 329 | ret = codec->hw_write(codec->control_data, data, 3); | 375 | ret = codec->hw_write(codec->control_data, data, 3); |
| 330 | if (ret == 3) | 376 | if (ret == 3) |
| 331 | return 0; | 377 | return 0; |
| @@ -366,6 +412,86 @@ static int snd_soc_16_8_spi_write(void *control_data, const char *data, | |||
| 366 | #define snd_soc_16_8_spi_write NULL | 412 | #define snd_soc_16_8_spi_write NULL |
| 367 | #endif | 413 | #endif |
| 368 | 414 | ||
| 415 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | ||
| 416 | static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, | ||
| 417 | unsigned int r) | ||
| 418 | { | ||
| 419 | struct i2c_msg xfer[2]; | ||
| 420 | u16 reg = cpu_to_be16(r); | ||
| 421 | u16 data; | ||
| 422 | int ret; | ||
| 423 | struct i2c_client *client = codec->control_data; | ||
| 424 | |||
| 425 | /* Write register */ | ||
| 426 | xfer[0].addr = client->addr; | ||
| 427 | xfer[0].flags = 0; | ||
| 428 | xfer[0].len = 2; | ||
| 429 | xfer[0].buf = (u8 *)® | ||
| 430 | |||
| 431 | /* Read data */ | ||
| 432 | xfer[1].addr = client->addr; | ||
| 433 | xfer[1].flags = I2C_M_RD; | ||
| 434 | xfer[1].len = 2; | ||
| 435 | xfer[1].buf = (u8 *)&data; | ||
| 436 | |||
| 437 | ret = i2c_transfer(client->adapter, xfer, 2); | ||
| 438 | if (ret != 2) { | ||
| 439 | dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); | ||
| 440 | return 0; | ||
| 441 | } | ||
| 442 | |||
| 443 | return be16_to_cpu(data); | ||
| 444 | } | ||
| 445 | #else | ||
| 446 | #define snd_soc_16_16_read_i2c NULL | ||
| 447 | #endif | ||
| 448 | |||
| 449 | static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec, | ||
| 450 | unsigned int reg) | ||
| 451 | { | ||
| 452 | u16 *cache = codec->reg_cache; | ||
| 453 | |||
| 454 | if (reg >= codec->reg_cache_size || | ||
| 455 | snd_soc_codec_volatile_register(codec, reg)) { | ||
| 456 | if (codec->cache_only) | ||
| 457 | return -EINVAL; | ||
| 458 | |||
| 459 | return codec->hw_read(codec, reg); | ||
| 460 | } | ||
| 461 | |||
| 462 | return cache[reg]; | ||
| 463 | } | ||
| 464 | |||
| 465 | static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, | ||
| 466 | unsigned int value) | ||
| 467 | { | ||
| 468 | u16 *cache = codec->reg_cache; | ||
| 469 | u8 data[4]; | ||
| 470 | int ret; | ||
| 471 | |||
| 472 | data[0] = (reg >> 8) & 0xff; | ||
| 473 | data[1] = reg & 0xff; | ||
| 474 | data[2] = (value >> 8) & 0xff; | ||
| 475 | data[3] = value & 0xff; | ||
| 476 | |||
| 477 | if (reg < codec->reg_cache_size) | ||
| 478 | cache[reg] = value; | ||
| 479 | |||
| 480 | if (codec->cache_only) { | ||
| 481 | codec->cache_sync = 1; | ||
| 482 | return 0; | ||
| 483 | } | ||
| 484 | |||
| 485 | dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); | ||
| 486 | |||
| 487 | ret = codec->hw_write(codec->control_data, data, 4); | ||
| 488 | if (ret == 4) | ||
| 489 | return 0; | ||
| 490 | if (ret < 0) | ||
| 491 | return ret; | ||
| 492 | else | ||
| 493 | return -EIO; | ||
| 494 | } | ||
| 369 | 495 | ||
| 370 | static struct { | 496 | static struct { |
| 371 | int addr_bits; | 497 | int addr_bits; |
| @@ -388,6 +514,7 @@ static struct { | |||
| 388 | { | 514 | { |
| 389 | .addr_bits = 8, .data_bits = 8, | 515 | .addr_bits = 8, .data_bits = 8, |
| 390 | .write = snd_soc_8_8_write, .read = snd_soc_8_8_read, | 516 | .write = snd_soc_8_8_write, .read = snd_soc_8_8_read, |
| 517 | .i2c_read = snd_soc_8_8_read_i2c, | ||
| 391 | }, | 518 | }, |
| 392 | { | 519 | { |
| 393 | .addr_bits = 8, .data_bits = 16, | 520 | .addr_bits = 8, .data_bits = 16, |
| @@ -400,6 +527,11 @@ static struct { | |||
| 400 | .i2c_read = snd_soc_16_8_read_i2c, | 527 | .i2c_read = snd_soc_16_8_read_i2c, |
| 401 | .spi_write = snd_soc_16_8_spi_write, | 528 | .spi_write = snd_soc_16_8_spi_write, |
| 402 | }, | 529 | }, |
| 530 | { | ||
| 531 | .addr_bits = 16, .data_bits = 16, | ||
| 532 | .write = snd_soc_16_16_write, .read = snd_soc_16_16_read, | ||
| 533 | .i2c_read = snd_soc_16_16_read_i2c, | ||
| 534 | }, | ||
| 403 | }; | 535 | }; |
| 404 | 536 | ||
| 405 | /** | 537 | /** |
