diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-05-07 11:42:31 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-05-08 12:01:33 -0400 |
commit | 128bc4ba8c52194eae5a80594ec9b7f6b35ba88f (patch) | |
tree | 02cf180917b5a5f6732eaa5f6bfebd91abc120d8 /sound/pci | |
parent | 23d30f28275ddd7fdb87f265e9a440baf4a4cf09 (diff) |
ALSA: hda - Move BIOS pin-parser code to hda_auto_parser.c
Just code shuffles.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_auto_parser.c | 597 | ||||
-rw-r--r-- | sound/pci/hda/hda_auto_parser.h | 80 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 596 | ||||
-rw-r--r-- | sound/pci/hda/hda_jack.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/hda_jack.h | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 82 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_ca0110.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_ca0132.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_cmedia.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 1 |
13 files changed, 690 insertions, 675 deletions
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c index 7cc3a1688240..6e9ef3e25093 100644 --- a/sound/pci/hda/hda_auto_parser.c +++ b/sound/pci/hda/hda_auto_parser.c | |||
@@ -13,10 +13,607 @@ | |||
13 | #include <linux/export.h> | 13 | #include <linux/export.h> |
14 | #include <sound/core.h> | 14 | #include <sound/core.h> |
15 | #include "hda_codec.h" | 15 | #include "hda_codec.h" |
16 | #include "hda_local.h" | ||
16 | #include "hda_auto_parser.h" | 17 | #include "hda_auto_parser.h" |
17 | 18 | ||
18 | #define SFX "hda_codec: " | 19 | #define SFX "hda_codec: " |
19 | 20 | ||
21 | /* | ||
22 | * Helper for automatic pin configuration | ||
23 | */ | ||
24 | |||
25 | static int is_in_nid_list(hda_nid_t nid, const hda_nid_t *list) | ||
26 | { | ||
27 | for (; *list; list++) | ||
28 | if (*list == nid) | ||
29 | return 1; | ||
30 | return 0; | ||
31 | } | ||
32 | |||
33 | |||
34 | /* | ||
35 | * Sort an associated group of pins according to their sequence numbers. | ||
36 | */ | ||
37 | static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences, | ||
38 | int num_pins) | ||
39 | { | ||
40 | int i, j; | ||
41 | short seq; | ||
42 | hda_nid_t nid; | ||
43 | |||
44 | for (i = 0; i < num_pins; i++) { | ||
45 | for (j = i + 1; j < num_pins; j++) { | ||
46 | if (sequences[i] > sequences[j]) { | ||
47 | seq = sequences[i]; | ||
48 | sequences[i] = sequences[j]; | ||
49 | sequences[j] = seq; | ||
50 | nid = pins[i]; | ||
51 | pins[i] = pins[j]; | ||
52 | pins[j] = nid; | ||
53 | } | ||
54 | } | ||
55 | } | ||
56 | } | ||
57 | |||
58 | |||
59 | /* add the found input-pin to the cfg->inputs[] table */ | ||
60 | static void add_auto_cfg_input_pin(struct auto_pin_cfg *cfg, hda_nid_t nid, | ||
61 | int type) | ||
62 | { | ||
63 | if (cfg->num_inputs < AUTO_CFG_MAX_INS) { | ||
64 | cfg->inputs[cfg->num_inputs].pin = nid; | ||
65 | cfg->inputs[cfg->num_inputs].type = type; | ||
66 | cfg->num_inputs++; | ||
67 | } | ||
68 | } | ||
69 | |||
70 | /* sort inputs in the order of AUTO_PIN_* type */ | ||
71 | static void sort_autocfg_input_pins(struct auto_pin_cfg *cfg) | ||
72 | { | ||
73 | int i, j; | ||
74 | |||
75 | for (i = 0; i < cfg->num_inputs; i++) { | ||
76 | for (j = i + 1; j < cfg->num_inputs; j++) { | ||
77 | if (cfg->inputs[i].type > cfg->inputs[j].type) { | ||
78 | struct auto_pin_cfg_item tmp; | ||
79 | tmp = cfg->inputs[i]; | ||
80 | cfg->inputs[i] = cfg->inputs[j]; | ||
81 | cfg->inputs[j] = tmp; | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | } | ||
86 | |||
87 | /* Reorder the surround channels | ||
88 | * ALSA sequence is front/surr/clfe/side | ||
89 | * HDA sequence is: | ||
90 | * 4-ch: front/surr => OK as it is | ||
91 | * 6-ch: front/clfe/surr | ||
92 | * 8-ch: front/clfe/rear/side|fc | ||
93 | */ | ||
94 | static void reorder_outputs(unsigned int nums, hda_nid_t *pins) | ||
95 | { | ||
96 | hda_nid_t nid; | ||
97 | |||
98 | switch (nums) { | ||
99 | case 3: | ||
100 | case 4: | ||
101 | nid = pins[1]; | ||
102 | pins[1] = pins[2]; | ||
103 | pins[2] = nid; | ||
104 | break; | ||
105 | } | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | * Parse all pin widgets and store the useful pin nids to cfg | ||
110 | * | ||
111 | * The number of line-outs or any primary output is stored in line_outs, | ||
112 | * and the corresponding output pins are assigned to line_out_pins[], | ||
113 | * in the order of front, rear, CLFE, side, ... | ||
114 | * | ||
115 | * If more extra outputs (speaker and headphone) are found, the pins are | ||
116 | * assisnged to hp_pins[] and speaker_pins[], respectively. If no line-out jack | ||
117 | * is detected, one of speaker of HP pins is assigned as the primary | ||
118 | * output, i.e. to line_out_pins[0]. So, line_outs is always positive | ||
119 | * if any analog output exists. | ||
120 | * | ||
121 | * The analog input pins are assigned to inputs array. | ||
122 | * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, | ||
123 | * respectively. | ||
124 | */ | ||
125 | int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | ||
126 | struct auto_pin_cfg *cfg, | ||
127 | const hda_nid_t *ignore_nids, | ||
128 | unsigned int cond_flags) | ||
129 | { | ||
130 | hda_nid_t nid, end_nid; | ||
131 | short seq, assoc_line_out; | ||
132 | short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)]; | ||
133 | short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)]; | ||
134 | short sequences_hp[ARRAY_SIZE(cfg->hp_pins)]; | ||
135 | int i; | ||
136 | |||
137 | memset(cfg, 0, sizeof(*cfg)); | ||
138 | |||
139 | memset(sequences_line_out, 0, sizeof(sequences_line_out)); | ||
140 | memset(sequences_speaker, 0, sizeof(sequences_speaker)); | ||
141 | memset(sequences_hp, 0, sizeof(sequences_hp)); | ||
142 | assoc_line_out = 0; | ||
143 | |||
144 | codec->ignore_misc_bit = true; | ||
145 | end_nid = codec->start_nid + codec->num_nodes; | ||
146 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
147 | unsigned int wid_caps = get_wcaps(codec, nid); | ||
148 | unsigned int wid_type = get_wcaps_type(wid_caps); | ||
149 | unsigned int def_conf; | ||
150 | short assoc, loc, conn, dev; | ||
151 | |||
152 | /* read all default configuration for pin complex */ | ||
153 | if (wid_type != AC_WID_PIN) | ||
154 | continue; | ||
155 | /* ignore the given nids (e.g. pc-beep returns error) */ | ||
156 | if (ignore_nids && is_in_nid_list(nid, ignore_nids)) | ||
157 | continue; | ||
158 | |||
159 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
160 | if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & | ||
161 | AC_DEFCFG_MISC_NO_PRESENCE)) | ||
162 | codec->ignore_misc_bit = false; | ||
163 | conn = get_defcfg_connect(def_conf); | ||
164 | if (conn == AC_JACK_PORT_NONE) | ||
165 | continue; | ||
166 | loc = get_defcfg_location(def_conf); | ||
167 | dev = get_defcfg_device(def_conf); | ||
168 | |||
169 | /* workaround for buggy BIOS setups */ | ||
170 | if (dev == AC_JACK_LINE_OUT) { | ||
171 | if (conn == AC_JACK_PORT_FIXED) | ||
172 | dev = AC_JACK_SPEAKER; | ||
173 | } | ||
174 | |||
175 | switch (dev) { | ||
176 | case AC_JACK_LINE_OUT: | ||
177 | seq = get_defcfg_sequence(def_conf); | ||
178 | assoc = get_defcfg_association(def_conf); | ||
179 | |||
180 | if (!(wid_caps & AC_WCAP_STEREO)) | ||
181 | if (!cfg->mono_out_pin) | ||
182 | cfg->mono_out_pin = nid; | ||
183 | if (!assoc) | ||
184 | continue; | ||
185 | if (!assoc_line_out) | ||
186 | assoc_line_out = assoc; | ||
187 | else if (assoc_line_out != assoc) | ||
188 | continue; | ||
189 | if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins)) | ||
190 | continue; | ||
191 | cfg->line_out_pins[cfg->line_outs] = nid; | ||
192 | sequences_line_out[cfg->line_outs] = seq; | ||
193 | cfg->line_outs++; | ||
194 | break; | ||
195 | case AC_JACK_SPEAKER: | ||
196 | seq = get_defcfg_sequence(def_conf); | ||
197 | assoc = get_defcfg_association(def_conf); | ||
198 | if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins)) | ||
199 | continue; | ||
200 | cfg->speaker_pins[cfg->speaker_outs] = nid; | ||
201 | sequences_speaker[cfg->speaker_outs] = (assoc << 4) | seq; | ||
202 | cfg->speaker_outs++; | ||
203 | break; | ||
204 | case AC_JACK_HP_OUT: | ||
205 | seq = get_defcfg_sequence(def_conf); | ||
206 | assoc = get_defcfg_association(def_conf); | ||
207 | if (cfg->hp_outs >= ARRAY_SIZE(cfg->hp_pins)) | ||
208 | continue; | ||
209 | cfg->hp_pins[cfg->hp_outs] = nid; | ||
210 | sequences_hp[cfg->hp_outs] = (assoc << 4) | seq; | ||
211 | cfg->hp_outs++; | ||
212 | break; | ||
213 | case AC_JACK_MIC_IN: | ||
214 | add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_MIC); | ||
215 | break; | ||
216 | case AC_JACK_LINE_IN: | ||
217 | add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_LINE_IN); | ||
218 | break; | ||
219 | case AC_JACK_CD: | ||
220 | add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_CD); | ||
221 | break; | ||
222 | case AC_JACK_AUX: | ||
223 | add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_AUX); | ||
224 | break; | ||
225 | case AC_JACK_SPDIF_OUT: | ||
226 | case AC_JACK_DIG_OTHER_OUT: | ||
227 | if (cfg->dig_outs >= ARRAY_SIZE(cfg->dig_out_pins)) | ||
228 | continue; | ||
229 | cfg->dig_out_pins[cfg->dig_outs] = nid; | ||
230 | cfg->dig_out_type[cfg->dig_outs] = | ||
231 | (loc == AC_JACK_LOC_HDMI) ? | ||
232 | HDA_PCM_TYPE_HDMI : HDA_PCM_TYPE_SPDIF; | ||
233 | cfg->dig_outs++; | ||
234 | break; | ||
235 | case AC_JACK_SPDIF_IN: | ||
236 | case AC_JACK_DIG_OTHER_IN: | ||
237 | cfg->dig_in_pin = nid; | ||
238 | if (loc == AC_JACK_LOC_HDMI) | ||
239 | cfg->dig_in_type = HDA_PCM_TYPE_HDMI; | ||
240 | else | ||
241 | cfg->dig_in_type = HDA_PCM_TYPE_SPDIF; | ||
242 | break; | ||
243 | } | ||
244 | } | ||
245 | |||
246 | /* FIX-UP: | ||
247 | * If no line-out is defined but multiple HPs are found, | ||
248 | * some of them might be the real line-outs. | ||
249 | */ | ||
250 | if (!cfg->line_outs && cfg->hp_outs > 1 && | ||
251 | !(cond_flags & HDA_PINCFG_NO_HP_FIXUP)) { | ||
252 | int i = 0; | ||
253 | while (i < cfg->hp_outs) { | ||
254 | /* The real HPs should have the sequence 0x0f */ | ||
255 | if ((sequences_hp[i] & 0x0f) == 0x0f) { | ||
256 | i++; | ||
257 | continue; | ||
258 | } | ||
259 | /* Move it to the line-out table */ | ||
260 | cfg->line_out_pins[cfg->line_outs] = cfg->hp_pins[i]; | ||
261 | sequences_line_out[cfg->line_outs] = sequences_hp[i]; | ||
262 | cfg->line_outs++; | ||
263 | cfg->hp_outs--; | ||
264 | memmove(cfg->hp_pins + i, cfg->hp_pins + i + 1, | ||
265 | sizeof(cfg->hp_pins[0]) * (cfg->hp_outs - i)); | ||
266 | memmove(sequences_hp + i, sequences_hp + i + 1, | ||
267 | sizeof(sequences_hp[0]) * (cfg->hp_outs - i)); | ||
268 | } | ||
269 | memset(cfg->hp_pins + cfg->hp_outs, 0, | ||
270 | sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - cfg->hp_outs)); | ||
271 | if (!cfg->hp_outs) | ||
272 | cfg->line_out_type = AUTO_PIN_HP_OUT; | ||
273 | |||
274 | } | ||
275 | |||
276 | /* sort by sequence */ | ||
277 | sort_pins_by_sequence(cfg->line_out_pins, sequences_line_out, | ||
278 | cfg->line_outs); | ||
279 | sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker, | ||
280 | cfg->speaker_outs); | ||
281 | sort_pins_by_sequence(cfg->hp_pins, sequences_hp, | ||
282 | cfg->hp_outs); | ||
283 | |||
284 | /* | ||
285 | * FIX-UP: if no line-outs are detected, try to use speaker or HP pin | ||
286 | * as a primary output | ||
287 | */ | ||
288 | if (!cfg->line_outs && | ||
289 | !(cond_flags & HDA_PINCFG_NO_LO_FIXUP)) { | ||
290 | if (cfg->speaker_outs) { | ||
291 | cfg->line_outs = cfg->speaker_outs; | ||
292 | memcpy(cfg->line_out_pins, cfg->speaker_pins, | ||
293 | sizeof(cfg->speaker_pins)); | ||
294 | cfg->speaker_outs = 0; | ||
295 | memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); | ||
296 | cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; | ||
297 | } else if (cfg->hp_outs) { | ||
298 | cfg->line_outs = cfg->hp_outs; | ||
299 | memcpy(cfg->line_out_pins, cfg->hp_pins, | ||
300 | sizeof(cfg->hp_pins)); | ||
301 | cfg->hp_outs = 0; | ||
302 | memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); | ||
303 | cfg->line_out_type = AUTO_PIN_HP_OUT; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | reorder_outputs(cfg->line_outs, cfg->line_out_pins); | ||
308 | reorder_outputs(cfg->hp_outs, cfg->hp_pins); | ||
309 | reorder_outputs(cfg->speaker_outs, cfg->speaker_pins); | ||
310 | |||
311 | sort_autocfg_input_pins(cfg); | ||
312 | |||
313 | /* | ||
314 | * debug prints of the parsed results | ||
315 | */ | ||
316 | snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x) type:%s\n", | ||
317 | cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1], | ||
318 | cfg->line_out_pins[2], cfg->line_out_pins[3], | ||
319 | cfg->line_out_pins[4], | ||
320 | cfg->line_out_type == AUTO_PIN_HP_OUT ? "hp" : | ||
321 | (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ? | ||
322 | "speaker" : "line")); | ||
323 | snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", | ||
324 | cfg->speaker_outs, cfg->speaker_pins[0], | ||
325 | cfg->speaker_pins[1], cfg->speaker_pins[2], | ||
326 | cfg->speaker_pins[3], cfg->speaker_pins[4]); | ||
327 | snd_printd(" hp_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", | ||
328 | cfg->hp_outs, cfg->hp_pins[0], | ||
329 | cfg->hp_pins[1], cfg->hp_pins[2], | ||
330 | cfg->hp_pins[3], cfg->hp_pins[4]); | ||
331 | snd_printd(" mono: mono_out=0x%x\n", cfg->mono_out_pin); | ||
332 | if (cfg->dig_outs) | ||
333 | snd_printd(" dig-out=0x%x/0x%x\n", | ||
334 | cfg->dig_out_pins[0], cfg->dig_out_pins[1]); | ||
335 | snd_printd(" inputs:"); | ||
336 | for (i = 0; i < cfg->num_inputs; i++) { | ||
337 | snd_printd(" %s=0x%x", | ||
338 | hda_get_autocfg_input_label(codec, cfg, i), | ||
339 | cfg->inputs[i].pin); | ||
340 | } | ||
341 | snd_printd("\n"); | ||
342 | if (cfg->dig_in_pin) | ||
343 | snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin); | ||
344 | |||
345 | return 0; | ||
346 | } | ||
347 | EXPORT_SYMBOL_HDA(snd_hda_parse_pin_defcfg); | ||
348 | |||
349 | int snd_hda_get_input_pin_attr(unsigned int def_conf) | ||
350 | { | ||
351 | unsigned int loc = get_defcfg_location(def_conf); | ||
352 | unsigned int conn = get_defcfg_connect(def_conf); | ||
353 | if (conn == AC_JACK_PORT_NONE) | ||
354 | return INPUT_PIN_ATTR_UNUSED; | ||
355 | /* Windows may claim the internal mic to be BOTH, too */ | ||
356 | if (conn == AC_JACK_PORT_FIXED || conn == AC_JACK_PORT_BOTH) | ||
357 | return INPUT_PIN_ATTR_INT; | ||
358 | if ((loc & 0x30) == AC_JACK_LOC_INTERNAL) | ||
359 | return INPUT_PIN_ATTR_INT; | ||
360 | if ((loc & 0x30) == AC_JACK_LOC_SEPARATE) | ||
361 | return INPUT_PIN_ATTR_DOCK; | ||
362 | if (loc == AC_JACK_LOC_REAR) | ||
363 | return INPUT_PIN_ATTR_REAR; | ||
364 | if (loc == AC_JACK_LOC_FRONT) | ||
365 | return INPUT_PIN_ATTR_FRONT; | ||
366 | return INPUT_PIN_ATTR_NORMAL; | ||
367 | } | ||
368 | EXPORT_SYMBOL_HDA(snd_hda_get_input_pin_attr); | ||
369 | |||
370 | /** | ||
371 | * hda_get_input_pin_label - Give a label for the given input pin | ||
372 | * | ||
373 | * When check_location is true, the function checks the pin location | ||
374 | * for mic and line-in pins, and set an appropriate prefix like "Front", | ||
375 | * "Rear", "Internal". | ||
376 | */ | ||
377 | |||
378 | static const char *hda_get_input_pin_label(struct hda_codec *codec, | ||
379 | hda_nid_t pin, bool check_location) | ||
380 | { | ||
381 | unsigned int def_conf; | ||
382 | static const char * const mic_names[] = { | ||
383 | "Internal Mic", "Dock Mic", "Mic", "Front Mic", "Rear Mic", | ||
384 | }; | ||
385 | int attr; | ||
386 | |||
387 | def_conf = snd_hda_codec_get_pincfg(codec, pin); | ||
388 | |||
389 | switch (get_defcfg_device(def_conf)) { | ||
390 | case AC_JACK_MIC_IN: | ||
391 | if (!check_location) | ||
392 | return "Mic"; | ||
393 | attr = snd_hda_get_input_pin_attr(def_conf); | ||
394 | if (!attr) | ||
395 | return "None"; | ||
396 | return mic_names[attr - 1]; | ||
397 | case AC_JACK_LINE_IN: | ||
398 | if (!check_location) | ||
399 | return "Line"; | ||
400 | attr = snd_hda_get_input_pin_attr(def_conf); | ||
401 | if (!attr) | ||
402 | return "None"; | ||
403 | if (attr == INPUT_PIN_ATTR_DOCK) | ||
404 | return "Dock Line"; | ||
405 | return "Line"; | ||
406 | case AC_JACK_AUX: | ||
407 | return "Aux"; | ||
408 | case AC_JACK_CD: | ||
409 | return "CD"; | ||
410 | case AC_JACK_SPDIF_IN: | ||
411 | return "SPDIF In"; | ||
412 | case AC_JACK_DIG_OTHER_IN: | ||
413 | return "Digital In"; | ||
414 | default: | ||
415 | return "Misc"; | ||
416 | } | ||
417 | } | ||
418 | |||
419 | /* Check whether the location prefix needs to be added to the label. | ||
420 | * If all mic-jacks are in the same location (e.g. rear panel), we don't | ||
421 | * have to put "Front" prefix to each label. In such a case, returns false. | ||
422 | */ | ||
423 | static int check_mic_location_need(struct hda_codec *codec, | ||
424 | const struct auto_pin_cfg *cfg, | ||
425 | int input) | ||
426 | { | ||
427 | unsigned int defc; | ||
428 | int i, attr, attr2; | ||
429 | |||
430 | defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[input].pin); | ||
431 | attr = snd_hda_get_input_pin_attr(defc); | ||
432 | /* for internal or docking mics, we need locations */ | ||
433 | if (attr <= INPUT_PIN_ATTR_NORMAL) | ||
434 | return 1; | ||
435 | |||
436 | attr = 0; | ||
437 | for (i = 0; i < cfg->num_inputs; i++) { | ||
438 | defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[i].pin); | ||
439 | attr2 = snd_hda_get_input_pin_attr(defc); | ||
440 | if (attr2 >= INPUT_PIN_ATTR_NORMAL) { | ||
441 | if (attr && attr != attr2) | ||
442 | return 1; /* different locations found */ | ||
443 | attr = attr2; | ||
444 | } | ||
445 | } | ||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | /** | ||
450 | * hda_get_autocfg_input_label - Get a label for the given input | ||
451 | * | ||
452 | * Get a label for the given input pin defined by the autocfg item. | ||
453 | * Unlike hda_get_input_pin_label(), this function checks all inputs | ||
454 | * defined in autocfg and avoids the redundant mic/line prefix as much as | ||
455 | * possible. | ||
456 | */ | ||
457 | const char *hda_get_autocfg_input_label(struct hda_codec *codec, | ||
458 | const struct auto_pin_cfg *cfg, | ||
459 | int input) | ||
460 | { | ||
461 | int type = cfg->inputs[input].type; | ||
462 | int has_multiple_pins = 0; | ||
463 | |||
464 | if ((input > 0 && cfg->inputs[input - 1].type == type) || | ||
465 | (input < cfg->num_inputs - 1 && cfg->inputs[input + 1].type == type)) | ||
466 | has_multiple_pins = 1; | ||
467 | if (has_multiple_pins && type == AUTO_PIN_MIC) | ||
468 | has_multiple_pins &= check_mic_location_need(codec, cfg, input); | ||
469 | return hda_get_input_pin_label(codec, cfg->inputs[input].pin, | ||
470 | has_multiple_pins); | ||
471 | } | ||
472 | EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label); | ||
473 | |||
474 | /* return the position of NID in the list, or -1 if not found */ | ||
475 | static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | ||
476 | { | ||
477 | int i; | ||
478 | for (i = 0; i < nums; i++) | ||
479 | if (list[i] == nid) | ||
480 | return i; | ||
481 | return -1; | ||
482 | } | ||
483 | |||
484 | /* get a unique suffix or an index number */ | ||
485 | static const char *check_output_sfx(hda_nid_t nid, const hda_nid_t *pins, | ||
486 | int num_pins, int *indexp) | ||
487 | { | ||
488 | static const char * const channel_sfx[] = { | ||
489 | " Front", " Surround", " CLFE", " Side" | ||
490 | }; | ||
491 | int i; | ||
492 | |||
493 | i = find_idx_in_nid_list(nid, pins, num_pins); | ||
494 | if (i < 0) | ||
495 | return NULL; | ||
496 | if (num_pins == 1) | ||
497 | return ""; | ||
498 | if (num_pins > ARRAY_SIZE(channel_sfx)) { | ||
499 | if (indexp) | ||
500 | *indexp = i; | ||
501 | return ""; | ||
502 | } | ||
503 | return channel_sfx[i]; | ||
504 | } | ||
505 | |||
506 | static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid, | ||
507 | const struct auto_pin_cfg *cfg, | ||
508 | const char *name, char *label, int maxlen, | ||
509 | int *indexp) | ||
510 | { | ||
511 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
512 | int attr = snd_hda_get_input_pin_attr(def_conf); | ||
513 | const char *pfx = "", *sfx = ""; | ||
514 | |||
515 | /* handle as a speaker if it's a fixed line-out */ | ||
516 | if (!strcmp(name, "Line Out") && attr == INPUT_PIN_ATTR_INT) | ||
517 | name = "Speaker"; | ||
518 | /* check the location */ | ||
519 | switch (attr) { | ||
520 | case INPUT_PIN_ATTR_DOCK: | ||
521 | pfx = "Dock "; | ||
522 | break; | ||
523 | case INPUT_PIN_ATTR_FRONT: | ||
524 | pfx = "Front "; | ||
525 | break; | ||
526 | } | ||
527 | if (cfg) { | ||
528 | /* try to give a unique suffix if needed */ | ||
529 | sfx = check_output_sfx(nid, cfg->line_out_pins, cfg->line_outs, | ||
530 | indexp); | ||
531 | if (!sfx) | ||
532 | sfx = check_output_sfx(nid, cfg->speaker_pins, cfg->speaker_outs, | ||
533 | indexp); | ||
534 | if (!sfx) { | ||
535 | /* don't add channel suffix for Headphone controls */ | ||
536 | int idx = find_idx_in_nid_list(nid, cfg->hp_pins, | ||
537 | cfg->hp_outs); | ||
538 | if (idx >= 0) | ||
539 | *indexp = idx; | ||
540 | sfx = ""; | ||
541 | } | ||
542 | } | ||
543 | snprintf(label, maxlen, "%s%s%s", pfx, name, sfx); | ||
544 | return 1; | ||
545 | } | ||
546 | |||
547 | /** | ||
548 | * snd_hda_get_pin_label - Get a label for the given I/O pin | ||
549 | * | ||
550 | * Get a label for the given pin. This function works for both input and | ||
551 | * output pins. When @cfg is given as non-NULL, the function tries to get | ||
552 | * an optimized label using hda_get_autocfg_input_label(). | ||
553 | * | ||
554 | * This function tries to give a unique label string for the pin as much as | ||
555 | * possible. For example, when the multiple line-outs are present, it adds | ||
556 | * the channel suffix like "Front", "Surround", etc (only when @cfg is given). | ||
557 | * If no unique name with a suffix is available and @indexp is non-NULL, the | ||
558 | * index number is stored in the pointer. | ||
559 | */ | ||
560 | int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, | ||
561 | const struct auto_pin_cfg *cfg, | ||
562 | char *label, int maxlen, int *indexp) | ||
563 | { | ||
564 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
565 | const char *name = NULL; | ||
566 | int i; | ||
567 | |||
568 | if (indexp) | ||
569 | *indexp = 0; | ||
570 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) | ||
571 | return 0; | ||
572 | |||
573 | switch (get_defcfg_device(def_conf)) { | ||
574 | case AC_JACK_LINE_OUT: | ||
575 | return fill_audio_out_name(codec, nid, cfg, "Line Out", | ||
576 | label, maxlen, indexp); | ||
577 | case AC_JACK_SPEAKER: | ||
578 | return fill_audio_out_name(codec, nid, cfg, "Speaker", | ||
579 | label, maxlen, indexp); | ||
580 | case AC_JACK_HP_OUT: | ||
581 | return fill_audio_out_name(codec, nid, cfg, "Headphone", | ||
582 | label, maxlen, indexp); | ||
583 | case AC_JACK_SPDIF_OUT: | ||
584 | case AC_JACK_DIG_OTHER_OUT: | ||
585 | if (get_defcfg_location(def_conf) == AC_JACK_LOC_HDMI) | ||
586 | name = "HDMI"; | ||
587 | else | ||
588 | name = "SPDIF"; | ||
589 | if (cfg && indexp) { | ||
590 | i = find_idx_in_nid_list(nid, cfg->dig_out_pins, | ||
591 | cfg->dig_outs); | ||
592 | if (i >= 0) | ||
593 | *indexp = i; | ||
594 | } | ||
595 | break; | ||
596 | default: | ||
597 | if (cfg) { | ||
598 | for (i = 0; i < cfg->num_inputs; i++) { | ||
599 | if (cfg->inputs[i].pin != nid) | ||
600 | continue; | ||
601 | name = hda_get_autocfg_input_label(codec, cfg, i); | ||
602 | if (name) | ||
603 | break; | ||
604 | } | ||
605 | } | ||
606 | if (!name) | ||
607 | name = hda_get_input_pin_label(codec, nid, true); | ||
608 | break; | ||
609 | } | ||
610 | if (!name) | ||
611 | return 0; | ||
612 | strlcpy(label, name, maxlen); | ||
613 | return 1; | ||
614 | } | ||
615 | EXPORT_SYMBOL_HDA(snd_hda_get_pin_label); | ||
616 | |||
20 | int snd_hda_gen_add_verbs(struct hda_gen_spec *spec, | 617 | int snd_hda_gen_add_verbs(struct hda_gen_spec *spec, |
21 | const struct hda_verb *list) | 618 | const struct hda_verb *list) |
22 | { | 619 | { |
diff --git a/sound/pci/hda/hda_auto_parser.h b/sound/pci/hda/hda_auto_parser.h index 9fe4f5d245ad..2a7889dfbd1b 100644 --- a/sound/pci/hda/hda_auto_parser.h +++ b/sound/pci/hda/hda_auto_parser.h | |||
@@ -12,6 +12,86 @@ | |||
12 | #ifndef __SOUND_HDA_AUTO_PARSER_H | 12 | #ifndef __SOUND_HDA_AUTO_PARSER_H |
13 | #define __SOUND_HDA_AUTO_PARSER_H | 13 | #define __SOUND_HDA_AUTO_PARSER_H |
14 | 14 | ||
15 | /* | ||
16 | * Helper for automatic pin configuration | ||
17 | */ | ||
18 | |||
19 | enum { | ||
20 | AUTO_PIN_MIC, | ||
21 | AUTO_PIN_LINE_IN, | ||
22 | AUTO_PIN_CD, | ||
23 | AUTO_PIN_AUX, | ||
24 | AUTO_PIN_LAST | ||
25 | }; | ||
26 | |||
27 | enum { | ||
28 | AUTO_PIN_LINE_OUT, | ||
29 | AUTO_PIN_SPEAKER_OUT, | ||
30 | AUTO_PIN_HP_OUT | ||
31 | }; | ||
32 | |||
33 | #define AUTO_CFG_MAX_OUTS HDA_MAX_OUTS | ||
34 | #define AUTO_CFG_MAX_INS 8 | ||
35 | |||
36 | struct auto_pin_cfg_item { | ||
37 | hda_nid_t pin; | ||
38 | int type; | ||
39 | }; | ||
40 | |||
41 | struct auto_pin_cfg; | ||
42 | const char *hda_get_autocfg_input_label(struct hda_codec *codec, | ||
43 | const struct auto_pin_cfg *cfg, | ||
44 | int input); | ||
45 | int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, | ||
46 | const struct auto_pin_cfg *cfg, | ||
47 | char *label, int maxlen, int *indexp); | ||
48 | |||
49 | enum { | ||
50 | INPUT_PIN_ATTR_UNUSED, /* pin not connected */ | ||
51 | INPUT_PIN_ATTR_INT, /* internal mic/line-in */ | ||
52 | INPUT_PIN_ATTR_DOCK, /* docking mic/line-in */ | ||
53 | INPUT_PIN_ATTR_NORMAL, /* mic/line-in jack */ | ||
54 | INPUT_PIN_ATTR_FRONT, /* mic/line-in jack in front */ | ||
55 | INPUT_PIN_ATTR_REAR, /* mic/line-in jack in rear */ | ||
56 | }; | ||
57 | |||
58 | int snd_hda_get_input_pin_attr(unsigned int def_conf); | ||
59 | |||
60 | struct auto_pin_cfg { | ||
61 | int line_outs; | ||
62 | /* sorted in the order of Front/Surr/CLFE/Side */ | ||
63 | hda_nid_t line_out_pins[AUTO_CFG_MAX_OUTS]; | ||
64 | int speaker_outs; | ||
65 | hda_nid_t speaker_pins[AUTO_CFG_MAX_OUTS]; | ||
66 | int hp_outs; | ||
67 | int line_out_type; /* AUTO_PIN_XXX_OUT */ | ||
68 | hda_nid_t hp_pins[AUTO_CFG_MAX_OUTS]; | ||
69 | int num_inputs; | ||
70 | struct auto_pin_cfg_item inputs[AUTO_CFG_MAX_INS]; | ||
71 | int dig_outs; | ||
72 | hda_nid_t dig_out_pins[2]; | ||
73 | hda_nid_t dig_in_pin; | ||
74 | hda_nid_t mono_out_pin; | ||
75 | int dig_out_type[2]; /* HDA_PCM_TYPE_XXX */ | ||
76 | int dig_in_type; /* HDA_PCM_TYPE_XXX */ | ||
77 | }; | ||
78 | |||
79 | /* bit-flags for snd_hda_parse_pin_def_config() behavior */ | ||
80 | #define HDA_PINCFG_NO_HP_FIXUP (1 << 0) /* no HP-split */ | ||
81 | #define HDA_PINCFG_NO_LO_FIXUP (1 << 1) /* don't take other outs as LO */ | ||
82 | |||
83 | int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | ||
84 | struct auto_pin_cfg *cfg, | ||
85 | const hda_nid_t *ignore_nids, | ||
86 | unsigned int cond_flags); | ||
87 | |||
88 | /* older function */ | ||
89 | #define snd_hda_parse_pin_def_config(codec, cfg, ignore) \ | ||
90 | snd_hda_parse_pin_defcfg(codec, cfg, ignore, 0) | ||
91 | |||
92 | /* | ||
93 | */ | ||
94 | |||
15 | struct hda_gen_spec { | 95 | struct hda_gen_spec { |
16 | /* fix-up list */ | 96 | /* fix-up list */ |
17 | int fixup_id; | 97 | int fixup_id; |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 30a3d8ff978b..f2bdf38be395 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -4877,602 +4877,6 @@ int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, | |||
4877 | } | 4877 | } |
4878 | EXPORT_SYMBOL_HDA(_snd_hda_set_pin_ctl); | 4878 | EXPORT_SYMBOL_HDA(_snd_hda_set_pin_ctl); |
4879 | 4879 | ||
4880 | /* | ||
4881 | * Helper for automatic pin configuration | ||
4882 | */ | ||
4883 | |||
4884 | static int is_in_nid_list(hda_nid_t nid, const hda_nid_t *list) | ||
4885 | { | ||
4886 | for (; *list; list++) | ||
4887 | if (*list == nid) | ||
4888 | return 1; | ||
4889 | return 0; | ||
4890 | } | ||
4891 | |||
4892 | |||
4893 | /* | ||
4894 | * Sort an associated group of pins according to their sequence numbers. | ||
4895 | */ | ||
4896 | static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences, | ||
4897 | int num_pins) | ||
4898 | { | ||
4899 | int i, j; | ||
4900 | short seq; | ||
4901 | hda_nid_t nid; | ||
4902 | |||
4903 | for (i = 0; i < num_pins; i++) { | ||
4904 | for (j = i + 1; j < num_pins; j++) { | ||
4905 | if (sequences[i] > sequences[j]) { | ||
4906 | seq = sequences[i]; | ||
4907 | sequences[i] = sequences[j]; | ||
4908 | sequences[j] = seq; | ||
4909 | nid = pins[i]; | ||
4910 | pins[i] = pins[j]; | ||
4911 | pins[j] = nid; | ||
4912 | } | ||
4913 | } | ||
4914 | } | ||
4915 | } | ||
4916 | |||
4917 | |||
4918 | /* add the found input-pin to the cfg->inputs[] table */ | ||
4919 | static void add_auto_cfg_input_pin(struct auto_pin_cfg *cfg, hda_nid_t nid, | ||
4920 | int type) | ||
4921 | { | ||
4922 | if (cfg->num_inputs < AUTO_CFG_MAX_INS) { | ||
4923 | cfg->inputs[cfg->num_inputs].pin = nid; | ||
4924 | cfg->inputs[cfg->num_inputs].type = type; | ||
4925 | cfg->num_inputs++; | ||
4926 | } | ||
4927 | } | ||
4928 | |||
4929 | /* sort inputs in the order of AUTO_PIN_* type */ | ||
4930 | static void sort_autocfg_input_pins(struct auto_pin_cfg *cfg) | ||
4931 | { | ||
4932 | int i, j; | ||
4933 | |||
4934 | for (i = 0; i < cfg->num_inputs; i++) { | ||
4935 | for (j = i + 1; j < cfg->num_inputs; j++) { | ||
4936 | if (cfg->inputs[i].type > cfg->inputs[j].type) { | ||
4937 | struct auto_pin_cfg_item tmp; | ||
4938 | tmp = cfg->inputs[i]; | ||
4939 | cfg->inputs[i] = cfg->inputs[j]; | ||
4940 | cfg->inputs[j] = tmp; | ||
4941 | } | ||
4942 | } | ||
4943 | } | ||
4944 | } | ||
4945 | |||
4946 | /* Reorder the surround channels | ||
4947 | * ALSA sequence is front/surr/clfe/side | ||
4948 | * HDA sequence is: | ||
4949 | * 4-ch: front/surr => OK as it is | ||
4950 | * 6-ch: front/clfe/surr | ||
4951 | * 8-ch: front/clfe/rear/side|fc | ||
4952 | */ | ||
4953 | static void reorder_outputs(unsigned int nums, hda_nid_t *pins) | ||
4954 | { | ||
4955 | hda_nid_t nid; | ||
4956 | |||
4957 | switch (nums) { | ||
4958 | case 3: | ||
4959 | case 4: | ||
4960 | nid = pins[1]; | ||
4961 | pins[1] = pins[2]; | ||
4962 | pins[2] = nid; | ||
4963 | break; | ||
4964 | } | ||
4965 | } | ||
4966 | |||
4967 | /* | ||
4968 | * Parse all pin widgets and store the useful pin nids to cfg | ||
4969 | * | ||
4970 | * The number of line-outs or any primary output is stored in line_outs, | ||
4971 | * and the corresponding output pins are assigned to line_out_pins[], | ||
4972 | * in the order of front, rear, CLFE, side, ... | ||
4973 | * | ||
4974 | * If more extra outputs (speaker and headphone) are found, the pins are | ||
4975 | * assisnged to hp_pins[] and speaker_pins[], respectively. If no line-out jack | ||
4976 | * is detected, one of speaker of HP pins is assigned as the primary | ||
4977 | * output, i.e. to line_out_pins[0]. So, line_outs is always positive | ||
4978 | * if any analog output exists. | ||
4979 | * | ||
4980 | * The analog input pins are assigned to inputs array. | ||
4981 | * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, | ||
4982 | * respectively. | ||
4983 | */ | ||
4984 | int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | ||
4985 | struct auto_pin_cfg *cfg, | ||
4986 | const hda_nid_t *ignore_nids, | ||
4987 | unsigned int cond_flags) | ||
4988 | { | ||
4989 | hda_nid_t nid, end_nid; | ||
4990 | short seq, assoc_line_out; | ||
4991 | short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)]; | ||
4992 | short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)]; | ||
4993 | short sequences_hp[ARRAY_SIZE(cfg->hp_pins)]; | ||
4994 | int i; | ||
4995 | |||
4996 | memset(cfg, 0, sizeof(*cfg)); | ||
4997 | |||
4998 | memset(sequences_line_out, 0, sizeof(sequences_line_out)); | ||
4999 | memset(sequences_speaker, 0, sizeof(sequences_speaker)); | ||
5000 | memset(sequences_hp, 0, sizeof(sequences_hp)); | ||
5001 | assoc_line_out = 0; | ||
5002 | |||
5003 | codec->ignore_misc_bit = true; | ||
5004 | end_nid = codec->start_nid + codec->num_nodes; | ||
5005 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
5006 | unsigned int wid_caps = get_wcaps(codec, nid); | ||
5007 | unsigned int wid_type = get_wcaps_type(wid_caps); | ||
5008 | unsigned int def_conf; | ||
5009 | short assoc, loc, conn, dev; | ||
5010 | |||
5011 | /* read all default configuration for pin complex */ | ||
5012 | if (wid_type != AC_WID_PIN) | ||
5013 | continue; | ||
5014 | /* ignore the given nids (e.g. pc-beep returns error) */ | ||
5015 | if (ignore_nids && is_in_nid_list(nid, ignore_nids)) | ||
5016 | continue; | ||
5017 | |||
5018 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
5019 | if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & | ||
5020 | AC_DEFCFG_MISC_NO_PRESENCE)) | ||
5021 | codec->ignore_misc_bit = false; | ||
5022 | conn = get_defcfg_connect(def_conf); | ||
5023 | if (conn == AC_JACK_PORT_NONE) | ||
5024 | continue; | ||
5025 | loc = get_defcfg_location(def_conf); | ||
5026 | dev = get_defcfg_device(def_conf); | ||
5027 | |||
5028 | /* workaround for buggy BIOS setups */ | ||
5029 | if (dev == AC_JACK_LINE_OUT) { | ||
5030 | if (conn == AC_JACK_PORT_FIXED) | ||
5031 | dev = AC_JACK_SPEAKER; | ||
5032 | } | ||
5033 | |||
5034 | switch (dev) { | ||
5035 | case AC_JACK_LINE_OUT: | ||
5036 | seq = get_defcfg_sequence(def_conf); | ||
5037 | assoc = get_defcfg_association(def_conf); | ||
5038 | |||
5039 | if (!(wid_caps & AC_WCAP_STEREO)) | ||
5040 | if (!cfg->mono_out_pin) | ||
5041 | cfg->mono_out_pin = nid; | ||
5042 | if (!assoc) | ||
5043 | continue; | ||
5044 | if (!assoc_line_out) | ||
5045 | assoc_line_out = assoc; | ||
5046 | else if (assoc_line_out != assoc) | ||
5047 | continue; | ||
5048 | if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins)) | ||
5049 | continue; | ||
5050 | cfg->line_out_pins[cfg->line_outs] = nid; | ||
5051 | sequences_line_out[cfg->line_outs] = seq; | ||
5052 | cfg->line_outs++; | ||
5053 | break; | ||
5054 | case AC_JACK_SPEAKER: | ||
5055 | seq = get_defcfg_sequence(def_conf); | ||
5056 | assoc = get_defcfg_association(def_conf); | ||
5057 | if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins)) | ||
5058 | continue; | ||
5059 | cfg->speaker_pins[cfg->speaker_outs] = nid; | ||
5060 | sequences_speaker[cfg->speaker_outs] = (assoc << 4) | seq; | ||
5061 | cfg->speaker_outs++; | ||
5062 | break; | ||
5063 | case AC_JACK_HP_OUT: | ||
5064 | seq = get_defcfg_sequence(def_conf); | ||
5065 | assoc = get_defcfg_association(def_conf); | ||
5066 | if (cfg->hp_outs >= ARRAY_SIZE(cfg->hp_pins)) | ||
5067 | continue; | ||
5068 | cfg->hp_pins[cfg->hp_outs] = nid; | ||
5069 | sequences_hp[cfg->hp_outs] = (assoc << 4) | seq; | ||
5070 | cfg->hp_outs++; | ||
5071 | break; | ||
5072 | case AC_JACK_MIC_IN: | ||
5073 | add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_MIC); | ||
5074 | break; | ||
5075 | case AC_JACK_LINE_IN: | ||
5076 | add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_LINE_IN); | ||
5077 | break; | ||
5078 | case AC_JACK_CD: | ||
5079 | add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_CD); | ||
5080 | break; | ||
5081 | case AC_JACK_AUX: | ||
5082 | add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_AUX); | ||
5083 | break; | ||
5084 | case AC_JACK_SPDIF_OUT: | ||
5085 | case AC_JACK_DIG_OTHER_OUT: | ||
5086 | if (cfg->dig_outs >= ARRAY_SIZE(cfg->dig_out_pins)) | ||
5087 | continue; | ||
5088 | cfg->dig_out_pins[cfg->dig_outs] = nid; | ||
5089 | cfg->dig_out_type[cfg->dig_outs] = | ||
5090 | (loc == AC_JACK_LOC_HDMI) ? | ||
5091 | HDA_PCM_TYPE_HDMI : HDA_PCM_TYPE_SPDIF; | ||
5092 | cfg->dig_outs++; | ||
5093 | break; | ||
5094 | case AC_JACK_SPDIF_IN: | ||
5095 | case AC_JACK_DIG_OTHER_IN: | ||
5096 | cfg->dig_in_pin = nid; | ||
5097 | if (loc == AC_JACK_LOC_HDMI) | ||
5098 | cfg->dig_in_type = HDA_PCM_TYPE_HDMI; | ||
5099 | else | ||
5100 | cfg->dig_in_type = HDA_PCM_TYPE_SPDIF; | ||
5101 | break; | ||
5102 | } | ||
5103 | } | ||
5104 | |||
5105 | /* FIX-UP: | ||
5106 | * If no line-out is defined but multiple HPs are found, | ||
5107 | * some of them might be the real line-outs. | ||
5108 | */ | ||
5109 | if (!cfg->line_outs && cfg->hp_outs > 1 && | ||
5110 | !(cond_flags & HDA_PINCFG_NO_HP_FIXUP)) { | ||
5111 | int i = 0; | ||
5112 | while (i < cfg->hp_outs) { | ||
5113 | /* The real HPs should have the sequence 0x0f */ | ||
5114 | if ((sequences_hp[i] & 0x0f) == 0x0f) { | ||
5115 | i++; | ||
5116 | continue; | ||
5117 | } | ||
5118 | /* Move it to the line-out table */ | ||
5119 | cfg->line_out_pins[cfg->line_outs] = cfg->hp_pins[i]; | ||
5120 | sequences_line_out[cfg->line_outs] = sequences_hp[i]; | ||
5121 | cfg->line_outs++; | ||
5122 | cfg->hp_outs--; | ||
5123 | memmove(cfg->hp_pins + i, cfg->hp_pins + i + 1, | ||
5124 | sizeof(cfg->hp_pins[0]) * (cfg->hp_outs - i)); | ||
5125 | memmove(sequences_hp + i, sequences_hp + i + 1, | ||
5126 | sizeof(sequences_hp[0]) * (cfg->hp_outs - i)); | ||
5127 | } | ||
5128 | memset(cfg->hp_pins + cfg->hp_outs, 0, | ||
5129 | sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - cfg->hp_outs)); | ||
5130 | if (!cfg->hp_outs) | ||
5131 | cfg->line_out_type = AUTO_PIN_HP_OUT; | ||
5132 | |||
5133 | } | ||
5134 | |||
5135 | /* sort by sequence */ | ||
5136 | sort_pins_by_sequence(cfg->line_out_pins, sequences_line_out, | ||
5137 | cfg->line_outs); | ||
5138 | sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker, | ||
5139 | cfg->speaker_outs); | ||
5140 | sort_pins_by_sequence(cfg->hp_pins, sequences_hp, | ||
5141 | cfg->hp_outs); | ||
5142 | |||
5143 | /* | ||
5144 | * FIX-UP: if no line-outs are detected, try to use speaker or HP pin | ||
5145 | * as a primary output | ||
5146 | */ | ||
5147 | if (!cfg->line_outs && | ||
5148 | !(cond_flags & HDA_PINCFG_NO_LO_FIXUP)) { | ||
5149 | if (cfg->speaker_outs) { | ||
5150 | cfg->line_outs = cfg->speaker_outs; | ||
5151 | memcpy(cfg->line_out_pins, cfg->speaker_pins, | ||
5152 | sizeof(cfg->speaker_pins)); | ||
5153 | cfg->speaker_outs = 0; | ||
5154 | memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); | ||
5155 | cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; | ||
5156 | } else if (cfg->hp_outs) { | ||
5157 | cfg->line_outs = cfg->hp_outs; | ||
5158 | memcpy(cfg->line_out_pins, cfg->hp_pins, | ||
5159 | sizeof(cfg->hp_pins)); | ||
5160 | cfg->hp_outs = 0; | ||
5161 | memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); | ||
5162 | cfg->line_out_type = AUTO_PIN_HP_OUT; | ||
5163 | } | ||
5164 | } | ||
5165 | |||
5166 | reorder_outputs(cfg->line_outs, cfg->line_out_pins); | ||
5167 | reorder_outputs(cfg->hp_outs, cfg->hp_pins); | ||
5168 | reorder_outputs(cfg->speaker_outs, cfg->speaker_pins); | ||
5169 | |||
5170 | sort_autocfg_input_pins(cfg); | ||
5171 | |||
5172 | /* | ||
5173 | * debug prints of the parsed results | ||
5174 | */ | ||
5175 | snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x) type:%s\n", | ||
5176 | cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1], | ||
5177 | cfg->line_out_pins[2], cfg->line_out_pins[3], | ||
5178 | cfg->line_out_pins[4], | ||
5179 | cfg->line_out_type == AUTO_PIN_HP_OUT ? "hp" : | ||
5180 | (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ? | ||
5181 | "speaker" : "line")); | ||
5182 | snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", | ||
5183 | cfg->speaker_outs, cfg->speaker_pins[0], | ||
5184 | cfg->speaker_pins[1], cfg->speaker_pins[2], | ||
5185 | cfg->speaker_pins[3], cfg->speaker_pins[4]); | ||
5186 | snd_printd(" hp_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", | ||
5187 | cfg->hp_outs, cfg->hp_pins[0], | ||
5188 | cfg->hp_pins[1], cfg->hp_pins[2], | ||
5189 | cfg->hp_pins[3], cfg->hp_pins[4]); | ||
5190 | snd_printd(" mono: mono_out=0x%x\n", cfg->mono_out_pin); | ||
5191 | if (cfg->dig_outs) | ||
5192 | snd_printd(" dig-out=0x%x/0x%x\n", | ||
5193 | cfg->dig_out_pins[0], cfg->dig_out_pins[1]); | ||
5194 | snd_printd(" inputs:"); | ||
5195 | for (i = 0; i < cfg->num_inputs; i++) { | ||
5196 | snd_printd(" %s=0x%x", | ||
5197 | hda_get_autocfg_input_label(codec, cfg, i), | ||
5198 | cfg->inputs[i].pin); | ||
5199 | } | ||
5200 | snd_printd("\n"); | ||
5201 | if (cfg->dig_in_pin) | ||
5202 | snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin); | ||
5203 | |||
5204 | return 0; | ||
5205 | } | ||
5206 | EXPORT_SYMBOL_HDA(snd_hda_parse_pin_defcfg); | ||
5207 | |||
5208 | int snd_hda_get_input_pin_attr(unsigned int def_conf) | ||
5209 | { | ||
5210 | unsigned int loc = get_defcfg_location(def_conf); | ||
5211 | unsigned int conn = get_defcfg_connect(def_conf); | ||
5212 | if (conn == AC_JACK_PORT_NONE) | ||
5213 | return INPUT_PIN_ATTR_UNUSED; | ||
5214 | /* Windows may claim the internal mic to be BOTH, too */ | ||
5215 | if (conn == AC_JACK_PORT_FIXED || conn == AC_JACK_PORT_BOTH) | ||
5216 | return INPUT_PIN_ATTR_INT; | ||
5217 | if ((loc & 0x30) == AC_JACK_LOC_INTERNAL) | ||
5218 | return INPUT_PIN_ATTR_INT; | ||
5219 | if ((loc & 0x30) == AC_JACK_LOC_SEPARATE) | ||
5220 | return INPUT_PIN_ATTR_DOCK; | ||
5221 | if (loc == AC_JACK_LOC_REAR) | ||
5222 | return INPUT_PIN_ATTR_REAR; | ||
5223 | if (loc == AC_JACK_LOC_FRONT) | ||
5224 | return INPUT_PIN_ATTR_FRONT; | ||
5225 | return INPUT_PIN_ATTR_NORMAL; | ||
5226 | } | ||
5227 | EXPORT_SYMBOL_HDA(snd_hda_get_input_pin_attr); | ||
5228 | |||
5229 | /** | ||
5230 | * hda_get_input_pin_label - Give a label for the given input pin | ||
5231 | * | ||
5232 | * When check_location is true, the function checks the pin location | ||
5233 | * for mic and line-in pins, and set an appropriate prefix like "Front", | ||
5234 | * "Rear", "Internal". | ||
5235 | */ | ||
5236 | |||
5237 | static const char *hda_get_input_pin_label(struct hda_codec *codec, | ||
5238 | hda_nid_t pin, bool check_location) | ||
5239 | { | ||
5240 | unsigned int def_conf; | ||
5241 | static const char * const mic_names[] = { | ||
5242 | "Internal Mic", "Dock Mic", "Mic", "Front Mic", "Rear Mic", | ||
5243 | }; | ||
5244 | int attr; | ||
5245 | |||
5246 | def_conf = snd_hda_codec_get_pincfg(codec, pin); | ||
5247 | |||
5248 | switch (get_defcfg_device(def_conf)) { | ||
5249 | case AC_JACK_MIC_IN: | ||
5250 | if (!check_location) | ||
5251 | return "Mic"; | ||
5252 | attr = snd_hda_get_input_pin_attr(def_conf); | ||
5253 | if (!attr) | ||
5254 | return "None"; | ||
5255 | return mic_names[attr - 1]; | ||
5256 | case AC_JACK_LINE_IN: | ||
5257 | if (!check_location) | ||
5258 | return "Line"; | ||
5259 | attr = snd_hda_get_input_pin_attr(def_conf); | ||
5260 | if (!attr) | ||
5261 | return "None"; | ||
5262 | if (attr == INPUT_PIN_ATTR_DOCK) | ||
5263 | return "Dock Line"; | ||
5264 | return "Line"; | ||
5265 | case AC_JACK_AUX: | ||
5266 | return "Aux"; | ||
5267 | case AC_JACK_CD: | ||
5268 | return "CD"; | ||
5269 | case AC_JACK_SPDIF_IN: | ||
5270 | return "SPDIF In"; | ||
5271 | case AC_JACK_DIG_OTHER_IN: | ||
5272 | return "Digital In"; | ||
5273 | default: | ||
5274 | return "Misc"; | ||
5275 | } | ||
5276 | } | ||
5277 | |||
5278 | /* Check whether the location prefix needs to be added to the label. | ||
5279 | * If all mic-jacks are in the same location (e.g. rear panel), we don't | ||
5280 | * have to put "Front" prefix to each label. In such a case, returns false. | ||
5281 | */ | ||
5282 | static int check_mic_location_need(struct hda_codec *codec, | ||
5283 | const struct auto_pin_cfg *cfg, | ||
5284 | int input) | ||
5285 | { | ||
5286 | unsigned int defc; | ||
5287 | int i, attr, attr2; | ||
5288 | |||
5289 | defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[input].pin); | ||
5290 | attr = snd_hda_get_input_pin_attr(defc); | ||
5291 | /* for internal or docking mics, we need locations */ | ||
5292 | if (attr <= INPUT_PIN_ATTR_NORMAL) | ||
5293 | return 1; | ||
5294 | |||
5295 | attr = 0; | ||
5296 | for (i = 0; i < cfg->num_inputs; i++) { | ||
5297 | defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[i].pin); | ||
5298 | attr2 = snd_hda_get_input_pin_attr(defc); | ||
5299 | if (attr2 >= INPUT_PIN_ATTR_NORMAL) { | ||
5300 | if (attr && attr != attr2) | ||
5301 | return 1; /* different locations found */ | ||
5302 | attr = attr2; | ||
5303 | } | ||
5304 | } | ||
5305 | return 0; | ||
5306 | } | ||
5307 | |||
5308 | /** | ||
5309 | * hda_get_autocfg_input_label - Get a label for the given input | ||
5310 | * | ||
5311 | * Get a label for the given input pin defined by the autocfg item. | ||
5312 | * Unlike hda_get_input_pin_label(), this function checks all inputs | ||
5313 | * defined in autocfg and avoids the redundant mic/line prefix as much as | ||
5314 | * possible. | ||
5315 | */ | ||
5316 | const char *hda_get_autocfg_input_label(struct hda_codec *codec, | ||
5317 | const struct auto_pin_cfg *cfg, | ||
5318 | int input) | ||
5319 | { | ||
5320 | int type = cfg->inputs[input].type; | ||
5321 | int has_multiple_pins = 0; | ||
5322 | |||
5323 | if ((input > 0 && cfg->inputs[input - 1].type == type) || | ||
5324 | (input < cfg->num_inputs - 1 && cfg->inputs[input + 1].type == type)) | ||
5325 | has_multiple_pins = 1; | ||
5326 | if (has_multiple_pins && type == AUTO_PIN_MIC) | ||
5327 | has_multiple_pins &= check_mic_location_need(codec, cfg, input); | ||
5328 | return hda_get_input_pin_label(codec, cfg->inputs[input].pin, | ||
5329 | has_multiple_pins); | ||
5330 | } | ||
5331 | EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label); | ||
5332 | |||
5333 | /* return the position of NID in the list, or -1 if not found */ | ||
5334 | static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | ||
5335 | { | ||
5336 | int i; | ||
5337 | for (i = 0; i < nums; i++) | ||
5338 | if (list[i] == nid) | ||
5339 | return i; | ||
5340 | return -1; | ||
5341 | } | ||
5342 | |||
5343 | /* get a unique suffix or an index number */ | ||
5344 | static const char *check_output_sfx(hda_nid_t nid, const hda_nid_t *pins, | ||
5345 | int num_pins, int *indexp) | ||
5346 | { | ||
5347 | static const char * const channel_sfx[] = { | ||
5348 | " Front", " Surround", " CLFE", " Side" | ||
5349 | }; | ||
5350 | int i; | ||
5351 | |||
5352 | i = find_idx_in_nid_list(nid, pins, num_pins); | ||
5353 | if (i < 0) | ||
5354 | return NULL; | ||
5355 | if (num_pins == 1) | ||
5356 | return ""; | ||
5357 | if (num_pins > ARRAY_SIZE(channel_sfx)) { | ||
5358 | if (indexp) | ||
5359 | *indexp = i; | ||
5360 | return ""; | ||
5361 | } | ||
5362 | return channel_sfx[i]; | ||
5363 | } | ||
5364 | |||
5365 | static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid, | ||
5366 | const struct auto_pin_cfg *cfg, | ||
5367 | const char *name, char *label, int maxlen, | ||
5368 | int *indexp) | ||
5369 | { | ||
5370 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
5371 | int attr = snd_hda_get_input_pin_attr(def_conf); | ||
5372 | const char *pfx = "", *sfx = ""; | ||
5373 | |||
5374 | /* handle as a speaker if it's a fixed line-out */ | ||
5375 | if (!strcmp(name, "Line Out") && attr == INPUT_PIN_ATTR_INT) | ||
5376 | name = "Speaker"; | ||
5377 | /* check the location */ | ||
5378 | switch (attr) { | ||
5379 | case INPUT_PIN_ATTR_DOCK: | ||
5380 | pfx = "Dock "; | ||
5381 | break; | ||
5382 | case INPUT_PIN_ATTR_FRONT: | ||
5383 | pfx = "Front "; | ||
5384 | break; | ||
5385 | } | ||
5386 | if (cfg) { | ||
5387 | /* try to give a unique suffix if needed */ | ||
5388 | sfx = check_output_sfx(nid, cfg->line_out_pins, cfg->line_outs, | ||
5389 | indexp); | ||
5390 | if (!sfx) | ||
5391 | sfx = check_output_sfx(nid, cfg->speaker_pins, cfg->speaker_outs, | ||
5392 | indexp); | ||
5393 | if (!sfx) { | ||
5394 | /* don't add channel suffix for Headphone controls */ | ||
5395 | int idx = find_idx_in_nid_list(nid, cfg->hp_pins, | ||
5396 | cfg->hp_outs); | ||
5397 | if (idx >= 0) | ||
5398 | *indexp = idx; | ||
5399 | sfx = ""; | ||
5400 | } | ||
5401 | } | ||
5402 | snprintf(label, maxlen, "%s%s%s", pfx, name, sfx); | ||
5403 | return 1; | ||
5404 | } | ||
5405 | |||
5406 | /** | ||
5407 | * snd_hda_get_pin_label - Get a label for the given I/O pin | ||
5408 | * | ||
5409 | * Get a label for the given pin. This function works for both input and | ||
5410 | * output pins. When @cfg is given as non-NULL, the function tries to get | ||
5411 | * an optimized label using hda_get_autocfg_input_label(). | ||
5412 | * | ||
5413 | * This function tries to give a unique label string for the pin as much as | ||
5414 | * possible. For example, when the multiple line-outs are present, it adds | ||
5415 | * the channel suffix like "Front", "Surround", etc (only when @cfg is given). | ||
5416 | * If no unique name with a suffix is available and @indexp is non-NULL, the | ||
5417 | * index number is stored in the pointer. | ||
5418 | */ | ||
5419 | int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, | ||
5420 | const struct auto_pin_cfg *cfg, | ||
5421 | char *label, int maxlen, int *indexp) | ||
5422 | { | ||
5423 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
5424 | const char *name = NULL; | ||
5425 | int i; | ||
5426 | |||
5427 | if (indexp) | ||
5428 | *indexp = 0; | ||
5429 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) | ||
5430 | return 0; | ||
5431 | |||
5432 | switch (get_defcfg_device(def_conf)) { | ||
5433 | case AC_JACK_LINE_OUT: | ||
5434 | return fill_audio_out_name(codec, nid, cfg, "Line Out", | ||
5435 | label, maxlen, indexp); | ||
5436 | case AC_JACK_SPEAKER: | ||
5437 | return fill_audio_out_name(codec, nid, cfg, "Speaker", | ||
5438 | label, maxlen, indexp); | ||
5439 | case AC_JACK_HP_OUT: | ||
5440 | return fill_audio_out_name(codec, nid, cfg, "Headphone", | ||
5441 | label, maxlen, indexp); | ||
5442 | case AC_JACK_SPDIF_OUT: | ||
5443 | case AC_JACK_DIG_OTHER_OUT: | ||
5444 | if (get_defcfg_location(def_conf) == AC_JACK_LOC_HDMI) | ||
5445 | name = "HDMI"; | ||
5446 | else | ||
5447 | name = "SPDIF"; | ||
5448 | if (cfg && indexp) { | ||
5449 | i = find_idx_in_nid_list(nid, cfg->dig_out_pins, | ||
5450 | cfg->dig_outs); | ||
5451 | if (i >= 0) | ||
5452 | *indexp = i; | ||
5453 | } | ||
5454 | break; | ||
5455 | default: | ||
5456 | if (cfg) { | ||
5457 | for (i = 0; i < cfg->num_inputs; i++) { | ||
5458 | if (cfg->inputs[i].pin != nid) | ||
5459 | continue; | ||
5460 | name = hda_get_autocfg_input_label(codec, cfg, i); | ||
5461 | if (name) | ||
5462 | break; | ||
5463 | } | ||
5464 | } | ||
5465 | if (!name) | ||
5466 | name = hda_get_input_pin_label(codec, nid, true); | ||
5467 | break; | ||
5468 | } | ||
5469 | if (!name) | ||
5470 | return 0; | ||
5471 | strlcpy(label, name, maxlen); | ||
5472 | return 1; | ||
5473 | } | ||
5474 | EXPORT_SYMBOL_HDA(snd_hda_get_pin_label); | ||
5475 | |||
5476 | /** | 4880 | /** |
5477 | * snd_hda_add_imux_item - Add an item to input_mux | 4881 | * snd_hda_add_imux_item - Add an item to input_mux |
5478 | * | 4882 | * |
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index d68948499fbc..2dd1c113a4c1 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <sound/jack.h> | 17 | #include <sound/jack.h> |
18 | #include "hda_codec.h" | 18 | #include "hda_codec.h" |
19 | #include "hda_local.h" | 19 | #include "hda_local.h" |
20 | #include "hda_auto_parser.h" | ||
20 | #include "hda_jack.h" | 21 | #include "hda_jack.h" |
21 | 22 | ||
22 | bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) | 23 | bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) |
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h index c66655cf413a..8ae52465ec5d 100644 --- a/sound/pci/hda/hda_jack.h +++ b/sound/pci/hda/hda_jack.h | |||
@@ -12,6 +12,8 @@ | |||
12 | #ifndef __SOUND_HDA_JACK_H | 12 | #ifndef __SOUND_HDA_JACK_H |
13 | #define __SOUND_HDA_JACK_H | 13 | #define __SOUND_HDA_JACK_H |
14 | 14 | ||
15 | struct auto_pin_cfg; | ||
16 | |||
15 | struct hda_jack_tbl { | 17 | struct hda_jack_tbl { |
16 | hda_nid_t nid; | 18 | hda_nid_t nid; |
17 | unsigned char action; /* event action (0 = none) */ | 19 | unsigned char action; /* event action (0 = none) */ |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index a5cee952547d..9a096a8e0fc5 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -262,6 +262,8 @@ int snd_hda_input_mux_put(struct hda_codec *codec, | |||
262 | const struct hda_input_mux *imux, | 262 | const struct hda_input_mux *imux, |
263 | struct snd_ctl_elem_value *ucontrol, hda_nid_t nid, | 263 | struct snd_ctl_elem_value *ucontrol, hda_nid_t nid, |
264 | unsigned int *cur_val); | 264 | unsigned int *cur_val); |
265 | int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label, | ||
266 | int index, int *type_index_ret); | ||
265 | 267 | ||
266 | /* | 268 | /* |
267 | * Channel mode helper | 269 | * Channel mode helper |
@@ -393,72 +395,7 @@ struct hda_bus_unsolicited { | |||
393 | struct hda_bus *bus; | 395 | struct hda_bus *bus; |
394 | }; | 396 | }; |
395 | 397 | ||
396 | /* | 398 | /* helper macros to retrieve pin default-config values */ |
397 | * Helper for automatic pin configuration | ||
398 | */ | ||
399 | |||
400 | enum { | ||
401 | AUTO_PIN_MIC, | ||
402 | AUTO_PIN_LINE_IN, | ||
403 | AUTO_PIN_CD, | ||
404 | AUTO_PIN_AUX, | ||
405 | AUTO_PIN_LAST | ||
406 | }; | ||
407 | |||
408 | enum { | ||
409 | AUTO_PIN_LINE_OUT, | ||
410 | AUTO_PIN_SPEAKER_OUT, | ||
411 | AUTO_PIN_HP_OUT | ||
412 | }; | ||
413 | |||
414 | #define AUTO_CFG_MAX_OUTS HDA_MAX_OUTS | ||
415 | #define AUTO_CFG_MAX_INS 8 | ||
416 | |||
417 | struct auto_pin_cfg_item { | ||
418 | hda_nid_t pin; | ||
419 | int type; | ||
420 | }; | ||
421 | |||
422 | struct auto_pin_cfg; | ||
423 | const char *hda_get_autocfg_input_label(struct hda_codec *codec, | ||
424 | const struct auto_pin_cfg *cfg, | ||
425 | int input); | ||
426 | int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, | ||
427 | const struct auto_pin_cfg *cfg, | ||
428 | char *label, int maxlen, int *indexp); | ||
429 | int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label, | ||
430 | int index, int *type_index_ret); | ||
431 | |||
432 | enum { | ||
433 | INPUT_PIN_ATTR_UNUSED, /* pin not connected */ | ||
434 | INPUT_PIN_ATTR_INT, /* internal mic/line-in */ | ||
435 | INPUT_PIN_ATTR_DOCK, /* docking mic/line-in */ | ||
436 | INPUT_PIN_ATTR_NORMAL, /* mic/line-in jack */ | ||
437 | INPUT_PIN_ATTR_FRONT, /* mic/line-in jack in front */ | ||
438 | INPUT_PIN_ATTR_REAR, /* mic/line-in jack in rear */ | ||
439 | }; | ||
440 | |||
441 | int snd_hda_get_input_pin_attr(unsigned int def_conf); | ||
442 | |||
443 | struct auto_pin_cfg { | ||
444 | int line_outs; | ||
445 | /* sorted in the order of Front/Surr/CLFE/Side */ | ||
446 | hda_nid_t line_out_pins[AUTO_CFG_MAX_OUTS]; | ||
447 | int speaker_outs; | ||
448 | hda_nid_t speaker_pins[AUTO_CFG_MAX_OUTS]; | ||
449 | int hp_outs; | ||
450 | int line_out_type; /* AUTO_PIN_XXX_OUT */ | ||
451 | hda_nid_t hp_pins[AUTO_CFG_MAX_OUTS]; | ||
452 | int num_inputs; | ||
453 | struct auto_pin_cfg_item inputs[AUTO_CFG_MAX_INS]; | ||
454 | int dig_outs; | ||
455 | hda_nid_t dig_out_pins[2]; | ||
456 | hda_nid_t dig_in_pin; | ||
457 | hda_nid_t mono_out_pin; | ||
458 | int dig_out_type[2]; /* HDA_PCM_TYPE_XXX */ | ||
459 | int dig_in_type; /* HDA_PCM_TYPE_XXX */ | ||
460 | }; | ||
461 | |||
462 | #define get_defcfg_connect(cfg) \ | 399 | #define get_defcfg_connect(cfg) \ |
463 | ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) | 400 | ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) |
464 | #define get_defcfg_association(cfg) \ | 401 | #define get_defcfg_association(cfg) \ |
@@ -472,19 +409,6 @@ struct auto_pin_cfg { | |||
472 | #define get_defcfg_misc(cfg) \ | 409 | #define get_defcfg_misc(cfg) \ |
473 | ((cfg & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT) | 410 | ((cfg & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT) |
474 | 411 | ||
475 | /* bit-flags for snd_hda_parse_pin_def_config() behavior */ | ||
476 | #define HDA_PINCFG_NO_HP_FIXUP (1 << 0) /* no HP-split */ | ||
477 | #define HDA_PINCFG_NO_LO_FIXUP (1 << 1) /* don't take other outs as LO */ | ||
478 | |||
479 | int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | ||
480 | struct auto_pin_cfg *cfg, | ||
481 | const hda_nid_t *ignore_nids, | ||
482 | unsigned int cond_flags); | ||
483 | |||
484 | /* older function */ | ||
485 | #define snd_hda_parse_pin_def_config(codec, cfg, ignore) \ | ||
486 | snd_hda_parse_pin_defcfg(codec, cfg, ignore, 0) | ||
487 | |||
488 | /* amp values */ | 412 | /* amp values */ |
489 | #define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8)) | 413 | #define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8)) |
490 | #define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8)) | 414 | #define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8)) |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 723bb9cb5f09..d8b2d6dee986 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <sound/core.h> | 28 | #include <sound/core.h> |
29 | #include "hda_codec.h" | 29 | #include "hda_codec.h" |
30 | #include "hda_local.h" | 30 | #include "hda_local.h" |
31 | #include "hda_auto_parser.h" | ||
31 | #include "hda_beep.h" | 32 | #include "hda_beep.h" |
32 | #include "hda_jack.h" | 33 | #include "hda_jack.h" |
33 | 34 | ||
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c index a3b70a8f6df8..19ae14f739cb 100644 --- a/sound/pci/hda/patch_ca0110.c +++ b/sound/pci/hda/patch_ca0110.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <sound/core.h> | 26 | #include <sound/core.h> |
27 | #include "hda_codec.h" | 27 | #include "hda_codec.h" |
28 | #include "hda_local.h" | 28 | #include "hda_local.h" |
29 | #include "hda_auto_parser.h" | ||
29 | 30 | ||
30 | /* | 31 | /* |
31 | */ | 32 | */ |
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index d290a8ff0108..d0d3540e39e7 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <sound/core.h> | 30 | #include <sound/core.h> |
31 | #include "hda_codec.h" | 31 | #include "hda_codec.h" |
32 | #include "hda_local.h" | 32 | #include "hda_local.h" |
33 | #include "hda_auto_parser.h" | ||
33 | 34 | ||
34 | #define WIDGET_CHIP_CTRL 0x15 | 35 | #define WIDGET_CHIP_CTRL 0x15 |
35 | #define WIDGET_DSP_CTRL 0x16 | 36 | #define WIDGET_DSP_CTRL 0x16 |
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 48c6d8186e90..9647ed4d7929 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <sound/core.h> | 26 | #include <sound/core.h> |
27 | #include "hda_codec.h" | 27 | #include "hda_codec.h" |
28 | #include "hda_local.h" | 28 | #include "hda_local.h" |
29 | #include "hda_auto_parser.h" | ||
29 | #include "hda_jack.h" | 30 | #include "hda_jack.h" |
30 | #include <sound/tlv.h> | 31 | #include <sound/tlv.h> |
31 | 32 | ||
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index b6767b4ced44..c8fdaaefe702 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <sound/core.h> | 29 | #include <sound/core.h> |
30 | #include "hda_codec.h" | 30 | #include "hda_codec.h" |
31 | #include "hda_local.h" | 31 | #include "hda_local.h" |
32 | #include "hda_auto_parser.h" | ||
32 | #define NUM_PINS 11 | 33 | #define NUM_PINS 11 |
33 | 34 | ||
34 | 35 | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 884f8ad351fd..baf1edde244d 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <sound/tlv.h> | 36 | #include <sound/tlv.h> |
37 | #include "hda_codec.h" | 37 | #include "hda_codec.h" |
38 | #include "hda_local.h" | 38 | #include "hda_local.h" |
39 | #include "hda_auto_parser.h" | ||
39 | #include "hda_beep.h" | 40 | #include "hda_beep.h" |
40 | #include "hda_jack.h" | 41 | #include "hda_jack.h" |
41 | 42 | ||
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 92e11672b91c..db272fb5e579 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <sound/asoundef.h> | 54 | #include <sound/asoundef.h> |
55 | #include "hda_codec.h" | 55 | #include "hda_codec.h" |
56 | #include "hda_local.h" | 56 | #include "hda_local.h" |
57 | #include "hda_auto_parser.h" | ||
57 | #include "hda_jack.h" | 58 | #include "hda_jack.h" |
58 | 59 | ||
59 | /* Pin Widget NID */ | 60 | /* Pin Widget NID */ |