aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/soc-cache.c')
-rw-r--r--sound/soc/soc-cache.c134
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))
239static 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 = &reg;
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))
229static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, 273static 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))
416static 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 *)&reg;
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
449static 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
465static 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
370static struct { 496static 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/**