[patch 06/86] ALSA: hda - Allow analog low-current mode when dynamic power-control is on

From: Greg KH
Date: Fri Feb 10 2012 - 17:41:33 EST


3.2-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <tiwai@xxxxxxx>

commit e9d010c2e8f03952e67a6fd8aed0f0dc92084ccc upstream.

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

Signed-off-by: Takashi Iwai <tiwai@xxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
sound/pci/hda/patch_via.c | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)

--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -198,6 +198,9 @@ struct via_spec {
unsigned int no_pin_power_ctl;
enum VIA_HDA_CODEC codec_type;

+ /* analog low-power control */
+ bool alc_mode;
+
/* smart51 setup */
unsigned int smart51_nums;
hda_nid_t smart51_pins[2];
@@ -748,6 +751,7 @@ static int via_pin_power_ctl_put(struct
return 0;
spec->no_pin_power_ctl = val;
set_widgets_power_state(codec);
+ analog_low_current_mode(codec);
return 1;
}

@@ -1035,13 +1039,19 @@ static bool is_aa_path_mute(struct hda_c
}

/* enter/exit analog low-current mode */
-static void analog_low_current_mode(struct hda_codec *codec)
+static void __analog_low_current_mode(struct hda_codec *codec, bool force)
{
struct via_spec *spec = codec->spec;
bool enable;
unsigned int verb, parm;

- enable = is_aa_path_mute(codec) && !spec->opened_streams;
+ if (spec->no_pin_power_ctl)
+ enable = false;
+ else
+ enable = is_aa_path_mute(codec) && !spec->opened_streams;
+ if (enable == spec->alc_mode && !force)
+ return;
+ spec->alc_mode = enable;

/* decide low current mode's verb & parameter */
switch (spec->codec_type) {
@@ -1073,6 +1083,11 @@ static void analog_low_current_mode(stru
snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
}

+static void analog_low_current_mode(struct hda_codec *codec)
+{
+ return __analog_low_current_mode(codec, false);
+}
+
/*
* generic initialization of ADC, input mixers and output mixers
*/
@@ -1498,10 +1513,6 @@ static int via_build_controls(struct hda
return err;
}

- /* init power states */
- set_widgets_power_state(codec);
- analog_low_current_mode(codec);
-
via_free_kctls(codec); /* no longer needed */
return 0;
}
@@ -2771,6 +2782,10 @@ static int via_init(struct hda_codec *co
for (i = 0; i < spec->num_iverbs; i++)
snd_hda_sequence_write(codec, spec->init_verbs[i]);

+ /* init power states */
+ set_widgets_power_state(codec);
+ __analog_low_current_mode(codec, true);
+
via_auto_init_multi_out(codec);
via_auto_init_hp_out(codec);
via_auto_init_speaker_out(codec);


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/