/[linux-patches]/genpatches-2.6/tags/2.6.16-7/2705_alsa-hda-auto-configuration.patch
Gentoo

Contents of /genpatches-2.6/tags/2.6.16-7/2705_alsa-hda-auto-configuration.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 451 - (show annotations) (download)
Mon May 1 23:04:47 2006 UTC (12 years, 6 months ago) by dsd
File size: 19547 byte(s)
2.6.16-7 release
1 From: Takashi Iwai <tiwai@suse.de>
2 Date: Tue, 21 Mar 2006 10:24:42 +0000 (+0100)
3 Subject: [ALSA] hda-codec - Fix BIOS auto-configuration
4 X-Git-Tag: v2.6.17-rc1
5 X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=82bc955f6379135e6ce35ff90c7ac411fd412c4c
6
7 [ALSA] hda-codec - Fix BIOS auto-configuration
8
9 Modules: HDA Codec driver,HDA generic driver
10
11 - Fix autoconfig speaker/hp detection
12 Now it allows multiple speaker pins (e.g. Dell laptops have such config)
13
14 - Use speaker or hp pins if no line-outs are available
15 This fixes the silence output on recent Dell laptops with STAC9200
16 (ALSA bug#1843)
17
18 - Fix analog/realtek/sigmatel autoconfig parser
19
20 Signed-off-by: Takashi Iwai <tiwai@suse.de>
21 ---
22
23 Index: linux-2.6.16-gentoo-r4/sound/pci/hda/hda_codec.c
24 ===================================================================
25 --- linux-2.6.16-gentoo-r4.orig/sound/pci/hda/hda_codec.c
26 +++ linux-2.6.16-gentoo-r4/sound/pci/hda/hda_codec.c
27 @@ -1890,6 +1890,13 @@ int snd_hda_multi_out_analog_prepare(str
28 if (mout->hp_nid)
29 /* headphone out will just decode front left/right (stereo) */
30 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format);
31 + /* extra outputs copied from front */
32 + for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
33 + if (mout->extra_out_nid[i])
34 + snd_hda_codec_setup_stream(codec,
35 + mout->extra_out_nid[i],
36 + stream_tag, 0, format);
37 +
38 /* surrounds */
39 for (i = 1; i < mout->num_dacs; i++) {
40 if (chs >= (i + 1) * 2) /* independent out */
41 @@ -1914,6 +1921,11 @@ int snd_hda_multi_out_analog_cleanup(str
42 snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0);
43 if (mout->hp_nid)
44 snd_hda_codec_setup_stream(codec, mout->hp_nid, 0, 0, 0);
45 + for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
46 + if (mout->extra_out_nid[i])
47 + snd_hda_codec_setup_stream(codec,
48 + mout->extra_out_nid[i],
49 + 0, 0, 0);
50 down(&codec->spdif_mutex);
51 if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
52 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);
53 @@ -1935,13 +1947,29 @@ static int is_in_nid_list(hda_nid_t nid,
54 return 0;
55 }
56
57 -/* parse all pin widgets and store the useful pin nids to cfg */
58 +/*
59 + * Parse all pin widgets and store the useful pin nids to cfg
60 + *
61 + * The number of line-outs or any primary output is stored in line_outs,
62 + * and the corresponding output pins are assigned to line_out_pins[],
63 + * in the order of front, rear, CLFE, side, ...
64 + *
65 + * If more extra outputs (speaker and headphone) are found, the pins are
66 + * assisnged to hp_pin and speaker_pins[], respectively. If no line-out jack
67 + * is detected, one of speaker of HP pins is assigned as the primary
68 + * output, i.e. to line_out_pins[0]. So, line_outs is always positive
69 + * if any analog output exists.
70 + *
71 + * The analog input pins are assigned to input_pins array.
72 + * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
73 + * respectively.
74 + */
75 int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg,
76 hda_nid_t *ignore_nids)
77 {
78 hda_nid_t nid, nid_start;
79 int i, j, nodes;
80 - short seq, sequences[4], assoc_line_out;
81 + short seq, assoc_line_out, sequences[ARRAY_SIZE(cfg->line_out_pins)];
82
83 memset(cfg, 0, sizeof(*cfg));
84
85 @@ -1983,7 +2011,10 @@ int snd_hda_parse_pin_def_config(struct
86 cfg->line_outs++;
87 break;
88 case AC_JACK_SPEAKER:
89 - cfg->speaker_pin = nid;
90 + if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins))
91 + continue;
92 + cfg->speaker_pins[cfg->speaker_outs] = nid;
93 + cfg->speaker_outs++;
94 break;
95 case AC_JACK_HP_OUT:
96 cfg->hp_pin = nid;
97 @@ -2048,6 +2079,46 @@ int snd_hda_parse_pin_def_config(struct
98 break;
99 }
100
101 + /*
102 + * debug prints of the parsed results
103 + */
104 + snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
105 + cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1],
106 + cfg->line_out_pins[2], cfg->line_out_pins[3],
107 + cfg->line_out_pins[4]);
108 + snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
109 + cfg->speaker_outs, cfg->speaker_pins[0],
110 + cfg->speaker_pins[1], cfg->speaker_pins[2],
111 + cfg->speaker_pins[3], cfg->speaker_pins[4]);
112 + snd_printd(" hp=0x%x, dig_out=0x%x, din_in=0x%x\n",
113 + cfg->hp_pin, cfg->dig_out_pin, cfg->dig_in_pin);
114 + snd_printd(" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x,"
115 + " cd=0x%x, aux=0x%x\n",
116 + cfg->input_pins[AUTO_PIN_MIC],
117 + cfg->input_pins[AUTO_PIN_FRONT_MIC],
118 + cfg->input_pins[AUTO_PIN_LINE],
119 + cfg->input_pins[AUTO_PIN_FRONT_LINE],
120 + cfg->input_pins[AUTO_PIN_CD],
121 + cfg->input_pins[AUTO_PIN_AUX]);
122 +
123 + /*
124 + * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
125 + * as a primary output
126 + */
127 + if (! cfg->line_outs) {
128 + if (cfg->speaker_outs) {
129 + cfg->line_outs = cfg->speaker_outs;
130 + memcpy(cfg->line_out_pins, cfg->speaker_pins,
131 + sizeof(cfg->speaker_pins));
132 + cfg->speaker_outs = 0;
133 + memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
134 + } else if (cfg->hp_pin) {
135 + cfg->line_outs = 1;
136 + cfg->line_out_pins[0] = cfg->hp_pin;
137 + cfg->hp_pin = 0;
138 + }
139 + }
140 +
141 return 0;
142 }
143
144 Index: linux-2.6.16-gentoo-r4/sound/pci/hda/hda_local.h
145 ===================================================================
146 --- linux-2.6.16-gentoo-r4.orig/sound/pci/hda/hda_local.h
147 +++ linux-2.6.16-gentoo-r4/sound/pci/hda/hda_local.h
148 @@ -130,6 +130,7 @@ struct hda_multi_out {
149 int num_dacs; /* # of DACs, must be more than 1 */
150 hda_nid_t *dac_nids; /* DAC list */
151 hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */
152 + hda_nid_t extra_out_nid[3]; /* optional DACs, 0 when not exists */
153 hda_nid_t dig_out_nid; /* digital out audio widget */
154 int max_channels; /* currently supported analog channels */
155 int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */
156 @@ -216,7 +217,8 @@ extern const char *auto_pin_cfg_labels[A
157 struct auto_pin_cfg {
158 int line_outs;
159 hda_nid_t line_out_pins[5]; /* sorted in the order of Front/Surr/CLFE/Side */
160 - hda_nid_t speaker_pin;
161 + int speaker_outs;
162 + hda_nid_t speaker_pins[5];
163 hda_nid_t hp_pin;
164 hda_nid_t input_pins[AUTO_PIN_LAST];
165 hda_nid_t dig_out_pin;
166 Index: linux-2.6.16-gentoo-r4/sound/pci/hda/patch_analog.c
167 ===================================================================
168 --- linux-2.6.16-gentoo-r4.orig/sound/pci/hda/patch_analog.c
169 +++ linux-2.6.16-gentoo-r4/sound/pci/hda/patch_analog.c
170 @@ -639,6 +639,8 @@ enum { AD1986A_6STACK, AD1986A_3STACK, A
171 static struct hda_board_config ad1986a_cfg_tbl[] = {
172 { .modelname = "6stack", .config = AD1986A_6STACK },
173 { .modelname = "3stack", .config = AD1986A_3STACK },
174 + { .pci_subvendor = 0x10de, .pci_subdevice = 0xcb84,
175 + .config = AD1986A_3STACK }, /* ASUS A8N-VM CSM */
176 { .modelname = "laptop", .config = AD1986A_LAPTOP },
177 { .pci_subvendor = 0x144d, .pci_subdevice = 0xc01e,
178 .config = AD1986A_LAPTOP }, /* FSC V2060 */
179 @@ -1926,14 +1928,11 @@ static int ad1988_auto_create_extra_out(
180
181 idx = ad1988_pin_idx(pin);
182 nid = ad1988_idx_to_dac(codec, idx);
183 - if (! spec->multiout.dac_nids[0]) {
184 - /* use this as the primary output */
185 - spec->multiout.dac_nids[0] = nid;
186 - if (! spec->multiout.num_dacs)
187 - spec->multiout.num_dacs = 1;
188 - } else
189 - /* specify the DAC as the extra output */
190 + /* specify the DAC as the extra output */
191 + if (! spec->multiout.hp_nid)
192 spec->multiout.hp_nid = nid;
193 + else
194 + spec->multiout.extra_out_nid[0] = nid;
195 /* control HP volume/switch on the output mixer amp */
196 sprintf(name, "%s Playback Volume", pfx);
197 if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
198 @@ -2052,7 +2051,7 @@ static void ad1988_auto_init_extra_out(s
199 struct ad198x_spec *spec = codec->spec;
200 hda_nid_t pin;
201
202 - pin = spec->autocfg.speaker_pin;
203 + pin = spec->autocfg.speaker_pins[0];
204 if (pin) /* connect to front */
205 ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
206 pin = spec->autocfg.hp_pin;
207 @@ -2101,13 +2100,13 @@ static int ad1988_parse_auto_config(stru
208 return err;
209 if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
210 return err;
211 - if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin &&
212 - ! spec->autocfg.hp_pin)
213 + if (! spec->autocfg.line_outs)
214 return 0; /* can't find valid BIOS pin config */
215 if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
216 - (err = ad1988_auto_create_extra_out(codec, spec->autocfg.speaker_pin,
217 + (err = ad1988_auto_create_extra_out(codec,
218 + spec->autocfg.speaker_pins[0],
219 "Speaker")) < 0 ||
220 - (err = ad1988_auto_create_extra_out(codec, spec->autocfg.speaker_pin,
221 + (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pin,
222 "Headphone")) < 0 ||
223 (err = ad1988_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
224 return err;
225 Index: linux-2.6.16-gentoo-r4/sound/pci/hda/patch_realtek.c
226 ===================================================================
227 --- linux-2.6.16-gentoo-r4.orig/sound/pci/hda/patch_realtek.c
228 +++ linux-2.6.16-gentoo-r4/sound/pci/hda/patch_realtek.c
229 @@ -2043,14 +2043,11 @@ static int alc880_auto_create_extra_out(
230
231 if (alc880_is_fixed_pin(pin)) {
232 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
233 - if (! spec->multiout.dac_nids[0]) {
234 - /* use this as the primary output */
235 - spec->multiout.dac_nids[0] = nid;
236 - if (! spec->multiout.num_dacs)
237 - spec->multiout.num_dacs = 1;
238 - } else
239 - /* specify the DAC as the extra output */
240 + /* specify the DAC as the extra output */
241 + if (! spec->multiout.hp_nid)
242 spec->multiout.hp_nid = nid;
243 + else
244 + spec->multiout.extra_out_nid[0] = nid;
245 /* control HP volume/switch on the output mixer amp */
246 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
247 sprintf(name, "%s Playback Volume", pfx);
248 @@ -2063,12 +2060,6 @@ static int alc880_auto_create_extra_out(
249 return err;
250 } else if (alc880_is_multi_pin(pin)) {
251 /* set manual connection */
252 - if (! spec->multiout.dac_nids[0]) {
253 - /* use this as the primary output */
254 - spec->multiout.dac_nids[0] = alc880_idx_to_dac(alc880_multi_pin_idx(pin));
255 - if (! spec->multiout.num_dacs)
256 - spec->multiout.num_dacs = 1;
257 - }
258 /* we have only a switch on HP-out PIN */
259 sprintf(name, "%s Playback Switch", pfx);
260 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
261 @@ -2152,7 +2143,7 @@ static void alc880_auto_init_extra_out(s
262 struct alc_spec *spec = codec->spec;
263 hda_nid_t pin;
264
265 - pin = spec->autocfg.speaker_pin;
266 + pin = spec->autocfg.speaker_pins[0];
267 if (pin) /* connect to front */
268 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
269 pin = spec->autocfg.hp_pin;
270 @@ -2188,15 +2179,15 @@ static int alc880_parse_auto_config(stru
271 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
272 alc880_ignore)) < 0)
273 return err;
274 - if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin &&
275 - ! spec->autocfg.hp_pin)
276 + if (! spec->autocfg.line_outs)
277 return 0; /* can't find valid BIOS pin config */
278
279 if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
280 (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
281 - (err = alc880_auto_create_extra_out(spec, spec->autocfg.speaker_pin,
282 + (err = alc880_auto_create_extra_out(spec,
283 + spec->autocfg.speaker_pins[0],
284 "Speaker")) < 0 ||
285 - (err = alc880_auto_create_extra_out(spec, spec->autocfg.speaker_pin,
286 + (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pin,
287 "Headphone")) < 0 ||
288 (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
289 return err;
290 @@ -2744,7 +2735,7 @@ static int alc260_auto_create_multi_out_
291 return err;
292 }
293
294 - nid = cfg->speaker_pin;
295 + nid = cfg->speaker_pins[0];
296 if (nid) {
297 err = alc260_add_playback_controls(spec, nid, "Speaker");
298 if (err < 0)
299 @@ -2817,7 +2808,7 @@ static void alc260_auto_init_multi_out(s
300 if (nid)
301 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
302
303 - nid = spec->autocfg.speaker_pin;
304 + nid = spec->autocfg.speaker_pins[0];
305 if (nid)
306 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
307
308 @@ -3761,7 +3752,7 @@ static int alc262_auto_create_multi_out_
309 return err;
310 }
311
312 - nid = cfg->speaker_pin;
313 + nid = cfg->speaker_pins[0];
314 if (nid) {
315 if (nid == 0x16) {
316 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",
317 @@ -3771,10 +3762,6 @@ static int alc262_auto_create_multi_out_
318 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
319 return err;
320 } else {
321 - if (! cfg->line_out_pins[0])
322 - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",
323 - HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
324 - return err;
325 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
326 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
327 return err;
328 @@ -3791,10 +3778,6 @@ static int alc262_auto_create_multi_out_
329 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
330 return err;
331 } else {
332 - if (! cfg->line_out_pins[0])
333 - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",
334 - HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
335 - return err;
336 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
337 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
338 return err;
339 @@ -3888,8 +3871,7 @@ static int alc262_parse_auto_config(stru
340 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
341 alc262_ignore)) < 0)
342 return err;
343 - if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin &&
344 - ! spec->autocfg.hp_pin)
345 + if (! spec->autocfg.line_outs)
346 return 0; /* can't find valid BIOS pin config */
347 if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
348 (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
349 @@ -4551,8 +4533,7 @@ static int alc861_parse_auto_config(stru
350 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
351 alc861_ignore)) < 0)
352 return err;
353 - if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin &&
354 - ! spec->autocfg.hp_pin)
355 + if (! spec->autocfg.line_outs)
356 return 0; /* can't find valid BIOS pin config */
357
358 if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
359 Index: linux-2.6.16-gentoo-r4/sound/pci/hda/patch_sigmatel.c
360 ===================================================================
361 --- linux-2.6.16-gentoo-r4.orig/sound/pci/hda/patch_sigmatel.c
362 +++ linux-2.6.16-gentoo-r4/sound/pci/hda/patch_sigmatel.c
363 @@ -51,6 +51,7 @@ struct sigmatel_spec {
364 unsigned int line_switch: 1;
365 unsigned int mic_switch: 1;
366 unsigned int alt_switch: 1;
367 + unsigned int hp_detect: 1;
368
369 /* playback */
370 struct hda_multi_out multiout;
371 @@ -691,13 +692,7 @@ static int stac92xx_auto_fill_dac_nids(s
372 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
373 }
374
375 - if (cfg->line_outs)
376 - spec->multiout.num_dacs = cfg->line_outs;
377 - else if (cfg->hp_pin) {
378 - spec->multiout.dac_nids[0] = snd_hda_codec_read(codec, cfg->hp_pin, 0,
379 - AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
380 - spec->multiout.num_dacs = 1;
381 - }
382 + spec->multiout.num_dacs = cfg->line_outs;
383
384 return 0;
385 }
386 @@ -766,11 +761,13 @@ static int stac92xx_auto_create_hp_ctls(
387 return 0;
388
389 wid_caps = get_wcaps(codec, pin);
390 - if (wid_caps & AC_WCAP_UNSOL_CAP)
391 + if (wid_caps & AC_WCAP_UNSOL_CAP) {
392 /* Enable unsolicited responses on the HP widget */
393 snd_hda_codec_write(codec, pin, 0,
394 AC_VERB_SET_UNSOLICITED_ENABLE,
395 STAC_UNSOL_ENABLE);
396 + spec->hp_detect = 1;
397 + }
398
399 nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
400 for (i = 0; i < cfg->line_outs; i++) {
401 @@ -804,9 +801,6 @@ static int stac92xx_auto_create_analog_i
402 for (i = 0; i < AUTO_PIN_LAST; i++) {
403 int index = -1;
404 if (cfg->input_pins[i]) {
405 - /* Enable active pin widget as an input */
406 - stac92xx_auto_set_pinctl(codec, cfg->input_pins[i], AC_PINCTL_IN_EN);
407 -
408 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
409
410 for (j=0; j<spec->num_muxes; j++) {
411 @@ -855,10 +849,8 @@ static int stac92xx_parse_auto_config(st
412
413 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
414 return err;
415 - if (! spec->autocfg.line_outs && ! spec->autocfg.hp_pin)
416 + if (! spec->autocfg.line_outs)
417 return 0; /* can't find valid pin config */
418 - stac92xx_auto_init_multi_out(codec);
419 - stac92xx_auto_init_hp_out(codec);
420 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
421 return err;
422 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
423 @@ -873,14 +865,10 @@ static int stac92xx_parse_auto_config(st
424 if (spec->multiout.max_channels > 2)
425 spec->surr_switch = 1;
426
427 - if (spec->autocfg.dig_out_pin) {
428 + if (spec->autocfg.dig_out_pin)
429 spec->multiout.dig_out_nid = dig_out;
430 - stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN);
431 - }
432 - if (spec->autocfg.dig_in_pin) {
433 + if (spec->autocfg.dig_in_pin)
434 spec->dig_in_nid = dig_in;
435 - stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN);
436 - }
437
438 if (spec->kctl_alloc)
439 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
440 @@ -890,6 +878,29 @@ static int stac92xx_parse_auto_config(st
441 return 1;
442 }
443
444 +/* add playback controls for HP output */
445 +static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
446 + struct auto_pin_cfg *cfg)
447 +{
448 + struct sigmatel_spec *spec = codec->spec;
449 + hda_nid_t pin = cfg->hp_pin;
450 + unsigned int wid_caps;
451 +
452 + if (! pin)
453 + return 0;
454 +
455 + wid_caps = get_wcaps(codec, pin);
456 + if (wid_caps & AC_WCAP_UNSOL_CAP) {
457 + /* Enable unsolicited responses on the HP widget */
458 + snd_hda_codec_write(codec, pin, 0,
459 + AC_VERB_SET_UNSOLICITED_ENABLE,
460 + STAC_UNSOL_ENABLE);
461 + spec->hp_detect = 1;
462 + }
463 +
464 + return 0;
465 +}
466 +
467 static int stac9200_parse_auto_config(struct hda_codec *codec)
468 {
469 struct sigmatel_spec *spec = codec->spec;
470 @@ -901,14 +912,13 @@ static int stac9200_parse_auto_config(st
471 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
472 return err;
473
474 - if (spec->autocfg.dig_out_pin) {
475 + if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)
476 + return err;
477 +
478 + if (spec->autocfg.dig_out_pin)
479 spec->multiout.dig_out_nid = 0x05;
480 - stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN);
481 - }
482 - if (spec->autocfg.dig_in_pin) {
483 + if (spec->autocfg.dig_in_pin)
484 spec->dig_in_nid = 0x04;
485 - stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN);
486 - }
487
488 if (spec->kctl_alloc)
489 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
490 @@ -921,9 +931,31 @@ static int stac9200_parse_auto_config(st
491 static int stac92xx_init(struct hda_codec *codec)
492 {
493 struct sigmatel_spec *spec = codec->spec;
494 + struct auto_pin_cfg *cfg = &spec->autocfg;
495 + int i;
496
497 snd_hda_sequence_write(codec, spec->init);
498
499 + /* set up pins */
500 + if (spec->hp_detect) {
501 + /* fake event to set up pins */
502 + codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
503 + } else {
504 + stac92xx_auto_init_multi_out(codec);
505 + stac92xx_auto_init_hp_out(codec);
506 + }
507 + for (i = 0; i < AUTO_PIN_LAST; i++) {
508 + if (cfg->input_pins[i])
509 + stac92xx_auto_set_pinctl(codec, cfg->input_pins[i],
510 + AC_PINCTL_IN_EN);
511 + }
512 + if (cfg->dig_out_pin)
513 + stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
514 + AC_PINCTL_OUT_EN);
515 + if (cfg->dig_in_pin)
516 + stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
517 + AC_PINCTL_IN_EN);
518 +
519 return 0;
520 }
521

  ViewVC Help
Powered by ViewVC 1.1.20