]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.drivers/alsa-post-ga-hda-sigmatel-update
Revert "Move xen patchset to new version's subdir."
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / alsa-post-ga-hda-sigmatel-update
CommitLineData
00e5a55c
BS
1From: Takashi Iwai <tiwai@suse.de>
2Subject: Backport fixes for patch_sigmatel.c from 2.6.29
3Patch-mainline: 2.6.29
4References: bcn#457472, bnc#462913, bnc#467381, bnc#479558, bnc#480617, bnc#480809
5
6Backport patch_sigmatel fixes from 2.6.29.
7This includes fixes for multiple Dell and HP laptops.
8
9Signed-off-by: Takashi Iwai <tiwai@suse.de>
10
11---
12 sound/pci/hda/patch_sigmatel.c | 896 +++++++++++++++++++++--------------------
13 1 file changed, 480 insertions(+), 416 deletions(-)
14
15--- a/sound/pci/hda/patch_sigmatel.c
16+++ b/sound/pci/hda/patch_sigmatel.c
17@@ -82,6 +82,7 @@
18
19 enum {
20 STAC_92HD83XXX_REF,
21+ STAC_92HD83XXX_PWR_REF,
22 STAC_92HD83XXX_MODELS
23 };
24
25@@ -144,6 +145,13 @@
26 STAC_927X_MODELS
27 };
28
29+struct sigmatel_event {
30+ hda_nid_t nid;
31+ unsigned char type;
32+ unsigned char tag;
33+ int data;
34+};
35+
36 struct sigmatel_spec {
37 struct snd_kcontrol_new *mixers[4];
38 unsigned int num_mixers;
39@@ -151,8 +159,6 @@
40 int board_config;
41 unsigned int eapd_switch: 1;
42 unsigned int surr_switch: 1;
43- unsigned int line_switch: 1;
44- unsigned int mic_switch: 1;
45 unsigned int alt_switch: 1;
46 unsigned int hp_detect: 1;
47 unsigned int spdif_mute: 1;
48@@ -178,12 +184,18 @@
49 hda_nid_t *pwr_nids;
50 hda_nid_t *dac_list;
51
52+ /* events */
53+ int num_events;
54+ struct sigmatel_event events[32];
55+
56 /* playback */
57 struct hda_input_mux *mono_mux;
58 struct hda_input_mux *amp_mux;
59 unsigned int cur_mmux;
60 struct hda_multi_out multiout;
61 hda_nid_t dac_nids[5];
62+ hda_nid_t hp_dacs[5];
63+ hda_nid_t speaker_dacs[5];
64
65 int volume_offset;
66
67@@ -230,7 +242,9 @@
68 /* i/o switches */
69 unsigned int io_switch[2];
70 unsigned int clfe_swap;
71- unsigned int hp_switch; /* NID of HP as line-out */
72+ hda_nid_t line_switch; /* shared line-in for input and output */
73+ hda_nid_t mic_switch; /* shared mic-in for input and output */
74+ hda_nid_t hp_switch; /* NID of HP as line-out */
75 unsigned int aloopback;
76
77 struct hda_pcm pcm_rec[2]; /* PCM information */
78@@ -282,9 +296,6 @@
79 };
80
81 #define STAC92HD73_DAC_COUNT 5
82-static hda_nid_t stac92hd73xx_dac_nids[STAC92HD73_DAC_COUNT] = {
83- 0x15, 0x16, 0x17, 0x18, 0x19,
84-};
85
86 static hda_nid_t stac92hd73xx_mux_nids[4] = {
87 0x28, 0x29, 0x2a, 0x2b,
88@@ -303,11 +314,7 @@
89 0x11, 0x12, 0
90 };
91
92-#define STAC92HD81_DAC_COUNT 2
93 #define STAC92HD83_DAC_COUNT 3
94-static hda_nid_t stac92hd83xxx_dac_nids[STAC92HD73_DAC_COUNT] = {
95- 0x13, 0x14, 0x22,
96-};
97
98 static hda_nid_t stac92hd83xxx_dmux_nids[2] = {
99 0x17, 0x18,
100@@ -326,7 +333,11 @@
101 };
102
103 static unsigned int stac92hd83xxx_pwr_mapping[4] = {
104- 0x03, 0x0c, 0x10, 0x40,
105+ 0x03, 0x0c, 0x20, 0x40,
106+};
107+
108+static hda_nid_t stac92hd83xxx_amp_nids[1] = {
109+ 0xc,
110 };
111
112 static hda_nid_t stac92hd71bxx_pwr_nids[3] = {
113@@ -349,10 +360,6 @@
114 0x24, 0x25,
115 };
116
117-static hda_nid_t stac92hd71bxx_dac_nids[1] = {
118- 0x10, /*0x11, */
119-};
120-
121 #define STAC92HD71BXX_NUM_DMICS 2
122 static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
123 0x18, 0x19, 0
124@@ -584,12 +591,12 @@
125 else
126 nid = codec->slave_dig_outs[smux_idx - 1];
127 if (spec->cur_smux[smux_idx] == smux->num_items - 1)
128- val = AMP_OUT_MUTE;
129+ val = HDA_AMP_MUTE;
130 else
131- val = AMP_OUT_UNMUTE;
132+ val = 0;
133 /* un/mute SPDIF out */
134- snd_hda_codec_write_cache(codec, nid, 0,
135- AC_VERB_SET_AMP_GAIN_MUTE, val);
136+ snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
137+ HDA_AMP_MUTE, val);
138 }
139 return 0;
140 }
141@@ -754,10 +761,6 @@
142 static struct hda_verb stac92hd73xx_6ch_core_init[] = {
143 /* set master volume and direct control */
144 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
145- /* setup audio connections */
146- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
147- { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
148- { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
149 /* setup adcs to point to mixer */
150 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
151 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
152@@ -776,10 +779,6 @@
153 /* set master volume to max value without distortion
154 * and direct control */
155 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
156- /* setup audio connections */
157- { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
158- { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x02},
159- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01},
160 /* setup adcs to point to mixer */
161 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
162 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
163@@ -793,10 +792,6 @@
164
165 static struct hda_verb dell_m6_core_init[] = {
166 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
167- /* setup audio connections */
168- { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
169- { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
170- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02},
171 /* setup adcs to point to mixer */
172 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
173 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
174@@ -811,13 +806,6 @@
175 static struct hda_verb stac92hd73xx_8ch_core_init[] = {
176 /* set master volume and direct control */
177 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
178- /* setup audio connections */
179- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
180- { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
181- { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
182- /* connect hp ports to dac3 */
183- { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x03},
184- { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x03},
185 /* setup adcs to point to mixer */
186 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
187 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
188@@ -835,15 +823,8 @@
189 static struct hda_verb stac92hd73xx_10ch_core_init[] = {
190 /* set master volume and direct control */
191 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
192- /* setup audio connections */
193- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
194- { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01 },
195- { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02 },
196 /* dac3 is connected to import3 mux */
197 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f},
198- /* connect hp ports to dac4 */
199- { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x04},
200- { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x04},
201 /* setup adcs to point to mixer */
202 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
203 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
204@@ -859,10 +840,6 @@
205 };
206
207 static struct hda_verb stac92hd83xxx_core_init[] = {
208- /* start of config #1 */
209- { 0xe, AC_VERB_SET_CONNECT_SEL, 0x3},
210-
211- /* start of config #2 */
212 { 0xa, AC_VERB_SET_CONNECT_SEL, 0x0},
213 { 0xb, AC_VERB_SET_CONNECT_SEL, 0x0},
214 { 0xd, AC_VERB_SET_CONNECT_SEL, 0x1},
215@@ -875,8 +852,6 @@
216 static struct hda_verb stac92hd71bxx_core_init[] = {
217 /* set master volume and direct control */
218 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
219- /* connect headphone jack to dac1 */
220- { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
221 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */
222 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
223 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
224@@ -896,8 +871,6 @@
225
226 /* set master volume and direct control */
227 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
228- /* connect headphone jack to dac1 */
229- { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
230 /* unmute right and left channels for nodes 0x0a, 0xd */
231 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
232 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
233@@ -1099,21 +1072,21 @@
234 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT),
235 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT),
236
237- HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0, HDA_INPUT),
238- HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0, HDA_INPUT),
239+ HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0x3, HDA_INPUT),
240+ HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0x3, HDA_INPUT),
241
242- HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x1, HDA_INPUT),
243- HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x1, HDA_INPUT),
244+ HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x4, HDA_INPUT),
245+ HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x4, HDA_INPUT),
246
247- HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x2, HDA_INPUT),
248- HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x2, HDA_INPUT),
249+ HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x0, HDA_INPUT),
250+ HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x0, HDA_INPUT),
251
252- HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x3, HDA_INPUT),
253- HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x3, HDA_INPUT),
254+ HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x2, HDA_INPUT),
255+ HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x2, HDA_INPUT),
256
257 /*
258- HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x4, HDA_INPUT),
259- HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x4, HDA_INPUT),
260+ HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x1, HDA_INPUT),
261+ HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x1, HDA_INPUT),
262 */
263 { } /* end */
264 };
265@@ -1726,10 +1699,12 @@
266
267 static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
268 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
269+ [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs,
270 };
271
272 static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
273 [STAC_92HD83XXX_REF] = "ref",
274+ [STAC_92HD83XXX_PWR_REF] = "mic-ref",
275 };
276
277 static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
278@@ -1788,11 +1763,13 @@
279 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2,
280 "HP dv5", STAC_HP_M4),
281 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4,
282- "HP dv7", STAC_HP_M4),
283+ "HP dv7", STAC_HP_DV5),
284 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f7,
285 "HP dv4", STAC_HP_DV5),
286 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc,
287 "HP dv7", STAC_HP_M4),
288+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3600,
289+ "HP dv5", STAC_HP_DV5),
290 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3603,
291 "HP dv5", STAC_HP_DV5),
292 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
293@@ -2419,7 +2396,7 @@
294
295 if (spec->powerdown_adcs) {
296 msleep(40);
297- snd_hda_codec_write_cache(codec, nid, 0,
298+ snd_hda_codec_write(codec, nid, 0,
299 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
300 }
301 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
302@@ -2435,7 +2412,7 @@
303
304 snd_hda_codec_cleanup_stream(codec, nid);
305 if (spec->powerdown_adcs)
306- snd_hda_codec_write_cache(codec, nid, 0,
307+ snd_hda_codec_write(codec, nid, 0,
308 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
309 return 0;
310 }
311@@ -2569,6 +2546,9 @@
312 return 0;
313 }
314
315+static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid,
316+ unsigned char type);
317+
318 static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
319 struct snd_ctl_elem_value *ucontrol)
320 {
321@@ -2581,8 +2561,7 @@
322 /* check to be sure that the ports are upto date with
323 * switch changes
324 */
325- codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
326-
327+ stac_issue_unsol_event(codec, nid, STAC_HP_EVENT);
328 return 1;
329 }
330
331@@ -2621,7 +2600,7 @@
332 * appropriately according to the pin direction
333 */
334 if (spec->hp_detect)
335- codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
336+ stac_issue_unsol_event(codec, nid, STAC_HP_EVENT);
337
338 return 1;
339 }
340@@ -2758,70 +2737,53 @@
341 return stac92xx_add_control_idx(spec, type, 0, name, val);
342 }
343
344-/* flag inputs as additional dynamic lineouts */
345-static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
346+/* check whether the line-input can be used as line-out */
347+static hda_nid_t check_line_out_switch(struct hda_codec *codec)
348 {
349 struct sigmatel_spec *spec = codec->spec;
350- unsigned int wcaps, wtype;
351- int i, num_dacs = 0;
352-
353- /* use the wcaps cache to count all DACs available for line-outs */
354- for (i = 0; i < codec->num_nodes; i++) {
355- wcaps = codec->wcaps[i];
356- wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
357+ struct auto_pin_cfg *cfg = &spec->autocfg;
358+ hda_nid_t nid;
359+ unsigned int pincap;
360
361- if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL))
362- num_dacs++;
363- }
364+ if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
365+ return 0;
366+ nid = cfg->input_pins[AUTO_PIN_LINE];
367+ pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
368+ if (pincap & AC_PINCAP_OUT)
369+ return nid;
370+ return 0;
371+}
372
373- snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
374-
375- switch (cfg->line_outs) {
376- case 3:
377- /* add line-in as side */
378- if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
379- cfg->line_out_pins[cfg->line_outs] =
380- cfg->input_pins[AUTO_PIN_LINE];
381- spec->line_switch = 1;
382- cfg->line_outs++;
383- }
384- break;
385- case 2:
386- /* add line-in as clfe and mic as side */
387- if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
388- cfg->line_out_pins[cfg->line_outs] =
389- cfg->input_pins[AUTO_PIN_LINE];
390- spec->line_switch = 1;
391- cfg->line_outs++;
392- }
393- if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
394- cfg->line_out_pins[cfg->line_outs] =
395- cfg->input_pins[AUTO_PIN_MIC];
396- spec->mic_switch = 1;
397- cfg->line_outs++;
398- }
399- break;
400- case 1:
401- /* add line-in as surr and mic as clfe */
402- if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
403- cfg->line_out_pins[cfg->line_outs] =
404- cfg->input_pins[AUTO_PIN_LINE];
405- spec->line_switch = 1;
406- cfg->line_outs++;
407- }
408- if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
409- cfg->line_out_pins[cfg->line_outs] =
410- cfg->input_pins[AUTO_PIN_MIC];
411- spec->mic_switch = 1;
412- cfg->line_outs++;
413+/* check whether the mic-input can be used as line-out */
414+static hda_nid_t check_mic_out_switch(struct hda_codec *codec)
415+{
416+ struct sigmatel_spec *spec = codec->spec;
417+ struct auto_pin_cfg *cfg = &spec->autocfg;
418+ unsigned int def_conf, pincap;
419+ unsigned int mic_pin;
420+
421+ if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
422+ return 0;
423+ mic_pin = AUTO_PIN_MIC;
424+ for (;;) {
425+ hda_nid_t nid = cfg->input_pins[mic_pin];
426+ def_conf = snd_hda_codec_read(codec, nid, 0,
427+ AC_VERB_GET_CONFIG_DEFAULT, 0);
428+ /* some laptops have an internal analog microphone
429+ * which can't be used as a output */
430+ if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) {
431+ pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
432+ if (pincap & AC_PINCAP_OUT)
433+ return nid;
434 }
435- break;
436+ if (mic_pin == AUTO_PIN_MIC)
437+ mic_pin = AUTO_PIN_FRONT_MIC;
438+ else
439+ break;
440 }
441-
442 return 0;
443 }
444
445-
446 static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
447 {
448 int i;
449@@ -2834,6 +2796,52 @@
450 return 0;
451 }
452
453+static int check_all_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
454+{
455+ int i;
456+ if (is_in_dac_nids(spec, nid))
457+ return 1;
458+ for (i = 0; i < spec->autocfg.hp_outs; i++)
459+ if (spec->hp_dacs[i] == nid)
460+ return 1;
461+ for (i = 0; i < spec->autocfg.speaker_outs; i++)
462+ if (spec->speaker_dacs[i] == nid)
463+ return 1;
464+ return 0;
465+}
466+
467+static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
468+{
469+ struct sigmatel_spec *spec = codec->spec;
470+ int j, conn_len;
471+ hda_nid_t conn[HDA_MAX_CONNECTIONS];
472+ unsigned int wcaps, wtype;
473+
474+ conn_len = snd_hda_get_connections(codec, nid, conn,
475+ HDA_MAX_CONNECTIONS);
476+ for (j = 0; j < conn_len; j++) {
477+ wcaps = snd_hda_param_read(codec, conn[j],
478+ AC_PAR_AUDIO_WIDGET_CAP);
479+ wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
480+ /* we check only analog outputs */
481+ if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL))
482+ continue;
483+ /* if this route has a free DAC, assign it */
484+ if (!check_all_dac_nids(spec, conn[j])) {
485+ if (conn_len > 1) {
486+ /* select this DAC in the pin's input mux */
487+ snd_hda_codec_write_cache(codec, nid, 0,
488+ AC_VERB_SET_CONNECT_SEL, j);
489+ }
490+ return conn[j];
491+ }
492+ }
493+ return 0;
494+}
495+
496+static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
497+static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
498+
499 /*
500 * Fill in the dac_nids table from the parsed pin configuration
501 * This function only works when every pin in line_out_pins[]
502@@ -2841,31 +2849,17 @@
503 * codecs are not connected directly to a DAC, such as the 9200
504 * and 9202/925x. For those, dac_nids[] must be hard-coded.
505 */
506-static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
507- struct auto_pin_cfg *cfg)
508+static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec)
509 {
510 struct sigmatel_spec *spec = codec->spec;
511- int i, j, conn_len = 0;
512- hda_nid_t nid, conn[HDA_MAX_CONNECTIONS];
513- unsigned int wcaps, wtype;
514+ struct auto_pin_cfg *cfg = &spec->autocfg;
515+ int i;
516+ hda_nid_t nid, dac;
517
518 for (i = 0; i < cfg->line_outs; i++) {
519 nid = cfg->line_out_pins[i];
520- conn_len = snd_hda_get_connections(codec, nid, conn,
521- HDA_MAX_CONNECTIONS);
522- for (j = 0; j < conn_len; j++) {
523- wcaps = snd_hda_param_read(codec, conn[j],
524- AC_PAR_AUDIO_WIDGET_CAP);
525- wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
526- if (wtype != AC_WID_AUD_OUT ||
527- (wcaps & AC_WCAP_DIGITAL))
528- continue;
529- /* conn[j] is a DAC routed to this line-out */
530- if (!is_in_dac_nids(spec, conn[j]))
531- break;
532- }
533-
534- if (j == conn_len) {
535+ dac = get_unassigned_dac(codec, nid);
536+ if (!dac) {
537 if (spec->multiout.num_dacs > 0) {
538 /* we have already working output pins,
539 * so let's drop the broken ones again
540@@ -2879,24 +2873,64 @@
541 __func__, nid);
542 return -ENODEV;
543 }
544+ add_spec_dacs(spec, dac);
545+ }
546
547- spec->multiout.dac_nids[i] = conn[j];
548- spec->multiout.num_dacs++;
549- if (conn_len > 1) {
550- /* select this DAC in the pin's input mux */
551- snd_hda_codec_write_cache(codec, nid, 0,
552- AC_VERB_SET_CONNECT_SEL, j);
553+ /* add line-in as output */
554+ nid = check_line_out_switch(codec);
555+ if (nid) {
556+ dac = get_unassigned_dac(codec, nid);
557+ if (dac) {
558+ snd_printdd("STAC: Add line-in 0x%x as output %d\n",
559+ nid, cfg->line_outs);
560+ cfg->line_out_pins[cfg->line_outs] = nid;
561+ cfg->line_outs++;
562+ spec->line_switch = nid;
563+ add_spec_dacs(spec, dac);
564+ }
565+ }
566+ /* add mic as output */
567+ nid = check_mic_out_switch(codec);
568+ if (nid) {
569+ dac = get_unassigned_dac(codec, nid);
570+ if (dac) {
571+ snd_printdd("STAC: Add mic-in 0x%x as output %d\n",
572+ nid, cfg->line_outs);
573+ cfg->line_out_pins[cfg->line_outs] = nid;
574+ cfg->line_outs++;
575+ spec->mic_switch = nid;
576+ add_spec_dacs(spec, dac);
577+ }
578+ }
579
580+ for (i = 0; i < cfg->hp_outs; i++) {
581+ nid = cfg->hp_pins[i];
582+ dac = get_unassigned_dac(codec, nid);
583+ if (dac) {
584+ if (!spec->multiout.hp_nid)
585+ spec->multiout.hp_nid = dac;
586+ else
587+ add_spec_extra_dacs(spec, dac);
588 }
589+ spec->hp_dacs[i] = dac;
590 }
591
592- snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
593+ for (i = 0; i < cfg->speaker_outs; i++) {
594+ nid = cfg->speaker_pins[i];
595+ dac = get_unassigned_dac(codec, nid);
596+ if (dac)
597+ add_spec_extra_dacs(spec, dac);
598+ spec->speaker_dacs[i] = dac;
599+ }
600+
601+ snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
602 spec->multiout.num_dacs,
603 spec->multiout.dac_nids[0],
604 spec->multiout.dac_nids[1],
605 spec->multiout.dac_nids[2],
606 spec->multiout.dac_nids[3],
607 spec->multiout.dac_nids[4]);
608+
609 return 0;
610 }
611
612@@ -2941,9 +2975,7 @@
613
614 static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
615 {
616- if (!spec->multiout.hp_nid)
617- spec->multiout.hp_nid = nid;
618- else if (spec->multiout.num_dacs > 4) {
619+ if (spec->multiout.num_dacs > 4) {
620 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
621 return 1;
622 } else {
623@@ -2953,35 +2985,47 @@
624 return 0;
625 }
626
627-static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
628+static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
629 {
630- if (is_in_dac_nids(spec, nid))
631- return 1;
632+ int i;
633+ for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) {
634+ if (!spec->multiout.extra_out_nid[i]) {
635+ spec->multiout.extra_out_nid[i] = nid;
636+ return 0;
637+ }
638+ }
639+ printk(KERN_WARNING "stac92xx: No space for extra DAC 0x%x\n", nid);
640+ return 1;
641+}
642+
643+static int is_unique_dac(struct sigmatel_spec *spec, hda_nid_t nid)
644+{
645+ int i;
646+
647+ if (spec->autocfg.line_outs != 1)
648+ return 0;
649 if (spec->multiout.hp_nid == nid)
650- return 1;
651- return 0;
652+ return 0;
653+ for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
654+ if (spec->multiout.extra_out_nid[i] == nid)
655+ return 0;
656+ return 1;
657 }
658
659 /* add playback controls from the parsed DAC table */
660 static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
661 const struct auto_pin_cfg *cfg)
662 {
663+ struct sigmatel_spec *spec = codec->spec;
664 static const char *chname[4] = {
665 "Front", "Surround", NULL /*CLFE*/, "Side"
666 };
667 hda_nid_t nid = 0;
668 int i, err;
669+ unsigned int wid_caps;
670
671- struct sigmatel_spec *spec = codec->spec;
672- unsigned int wid_caps, pincap;
673-
674-
675- for (i = 0; i < cfg->line_outs && i < spec->multiout.num_dacs; i++) {
676- if (!spec->multiout.dac_nids[i])
677- continue;
678-
679+ for (i = 0; i < cfg->line_outs && spec->multiout.dac_nids[i]; i++) {
680 nid = spec->multiout.dac_nids[i];
681-
682 if (i == 2) {
683 /* Center/LFE */
684 err = create_controls(codec, "Center", nid, 1);
685@@ -3003,16 +3047,24 @@
686 }
687
688 } else {
689- err = create_controls(codec, chname[i], nid, 3);
690+ const char *name = chname[i];
691+ /* if it's a single DAC, assign a better name */
692+ if (!i && is_unique_dac(spec, nid)) {
693+ switch (cfg->line_out_type) {
694+ case AUTO_PIN_HP_OUT:
695+ name = "Headphone";
696+ break;
697+ case AUTO_PIN_SPEAKER_OUT:
698+ name = "Speaker";
699+ break;
700+ }
701+ }
702+ err = create_controls(codec, name, nid, 3);
703 if (err < 0)
704 return err;
705 }
706 }
707
708- if ((spec->multiout.num_dacs - cfg->line_outs) > 0 &&
709- cfg->hp_outs == 1 && !spec->multiout.hp_nid)
710- spec->multiout.hp_nid = nid;
711-
712 if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) {
713 err = stac92xx_add_control(spec,
714 STAC_CTL_WIDGET_HP_SWITCH,
715@@ -3023,45 +3075,19 @@
716 }
717
718 if (spec->line_switch) {
719- nid = cfg->input_pins[AUTO_PIN_LINE];
720- pincap = snd_hda_param_read(codec, nid,
721- AC_PAR_PIN_CAP);
722- if (pincap & AC_PINCAP_OUT) {
723- err = stac92xx_add_control(spec,
724- STAC_CTL_WIDGET_IO_SWITCH,
725- "Line In as Output Switch", nid << 8);
726- if (err < 0)
727- return err;
728- }
729+ err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH,
730+ "Line In as Output Switch",
731+ spec->line_switch << 8);
732+ if (err < 0)
733+ return err;
734 }
735
736 if (spec->mic_switch) {
737- unsigned int def_conf;
738- unsigned int mic_pin = AUTO_PIN_MIC;
739-again:
740- nid = cfg->input_pins[mic_pin];
741- def_conf = snd_hda_codec_read(codec, nid, 0,
742- AC_VERB_GET_CONFIG_DEFAULT, 0);
743- /* some laptops have an internal analog microphone
744- * which can't be used as a output */
745- if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) {
746- pincap = snd_hda_param_read(codec, nid,
747- AC_PAR_PIN_CAP);
748- if (pincap & AC_PINCAP_OUT) {
749- err = stac92xx_add_control(spec,
750- STAC_CTL_WIDGET_IO_SWITCH,
751- "Mic as Output Switch", (nid << 8) | 1);
752- nid = snd_hda_codec_read(codec, nid, 0,
753- AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
754- if (!check_in_dac_nids(spec, nid))
755- add_spec_dacs(spec, nid);
756- if (err < 0)
757- return err;
758- }
759- } else if (mic_pin == AUTO_PIN_MIC) {
760- mic_pin = AUTO_PIN_FRONT_MIC;
761- goto again;
762- }
763+ err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH,
764+ "Mic as Output Switch",
765+ (spec->mic_switch << 8) | 1);
766+ if (err < 0)
767+ return err;
768 }
769
770 return 0;
771@@ -3073,55 +3099,39 @@
772 {
773 struct sigmatel_spec *spec = codec->spec;
774 hda_nid_t nid;
775- int i, old_num_dacs, err;
776+ int i, err, nums;
777
778- old_num_dacs = spec->multiout.num_dacs;
779+ nums = 0;
780 for (i = 0; i < cfg->hp_outs; i++) {
781+ static const char *pfxs[] = {
782+ "Headphone", "Headphone2", "Headphone3",
783+ };
784 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]);
785 if (wid_caps & AC_WCAP_UNSOL_CAP)
786 spec->hp_detect = 1;
787- nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
788- AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
789- if (check_in_dac_nids(spec, nid))
790- nid = 0;
791- if (! nid)
792+ if (nums >= ARRAY_SIZE(pfxs))
793 continue;
794- add_spec_dacs(spec, nid);
795- }
796- for (i = 0; i < cfg->speaker_outs; i++) {
797- nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
798- AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
799- if (check_in_dac_nids(spec, nid))
800- nid = 0;
801- if (! nid)
802+ nid = spec->hp_dacs[i];
803+ if (!nid)
804 continue;
805- add_spec_dacs(spec, nid);
806- }
807- for (i = 0; i < cfg->line_outs; i++) {
808- nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0,
809- AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
810- if (check_in_dac_nids(spec, nid))
811- nid = 0;
812- if (! nid)
813- continue;
814- add_spec_dacs(spec, nid);
815+ err = create_controls(codec, pfxs[nums++], nid, 3);
816+ if (err < 0)
817+ return err;
818 }
819- for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) {
820+ nums = 0;
821+ for (i = 0; i < cfg->speaker_outs; i++) {
822 static const char *pfxs[] = {
823 "Speaker", "External Speaker", "Speaker2",
824 };
825- err = create_controls(codec, pfxs[i - old_num_dacs],
826- spec->multiout.dac_nids[i], 3);
827- if (err < 0)
828- return err;
829- }
830- if (spec->multiout.hp_nid) {
831- err = create_controls(codec, "Headphone",
832- spec->multiout.hp_nid, 3);
833+ if (nums >= ARRAY_SIZE(pfxs))
834+ continue;
835+ nid = spec->speaker_dacs[i];
836+ if (!nid)
837+ continue;
838+ err = create_controls(codec, pfxs[nums++], nid, 3);
839 if (err < 0)
840 return err;
841 }
842-
843 return 0;
844 }
845
846@@ -3459,7 +3469,6 @@
847 {
848 struct sigmatel_spec *spec = codec->spec;
849 int err;
850- int hp_speaker_swap = 0;
851
852 if ((err = snd_hda_parse_pin_def_config(codec,
853 &spec->autocfg,
854@@ -3477,13 +3486,15 @@
855 * speaker_outs so that the following routines can handle
856 * HP pins as primary outputs.
857 */
858+ snd_printdd("stac92xx: Enabling multi-HPs workaround\n");
859 memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins,
860 sizeof(spec->autocfg.line_out_pins));
861 spec->autocfg.speaker_outs = spec->autocfg.line_outs;
862 memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins,
863 sizeof(spec->autocfg.hp_pins));
864 spec->autocfg.line_outs = spec->autocfg.hp_outs;
865- hp_speaker_swap = 1;
866+ spec->autocfg.line_out_type = AUTO_PIN_HP_OUT;
867+ spec->autocfg.hp_outs = 0;
868 }
869 if (spec->autocfg.mono_out_pin) {
870 int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) &
871@@ -3535,10 +3546,9 @@
872 AC_PINCTL_OUT_EN);
873 }
874
875- if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
876- return err;
877- if (spec->multiout.num_dacs == 0) {
878- if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
879+ if (!spec->multiout.num_dacs) {
880+ err = stac92xx_auto_fill_dac_nids(codec);
881+ if (err < 0)
882 return err;
883 err = stac92xx_auto_create_multi_out_ctls(codec,
884 &spec->autocfg);
885@@ -3577,19 +3587,6 @@
886 }
887 #endif
888
889- if (hp_speaker_swap == 1) {
890- /* Restore the hp_outs and line_outs */
891- memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
892- sizeof(spec->autocfg.line_out_pins));
893- spec->autocfg.hp_outs = spec->autocfg.line_outs;
894- memcpy(spec->autocfg.line_out_pins, spec->autocfg.speaker_pins,
895- sizeof(spec->autocfg.speaker_pins));
896- spec->autocfg.line_outs = spec->autocfg.speaker_outs;
897- memset(spec->autocfg.speaker_pins, 0,
898- sizeof(spec->autocfg.speaker_pins));
899- spec->autocfg.speaker_outs = 0;
900- }
901-
902 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
903
904 if (err < 0)
905@@ -3638,7 +3635,8 @@
906 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
907
908 spec->input_mux = &spec->private_imux;
909- spec->dinput_mux = &spec->private_dimux;
910+ if (!spec->dinput_mux)
911+ spec->dinput_mux = &spec->private_dimux;
912 spec->sinput_mux = &spec->private_smux;
913 spec->mono_mux = &spec->private_mono_mux;
914 spec->amp_mux = &spec->private_amp_mux;
915@@ -3787,13 +3785,68 @@
916 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
917 }
918
919+static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid,
920+ unsigned char type, int data)
921+{
922+ struct sigmatel_event *event;
923+
924+ if (spec->num_events >= ARRAY_SIZE(spec->events))
925+ return -ENOMEM;
926+ event = &spec->events[spec->num_events++];
927+ event->nid = nid;
928+ event->type = type;
929+ event->tag = spec->num_events;
930+ event->data = data;
931+
932+ return event->tag;
933+}
934+
935+static struct sigmatel_event *stac_get_event(struct hda_codec *codec,
936+ hda_nid_t nid, unsigned char type)
937+{
938+ struct sigmatel_spec *spec = codec->spec;
939+ struct sigmatel_event *event = spec->events;
940+ int i;
941+
942+ for (i = 0; i < spec->num_events; i++, event++) {
943+ if (event->nid == nid && event->type == type)
944+ return event;
945+ }
946+ return NULL;
947+}
948+
949+static struct sigmatel_event *stac_get_event_from_tag(struct hda_codec *codec,
950+ unsigned char tag)
951+{
952+ struct sigmatel_spec *spec = codec->spec;
953+ struct sigmatel_event *event = spec->events;
954+ int i;
955+
956+ for (i = 0; i < spec->num_events; i++, event++) {
957+ if (event->tag == tag)
958+ return event;
959+ }
960+ return NULL;
961+}
962+
963 static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
964- unsigned int event)
965+ unsigned int type)
966 {
967- if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)
968- snd_hda_codec_write_cache(codec, nid, 0,
969- AC_VERB_SET_UNSOLICITED_ENABLE,
970- (AC_USRSP_EN | event));
971+ struct sigmatel_event *event;
972+ int tag;
973+
974+ if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
975+ return;
976+ event = stac_get_event(codec, nid, type);
977+ if (event)
978+ tag = event->tag;
979+ else
980+ tag = stac_add_event(codec->spec, nid, type, 0);
981+ if (tag < 0)
982+ return;
983+ snd_hda_codec_write_cache(codec, nid, 0,
984+ AC_VERB_SET_UNSOLICITED_ENABLE,
985+ AC_USRSP_EN | tag);
986 }
987
988 static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
989@@ -3813,9 +3866,8 @@
990 /* power down inactive DACs */
991 hda_nid_t *dac;
992 for (dac = spec->dac_list; *dac; dac++)
993- if (!is_in_dac_nids(spec, *dac) &&
994- spec->multiout.hp_nid != *dac)
995- snd_hda_codec_write_cache(codec, *dac, 0,
996+ if (!check_all_dac_nids(spec, *dac))
997+ snd_hda_codec_write(codec, *dac, 0,
998 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
999 }
1000
1001@@ -3834,7 +3886,7 @@
1002 /* power down adcs initially */
1003 if (spec->powerdown_adcs)
1004 for (i = 0; i < spec->num_adcs; i++)
1005- snd_hda_codec_write_cache(codec,
1006+ snd_hda_codec_write(codec,
1007 spec->adc_nids[i], 0,
1008 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1009
1010@@ -3850,37 +3902,51 @@
1011 /* set up pins */
1012 if (spec->hp_detect) {
1013 /* Enable unsolicited responses on the HP widget */
1014- for (i = 0; i < cfg->hp_outs; i++)
1015- enable_pin_detect(codec, cfg->hp_pins[i],
1016- STAC_HP_EVENT);
1017+ for (i = 0; i < cfg->hp_outs; i++) {
1018+ hda_nid_t nid = cfg->hp_pins[i];
1019+ enable_pin_detect(codec, nid, STAC_HP_EVENT);
1020+ }
1021 /* force to enable the first line-out; the others are set up
1022 * in unsol_event
1023 */
1024 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
1025 AC_PINCTL_OUT_EN);
1026- stac92xx_auto_init_hp_out(codec);
1027 /* fake event to set up pins */
1028- codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
1029+ stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0],
1030+ STAC_HP_EVENT);
1031 } else {
1032 stac92xx_auto_init_multi_out(codec);
1033 stac92xx_auto_init_hp_out(codec);
1034+ for (i = 0; i < cfg->hp_outs; i++)
1035+ stac_toggle_power_map(codec, cfg->hp_pins[i], 1);
1036 }
1037 for (i = 0; i < AUTO_PIN_LAST; i++) {
1038 hda_nid_t nid = cfg->input_pins[i];
1039 if (nid) {
1040- unsigned int pinctl;
1041+ unsigned int pinctl, conf;
1042 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) {
1043 /* for mic pins, force to initialize */
1044 pinctl = stac92xx_get_vref(codec, nid);
1045+ pinctl |= AC_PINCTL_IN_EN;
1046+ stac92xx_auto_set_pinctl(codec, nid, pinctl);
1047 } else {
1048 pinctl = snd_hda_codec_read(codec, nid, 0,
1049 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1050 /* if PINCTL already set then skip */
1051- if (pinctl & AC_PINCTL_IN_EN)
1052- continue;
1053+ if (!(pinctl & AC_PINCTL_IN_EN)) {
1054+ pinctl |= AC_PINCTL_IN_EN;
1055+ stac92xx_auto_set_pinctl(codec, nid,
1056+ pinctl);
1057+ }
1058+ }
1059+ conf = snd_hda_codec_read(codec, nid, 0,
1060+ AC_VERB_GET_CONFIG_DEFAULT, 0);
1061+ if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
1062+ enable_pin_detect(codec, nid,
1063+ STAC_INSERT_EVENT);
1064+ stac_issue_unsol_event(codec, nid,
1065+ STAC_INSERT_EVENT);
1066 }
1067- pinctl |= AC_PINCTL_IN_EN;
1068- stac92xx_auto_set_pinctl(codec, nid, pinctl);
1069 }
1070 }
1071 for (i = 0; i < spec->num_dmics; i++)
1072@@ -3895,9 +3961,14 @@
1073 for (i = 0; i < spec->num_pwrs; i++) {
1074 hda_nid_t nid = spec->pwr_nids[i];
1075 int pinctl, def_conf;
1076- int event = STAC_PWR_EVENT;
1077
1078- if (is_nid_hp_pin(cfg, nid) && spec->hp_detect)
1079+ /* power on when no jack detection is available */
1080+ if (!spec->hp_detect) {
1081+ stac_toggle_power_map(codec, nid, 1);
1082+ continue;
1083+ }
1084+
1085+ if (is_nid_hp_pin(cfg, nid))
1086 continue; /* already has an unsol event */
1087
1088 pinctl = snd_hda_codec_read(codec, nid, 0,
1089@@ -3906,8 +3977,10 @@
1090 * any attempts on powering down a input port cause the
1091 * referenced VREF to act quirky.
1092 */
1093- if (pinctl & AC_PINCTL_IN_EN)
1094+ if (pinctl & AC_PINCTL_IN_EN) {
1095+ stac_toggle_power_map(codec, nid, 1);
1096 continue;
1097+ }
1098 def_conf = snd_hda_codec_read(codec, nid, 0,
1099 AC_VERB_GET_CONFIG_DEFAULT, 0);
1100 def_conf = get_defcfg_connect(def_conf);
1101@@ -3918,8 +3991,10 @@
1102 stac_toggle_power_map(codec, nid, 1);
1103 continue;
1104 }
1105- enable_pin_detect(codec, spec->pwr_nids[i], event | i);
1106- codec->patch_ops.unsol_event(codec, (event | i) << 26);
1107+ if (!stac_get_event(codec, nid, STAC_INSERT_EVENT)) {
1108+ enable_pin_detect(codec, nid, STAC_PWR_EVENT);
1109+ stac_issue_unsol_event(codec, nid, STAC_PWR_EVENT);
1110+ }
1111 }
1112 if (spec->dac_list)
1113 stac92xx_power_down(codec);
1114@@ -3960,11 +4035,7 @@
1115 * "xxx as Output" mixer switch
1116 */
1117 struct sigmatel_spec *spec = codec->spec;
1118- struct auto_pin_cfg *cfg = &spec->autocfg;
1119- if ((nid == cfg->input_pins[AUTO_PIN_LINE] &&
1120- spec->line_switch) ||
1121- (nid == cfg->input_pins[AUTO_PIN_MIC] &&
1122- spec->mic_switch))
1123+ if (nid == spec->line_switch || nid == spec->mic_switch)
1124 return;
1125 }
1126
1127@@ -3988,20 +4059,13 @@
1128 pin_ctl & ~flag);
1129 }
1130
1131-static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid)
1132+static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
1133 {
1134 if (!nid)
1135 return 0;
1136 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00)
1137- & (1 << 31)) {
1138- unsigned int pinctl;
1139- pinctl = snd_hda_codec_read(codec, nid, 0,
1140- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1141- if (pinctl & AC_PINCTL_IN_EN)
1142- return 0; /* mic- or line-input */
1143- else
1144- return 1; /* HP-output */
1145- }
1146+ & (1 << 31))
1147+ return 1;
1148 return 0;
1149 }
1150
1151@@ -4013,11 +4077,9 @@
1152 struct auto_pin_cfg *cfg = &spec->autocfg;
1153
1154 /* ignore sensing of shared line and mic jacks */
1155- if (spec->line_switch &&
1156- cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_LINE])
1157+ if (cfg->hp_pins[i] == spec->line_switch)
1158 return 1;
1159- if (spec->mic_switch &&
1160- cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_MIC])
1161+ if (cfg->hp_pins[i] == spec->mic_switch)
1162 return 1;
1163 /* ignore if the pin is set as line-out */
1164 if (cfg->hp_pins[i] == spec->hp_switch)
1165@@ -4025,7 +4087,7 @@
1166 return 0;
1167 }
1168
1169-static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
1170+static void stac92xx_hp_detect(struct hda_codec *codec)
1171 {
1172 struct sigmatel_spec *spec = codec->spec;
1173 struct auto_pin_cfg *cfg = &spec->autocfg;
1174@@ -4041,7 +4103,14 @@
1175 break;
1176 if (no_hp_sensing(spec, i))
1177 continue;
1178- presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);
1179+ presence = get_pin_presence(codec, cfg->hp_pins[i]);
1180+ if (presence) {
1181+ unsigned int pinctl;
1182+ pinctl = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
1183+ AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1184+ if (pinctl & AC_PINCTL_IN_EN)
1185+ presence = 0; /* mic- or line-input */
1186+ }
1187 }
1188
1189 if (presence) {
1190@@ -4082,8 +4151,19 @@
1191 continue;
1192 if (presence)
1193 stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);
1194+#if 0 /* FIXME */
1195+/* Resetting the pinctl like below may lead to (a sort of) regressions
1196+ * on some devices since they use the HP pin actually for line/speaker
1197+ * outs although the default pin config shows a different pin (that is
1198+ * wrong and useless).
1199+ *
1200+ * So, it's basically a problem of default pin configs, likely a BIOS issue.
1201+ * But, disabling the code below just works around it, and I'm too tired of
1202+ * bug reports with such devices...
1203+ */
1204 else
1205 stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val);
1206+#endif /* FIXME */
1207 }
1208 }
1209
1210@@ -4118,30 +4198,45 @@
1211
1212 static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid)
1213 {
1214- stac_toggle_power_map(codec, nid, get_hp_pin_presence(codec, nid));
1215+ stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid));
1216+}
1217+
1218+static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid,
1219+ unsigned char type)
1220+{
1221+ struct sigmatel_event *event = stac_get_event(codec, nid, type);
1222+ if (!event)
1223+ return;
1224+ codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26);
1225 }
1226
1227 static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
1228 {
1229 struct sigmatel_spec *spec = codec->spec;
1230- int idx = res >> 26 & 0x0f;
1231+ struct sigmatel_event *event;
1232+ int tag, data;
1233+
1234+ tag = (res >> 26) & 0x7f;
1235+ event = stac_get_event_from_tag(codec, tag);
1236+ if (!event)
1237+ return;
1238
1239- switch ((res >> 26) & 0x70) {
1240+ switch (event->type) {
1241 case STAC_HP_EVENT:
1242- stac92xx_hp_detect(codec, res);
1243+ stac92xx_hp_detect(codec);
1244 /* fallthru */
1245+ case STAC_INSERT_EVENT:
1246 case STAC_PWR_EVENT:
1247 if (spec->num_pwrs > 0)
1248- stac92xx_pin_sense(codec, idx);
1249+ stac92xx_pin_sense(codec, event->nid);
1250 break;
1251- case STAC_VREF_EVENT: {
1252- int data = snd_hda_codec_read(codec, codec->afg, 0,
1253- AC_VERB_GET_GPIO_DATA, 0);
1254+ case STAC_VREF_EVENT:
1255+ data = snd_hda_codec_read(codec, codec->afg, 0,
1256+ AC_VERB_GET_GPIO_DATA, 0);
1257 /* toggle VREF state based on GPIOx status */
1258 snd_hda_codec_write(codec, codec->afg, 0, 0x7e0,
1259- !!(data & (1 << idx)));
1260+ !!(data & (1 << event->data)));
1261 break;
1262- }
1263 }
1264 }
1265
1266@@ -4151,17 +4246,23 @@
1267 struct sigmatel_spec *spec = codec->spec;
1268
1269 stac92xx_set_config_regs(codec);
1270- snd_hda_sequence_write(codec, spec->init);
1271- stac_gpio_set(codec, spec->gpio_mask,
1272- spec->gpio_dir, spec->gpio_data);
1273+ stac92xx_init(codec);
1274 snd_hda_codec_resume_amp(codec);
1275 snd_hda_codec_resume_cache(codec);
1276- /* power down inactive DACs */
1277- if (spec->dac_list)
1278- stac92xx_power_down(codec);
1279- /* invoke unsolicited event to reset the HP state */
1280+ /* fake event to set up pins again to override cached values */
1281 if (spec->hp_detect)
1282- codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
1283+ stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0],
1284+ STAC_HP_EVENT);
1285+ return 0;
1286+}
1287+
1288+static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
1289+{
1290+ struct sigmatel_spec *spec = codec->spec;
1291+ if (spec->eapd_mask)
1292+ stac_gpio_set(codec, spec->gpio_mask,
1293+ spec->gpio_dir, spec->gpio_data &
1294+ ~spec->eapd_mask);
1295 return 0;
1296 }
1297 #endif
1298@@ -4173,6 +4274,7 @@
1299 .free = stac92xx_free,
1300 .unsol_event = stac92xx_unsol_event,
1301 #ifdef SND_HDA_NEEDS_RESUME
1302+ .suspend = stac92xx_suspend,
1303 .resume = stac92xx_resume,
1304 #endif
1305 };
1306@@ -4234,6 +4336,12 @@
1307 return err;
1308 }
1309
1310+ /* CF-74 has no headphone detection, and the driver should *NOT*
1311+ * do detection and HP/speaker toggle because the hardware does it.
1312+ */
1313+ if (spec->board_config == STAC_9200_PANASONIC)
1314+ spec->hp_detect = 0;
1315+
1316 codec->patch_ops = stac92xx_patch_ops;
1317
1318 return 0;
1319@@ -4340,6 +4448,7 @@
1320 struct sigmatel_spec *spec;
1321 hda_nid_t conn[STAC92HD73_DAC_COUNT + 2];
1322 int err = 0;
1323+ int num_dacs;
1324
1325 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1326 if (spec == NULL)
1327@@ -4368,33 +4477,29 @@
1328 stac92xx_set_config_regs(codec);
1329 }
1330
1331- spec->multiout.num_dacs = snd_hda_get_connections(codec, 0x0a,
1332+ num_dacs = snd_hda_get_connections(codec, 0x0a,
1333 conn, STAC92HD73_DAC_COUNT + 2) - 1;
1334
1335- if (spec->multiout.num_dacs < 0) {
1336+ if (num_dacs < 3 || num_dacs > 5) {
1337 printk(KERN_WARNING "hda_codec: Could not determine "
1338 "number of channels defaulting to DAC count\n");
1339- spec->multiout.num_dacs = STAC92HD73_DAC_COUNT;
1340+ num_dacs = STAC92HD73_DAC_COUNT;
1341 }
1342-
1343- switch (spec->multiout.num_dacs) {
1344+ switch (num_dacs) {
1345 case 0x3: /* 6 Channel */
1346- spec->multiout.hp_nid = 0x17;
1347 spec->mixer = stac92hd73xx_6ch_mixer;
1348 spec->init = stac92hd73xx_6ch_core_init;
1349 break;
1350 case 0x4: /* 8 Channel */
1351- spec->multiout.hp_nid = 0x18;
1352 spec->mixer = stac92hd73xx_8ch_mixer;
1353 spec->init = stac92hd73xx_8ch_core_init;
1354 break;
1355 case 0x5: /* 10 Channel */
1356- spec->multiout.hp_nid = 0x19;
1357 spec->mixer = stac92hd73xx_10ch_mixer;
1358 spec->init = stac92hd73xx_10ch_core_init;
1359- };
1360+ }
1361+ spec->multiout.dac_nids = spec->dac_nids;
1362
1363- spec->multiout.dac_nids = stac92hd73xx_dac_nids;
1364 spec->aloopback_mask = 0x01;
1365 spec->aloopback_shift = 8;
1366
1367@@ -4425,9 +4530,8 @@
1368 spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP];
1369 spec->eapd_switch = 0;
1370 spec->num_amps = 1;
1371- spec->multiout.hp_nid = 0; /* dual HPs */
1372
1373- if (!spec->init)
1374+ if (spec->board_config != STAC_DELL_EQ)
1375 spec->init = dell_m6_core_init;
1376 switch (spec->board_config) {
1377 case STAC_DELL_M6_AMIC: /* Analog Mics */
1378@@ -4500,7 +4604,9 @@
1379 static int patch_stac92hd83xxx(struct hda_codec *codec)
1380 {
1381 struct sigmatel_spec *spec;
1382+ hda_nid_t conn[STAC92HD83_DAC_COUNT + 1];
1383 int err;
1384+ int num_dacs;
1385
1386 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1387 if (spec == NULL)
1388@@ -4514,25 +4620,25 @@
1389 spec->dmux_nids = stac92hd83xxx_dmux_nids;
1390 spec->adc_nids = stac92hd83xxx_adc_nids;
1391 spec->pwr_nids = stac92hd83xxx_pwr_nids;
1392+ spec->amp_nids = stac92hd83xxx_amp_nids;
1393 spec->pwr_mapping = stac92hd83xxx_pwr_mapping;
1394 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
1395- spec->multiout.dac_nids = stac92hd83xxx_dac_nids;
1396+ spec->multiout.dac_nids = spec->dac_nids;
1397
1398- spec->init = stac92hd83xxx_core_init;
1399- switch (codec->vendor_id) {
1400- case 0x111d7605:
1401- spec->multiout.num_dacs = STAC92HD81_DAC_COUNT;
1402- break;
1403- default:
1404- spec->num_pwrs--;
1405- spec->init++; /* switch to config #2 */
1406- spec->multiout.num_dacs = STAC92HD83_DAC_COUNT;
1407- }
1408+ /* set port 0xe to select the last DAC
1409+ */
1410+ num_dacs = snd_hda_get_connections(codec, 0x0e,
1411+ conn, STAC92HD83_DAC_COUNT + 1) - 1;
1412+
1413+ snd_hda_codec_write_cache(codec, 0xe, 0,
1414+ AC_VERB_SET_CONNECT_SEL, num_dacs);
1415
1416+ spec->init = stac92hd83xxx_core_init;
1417 spec->mixer = stac92hd83xxx_mixer;
1418 spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids);
1419 spec->num_dmuxes = ARRAY_SIZE(stac92hd83xxx_dmux_nids);
1420 spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids);
1421+ spec->num_amps = ARRAY_SIZE(stac92hd83xxx_amp_nids);
1422 spec->num_dmics = STAC92HD83XXX_NUM_DMICS;
1423 spec->dinput_mux = &stac92hd83xxx_dmux;
1424 spec->pin_nids = stac92hd83xxx_pin_nids;
1425@@ -4555,6 +4661,15 @@
1426 stac92xx_set_config_regs(codec);
1427 }
1428
1429+ switch (codec->vendor_id) {
1430+ case 0x111d7604:
1431+ case 0x111d7605:
1432+ if (spec->board_config == STAC_92HD83XXX_PWR_REF)
1433+ break;
1434+ spec->num_pwrs = 0;
1435+ break;
1436+ }
1437+
1438 err = stac92xx_parse_auto_config(codec, 0x1d, 0);
1439 if (!err) {
1440 if (spec->board_config < 0) {
1441@@ -4576,54 +4691,6 @@
1442 return 0;
1443 }
1444
1445-#ifdef SND_HDA_NEEDS_RESUME
1446-static void stac92hd71xx_set_power_state(struct hda_codec *codec, int pwr)
1447-{
1448- struct sigmatel_spec *spec = codec->spec;
1449- int i;
1450- snd_hda_codec_write_cache(codec, codec->afg, 0,
1451- AC_VERB_SET_POWER_STATE, pwr);
1452-
1453- msleep(1);
1454- for (i = 0; i < spec->num_adcs; i++) {
1455- snd_hda_codec_write_cache(codec,
1456- spec->adc_nids[i], 0,
1457- AC_VERB_SET_POWER_STATE, pwr);
1458- }
1459-};
1460-
1461-static int stac92hd71xx_resume(struct hda_codec *codec)
1462-{
1463- stac92hd71xx_set_power_state(codec, AC_PWRST_D0);
1464- return stac92xx_resume(codec);
1465-}
1466-
1467-static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state)
1468-{
1469- struct sigmatel_spec *spec = codec->spec;
1470-
1471- stac92hd71xx_set_power_state(codec, AC_PWRST_D3);
1472- if (spec->eapd_mask)
1473- stac_gpio_set(codec, spec->gpio_mask,
1474- spec->gpio_dir, spec->gpio_data &
1475- ~spec->eapd_mask);
1476- return 0;
1477-};
1478-
1479-#endif
1480-
1481-static struct hda_codec_ops stac92hd71bxx_patch_ops = {
1482- .build_controls = stac92xx_build_controls,
1483- .build_pcms = stac92xx_build_pcms,
1484- .init = stac92xx_init,
1485- .free = stac92xx_free,
1486- .unsol_event = stac92xx_unsol_event,
1487-#ifdef SND_HDA_NEEDS_RESUME
1488- .resume = stac92hd71xx_resume,
1489- .suspend = stac92hd71xx_suspend,
1490-#endif
1491-};
1492-
1493 static struct hda_input_mux stac92hd71bxx_dmux = {
1494 .num_items = 4,
1495 .items = {
1496@@ -4689,21 +4756,21 @@
1497 switch (spec->board_config) {
1498 case STAC_HP_M4:
1499 /* Enable VREF power saving on GPIO1 detect */
1500+ err = stac_add_event(spec, codec->afg,
1501+ STAC_VREF_EVENT, 0x02);
1502+ if (err < 0)
1503+ return err;
1504 snd_hda_codec_write_cache(codec, codec->afg, 0,
1505 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
1506 snd_hda_codec_write_cache(codec, codec->afg, 0,
1507- AC_VERB_SET_UNSOLICITED_ENABLE,
1508- (AC_USRSP_EN | STAC_VREF_EVENT | 0x01));
1509+ AC_VERB_SET_UNSOLICITED_ENABLE,
1510+ AC_USRSP_EN | err);
1511 spec->gpio_mask |= 0x02;
1512 break;
1513 }
1514 if ((codec->revision_id & 0xf) == 0 ||
1515- (codec->revision_id & 0xf) == 1) {
1516-#ifdef SND_HDA_NEEDS_RESUME
1517- codec->patch_ops = stac92hd71bxx_patch_ops;
1518-#endif
1519+ (codec->revision_id & 0xf) == 1)
1520 spec->stream_delay = 40; /* 40 milliseconds */
1521- }
1522
1523 /* no output amps */
1524 spec->num_pwrs = 0;
1525@@ -4715,12 +4782,8 @@
1526 stac92xx_set_config_reg(codec, 0xf, 0x40f000f0);
1527 break;
1528 case 0x111d7603: /* 6 Port with Analog Mixer */
1529- if ((codec->revision_id & 0xf) == 1) {
1530-#ifdef SND_HDA_NEEDS_RESUME
1531- codec->patch_ops = stac92hd71bxx_patch_ops;
1532-#endif
1533+ if ((codec->revision_id & 0xf) == 1)
1534 spec->stream_delay = 40; /* 40 milliseconds */
1535- }
1536
1537 /* no output amps */
1538 spec->num_pwrs = 0;
1539@@ -4763,7 +4826,7 @@
1540 case STAC_DELL_M4_3:
1541 spec->num_dmics = 1;
1542 spec->num_smuxes = 0;
1543- spec->num_dmuxes = 0;
1544+ spec->num_dmuxes = 1;
1545 break;
1546 default:
1547 spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
1548@@ -4771,9 +4834,7 @@
1549 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
1550 };
1551
1552- spec->multiout.num_dacs = 1;
1553- spec->multiout.hp_nid = 0x11;
1554- spec->multiout.dac_nids = stac92hd71bxx_dac_nids;
1555+ spec->multiout.dac_nids = spec->dac_nids;
1556 if (spec->dinput_mux)
1557 spec->private_dimux.num_items +=
1558 spec->num_dmics -
1559@@ -5097,11 +5158,14 @@
1560 stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
1561
1562 /* Enable unsol response for GPIO4/Dock HP connection */
1563+ err = stac_add_event(spec, codec->afg, STAC_VREF_EVENT, 0x01);
1564+ if (err < 0)
1565+ return err;
1566 snd_hda_codec_write_cache(codec, codec->afg, 0,
1567 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
1568 snd_hda_codec_write_cache(codec, codec->afg, 0,
1569 AC_VERB_SET_UNSOLICITED_ENABLE,
1570- (AC_USRSP_EN | STAC_HP_EVENT));
1571+ AC_USRSP_EN | err);
1572
1573 spec->gpio_dir = 0x0b;
1574 spec->eapd_mask = 0x01;
1575@@ -5275,7 +5339,7 @@
1576
1577 static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
1578 {
1579- if (get_hp_pin_presence(codec, 0x0a)) {
1580+ if (get_pin_presence(codec, 0x0a)) {
1581 stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
1582 stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
1583 } else {