diff options
author | Dimitris Papastamos <dp@opensource.wolfsonmicro.com> | 2011-03-22 06:37:01 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-03-26 13:44:05 -0400 |
commit | f3594f5c5c489d159f6d487a889d9d68ca4c0123 (patch) | |
tree | f8e0f85887c429f9ec183ab372a1610a76397a8c /sound/soc/soc-cache.c | |
parent | 8b573c95d7bd1cf28c69ab4e0255cd272d214482 (diff) |
ASoC: soc-cache: Factor-out the I2C read code
The handling of all snd_soc_x_y_read_i2c() functions is similar.
Make a generic I2C read function and update all callers to use it.
Signed-off-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@ti.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-cache.c')
-rw-r--r-- | sound/soc/soc-cache.c | 100 |
1 files changed, 32 insertions, 68 deletions
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 5d76da43b14c..9f6737413a6e 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c | |||
@@ -351,33 +351,48 @@ static int snd_soc_8_16_spi_write(void *control_data, const char *data, | |||
351 | #endif | 351 | #endif |
352 | 352 | ||
353 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | 353 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) |
354 | static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec, | 354 | static unsigned int do_i2c_read(struct snd_soc_codec *codec, |
355 | unsigned int r) | 355 | void *reg, int reglen, |
356 | void *data, int datalen) | ||
356 | { | 357 | { |
357 | struct i2c_msg xfer[2]; | 358 | struct i2c_msg xfer[2]; |
358 | u8 reg = r; | ||
359 | u8 data; | ||
360 | int ret; | 359 | int ret; |
361 | struct i2c_client *client = codec->control_data; | 360 | struct i2c_client *client = codec->control_data; |
362 | 361 | ||
363 | /* Write register */ | 362 | /* Write register */ |
364 | xfer[0].addr = client->addr; | 363 | xfer[0].addr = client->addr; |
365 | xfer[0].flags = 0; | 364 | xfer[0].flags = 0; |
366 | xfer[0].len = 1; | 365 | xfer[0].len = reglen; |
367 | xfer[0].buf = ® | 366 | xfer[0].buf = reg; |
368 | 367 | ||
369 | /* Read data */ | 368 | /* Read data */ |
370 | xfer[1].addr = client->addr; | 369 | xfer[1].addr = client->addr; |
371 | xfer[1].flags = I2C_M_RD; | 370 | xfer[1].flags = I2C_M_RD; |
372 | xfer[1].len = 1; | 371 | xfer[1].len = datalen; |
373 | xfer[1].buf = &data; | 372 | xfer[1].buf = data; |
374 | 373 | ||
375 | ret = i2c_transfer(client->adapter, xfer, 2); | 374 | ret = i2c_transfer(client->adapter, xfer, 2); |
376 | if (ret != 2) { | 375 | dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); |
377 | dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); | 376 | if (ret == 2) |
378 | return 0; | 377 | return 0; |
379 | } | 378 | else if (ret < 0) |
379 | return ret; | ||
380 | else | ||
381 | return -EIO; | ||
382 | } | ||
383 | #endif | ||
384 | |||
385 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | ||
386 | static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec, | ||
387 | unsigned int r) | ||
388 | { | ||
389 | u8 reg = r; | ||
390 | u8 data; | ||
391 | int ret; | ||
380 | 392 | ||
393 | ret = do_i2c_read(codec, ®, 1, &data, 1); | ||
394 | if (ret < 0) | ||
395 | return 0; | ||
381 | return data; | 396 | return data; |
382 | } | 397 | } |
383 | #else | 398 | #else |
@@ -388,30 +403,13 @@ static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec, | |||
388 | static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, | 403 | static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, |
389 | unsigned int r) | 404 | unsigned int r) |
390 | { | 405 | { |
391 | struct i2c_msg xfer[2]; | ||
392 | u8 reg = r; | 406 | u8 reg = r; |
393 | u16 data; | 407 | u16 data; |
394 | int ret; | 408 | 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 | ||
409 | ret = i2c_transfer(client->adapter, xfer, 2); | 410 | ret = do_i2c_read(codec, ®, 1, &data, 2); |
410 | if (ret != 2) { | 411 | if (ret < 0) |
411 | dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); | ||
412 | return 0; | 412 | return 0; |
413 | } | ||
414 | |||
415 | return (data >> 8) | ((data & 0xff) << 8); | 413 | return (data >> 8) | ((data & 0xff) << 8); |
416 | } | 414 | } |
417 | #else | 415 | #else |
@@ -422,30 +420,13 @@ static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, | |||
422 | static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec, | 420 | static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec, |
423 | unsigned int r) | 421 | unsigned int r) |
424 | { | 422 | { |
425 | struct i2c_msg xfer[2]; | ||
426 | u16 reg = r; | 423 | u16 reg = r; |
427 | u8 data; | 424 | u8 data; |
428 | int ret; | 425 | 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 | 426 | ||
443 | ret = i2c_transfer(client->adapter, xfer, 2); | 427 | ret = do_i2c_read(codec, ®, 2, &data, 1); |
444 | if (ret != 2) { | 428 | if (ret < 0) |
445 | dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); | ||
446 | return 0; | 429 | return 0; |
447 | } | ||
448 | |||
449 | return data; | 430 | return data; |
450 | } | 431 | } |
451 | #else | 432 | #else |
@@ -543,30 +524,13 @@ static int snd_soc_16_8_spi_write(void *control_data, const char *data, | |||
543 | static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, | 524 | static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, |
544 | unsigned int r) | 525 | unsigned int r) |
545 | { | 526 | { |
546 | struct i2c_msg xfer[2]; | ||
547 | u16 reg = cpu_to_be16(r); | 527 | u16 reg = cpu_to_be16(r); |
548 | u16 data; | 528 | u16 data; |
549 | int ret; | 529 | 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 | 530 | ||
558 | /* Read data */ | 531 | ret = do_i2c_read(codec, ®, 2, &data, 2); |
559 | xfer[1].addr = client->addr; | 532 | if (ret < 0) |
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; | 533 | return 0; |
568 | } | ||
569 | |||
570 | return be16_to_cpu(data); | 534 | return be16_to_cpu(data); |
571 | } | 535 | } |
572 | #else | 536 | #else |