diff options
-rw-r--r-- | sound/soc/codecs/wm8510.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 142c49bf18e6..94cab495d5f3 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c | |||
@@ -55,6 +55,9 @@ static const u16 wm8510_reg[WM8510_CACHEREGNUM] = { | |||
55 | 0x0001, | 55 | 0x0001, |
56 | }; | 56 | }; |
57 | 57 | ||
58 | #define WM8510_POWER1_BIASEN 0x08 | ||
59 | #define WM8510_POWER1_BUFIOEN 0x10 | ||
60 | |||
58 | /* | 61 | /* |
59 | * read wm8510 register cache | 62 | * read wm8510 register cache |
60 | */ | 63 | */ |
@@ -526,23 +529,35 @@ static int wm8510_mute(struct snd_soc_dai *dai, int mute) | |||
526 | static int wm8510_set_bias_level(struct snd_soc_codec *codec, | 529 | static int wm8510_set_bias_level(struct snd_soc_codec *codec, |
527 | enum snd_soc_bias_level level) | 530 | enum snd_soc_bias_level level) |
528 | { | 531 | { |
532 | u16 power1 = wm8510_read_reg_cache(codec, WM8510_POWER1) & ~0x3; | ||
529 | 533 | ||
530 | switch (level) { | 534 | switch (level) { |
531 | case SND_SOC_BIAS_ON: | 535 | case SND_SOC_BIAS_ON: |
532 | wm8510_write(codec, WM8510_POWER1, 0x1ff); | ||
533 | wm8510_write(codec, WM8510_POWER2, 0x1ff); | ||
534 | wm8510_write(codec, WM8510_POWER3, 0x1ff); | ||
535 | break; | ||
536 | case SND_SOC_BIAS_PREPARE: | 536 | case SND_SOC_BIAS_PREPARE: |
537 | power1 |= 0x1; /* VMID 50k */ | ||
538 | wm8510_write(codec, WM8510_POWER1, power1); | ||
539 | break; | ||
540 | |||
537 | case SND_SOC_BIAS_STANDBY: | 541 | case SND_SOC_BIAS_STANDBY: |
542 | power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN; | ||
543 | |||
544 | if (codec->bias_level == SND_SOC_BIAS_OFF) { | ||
545 | /* Initial cap charge at VMID 5k */ | ||
546 | wm8510_write(codec, WM8510_POWER1, power1 | 0x3); | ||
547 | mdelay(100); | ||
548 | } | ||
549 | |||
550 | power1 |= 0x2; /* VMID 500k */ | ||
551 | wm8510_write(codec, WM8510_POWER1, power1); | ||
538 | break; | 552 | break; |
553 | |||
539 | case SND_SOC_BIAS_OFF: | 554 | case SND_SOC_BIAS_OFF: |
540 | /* everything off, dac mute, inactive */ | 555 | wm8510_write(codec, WM8510_POWER1, 0); |
541 | wm8510_write(codec, WM8510_POWER1, 0x0); | 556 | wm8510_write(codec, WM8510_POWER2, 0); |
542 | wm8510_write(codec, WM8510_POWER2, 0x0); | 557 | wm8510_write(codec, WM8510_POWER3, 0); |
543 | wm8510_write(codec, WM8510_POWER3, 0x0); | ||
544 | break; | 558 | break; |
545 | } | 559 | } |
560 | |||
546 | codec->bias_level = level; | 561 | codec->bias_level = level; |
547 | return 0; | 562 | return 0; |
548 | } | 563 | } |
@@ -640,6 +655,7 @@ static int wm8510_init(struct snd_soc_device *socdev) | |||
640 | } | 655 | } |
641 | 656 | ||
642 | /* power on device */ | 657 | /* power on device */ |
658 | codec->bias_level = SND_SOC_BIAS_OFF; | ||
643 | wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 659 | wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
644 | wm8510_add_controls(codec); | 660 | wm8510_add_controls(codec); |
645 | wm8510_add_widgets(codec); | 661 | wm8510_add_widgets(codec); |