[ALSA] hda-codec - Fix Gateway laptops with STAC9200

Fix the output of Gateway laptops with STAC9200 codec chip.
They require the EAPD control for some pins.  These pins shouldn't be
powered down.
To enable EAPD control, a new model 'gateway' was added to STAC9200.
The known PCI SSIDs are included in the quirk list.
The fix was originally suggested by Brian Hinz, in ALSA bug#2948.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
This commit is contained in:
Takashi Iwai 2007-10-10 10:04:26 +02:00 committed by Jaroslav Kysela
parent 5513b0c582
commit 1194b5b70a
3 changed files with 35 additions and 3 deletions

View file

@ -972,6 +972,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dell-m25 Dell Inspiron E1505n dell-m25 Dell Inspiron E1505n
dell-m26 Dell Inspiron 1501 dell-m26 Dell Inspiron 1501
dell-m27 Dell Inspiron E1705/9400 dell-m27 Dell Inspiron E1705/9400
gateway Gateway laptops with EAPD control
STAC9205/9254 STAC9205/9254
ref Reference board ref Reference board

View file

@ -1630,10 +1630,24 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
nid = codec->start_nid; nid = codec->start_nid;
for (i = 0; i < codec->num_nodes; i++, nid++) { for (i = 0; i < codec->num_nodes; i++, nid++) {
if (get_wcaps(codec, nid) & AC_WCAP_POWER) if (get_wcaps(codec, nid) & AC_WCAP_POWER) {
unsigned int pincap;
/*
* don't power down the widget if it controls eapd
* and EAPD_BTLENABLE is set.
*/
pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
if (pincap & AC_PINCAP_EAPD) {
int eapd = snd_hda_codec_read(codec, nid,
0, AC_VERB_GET_EAPD_BTLENABLE, 0);
eapd &= 0x02;
if (power_state == AC_PWRST_D3 && eapd)
continue;
}
snd_hda_codec_write(codec, nid, 0, snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_POWER_STATE, AC_VERB_SET_POWER_STATE,
power_state); power_state);
}
} }
if (power_state == AC_PWRST_D0) { if (power_state == AC_PWRST_D0) {

View file

@ -49,6 +49,7 @@ enum {
STAC_9200_DELL_M25, STAC_9200_DELL_M25,
STAC_9200_DELL_M26, STAC_9200_DELL_M26,
STAC_9200_DELL_M27, STAC_9200_DELL_M27,
STAC_9200_GATEWAY,
STAC_9200_MODELS STAC_9200_MODELS
}; };
@ -378,6 +379,13 @@ static struct hda_verb stac9200_core_init[] = {
{} {}
}; };
static struct hda_verb stac9200_eapd_init[] = {
/* set dac0mux for dac converter */
{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
{0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
{}
};
static struct hda_verb stac925x_core_init[] = { static struct hda_verb stac925x_core_init[] = {
/* set dac0mux for dac converter */ /* set dac0mux for dac converter */
{ 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
@ -693,6 +701,7 @@ static const char *stac9200_models[STAC_9200_MODELS] = {
[STAC_9200_DELL_M25] = "dell-m25", [STAC_9200_DELL_M25] = "dell-m25",
[STAC_9200_DELL_M26] = "dell-m26", [STAC_9200_DELL_M26] = "dell-m26",
[STAC_9200_DELL_M27] = "dell-m27", [STAC_9200_DELL_M27] = "dell-m27",
[STAC_9200_GATEWAY] = "gateway",
}; };
static struct snd_pci_quirk stac9200_cfg_tbl[] = { static struct snd_pci_quirk stac9200_cfg_tbl[] = {
@ -760,7 +769,12 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = {
"unknown Dell", STAC_9200_DELL_M26), "unknown Dell", STAC_9200_DELL_M26),
/* Panasonic */ /* Panasonic */
SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_REF), SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_REF),
/* Gateway machines needs EAPD to be set on resume */
SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY),
SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*",
STAC_9200_GATEWAY),
SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707",
STAC_9200_GATEWAY),
{} /* terminator */ {} /* terminator */
}; };
@ -2492,7 +2506,10 @@ static int patch_stac9200(struct hda_codec *codec)
spec->num_dmics = 0; spec->num_dmics = 0;
spec->num_adcs = 1; spec->num_adcs = 1;
spec->init = stac9200_core_init; if (spec->board_config == STAC_9200_GATEWAY)
spec->init = stac9200_eapd_init;
else
spec->init = stac9200_core_init;
spec->mixer = stac9200_mixer; spec->mixer = stac9200_mixer;
err = stac9200_parse_auto_config(codec); err = stac9200_parse_auto_config(codec);