Re: regression: from 3.8 to 3.9: headphones output no sound on Intel HDA, codec VIA VT1802

From: Takashi Iwai
Date: Tue May 14 2013 - 06:58:13 EST


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@xxxxxxx> 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@xxxxxxx>
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@xxxxxxxxx>
Cc: <stable@xxxxxxxxxxxxxxx> [v3.9+]
Signed-off-by: Takashi Iwai <tiwai@xxxxxxx>
---
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) */
--
1.8.2.1

--
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/