At Tue, 14 May 2013 07:59:07 +0200, Takashi Iwai wrote:
At Mon, 13 May 2013 20:24:42 +0200, Alex Riesen wrote:
On Mon, May 13, 2013 at 5:53 PM, Takashi Iwai tiwai@suse.de wrote:
At Mon, 13 May 2013 17:26:04 +0200, Takashi Iwai wrote:
At Sun, 12 May 2013 11:53:41 +0200, Alex Riesen wrote:
I just noticed (use the headphones rarely) that the headphones on this System76 Lemur Ultra (lemu4) stopped working. There is absolutely no output.
It's strange that the pin 0x25 shows EAPD 0x00 and pin-control 0x00. They should be 0x02 and 0xc0 constantly. Is it taken at the moment the headphone is plugged, right? Please give alsa-info.sh outputs at both the headphone plugged and unplugged.
Attached. Sorry for gzipping, the alsa-devel rejects two at a time: too large.
Could you check whether changing them makes the headphone output working? For example, get hda-verb program (see Documentation/sound/alsa/HD-Audio.txt) and run it like
hda-verb /dev/snd/hwC0D0 0x25 SET_PIN_WID 0xc0 hda-verb /dev/snd/hwC0D0 0x25 SET_EAPD 0x02
It helps, headphones start working.
Also, what happens if you apply the patch below?
spec->set_widgets_power_state = set_widgets_power_state_vt2002P;
//spec->set_widgets_power_state = set_widgets_power_state_vt2002P;
This helps as well. Yay! Thanks :) Whatever the outcome, I have them back more or less (more, for me) properly.
OK, then we know the place to fix now. Try the patch below instead. Does it fix the problem as well?
The below is the revised patch, fixing not only for VT1802 but other VIA codecs, too. Please let me know if it works.
thanks,
Takashi
--- From: Takashi Iwai tiwai@suse.de Subject: [PATCH] ALSA: hda - Fix wrong power setup for HP paths of VIA codecs
The set_widgets_power_state_*() callbacks in patch_via.c are converted to evaluate spec->gen.indep_hp_enabled when the codec parser was switched to use the generic parser. However, the generic parser takes the headphone paths in a different way as the original VIA parser; it tries the paths with individual DACs as much as possible. This ended up with the incorrect check of the power status in the HP paths, resulting in the silent output from the headphones.
This patch removes the invalid check of indep_hp_enabled flag and sets the proper power status for those paths.
Reported-by: Alex Riesen raa.lkml@gmail.com Cc: stable@vger.kernel.org [v3.9+] Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/patch_via.c | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-)
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index e0dadcf..c74e1a1 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -856,7 +856,7 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) if (is_8ch) { update_power_state(codec, 0x25, parm); update_power_state(codec, 0x27, parm); - } else if (codec->vendor_id == 0x11064397 && spec->gen.indep_hp_enabled) + } else if (codec->vendor_id == 0x11064397) update_power_state(codec, 0x25, parm); }
@@ -1042,7 +1042,6 @@ static const struct hda_verb vt1718S_init_verbs[] = {
static void set_widgets_power_state_vt1718S(struct hda_codec *codec) { - struct via_spec *spec = codec->spec; int imux_is_smixer; unsigned int parm, parm2; /* MUX6 (1eh) = stereo mixer */ @@ -1079,10 +1078,9 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec) /* PW0 (24h), AOW0 (8h) */ parm = AC_PWRST_D3; set_pin_power_state(codec, 0x24, &parm); - if (!spec->gen.indep_hp_enabled) /* check for redirected HP */ - set_pin_power_state(codec, 0x28, &parm); + set_pin_power_state(codec, 0x28, &parm); update_power_state(codec, 0x8, parm); - if (!spec->gen.indep_hp_enabled && parm2 != AC_PWRST_D3) + if (parm2 != AC_PWRST_D3) parm = parm2; update_power_state(codec, 0xb, parm); /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ @@ -1095,14 +1093,12 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec) set_pin_power_state(codec, 0x2a, &parm); update_power_state(codec, 0x9, parm);
- if (spec->gen.indep_hp_enabled) { - /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x28, &parm); - update_power_state(codec, 0x1b, parm); - update_power_state(codec, 0x34, parm); - update_power_state(codec, 0xc, parm); - } + /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x28, &parm); + update_power_state(codec, 0x1b, parm); + update_power_state(codec, 0x34, parm); + update_power_state(codec, 0xc, parm); }
/* Add a connection to the primary DAC from AA-mixer for some codecs @@ -1307,7 +1303,7 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) mono_out = 0; else { present = snd_hda_jack_detect(codec, 0x1d); - if (!spec->gen.indep_hp_enabled && present) + if (present) mono_out = 0; else mono_out = 1; @@ -1321,9 +1317,7 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) parm = AC_PWRST_D3; set_pin_power_state(codec, 0x1c, &parm); set_pin_power_state(codec, 0x1d, &parm); - /* HP Independent Mode, power on AOW3 */ - if (spec->gen.indep_hp_enabled) - update_power_state(codec, 0x25, parm); + update_power_state(codec, 0x25, parm);
/* force to D0 for internal Speaker */ /* MW0 (16h), AOW0 (10h) */ @@ -1410,6 +1404,7 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) /* outputs */ /* AOW0 (8h)*/ update_power_state(codec, 0x8, parm); + update_power_state(codec, 0x9, parm);
if (spec->codec_type == VT1802) { /* PW4 (28h), MW4 (18h), MUX4(38h) */ @@ -1439,9 +1434,6 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) update_power_state(codec, 0x35, parm); }
- if (spec->gen.indep_hp_enabled) - update_power_state(codec, 0x9, AC_PWRST_D0); - /* Class-D */ /* PW0 (24h), MW0(18h/14h), MUX0(34h) */ present = snd_hda_jack_detect(codec, 0x25); @@ -1577,7 +1569,6 @@ static const struct hda_verb vt1812_init_verbs[] = {
static void set_widgets_power_state_vt1812(struct hda_codec *codec) { - struct via_spec *spec = codec->spec; unsigned int parm; unsigned int present; /* inputs */ @@ -1596,6 +1587,7 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec) /* outputs */ /* AOW0 (8h)*/ update_power_state(codec, 0x8, AC_PWRST_D0); + update_power_state(codec, 0x9, AC_PWRST_D0);
/* PW4 (28h), MW4 (18h), MUX4(38h) */ parm = AC_PWRST_D3; @@ -1608,8 +1600,6 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec) set_pin_power_state(codec, 0x25, &parm); update_power_state(codec, 0x15, parm); update_power_state(codec, 0x35, parm); - if (spec->gen.indep_hp_enabled) - update_power_state(codec, 0x9, AC_PWRST_D0);
/* Internal Speaker */ /* PW0 (24h), MW0(14h), MUX0(34h) */ @@ -1756,15 +1746,14 @@ static void set_widgets_power_state_vt3476(struct hda_codec *codec) set_pin_power_state(codec, 0x28, &parm); update_power_state(codec, 0x38, parm); update_power_state(codec, 0x18, parm); - if (spec->gen.indep_hp_enabled) - update_conv_power_state(codec, 0xb, parm, 3); + update_conv_power_state(codec, 0xb, parm, 3); parm2 = parm; /* for pin 0x0b */
/* PW0 (24h), MW0(34h), MW9(3fh), AOW0 (8h) */ parm = AC_PWRST_D3; set_pin_power_state(codec, 0x24, &parm); update_power_state(codec, 0x34, parm); - if (!spec->gen.indep_hp_enabled && parm2 != AC_PWRST_D3) + if (parm2 != AC_PWRST_D3) parm = parm2; update_conv_power_state(codec, 0x8, parm, 0); /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */