aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2006-03-21 05:24:42 -0500
committerJaroslav Kysela <perex@suse.cz>2006-03-22 04:40:14 -0500
commit82bc955f6379135e6ce35ff90c7ac411fd412c4c (patch)
tree314610afb5a469ac6a5a9f4d5e947436bb2c0538 /sound/pci
parent19739fef0203d2f3eecc9c4b1ef25b57d85f2b30 (diff)
[ALSA] hda-codec - Fix BIOS auto-configuration
Modules: HDA Codec driver,HDA generic driver - Fix autoconfig speaker/hp detection Now it allows multiple speaker pins (e.g. Dell laptops have such config) - Use speaker or hp pins if no line-outs are available This fixes the silence output on recent Dell laptops with STAC9200 (ALSA bug#1843) - Fix analog/realtek/sigmatel autoconfig parser Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_codec.c77
-rw-r--r--sound/pci/hda/hda_local.h4
-rw-r--r--sound/pci/hda/patch_analog.c23
-rw-r--r--sound/pci/hda/patch_realtek.c47
-rw-r--r--sound/pci/hda/patch_sigmatel.c84
5 files changed, 160 insertions, 75 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index fc91256e42eb..b42dff7ceed0 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1899,6 +1899,13 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o
1899 if (mout->hp_nid) 1899 if (mout->hp_nid)
1900 /* headphone out will just decode front left/right (stereo) */ 1900 /* headphone out will just decode front left/right (stereo) */
1901 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format); 1901 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format);
1902 /* extra outputs copied from front */
1903 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1904 if (mout->extra_out_nid[i])
1905 snd_hda_codec_setup_stream(codec,
1906 mout->extra_out_nid[i],
1907 stream_tag, 0, format);
1908
1902 /* surrounds */ 1909 /* surrounds */
1903 for (i = 1; i < mout->num_dacs; i++) { 1910 for (i = 1; i < mout->num_dacs; i++) {
1904 if (chs >= (i + 1) * 2) /* independent out */ 1911 if (chs >= (i + 1) * 2) /* independent out */
@@ -1923,6 +1930,11 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_o
1923 snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0); 1930 snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0);
1924 if (mout->hp_nid) 1931 if (mout->hp_nid)
1925 snd_hda_codec_setup_stream(codec, mout->hp_nid, 0, 0, 0); 1932 snd_hda_codec_setup_stream(codec, mout->hp_nid, 0, 0, 0);
1933 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1934 if (mout->extra_out_nid[i])
1935 snd_hda_codec_setup_stream(codec,
1936 mout->extra_out_nid[i],
1937 0, 0, 0);
1926 mutex_lock(&codec->spdif_mutex); 1938 mutex_lock(&codec->spdif_mutex);
1927 if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) { 1939 if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
1928 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); 1940 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);
@@ -1944,13 +1956,29 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
1944 return 0; 1956 return 0;
1945} 1957}
1946 1958
1947/* parse all pin widgets and store the useful pin nids to cfg */ 1959/*
1960 * Parse all pin widgets and store the useful pin nids to cfg
1961 *
1962 * The number of line-outs or any primary output is stored in line_outs,
1963 * and the corresponding output pins are assigned to line_out_pins[],
1964 * in the order of front, rear, CLFE, side, ...
1965 *
1966 * If more extra outputs (speaker and headphone) are found, the pins are
1967 * assisnged to hp_pin and speaker_pins[], respectively. If no line-out jack
1968 * is detected, one of speaker of HP pins is assigned as the primary
1969 * output, i.e. to line_out_pins[0]. So, line_outs is always positive
1970 * if any analog output exists.
1971 *
1972 * The analog input pins are assigned to input_pins array.
1973 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
1974 * respectively.
1975 */
1948int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, 1976int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg,
1949 hda_nid_t *ignore_nids) 1977 hda_nid_t *ignore_nids)
1950{ 1978{
1951 hda_nid_t nid, nid_start; 1979 hda_nid_t nid, nid_start;
1952 int i, j, nodes; 1980 int i, j, nodes;
1953 short seq, sequences[4], assoc_line_out; 1981 short seq, assoc_line_out, sequences[ARRAY_SIZE(cfg->line_out_pins)];
1954 1982
1955 memset(cfg, 0, sizeof(*cfg)); 1983 memset(cfg, 0, sizeof(*cfg));
1956 1984
@@ -1992,7 +2020,10 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
1992 cfg->line_outs++; 2020 cfg->line_outs++;
1993 break; 2021 break;
1994 case AC_JACK_SPEAKER: 2022 case AC_JACK_SPEAKER:
1995 cfg->speaker_pin = nid; 2023 if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins))
2024 continue;
2025 cfg->speaker_pins[cfg->speaker_outs] = nid;
2026 cfg->speaker_outs++;
1996 break; 2027 break;
1997 case AC_JACK_HP_OUT: 2028 case AC_JACK_HP_OUT:
1998 cfg->hp_pin = nid; 2029 cfg->hp_pin = nid;
@@ -2057,6 +2088,46 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
2057 break; 2088 break;
2058 } 2089 }
2059 2090
2091 /*
2092 * debug prints of the parsed results
2093 */
2094 snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
2095 cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1],
2096 cfg->line_out_pins[2], cfg->line_out_pins[3],
2097 cfg->line_out_pins[4]);
2098 snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
2099 cfg->speaker_outs, cfg->speaker_pins[0],
2100 cfg->speaker_pins[1], cfg->speaker_pins[2],
2101 cfg->speaker_pins[3], cfg->speaker_pins[4]);
2102 snd_printd(" hp=0x%x, dig_out=0x%x, din_in=0x%x\n",
2103 cfg->hp_pin, cfg->dig_out_pin, cfg->dig_in_pin);
2104 snd_printd(" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x,"
2105 " cd=0x%x, aux=0x%x\n",
2106 cfg->input_pins[AUTO_PIN_MIC],
2107 cfg->input_pins[AUTO_PIN_FRONT_MIC],
2108 cfg->input_pins[AUTO_PIN_LINE],
2109 cfg->input_pins[AUTO_PIN_FRONT_LINE],
2110 cfg->input_pins[AUTO_PIN_CD],
2111 cfg->input_pins[AUTO_PIN_AUX]);
2112
2113 /*
2114 * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
2115 * as a primary output
2116 */
2117 if (! cfg->line_outs) {
2118 if (cfg->speaker_outs) {
2119 cfg->line_outs = cfg->speaker_outs;
2120 memcpy(cfg->line_out_pins, cfg->speaker_pins,
2121 sizeof(cfg->speaker_pins));
2122 cfg->speaker_outs = 0;
2123 memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
2124 } else if (cfg->hp_pin) {
2125 cfg->line_outs = 1;
2126 cfg->line_out_pins[0] = cfg->hp_pin;
2127 cfg->hp_pin = 0;
2128 }
2129 }
2130
2060 return 0; 2131 return 0;
2061} 2132}
2062 2133
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 548a8b698487..14e8aa2806ed 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -135,6 +135,7 @@ struct hda_multi_out {
135 int num_dacs; /* # of DACs, must be more than 1 */ 135 int num_dacs; /* # of DACs, must be more than 1 */
136 hda_nid_t *dac_nids; /* DAC list */ 136 hda_nid_t *dac_nids; /* DAC list */
137 hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */ 137 hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */
138 hda_nid_t extra_out_nid[3]; /* optional DACs, 0 when not exists */
138 hda_nid_t dig_out_nid; /* digital out audio widget */ 139 hda_nid_t dig_out_nid; /* digital out audio widget */
139 int max_channels; /* currently supported analog channels */ 140 int max_channels; /* currently supported analog channels */
140 int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */ 141 int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */
@@ -221,7 +222,8 @@ extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST];
221struct auto_pin_cfg { 222struct auto_pin_cfg {
222 int line_outs; 223 int line_outs;
223 hda_nid_t line_out_pins[5]; /* sorted in the order of Front/Surr/CLFE/Side */ 224 hda_nid_t line_out_pins[5]; /* sorted in the order of Front/Surr/CLFE/Side */
224 hda_nid_t speaker_pin; 225 int speaker_outs;
226 hda_nid_t speaker_pins[5];
225 hda_nid_t hp_pin; 227 hda_nid_t hp_pin;
226 hda_nid_t input_pins[AUTO_PIN_LAST]; 228 hda_nid_t input_pins[AUTO_PIN_LAST];
227 hda_nid_t dig_out_pin; 229 hda_nid_t dig_out_pin;
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 2b14fa74a8fd..7fbe71e69cfc 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -786,6 +786,8 @@ enum { AD1986A_6STACK, AD1986A_3STACK, AD1986A_LAPTOP, AD1986A_LAPTOP_EAPD };
786static struct hda_board_config ad1986a_cfg_tbl[] = { 786static struct hda_board_config ad1986a_cfg_tbl[] = {
787 { .modelname = "6stack", .config = AD1986A_6STACK }, 787 { .modelname = "6stack", .config = AD1986A_6STACK },
788 { .modelname = "3stack", .config = AD1986A_3STACK }, 788 { .modelname = "3stack", .config = AD1986A_3STACK },
789 { .pci_subvendor = 0x10de, .pci_subdevice = 0xcb84,
790 .config = AD1986A_3STACK }, /* ASUS A8N-VM CSM */
789 { .modelname = "laptop", .config = AD1986A_LAPTOP }, 791 { .modelname = "laptop", .config = AD1986A_LAPTOP },
790 { .pci_subvendor = 0x144d, .pci_subdevice = 0xc01e, 792 { .pci_subvendor = 0x144d, .pci_subdevice = 0xc01e,
791 .config = AD1986A_LAPTOP }, /* FSC V2060 */ 793 .config = AD1986A_LAPTOP }, /* FSC V2060 */
@@ -2253,14 +2255,11 @@ static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2253 2255
2254 idx = ad1988_pin_idx(pin); 2256 idx = ad1988_pin_idx(pin);
2255 nid = ad1988_idx_to_dac(codec, idx); 2257 nid = ad1988_idx_to_dac(codec, idx);
2256 if (! spec->multiout.dac_nids[0]) { 2258 /* specify the DAC as the extra output */
2257 /* use this as the primary output */ 2259 if (! spec->multiout.hp_nid)
2258 spec->multiout.dac_nids[0] = nid;
2259 if (! spec->multiout.num_dacs)
2260 spec->multiout.num_dacs = 1;
2261 } else
2262 /* specify the DAC as the extra output */
2263 spec->multiout.hp_nid = nid; 2260 spec->multiout.hp_nid = nid;
2261 else
2262 spec->multiout.extra_out_nid[0] = nid;
2264 /* control HP volume/switch on the output mixer amp */ 2263 /* control HP volume/switch on the output mixer amp */
2265 sprintf(name, "%s Playback Volume", pfx); 2264 sprintf(name, "%s Playback Volume", pfx);
2266 if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name, 2265 if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
@@ -2379,7 +2378,7 @@ static void ad1988_auto_init_extra_out(struct hda_codec *codec)
2379 struct ad198x_spec *spec = codec->spec; 2378 struct ad198x_spec *spec = codec->spec;
2380 hda_nid_t pin; 2379 hda_nid_t pin;
2381 2380
2382 pin = spec->autocfg.speaker_pin; 2381 pin = spec->autocfg.speaker_pins[0];
2383 if (pin) /* connect to front */ 2382 if (pin) /* connect to front */
2384 ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 2383 ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
2385 pin = spec->autocfg.hp_pin; 2384 pin = spec->autocfg.hp_pin;
@@ -2428,13 +2427,13 @@ static int ad1988_parse_auto_config(struct hda_codec *codec)
2428 return err; 2427 return err;
2429 if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) 2428 if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
2430 return err; 2429 return err;
2431 if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin && 2430 if (! spec->autocfg.line_outs)
2432 ! spec->autocfg.hp_pin)
2433 return 0; /* can't find valid BIOS pin config */ 2431 return 0; /* can't find valid BIOS pin config */
2434 if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || 2432 if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
2435 (err = ad1988_auto_create_extra_out(codec, spec->autocfg.speaker_pin, 2433 (err = ad1988_auto_create_extra_out(codec,
2434 spec->autocfg.speaker_pins[0],
2436 "Speaker")) < 0 || 2435 "Speaker")) < 0 ||
2437 (err = ad1988_auto_create_extra_out(codec, spec->autocfg.speaker_pin, 2436 (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pin,
2438 "Headphone")) < 0 || 2437 "Headphone")) < 0 ||
2439 (err = ad1988_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) 2438 (err = ad1988_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
2440 return err; 2439 return err;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 1607a1fab568..de145d102d9f 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -2431,14 +2431,11 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
2431 2431
2432 if (alc880_is_fixed_pin(pin)) { 2432 if (alc880_is_fixed_pin(pin)) {
2433 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 2433 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
2434 if (! spec->multiout.dac_nids[0]) { 2434 /* specify the DAC as the extra output */
2435 /* use this as the primary output */ 2435 if (! spec->multiout.hp_nid)
2436 spec->multiout.dac_nids[0] = nid;
2437 if (! spec->multiout.num_dacs)
2438 spec->multiout.num_dacs = 1;
2439 } else
2440 /* specify the DAC as the extra output */
2441 spec->multiout.hp_nid = nid; 2436 spec->multiout.hp_nid = nid;
2437 else
2438 spec->multiout.extra_out_nid[0] = nid;
2442 /* control HP volume/switch on the output mixer amp */ 2439 /* control HP volume/switch on the output mixer amp */
2443 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); 2440 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
2444 sprintf(name, "%s Playback Volume", pfx); 2441 sprintf(name, "%s Playback Volume", pfx);
@@ -2451,12 +2448,6 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
2451 return err; 2448 return err;
2452 } else if (alc880_is_multi_pin(pin)) { 2449 } else if (alc880_is_multi_pin(pin)) {
2453 /* set manual connection */ 2450 /* set manual connection */
2454 if (! spec->multiout.dac_nids[0]) {
2455 /* use this as the primary output */
2456 spec->multiout.dac_nids[0] = alc880_idx_to_dac(alc880_multi_pin_idx(pin));
2457 if (! spec->multiout.num_dacs)
2458 spec->multiout.num_dacs = 1;
2459 }
2460 /* we have only a switch on HP-out PIN */ 2451 /* we have only a switch on HP-out PIN */
2461 sprintf(name, "%s Playback Switch", pfx); 2452 sprintf(name, "%s Playback Switch", pfx);
2462 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 2453 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
@@ -2540,7 +2531,7 @@ static void alc880_auto_init_extra_out(struct hda_codec *codec)
2540 struct alc_spec *spec = codec->spec; 2531 struct alc_spec *spec = codec->spec;
2541 hda_nid_t pin; 2532 hda_nid_t pin;
2542 2533
2543 pin = spec->autocfg.speaker_pin; 2534 pin = spec->autocfg.speaker_pins[0];
2544 if (pin) /* connect to front */ 2535 if (pin) /* connect to front */
2545 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 2536 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
2546 pin = spec->autocfg.hp_pin; 2537 pin = spec->autocfg.hp_pin;
@@ -2576,15 +2567,15 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
2576 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 2567 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
2577 alc880_ignore)) < 0) 2568 alc880_ignore)) < 0)
2578 return err; 2569 return err;
2579 if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin && 2570 if (! spec->autocfg.line_outs)
2580 ! spec->autocfg.hp_pin)
2581 return 0; /* can't find valid BIOS pin config */ 2571 return 0; /* can't find valid BIOS pin config */
2582 2572
2583 if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || 2573 if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
2584 (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || 2574 (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
2585 (err = alc880_auto_create_extra_out(spec, spec->autocfg.speaker_pin, 2575 (err = alc880_auto_create_extra_out(spec,
2576 spec->autocfg.speaker_pins[0],
2586 "Speaker")) < 0 || 2577 "Speaker")) < 0 ||
2587 (err = alc880_auto_create_extra_out(spec, spec->autocfg.speaker_pin, 2578 (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pin,
2588 "Headphone")) < 0 || 2579 "Headphone")) < 0 ||
2589 (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) 2580 (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
2590 return err; 2581 return err;
@@ -3445,7 +3436,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
3445 return err; 3436 return err;
3446 } 3437 }
3447 3438
3448 nid = cfg->speaker_pin; 3439 nid = cfg->speaker_pins[0];
3449 if (nid) { 3440 if (nid) {
3450 err = alc260_add_playback_controls(spec, nid, "Speaker"); 3441 err = alc260_add_playback_controls(spec, nid, "Speaker");
3451 if (err < 0) 3442 if (err < 0)
@@ -3518,7 +3509,7 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec)
3518 if (nid) 3509 if (nid)
3519 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 3510 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
3520 3511
3521 nid = spec->autocfg.speaker_pin; 3512 nid = spec->autocfg.speaker_pins[0];
3522 if (nid) 3513 if (nid)
3523 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 3514 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
3524 3515
@@ -4602,7 +4593,7 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct
4602 return err; 4593 return err;
4603 } 4594 }
4604 4595
4605 nid = cfg->speaker_pin; 4596 nid = cfg->speaker_pins[0];
4606 if (nid) { 4597 if (nid) {
4607 if (nid == 0x16) { 4598 if (nid == 0x16) {
4608 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume", 4599 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",
@@ -4612,10 +4603,6 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct
4612 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) 4603 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
4613 return err; 4604 return err;
4614 } else { 4605 } else {
4615 if (! cfg->line_out_pins[0])
4616 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",
4617 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
4618 return err;
4619 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", 4606 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
4620 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) 4607 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
4621 return err; 4608 return err;
@@ -4632,10 +4619,6 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct
4632 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) 4619 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
4633 return err; 4620 return err;
4634 } else { 4621 } else {
4635 if (! cfg->line_out_pins[0])
4636 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",
4637 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
4638 return err;
4639 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", 4622 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
4640 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) 4623 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
4641 return err; 4624 return err;
@@ -4729,8 +4712,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
4729 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4712 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4730 alc262_ignore)) < 0) 4713 alc262_ignore)) < 0)
4731 return err; 4714 return err;
4732 if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin && 4715 if (! spec->autocfg.line_outs)
4733 ! spec->autocfg.hp_pin)
4734 return 0; /* can't find valid BIOS pin config */ 4716 return 0; /* can't find valid BIOS pin config */
4735 if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || 4717 if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
4736 (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) 4718 (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
@@ -5404,8 +5386,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
5404 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 5386 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5405 alc861_ignore)) < 0) 5387 alc861_ignore)) < 0)
5406 return err; 5388 return err;
5407 if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin && 5389 if (! spec->autocfg.line_outs)
5408 ! spec->autocfg.hp_pin)
5409 return 0; /* can't find valid BIOS pin config */ 5390 return 0; /* can't find valid BIOS pin config */
5410 5391
5411 if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || 5392 if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 240958df26ce..b56ca4019392 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -51,6 +51,7 @@ struct sigmatel_spec {
51 unsigned int line_switch: 1; 51 unsigned int line_switch: 1;
52 unsigned int mic_switch: 1; 52 unsigned int mic_switch: 1;
53 unsigned int alt_switch: 1; 53 unsigned int alt_switch: 1;
54 unsigned int hp_detect: 1;
54 55
55 /* playback */ 56 /* playback */
56 struct hda_multi_out multiout; 57 struct hda_multi_out multiout;
@@ -697,13 +698,7 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct aut
697 AC_VERB_GET_CONNECT_LIST, 0) & 0xff; 698 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
698 } 699 }
699 700
700 if (cfg->line_outs) 701 spec->multiout.num_dacs = cfg->line_outs;
701 spec->multiout.num_dacs = cfg->line_outs;
702 else if (cfg->hp_pin) {
703 spec->multiout.dac_nids[0] = snd_hda_codec_read(codec, cfg->hp_pin, 0,
704 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
705 spec->multiout.num_dacs = 1;
706 }
707 702
708 return 0; 703 return 0;
709} 704}
@@ -772,11 +767,13 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, struct auto_pin
772 return 0; 767 return 0;
773 768
774 wid_caps = get_wcaps(codec, pin); 769 wid_caps = get_wcaps(codec, pin);
775 if (wid_caps & AC_WCAP_UNSOL_CAP) 770 if (wid_caps & AC_WCAP_UNSOL_CAP) {
776 /* Enable unsolicited responses on the HP widget */ 771 /* Enable unsolicited responses on the HP widget */
777 snd_hda_codec_write(codec, pin, 0, 772 snd_hda_codec_write(codec, pin, 0,
778 AC_VERB_SET_UNSOLICITED_ENABLE, 773 AC_VERB_SET_UNSOLICITED_ENABLE,
779 STAC_UNSOL_ENABLE); 774 STAC_UNSOL_ENABLE);
775 spec->hp_detect = 1;
776 }
780 777
781 nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff; 778 nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
782 for (i = 0; i < cfg->line_outs; i++) { 779 for (i = 0; i < cfg->line_outs; i++) {
@@ -810,9 +807,6 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
810 for (i = 0; i < AUTO_PIN_LAST; i++) { 807 for (i = 0; i < AUTO_PIN_LAST; i++) {
811 int index = -1; 808 int index = -1;
812 if (cfg->input_pins[i]) { 809 if (cfg->input_pins[i]) {
813 /* Enable active pin widget as an input */
814 stac92xx_auto_set_pinctl(codec, cfg->input_pins[i], AC_PINCTL_IN_EN);
815
816 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 810 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
817 811
818 for (j=0; j<spec->num_muxes; j++) { 812 for (j=0; j<spec->num_muxes; j++) {
@@ -861,10 +855,8 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
861 855
862 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0) 856 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
863 return err; 857 return err;
864 if (! spec->autocfg.line_outs && ! spec->autocfg.hp_pin) 858 if (! spec->autocfg.line_outs)
865 return 0; /* can't find valid pin config */ 859 return 0; /* can't find valid pin config */
866 stac92xx_auto_init_multi_out(codec);
867 stac92xx_auto_init_hp_out(codec);
868 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) 860 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
869 return err; 861 return err;
870 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) 862 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
@@ -879,14 +871,10 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
879 if (spec->multiout.max_channels > 2) 871 if (spec->multiout.max_channels > 2)
880 spec->surr_switch = 1; 872 spec->surr_switch = 1;
881 873
882 if (spec->autocfg.dig_out_pin) { 874 if (spec->autocfg.dig_out_pin)
883 spec->multiout.dig_out_nid = dig_out; 875 spec->multiout.dig_out_nid = dig_out;
884 stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN); 876 if (spec->autocfg.dig_in_pin)
885 }
886 if (spec->autocfg.dig_in_pin) {
887 spec->dig_in_nid = dig_in; 877 spec->dig_in_nid = dig_in;
888 stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN);
889 }
890 878
891 if (spec->kctl_alloc) 879 if (spec->kctl_alloc)
892 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 880 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
@@ -896,6 +884,29 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
896 return 1; 884 return 1;
897} 885}
898 886
887/* add playback controls for HP output */
888static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
889 struct auto_pin_cfg *cfg)
890{
891 struct sigmatel_spec *spec = codec->spec;
892 hda_nid_t pin = cfg->hp_pin;
893 unsigned int wid_caps;
894
895 if (! pin)
896 return 0;
897
898 wid_caps = get_wcaps(codec, pin);
899 if (wid_caps & AC_WCAP_UNSOL_CAP) {
900 /* Enable unsolicited responses on the HP widget */
901 snd_hda_codec_write(codec, pin, 0,
902 AC_VERB_SET_UNSOLICITED_ENABLE,
903 STAC_UNSOL_ENABLE);
904 spec->hp_detect = 1;
905 }
906
907 return 0;
908}
909
899static int stac9200_parse_auto_config(struct hda_codec *codec) 910static int stac9200_parse_auto_config(struct hda_codec *codec)
900{ 911{
901 struct sigmatel_spec *spec = codec->spec; 912 struct sigmatel_spec *spec = codec->spec;
@@ -907,14 +918,13 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
907 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0) 918 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
908 return err; 919 return err;
909 920
910 if (spec->autocfg.dig_out_pin) { 921 if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)
922 return err;
923
924 if (spec->autocfg.dig_out_pin)
911 spec->multiout.dig_out_nid = 0x05; 925 spec->multiout.dig_out_nid = 0x05;
912 stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN); 926 if (spec->autocfg.dig_in_pin)
913 }
914 if (spec->autocfg.dig_in_pin) {
915 spec->dig_in_nid = 0x04; 927 spec->dig_in_nid = 0x04;
916 stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN);
917 }
918 928
919 if (spec->kctl_alloc) 929 if (spec->kctl_alloc)
920 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 930 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
@@ -927,9 +937,31 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
927static int stac92xx_init(struct hda_codec *codec) 937static int stac92xx_init(struct hda_codec *codec)
928{ 938{
929 struct sigmatel_spec *spec = codec->spec; 939 struct sigmatel_spec *spec = codec->spec;
940 struct auto_pin_cfg *cfg = &spec->autocfg;
941 int i;
930 942
931 snd_hda_sequence_write(codec, spec->init); 943 snd_hda_sequence_write(codec, spec->init);
932 944
945 /* set up pins */
946 if (spec->hp_detect) {
947 /* fake event to set up pins */
948 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
949 } else {
950 stac92xx_auto_init_multi_out(codec);
951 stac92xx_auto_init_hp_out(codec);
952 }
953 for (i = 0; i < AUTO_PIN_LAST; i++) {
954 if (cfg->input_pins[i])
955 stac92xx_auto_set_pinctl(codec, cfg->input_pins[i],
956 AC_PINCTL_IN_EN);
957 }
958 if (cfg->dig_out_pin)
959 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
960 AC_PINCTL_OUT_EN);
961 if (cfg->dig_in_pin)
962 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
963 AC_PINCTL_IN_EN);
964
933 return 0; 965 return 0;
934} 966}
935 967