aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2008-10-07 08:04:58 -0400
committerTakashi Iwai <tiwai@suse.de>2008-10-12 20:17:31 -0400
commit09af98b08f72471ea53efe26494eef0947a6a10d (patch)
tree0645d68d151697d906353d7e23be0c3c206404ac
parent3ab57fbe91994e5d6fb371a34390520c6c905bee (diff)
ALSA: ASoC: Implement WM8510 bias level control
The WM8510 bias level configuration blindly overwrites the power management registers, interfering with the operation of DAPM. Only adjust the specific bits required, implementing use of the VMID resistor string configuration control as we go. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/soc/codecs/wm8510.c32
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)
526static int wm8510_set_bias_level(struct snd_soc_codec *codec, 529static 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);