aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
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/hda/hda_codec.c
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/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c77
1 files changed, 74 insertions, 3 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