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 | /** |