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); |
