aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_via.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-02-01 04:33:23 -0500
committerTakashi Iwai <tiwai@suse.de>2012-02-02 04:18:09 -0500
commite9d010c2e8f03952e67a6fd8aed0f0dc92084ccc (patch)
treeef54a3c768f43e761577dd67d682cc680865981a /sound/pci/hda/patch_via.c
parent924339239fd5ba3e505f9420d41f0939196f3530 (diff)
ALSA: hda - Allow analog low-current mode when dynamic power-control is on
VIA codecs have several different power-saving features, and one of them is the analog low-current mode. But it turned out that the ALC mode causes pop-noises at each on/off time on some machines. As a quick workaround, disable the ALC when another power-saving feature, the dynamic pin power-control, is turned off, too, since the dynamic power-control is already exposed as a mixer enum element so that user can turn it on/off freely. Bugzilla: https://bugzilla.novell.com/show_bug.cgi?id=741128 Cc: <stable@kernel.org> [v3.1+] Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_via.c')
-rw-r--r--sound/pci/hda/patch_via.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index de43cd92b0a5..79166fb8b074 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -199,6 +199,9 @@ struct via_spec {
199 unsigned int no_pin_power_ctl; 199 unsigned int no_pin_power_ctl;
200 enum VIA_HDA_CODEC codec_type; 200 enum VIA_HDA_CODEC codec_type;
201 201
202 /* analog low-power control */
203 bool alc_mode;
204
202 /* smart51 setup */ 205 /* smart51 setup */
203 unsigned int smart51_nums; 206 unsigned int smart51_nums;
204 hda_nid_t smart51_pins[2]; 207 hda_nid_t smart51_pins[2];
@@ -758,6 +761,7 @@ static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol,
758 return 0; 761 return 0;
759 spec->no_pin_power_ctl = val; 762 spec->no_pin_power_ctl = val;
760 set_widgets_power_state(codec); 763 set_widgets_power_state(codec);
764 analog_low_current_mode(codec);
761 return 1; 765 return 1;
762} 766}
763 767
@@ -1045,13 +1049,19 @@ static bool is_aa_path_mute(struct hda_codec *codec)
1045} 1049}
1046 1050
1047/* enter/exit analog low-current mode */ 1051/* enter/exit analog low-current mode */
1048static void analog_low_current_mode(struct hda_codec *codec) 1052static void __analog_low_current_mode(struct hda_codec *codec, bool force)
1049{ 1053{
1050 struct via_spec *spec = codec->spec; 1054 struct via_spec *spec = codec->spec;
1051 bool enable; 1055 bool enable;
1052 unsigned int verb, parm; 1056 unsigned int verb, parm;
1053 1057
1054 enable = is_aa_path_mute(codec) && !spec->opened_streams; 1058 if (spec->no_pin_power_ctl)
1059 enable = false;
1060 else
1061 enable = is_aa_path_mute(codec) && !spec->opened_streams;
1062 if (enable == spec->alc_mode && !force)
1063 return;
1064 spec->alc_mode = enable;
1055 1065
1056 /* decide low current mode's verb & parameter */ 1066 /* decide low current mode's verb & parameter */
1057 switch (spec->codec_type) { 1067 switch (spec->codec_type) {
@@ -1083,6 +1093,11 @@ static void analog_low_current_mode(struct hda_codec *codec)
1083 snd_hda_codec_write(codec, codec->afg, 0, verb, parm); 1093 snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
1084} 1094}
1085 1095
1096static void analog_low_current_mode(struct hda_codec *codec)
1097{
1098 return __analog_low_current_mode(codec, false);
1099}
1100
1086/* 1101/*
1087 * generic initialization of ADC, input mixers and output mixers 1102 * generic initialization of ADC, input mixers and output mixers
1088 */ 1103 */
@@ -1508,10 +1523,6 @@ static int via_build_controls(struct hda_codec *codec)
1508 return err; 1523 return err;
1509 } 1524 }
1510 1525
1511 /* init power states */
1512 set_widgets_power_state(codec);
1513 analog_low_current_mode(codec);
1514
1515 via_free_kctls(codec); /* no longer needed */ 1526 via_free_kctls(codec); /* no longer needed */
1516 1527
1517 err = snd_hda_jack_add_kctls(codec, &spec->autocfg); 1528 err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
@@ -2782,6 +2793,10 @@ static int via_init(struct hda_codec *codec)
2782 for (i = 0; i < spec->num_iverbs; i++) 2793 for (i = 0; i < spec->num_iverbs; i++)
2783 snd_hda_sequence_write(codec, spec->init_verbs[i]); 2794 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2784 2795
2796 /* init power states */
2797 set_widgets_power_state(codec);
2798 __analog_low_current_mode(codec, true);
2799
2785 via_auto_init_multi_out(codec); 2800 via_auto_init_multi_out(codec);
2786 via_auto_init_hp_out(codec); 2801 via_auto_init_hp_out(codec);
2787 via_auto_init_speaker_out(codec); 2802 via_auto_init_speaker_out(codec);