aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-09-10 05:07:24 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-09-10 05:25:47 -0400
commit59ac2149aee9b69732dad602ea250ecb60b9e617 (patch)
treefd5828205bd28b3e8406f4731a80cecba6a06976
parentb9288f49dc5ac8342cc34163093c9f7d096b6378 (diff)
ASoC: wm8523: Move device ID verification and reset to I2C probe
Ensure that we have confirmed that we've got the device in place before we register with ASoC. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/codecs/wm8523.c84
1 files changed, 38 insertions, 46 deletions
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index d7d5fe6866a6..8d5c27673501 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -68,11 +68,6 @@ static bool wm8523_volatile_register(struct device *dev, unsigned int reg)
68 } 68 }
69} 69}
70 70
71static int wm8523_reset(struct snd_soc_codec *codec)
72{
73 return snd_soc_write(codec, WM8523_DEVICE_ID, 0);
74}
75
76static const DECLARE_TLV_DB_SCALE(dac_tlv, -10000, 25, 0); 71static const DECLARE_TLV_DB_SCALE(dac_tlv, -10000, 25, 0);
77 72
78static const char *wm8523_zd_count_text[] = { 73static const char *wm8523_zd_count_text[] = {
@@ -409,38 +404,6 @@ static int wm8523_probe(struct snd_soc_codec *codec)
409 return ret; 404 return ret;
410 } 405 }
411 406
412 ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
413 wm8523->supplies);
414 if (ret != 0) {
415 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
416 goto err_get;
417 }
418
419 ret = snd_soc_read(codec, WM8523_DEVICE_ID);
420 if (ret < 0) {
421 dev_err(codec->dev, "Failed to read ID register\n");
422 goto err_enable;
423 }
424 if (ret != 0x8523) {
425 dev_err(codec->dev, "Device is not a WM8523, ID is %x\n", ret);
426 ret = -EINVAL;
427 goto err_enable;
428 }
429
430 ret = snd_soc_read(codec, WM8523_REVISION);
431 if (ret < 0) {
432 dev_err(codec->dev, "Failed to read revision register\n");
433 goto err_enable;
434 }
435 dev_info(codec->dev, "revision %c\n",
436 (ret & WM8523_CHIP_REV_MASK) + 'A');
437
438 ret = wm8523_reset(codec);
439 if (ret < 0) {
440 dev_err(codec->dev, "Failed to issue reset\n");
441 goto err_enable;
442 }
443
444 /* Change some default settings - latch VU and enable ZC */ 407 /* Change some default settings - latch VU and enable ZC */
445 snd_soc_update_bits(codec, WM8523_DAC_GAINR, 408 snd_soc_update_bits(codec, WM8523_DAC_GAINR,
446 WM8523_DACR_VU, WM8523_DACR_VU); 409 WM8523_DACR_VU, WM8523_DACR_VU);
@@ -448,16 +411,7 @@ static int wm8523_probe(struct snd_soc_codec *codec)
448 411
449 wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 412 wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
450 413
451 /* Bias level configuration will have done an extra enable */
452 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
453
454 return 0; 414 return 0;
455
456err_enable:
457 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
458err_get:
459
460 return ret;
461} 415}
462 416
463static int wm8523_remove(struct snd_soc_codec *codec) 417static int wm8523_remove(struct snd_soc_codec *codec)
@@ -503,6 +457,7 @@ static __devinit int wm8523_i2c_probe(struct i2c_client *i2c,
503 const struct i2c_device_id *id) 457 const struct i2c_device_id *id)
504{ 458{
505 struct wm8523_priv *wm8523; 459 struct wm8523_priv *wm8523;
460 unsigned int val;
506 int ret, i; 461 int ret, i;
507 462
508 wm8523 = devm_kzalloc(&i2c->dev, sizeof(struct wm8523_priv), 463 wm8523 = devm_kzalloc(&i2c->dev, sizeof(struct wm8523_priv),
@@ -527,6 +482,40 @@ static __devinit int wm8523_i2c_probe(struct i2c_client *i2c,
527 return ret; 482 return ret;
528 } 483 }
529 484
485 ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
486 wm8523->supplies);
487 if (ret != 0) {
488 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
489 return ret;
490 }
491
492 ret = regmap_read(wm8523->regmap, WM8523_DEVICE_ID, &val);
493 if (ret < 0) {
494 dev_err(&i2c->dev, "Failed to read ID register\n");
495 goto err_enable;
496 }
497 if (val != 0x8523) {
498 dev_err(&i2c->dev, "Device is not a WM8523, ID is %x\n", ret);
499 ret = -EINVAL;
500 goto err_enable;
501 }
502
503 ret = regmap_read(wm8523->regmap, WM8523_REVISION, &val);
504 if (ret < 0) {
505 dev_err(&i2c->dev, "Failed to read revision register\n");
506 goto err_enable;
507 }
508 dev_info(&i2c->dev, "revision %c\n",
509 (val & WM8523_CHIP_REV_MASK) + 'A');
510
511 ret = regmap_write(wm8523->regmap, WM8523_DEVICE_ID, 0x8523);
512 if (ret != 0) {
513 dev_err(&i2c->dev, "Failed to reset device: %d\n", ret);
514 goto err_enable;
515 }
516
517 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
518
530 i2c_set_clientdata(i2c, wm8523); 519 i2c_set_clientdata(i2c, wm8523);
531 520
532 ret = snd_soc_register_codec(&i2c->dev, 521 ret = snd_soc_register_codec(&i2c->dev,
@@ -534,6 +523,9 @@ static __devinit int wm8523_i2c_probe(struct i2c_client *i2c,
534 523
535 return ret; 524 return ret;
536 525
526err_enable:
527 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
528 return ret;
537} 529}
538 530
539static __devexit int wm8523_i2c_remove(struct i2c_client *client) 531static __devexit int wm8523_i2c_remove(struct i2c_client *client)