diff options
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 904 |
1 files changed, 716 insertions, 188 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index ea99083a1024..731b7b97ee71 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -36,15 +36,15 @@ | |||
36 | 36 | ||
37 | #define NUM_CONTROL_ALLOC 32 | 37 | #define NUM_CONTROL_ALLOC 32 |
38 | #define STAC_HP_EVENT 0x37 | 38 | #define STAC_HP_EVENT 0x37 |
39 | #define STAC_UNSOL_ENABLE (AC_USRSP_EN | STAC_HP_EVENT) | ||
40 | 39 | ||
41 | #define STAC_REF 0 | 40 | #define STAC_REF 0 |
42 | #define STAC_D945GTP3 1 | 41 | #define STAC_D945GTP3 1 |
43 | #define STAC_D945GTP5 2 | 42 | #define STAC_D945GTP5 2 |
44 | #define STAC_MACMINI 3 | 43 | #define STAC_MACMINI 3 |
45 | #define STAC_D965_2112 4 | 44 | #define STAC_922X_MODELS 4 /* number of 922x models */ |
46 | #define STAC_D965_284B 5 | 45 | #define STAC_D965_3ST 4 |
47 | #define STAC_922X_MODELS 6 /* number of 922x models */ | 46 | #define STAC_D965_5ST 5 |
47 | #define STAC_927X_MODELS 6 /* number of 922x models */ | ||
48 | 48 | ||
49 | struct sigmatel_spec { | 49 | struct sigmatel_spec { |
50 | struct snd_kcontrol_new *mixers[4]; | 50 | struct snd_kcontrol_new *mixers[4]; |
@@ -73,6 +73,7 @@ struct sigmatel_spec { | |||
73 | hda_nid_t *pin_nids; | 73 | hda_nid_t *pin_nids; |
74 | unsigned int num_pins; | 74 | unsigned int num_pins; |
75 | unsigned int *pin_configs; | 75 | unsigned int *pin_configs; |
76 | unsigned int *bios_pin_configs; | ||
76 | 77 | ||
77 | /* codec specific stuff */ | 78 | /* codec specific stuff */ |
78 | struct hda_verb *init; | 79 | struct hda_verb *init; |
@@ -110,24 +111,10 @@ static hda_nid_t stac922x_adc_nids[2] = { | |||
110 | 0x06, 0x07, | 111 | 0x06, 0x07, |
111 | }; | 112 | }; |
112 | 113 | ||
113 | static hda_nid_t stac9227_adc_nids[2] = { | ||
114 | 0x07, 0x08, | ||
115 | }; | ||
116 | |||
117 | #if 0 | ||
118 | static hda_nid_t d965_2112_dac_nids[3] = { | ||
119 | 0x02, 0x03, 0x05, | ||
120 | }; | ||
121 | #endif | ||
122 | |||
123 | static hda_nid_t stac922x_mux_nids[2] = { | 114 | static hda_nid_t stac922x_mux_nids[2] = { |
124 | 0x12, 0x13, | 115 | 0x12, 0x13, |
125 | }; | 116 | }; |
126 | 117 | ||
127 | static hda_nid_t stac9227_mux_nids[2] = { | ||
128 | 0x15, 0x16, | ||
129 | }; | ||
130 | |||
131 | static hda_nid_t stac927x_adc_nids[3] = { | 118 | static hda_nid_t stac927x_adc_nids[3] = { |
132 | 0x07, 0x08, 0x09 | 119 | 0x07, 0x08, 0x09 |
133 | }; | 120 | }; |
@@ -136,8 +123,17 @@ static hda_nid_t stac927x_mux_nids[3] = { | |||
136 | 0x15, 0x16, 0x17 | 123 | 0x15, 0x16, 0x17 |
137 | }; | 124 | }; |
138 | 125 | ||
126 | static hda_nid_t stac9205_adc_nids[2] = { | ||
127 | 0x12, 0x13 | ||
128 | }; | ||
129 | |||
130 | static hda_nid_t stac9205_mux_nids[2] = { | ||
131 | 0x19, 0x1a | ||
132 | }; | ||
133 | |||
139 | static hda_nid_t stac9200_pin_nids[8] = { | 134 | static hda_nid_t stac9200_pin_nids[8] = { |
140 | 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, | 135 | 0x08, 0x09, 0x0d, 0x0e, |
136 | 0x0f, 0x10, 0x11, 0x12, | ||
141 | }; | 137 | }; |
142 | 138 | ||
143 | static hda_nid_t stac922x_pin_nids[10] = { | 139 | static hda_nid_t stac922x_pin_nids[10] = { |
@@ -151,6 +147,13 @@ static hda_nid_t stac927x_pin_nids[14] = { | |||
151 | 0x14, 0x21, 0x22, 0x23, | 147 | 0x14, 0x21, 0x22, 0x23, |
152 | }; | 148 | }; |
153 | 149 | ||
150 | static hda_nid_t stac9205_pin_nids[12] = { | ||
151 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | ||
152 | 0x0f, 0x14, 0x16, 0x17, 0x18, | ||
153 | 0x21, 0x22, | ||
154 | |||
155 | }; | ||
156 | |||
154 | static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 157 | static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
155 | { | 158 | { |
156 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 159 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
@@ -190,25 +193,23 @@ static struct hda_verb stac922x_core_init[] = { | |||
190 | {} | 193 | {} |
191 | }; | 194 | }; |
192 | 195 | ||
193 | static struct hda_verb stac9227_core_init[] = { | 196 | static struct hda_verb d965_core_init[] = { |
194 | /* set master volume and direct control */ | 197 | /* set master volume and direct control */ |
195 | { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 198 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
196 | /* unmute node 0x1b */ | 199 | /* unmute node 0x1b */ |
197 | { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | 200 | { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, |
201 | /* select node 0x03 as DAC */ | ||
202 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
198 | {} | 203 | {} |
199 | }; | 204 | }; |
200 | 205 | ||
201 | static struct hda_verb d965_2112_core_init[] = { | 206 | static struct hda_verb stac927x_core_init[] = { |
202 | /* set master volume and direct control */ | 207 | /* set master volume and direct control */ |
203 | { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 208 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
204 | /* unmute node 0x1b */ | ||
205 | { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
206 | /* select node 0x03 as DAC */ | ||
207 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
208 | {} | 209 | {} |
209 | }; | 210 | }; |
210 | 211 | ||
211 | static struct hda_verb stac927x_core_init[] = { | 212 | static struct hda_verb stac9205_core_init[] = { |
212 | /* set master volume and direct control */ | 213 | /* set master volume and direct control */ |
213 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 214 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
214 | {} | 215 | {} |
@@ -277,6 +278,21 @@ static snd_kcontrol_new_t stac927x_mixer[] = { | |||
277 | { } /* end */ | 278 | { } /* end */ |
278 | }; | 279 | }; |
279 | 280 | ||
281 | static snd_kcontrol_new_t stac9205_mixer[] = { | ||
282 | { | ||
283 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
284 | .name = "Input Source", | ||
285 | .count = 1, | ||
286 | .info = stac92xx_mux_enum_info, | ||
287 | .get = stac92xx_mux_enum_get, | ||
288 | .put = stac92xx_mux_enum_put, | ||
289 | }, | ||
290 | HDA_CODEC_VOLUME("InMux Capture Volume", 0x19, 0x0, HDA_OUTPUT), | ||
291 | HDA_CODEC_VOLUME("InVol Capture Volume", 0x1b, 0x0, HDA_INPUT), | ||
292 | HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1d, 0x0, HDA_OUTPUT), | ||
293 | { } /* end */ | ||
294 | }; | ||
295 | |||
280 | static int stac92xx_build_controls(struct hda_codec *codec) | 296 | static int stac92xx_build_controls(struct hda_codec *codec) |
281 | { | 297 | { |
282 | struct sigmatel_spec *spec = codec->spec; | 298 | struct sigmatel_spec *spec = codec->spec; |
@@ -341,38 +357,67 @@ static unsigned int d945gtp5_pin_configs[10] = { | |||
341 | 0x02a19320, 0x40000100, | 357 | 0x02a19320, 0x40000100, |
342 | }; | 358 | }; |
343 | 359 | ||
344 | static unsigned int d965_2112_pin_configs[10] = { | ||
345 | 0x0221401f, 0x40000100, 0x40000100, 0x01014011, | ||
346 | 0x01a19021, 0x01813024, 0x01452130, 0x40000100, | ||
347 | 0x02a19320, 0x40000100, | ||
348 | }; | ||
349 | |||
350 | static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { | 360 | static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { |
351 | [STAC_REF] = ref922x_pin_configs, | 361 | [STAC_REF] = ref922x_pin_configs, |
352 | [STAC_D945GTP3] = d945gtp3_pin_configs, | 362 | [STAC_D945GTP3] = d945gtp3_pin_configs, |
353 | [STAC_D945GTP5] = d945gtp5_pin_configs, | 363 | [STAC_D945GTP5] = d945gtp5_pin_configs, |
354 | [STAC_MACMINI] = d945gtp5_pin_configs, | 364 | [STAC_MACMINI] = d945gtp5_pin_configs, |
355 | [STAC_D965_2112] = d965_2112_pin_configs, | ||
356 | }; | 365 | }; |
357 | 366 | ||
358 | static struct hda_board_config stac922x_cfg_tbl[] = { | 367 | static struct hda_board_config stac922x_cfg_tbl[] = { |
368 | { .modelname = "5stack", .config = STAC_D945GTP5 }, | ||
369 | { .modelname = "3stack", .config = STAC_D945GTP3 }, | ||
359 | { .modelname = "ref", | 370 | { .modelname = "ref", |
360 | .pci_subvendor = PCI_VENDOR_ID_INTEL, | 371 | .pci_subvendor = PCI_VENDOR_ID_INTEL, |
361 | .pci_subdevice = 0x2668, /* DFI LanParty */ | 372 | .pci_subdevice = 0x2668, /* DFI LanParty */ |
362 | .config = STAC_REF }, /* SigmaTel reference board */ | 373 | .config = STAC_REF }, /* SigmaTel reference board */ |
374 | /* Intel 945G based systems */ | ||
363 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | 375 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, |
364 | .pci_subdevice = 0x0101, | 376 | .pci_subdevice = 0x0101, |
365 | .config = STAC_D945GTP3 }, /* Intel D945GTP - 3 Stack */ | 377 | .config = STAC_D945GTP3 }, /* Intel D945GTP - 3 Stack */ |
366 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | 378 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, |
367 | .pci_subdevice = 0x0202, | 379 | .pci_subdevice = 0x0202, |
368 | .config = STAC_D945GTP3 }, /* Intel D945GNT - 3 Stack, 9221 A1 */ | 380 | .config = STAC_D945GTP3 }, /* Intel D945GNT - 3 Stack */ |
369 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | 381 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, |
370 | .pci_subdevice = 0x0b0b, | 382 | .pci_subdevice = 0x0606, |
371 | .config = STAC_D945GTP3 }, /* Intel D945PSN - 3 Stack, 9221 A1 */ | 383 | .config = STAC_D945GTP3 }, /* Intel D945GTP - 3 Stack */ |
384 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
385 | .pci_subdevice = 0x0601, | ||
386 | .config = STAC_D945GTP3 }, /* Intel D945GTP - 3 Stack */ | ||
387 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
388 | .pci_subdevice = 0x0111, | ||
389 | .config = STAC_D945GTP3 }, /* Intel D945GZP - 3 Stack */ | ||
390 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
391 | .pci_subdevice = 0x1115, | ||
392 | .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ | ||
393 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
394 | .pci_subdevice = 0x1116, | ||
395 | .config = STAC_D945GTP3 }, /* Intel D945GBO - 3 Stack */ | ||
396 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
397 | .pci_subdevice = 0x1117, | ||
398 | .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ | ||
399 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
400 | .pci_subdevice = 0x1118, | ||
401 | .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ | ||
402 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
403 | .pci_subdevice = 0x1119, | ||
404 | .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ | ||
405 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
406 | .pci_subdevice = 0x8826, | ||
407 | .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ | ||
408 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
409 | .pci_subdevice = 0x5049, | ||
410 | .config = STAC_D945GTP3 }, /* Intel D945GCZ - 3 Stack */ | ||
411 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
412 | .pci_subdevice = 0x5055, | ||
413 | .config = STAC_D945GTP3 }, /* Intel D945GCZ - 3 Stack */ | ||
414 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
415 | .pci_subdevice = 0x5048, | ||
416 | .config = STAC_D945GTP3 }, /* Intel D945GPB - 3 Stack */ | ||
417 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
418 | .pci_subdevice = 0x0110, | ||
419 | .config = STAC_D945GTP3 }, /* Intel D945GLR - 3 Stack */ | ||
372 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | 420 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, |
373 | .pci_subdevice = 0x0707, | ||
374 | .config = STAC_D945GTP5 }, /* Intel D945PSV - 5 Stack */ | ||
375 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
376 | .pci_subdevice = 0x0404, | 421 | .pci_subdevice = 0x0404, |
377 | .config = STAC_D945GTP5 }, /* Intel D945GTP - 5 Stack */ | 422 | .config = STAC_D945GTP5 }, /* Intel D945GTP - 5 Stack */ |
378 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | 423 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, |
@@ -384,44 +429,214 @@ static struct hda_board_config stac922x_cfg_tbl[] = { | |||
384 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | 429 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, |
385 | .pci_subdevice = 0x0417, | 430 | .pci_subdevice = 0x0417, |
386 | .config = STAC_D945GTP5 }, /* Intel D975XBK - 5 Stack */ | 431 | .config = STAC_D945GTP5 }, /* Intel D975XBK - 5 Stack */ |
432 | /* Intel 945P based systems */ | ||
433 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
434 | .pci_subdevice = 0x0b0b, | ||
435 | .config = STAC_D945GTP3 }, /* Intel D945PSN - 3 Stack */ | ||
436 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
437 | .pci_subdevice = 0x0112, | ||
438 | .config = STAC_D945GTP3 }, /* Intel D945PLN - 3 Stack */ | ||
439 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
440 | .pci_subdevice = 0x0d0d, | ||
441 | .config = STAC_D945GTP3 }, /* Intel D945PLM - 3 Stack */ | ||
442 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
443 | .pci_subdevice = 0x0909, | ||
444 | .config = STAC_D945GTP3 }, /* Intel D945PAW - 3 Stack */ | ||
445 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
446 | .pci_subdevice = 0x0505, | ||
447 | .config = STAC_D945GTP3 }, /* Intel D945PLM - 3 Stack */ | ||
448 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
449 | .pci_subdevice = 0x0707, | ||
450 | .config = STAC_D945GTP5 }, /* Intel D945PSV - 5 Stack */ | ||
451 | /* other systems */ | ||
387 | { .pci_subvendor = 0x8384, | 452 | { .pci_subvendor = 0x8384, |
388 | .pci_subdevice = 0x7680, | 453 | .pci_subdevice = 0x7680, |
389 | .config = STAC_MACMINI }, /* Apple Mac Mini (early 2006) */ | 454 | .config = STAC_MACMINI }, /* Apple Mac Mini (early 2006) */ |
455 | {} /* terminator */ | ||
456 | }; | ||
457 | |||
458 | static unsigned int ref927x_pin_configs[14] = { | ||
459 | 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, | ||
460 | 0x01a19040, 0x01011012, 0x01016011, 0x0101201f, | ||
461 | 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070, | ||
462 | 0x01c42190, 0x40000100, | ||
463 | }; | ||
464 | |||
465 | static unsigned int d965_3st_pin_configs[14] = { | ||
466 | 0x0221401f, 0x02a19120, 0x40000100, 0x01014011, | ||
467 | 0x01a19021, 0x01813024, 0x40000100, 0x40000100, | ||
468 | 0x40000100, 0x40000100, 0x40000100, 0x40000100, | ||
469 | 0x40000100, 0x40000100 | ||
470 | }; | ||
471 | |||
472 | static unsigned int d965_5st_pin_configs[14] = { | ||
473 | 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, | ||
474 | 0x01a19040, 0x01011012, 0x01016011, 0x40000100, | ||
475 | 0x40000100, 0x40000100, 0x40000100, 0x01442070, | ||
476 | 0x40000100, 0x40000100 | ||
477 | }; | ||
478 | |||
479 | static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { | ||
480 | [STAC_REF] = ref927x_pin_configs, | ||
481 | [STAC_D965_3ST] = d965_3st_pin_configs, | ||
482 | [STAC_D965_5ST] = d965_5st_pin_configs, | ||
483 | }; | ||
484 | |||
485 | static struct hda_board_config stac927x_cfg_tbl[] = { | ||
486 | { .modelname = "5stack", .config = STAC_D965_5ST }, | ||
487 | { .modelname = "3stack", .config = STAC_D965_3ST }, | ||
488 | { .modelname = "ref", | ||
489 | .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
490 | .pci_subdevice = 0x2668, /* DFI LanParty */ | ||
491 | .config = STAC_REF }, /* SigmaTel reference board */ | ||
492 | /* Intel 946 based systems */ | ||
493 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
494 | .pci_subdevice = 0x3d01, | ||
495 | .config = STAC_D965_3ST }, /* D946 configuration */ | ||
496 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
497 | .pci_subdevice = 0xa301, | ||
498 | .config = STAC_D965_3ST }, /* Intel D946GZT - 3 stack */ | ||
499 | /* 965 based 3 stack systems */ | ||
500 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
501 | .pci_subdevice = 0x2116, | ||
502 | .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ | ||
503 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
504 | .pci_subdevice = 0x2115, | ||
505 | .config = STAC_D965_3ST }, /* Intel DQ965WC - 3 Stack */ | ||
506 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
507 | .pci_subdevice = 0x2114, | ||
508 | .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ | ||
509 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
510 | .pci_subdevice = 0x2113, | ||
511 | .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ | ||
390 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | 512 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, |
391 | .pci_subdevice = 0x2112, | 513 | .pci_subdevice = 0x2112, |
392 | .config = STAC_D965_2112 }, | 514 | .config = STAC_D965_3ST }, /* Intel DG965MS - 3 Stack */ |
515 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
516 | .pci_subdevice = 0x2111, | ||
517 | .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ | ||
518 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
519 | .pci_subdevice = 0x2110, | ||
520 | .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ | ||
521 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
522 | .pci_subdevice = 0x2009, | ||
523 | .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ | ||
524 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
525 | .pci_subdevice = 0x2008, | ||
526 | .config = STAC_D965_3ST }, /* Intel DQ965GF - 3 Stack */ | ||
527 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
528 | .pci_subdevice = 0x2007, | ||
529 | .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ | ||
530 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
531 | .pci_subdevice = 0x2006, | ||
532 | .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ | ||
533 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
534 | .pci_subdevice = 0x2005, | ||
535 | .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ | ||
536 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
537 | .pci_subdevice = 0x2004, | ||
538 | .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ | ||
539 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
540 | .pci_subdevice = 0x2003, | ||
541 | .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ | ||
542 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
543 | .pci_subdevice = 0x2002, | ||
544 | .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ | ||
545 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
546 | .pci_subdevice = 0x2001, | ||
547 | .config = STAC_D965_3ST }, /* Intel DQ965GF - 3 Stack */ | ||
548 | /* 965 based 5 stack systems */ | ||
549 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
550 | .pci_subdevice = 0x2301, | ||
551 | .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ | ||
552 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
553 | .pci_subdevice = 0x2302, | ||
554 | .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ | ||
555 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
556 | .pci_subdevice = 0x2303, | ||
557 | .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ | ||
393 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | 558 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, |
394 | .pci_subdevice = 0x284b, | 559 | .pci_subdevice = 0x2304, |
395 | .config = STAC_D965_284B }, | 560 | .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ |
561 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
562 | .pci_subdevice = 0x2305, | ||
563 | .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ | ||
564 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
565 | .pci_subdevice = 0x2501, | ||
566 | .config = STAC_D965_5ST }, /* Intel DG965MQ - 5 Stack */ | ||
567 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
568 | .pci_subdevice = 0x2502, | ||
569 | .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ | ||
570 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
571 | .pci_subdevice = 0x2503, | ||
572 | .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ | ||
573 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
574 | .pci_subdevice = 0x2504, | ||
575 | .config = STAC_D965_5ST }, /* Intel DQ965GF - 5 Stack */ | ||
396 | {} /* terminator */ | 576 | {} /* terminator */ |
397 | }; | 577 | }; |
398 | 578 | ||
399 | static unsigned int ref927x_pin_configs[14] = { | 579 | static unsigned int ref9205_pin_configs[12] = { |
400 | 0x01813122, 0x01a19021, 0x01014010, 0x01016011, | 580 | 0x40000100, 0x40000100, 0x01016011, 0x01014010, |
401 | 0x01012012, 0x01011014, 0x40000100, 0x40000100, | 581 | 0x01813122, 0x01a19021, 0x40000100, 0x40000100, |
402 | 0x40000100, 0x40000100, 0x40000100, 0x01441030, | 582 | 0x40000100, 0x40000100, 0x01441030, 0x01c41030 |
403 | 0x01c41030, 0x40000100, | ||
404 | }; | 583 | }; |
405 | 584 | ||
406 | static unsigned int *stac927x_brd_tbl[] = { | 585 | static unsigned int *stac9205_brd_tbl[] = { |
407 | ref927x_pin_configs, | 586 | ref9205_pin_configs, |
408 | }; | 587 | }; |
409 | 588 | ||
410 | static struct hda_board_config stac927x_cfg_tbl[] = { | 589 | static struct hda_board_config stac9205_cfg_tbl[] = { |
411 | { .modelname = "ref", | 590 | { .modelname = "ref", |
412 | .pci_subvendor = PCI_VENDOR_ID_INTEL, | 591 | .pci_subvendor = PCI_VENDOR_ID_INTEL, |
413 | .pci_subdevice = 0x2668, /* DFI LanParty */ | 592 | .pci_subdevice = 0x2668, /* DFI LanParty */ |
414 | .config = STAC_REF }, /* SigmaTel reference board */ | 593 | .config = STAC_REF }, /* SigmaTel reference board */ |
594 | /* Dell laptops have BIOS problem */ | ||
595 | { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01b5, | ||
596 | .config = STAC_REF }, /* Dell Inspiron 630m */ | ||
597 | { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01c2, | ||
598 | .config = STAC_REF }, /* Dell Latitude D620 */ | ||
599 | { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01cb, | ||
600 | .config = STAC_REF }, /* Dell Latitude 120L */ | ||
415 | {} /* terminator */ | 601 | {} /* terminator */ |
416 | }; | 602 | }; |
417 | 603 | ||
604 | static int stac92xx_save_bios_config_regs(struct hda_codec *codec) | ||
605 | { | ||
606 | int i; | ||
607 | struct sigmatel_spec *spec = codec->spec; | ||
608 | |||
609 | if (! spec->bios_pin_configs) { | ||
610 | spec->bios_pin_configs = kcalloc(spec->num_pins, | ||
611 | sizeof(*spec->bios_pin_configs), GFP_KERNEL); | ||
612 | if (! spec->bios_pin_configs) | ||
613 | return -ENOMEM; | ||
614 | } | ||
615 | |||
616 | for (i = 0; i < spec->num_pins; i++) { | ||
617 | hda_nid_t nid = spec->pin_nids[i]; | ||
618 | unsigned int pin_cfg; | ||
619 | |||
620 | pin_cfg = snd_hda_codec_read(codec, nid, 0, | ||
621 | AC_VERB_GET_CONFIG_DEFAULT, 0x00); | ||
622 | snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n", | ||
623 | nid, pin_cfg); | ||
624 | spec->bios_pin_configs[i] = pin_cfg; | ||
625 | } | ||
626 | |||
627 | return 0; | ||
628 | } | ||
629 | |||
418 | static void stac92xx_set_config_regs(struct hda_codec *codec) | 630 | static void stac92xx_set_config_regs(struct hda_codec *codec) |
419 | { | 631 | { |
420 | int i; | 632 | int i; |
421 | struct sigmatel_spec *spec = codec->spec; | 633 | struct sigmatel_spec *spec = codec->spec; |
422 | unsigned int pin_cfg; | 634 | unsigned int pin_cfg; |
423 | 635 | ||
424 | for (i=0; i < spec->num_pins; i++) { | 636 | if (! spec->pin_nids || ! spec->pin_configs) |
637 | return; | ||
638 | |||
639 | for (i = 0; i < spec->num_pins; i++) { | ||
425 | snd_hda_codec_write(codec, spec->pin_nids[i], 0, | 640 | snd_hda_codec_write(codec, spec->pin_nids[i], 0, |
426 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, | 641 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, |
427 | spec->pin_configs[i] & 0x000000ff); | 642 | spec->pin_configs[i] & 0x000000ff); |
@@ -795,11 +1010,29 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, | |||
795 | return 0; | 1010 | return 0; |
796 | } | 1011 | } |
797 | 1012 | ||
1013 | /* create volume control/switch for the given prefx type */ | ||
1014 | static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_t nid, int chs) | ||
1015 | { | ||
1016 | char name[32]; | ||
1017 | int err; | ||
1018 | |||
1019 | sprintf(name, "%s Playback Volume", pfx); | ||
1020 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name, | ||
1021 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | ||
1022 | if (err < 0) | ||
1023 | return err; | ||
1024 | sprintf(name, "%s Playback Switch", pfx); | ||
1025 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name, | ||
1026 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | ||
1027 | if (err < 0) | ||
1028 | return err; | ||
1029 | return 0; | ||
1030 | } | ||
1031 | |||
798 | /* add playback controls from the parsed DAC table */ | 1032 | /* add playback controls from the parsed DAC table */ |
799 | static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, | 1033 | static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, |
800 | const struct auto_pin_cfg *cfg) | 1034 | const struct auto_pin_cfg *cfg) |
801 | { | 1035 | { |
802 | char name[32]; | ||
803 | static const char *chname[4] = { | 1036 | static const char *chname[4] = { |
804 | "Front", "Surround", NULL /*CLFE*/, "Side" | 1037 | "Front", "Surround", NULL /*CLFE*/, "Side" |
805 | }; | 1038 | }; |
@@ -814,26 +1047,15 @@ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, | |||
814 | 1047 | ||
815 | if (i == 2) { | 1048 | if (i == 2) { |
816 | /* Center/LFE */ | 1049 | /* Center/LFE */ |
817 | if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "Center Playback Volume", | 1050 | err = create_controls(spec, "Center", nid, 1); |
818 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) | 1051 | if (err < 0) |
819 | return err; | ||
820 | if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "LFE Playback Volume", | ||
821 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) | ||
822 | return err; | ||
823 | if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "Center Playback Switch", | ||
824 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) | ||
825 | return err; | 1052 | return err; |
826 | if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "LFE Playback Switch", | 1053 | err = create_controls(spec, "LFE", nid, 2); |
827 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) | 1054 | if (err < 0) |
828 | return err; | 1055 | return err; |
829 | } else { | 1056 | } else { |
830 | sprintf(name, "%s Playback Volume", chname[i]); | 1057 | err = create_controls(spec, chname[i], nid, 3); |
831 | if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name, | 1058 | if (err < 0) |
832 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | ||
833 | return err; | ||
834 | sprintf(name, "%s Playback Switch", chname[i]); | ||
835 | if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name, | ||
836 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | ||
837 | return err; | 1059 | return err; |
838 | } | 1060 | } |
839 | } | 1061 | } |
@@ -849,39 +1071,85 @@ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, | |||
849 | return 0; | 1071 | return 0; |
850 | } | 1072 | } |
851 | 1073 | ||
852 | /* add playback controls for HP output */ | 1074 | static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) |
853 | static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, struct auto_pin_cfg *cfg) | ||
854 | { | 1075 | { |
855 | struct sigmatel_spec *spec = codec->spec; | 1076 | int i; |
856 | hda_nid_t pin = cfg->hp_pin; | ||
857 | hda_nid_t nid; | ||
858 | int i, err; | ||
859 | unsigned int wid_caps; | ||
860 | 1077 | ||
861 | if (! pin) | 1078 | for (i = 0; i < spec->multiout.num_dacs; i++) { |
862 | return 0; | 1079 | if (spec->multiout.dac_nids[i] == nid) |
1080 | return 1; | ||
1081 | } | ||
1082 | if (spec->multiout.hp_nid == nid) | ||
1083 | return 1; | ||
1084 | return 0; | ||
1085 | } | ||
863 | 1086 | ||
864 | wid_caps = get_wcaps(codec, pin); | 1087 | static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) |
865 | if (wid_caps & AC_WCAP_UNSOL_CAP) | 1088 | { |
866 | spec->hp_detect = 1; | 1089 | if (!spec->multiout.hp_nid) |
1090 | spec->multiout.hp_nid = nid; | ||
1091 | else if (spec->multiout.num_dacs > 4) { | ||
1092 | printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid); | ||
1093 | return 1; | ||
1094 | } else { | ||
1095 | spec->multiout.dac_nids[spec->multiout.num_dacs] = nid; | ||
1096 | spec->multiout.num_dacs++; | ||
1097 | } | ||
1098 | return 0; | ||
1099 | } | ||
867 | 1100 | ||
868 | nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff; | 1101 | /* add playback controls for Speaker and HP outputs */ |
869 | for (i = 0; i < cfg->line_outs; i++) { | 1102 | static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, |
870 | if (! spec->multiout.dac_nids[i]) | 1103 | struct auto_pin_cfg *cfg) |
1104 | { | ||
1105 | struct sigmatel_spec *spec = codec->spec; | ||
1106 | hda_nid_t nid; | ||
1107 | int i, old_num_dacs, err; | ||
1108 | |||
1109 | old_num_dacs = spec->multiout.num_dacs; | ||
1110 | for (i = 0; i < cfg->hp_outs; i++) { | ||
1111 | unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]); | ||
1112 | if (wid_caps & AC_WCAP_UNSOL_CAP) | ||
1113 | spec->hp_detect = 1; | ||
1114 | nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0, | ||
1115 | AC_VERB_GET_CONNECT_LIST, 0) & 0xff; | ||
1116 | if (check_in_dac_nids(spec, nid)) | ||
1117 | nid = 0; | ||
1118 | if (! nid) | ||
871 | continue; | 1119 | continue; |
872 | if (spec->multiout.dac_nids[i] == nid) | 1120 | add_spec_dacs(spec, nid); |
873 | return 0; | 1121 | } |
1122 | for (i = 0; i < cfg->speaker_outs; i++) { | ||
1123 | nid = snd_hda_codec_read(codec, cfg->speaker_pins[0], 0, | ||
1124 | AC_VERB_GET_CONNECT_LIST, 0) & 0xff; | ||
1125 | if (check_in_dac_nids(spec, nid)) | ||
1126 | nid = 0; | ||
1127 | if (check_in_dac_nids(spec, nid)) | ||
1128 | nid = 0; | ||
1129 | if (! nid) | ||
1130 | continue; | ||
1131 | add_spec_dacs(spec, nid); | ||
874 | } | 1132 | } |
875 | 1133 | ||
876 | spec->multiout.hp_nid = nid; | 1134 | for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) { |
877 | 1135 | static const char *pfxs[] = { | |
878 | /* control HP volume/switch on the output mixer amp */ | 1136 | "Speaker", "External Speaker", "Speaker2", |
879 | if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "Headphone Playback Volume", | 1137 | }; |
880 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 1138 | err = create_controls(spec, pfxs[i - old_num_dacs], |
881 | return err; | 1139 | spec->multiout.dac_nids[i], 3); |
882 | if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "Headphone Playback Switch", | 1140 | if (err < 0) |
883 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 1141 | return err; |
884 | return err; | 1142 | } |
1143 | if (spec->multiout.hp_nid) { | ||
1144 | const char *pfx; | ||
1145 | if (old_num_dacs == spec->multiout.num_dacs) | ||
1146 | pfx = "Master"; | ||
1147 | else | ||
1148 | pfx = "Headphone"; | ||
1149 | err = create_controls(spec, pfx, spec->multiout.hp_nid, 3); | ||
1150 | if (err < 0) | ||
1151 | return err; | ||
1152 | } | ||
885 | 1153 | ||
886 | return 0; | 1154 | return 0; |
887 | } | 1155 | } |
@@ -895,23 +1163,28 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const | |||
895 | int i, j, k; | 1163 | int i, j, k; |
896 | 1164 | ||
897 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 1165 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
898 | int index = -1; | 1166 | int index; |
899 | if (cfg->input_pins[i]) { | 1167 | |
900 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; | 1168 | if (!cfg->input_pins[i]) |
901 | 1169 | continue; | |
902 | for (j=0; j<spec->num_muxes; j++) { | 1170 | index = -1; |
903 | int num_cons = snd_hda_get_connections(codec, spec->mux_nids[j], con_lst, HDA_MAX_NUM_INPUTS); | 1171 | for (j = 0; j < spec->num_muxes; j++) { |
904 | for (k=0; k<num_cons; k++) | 1172 | int num_cons; |
905 | if (con_lst[k] == cfg->input_pins[i]) { | 1173 | num_cons = snd_hda_get_connections(codec, |
906 | index = k; | 1174 | spec->mux_nids[j], |
907 | break; | 1175 | con_lst, |
908 | } | 1176 | HDA_MAX_NUM_INPUTS); |
909 | if (index >= 0) | 1177 | for (k = 0; k < num_cons; k++) |
910 | break; | 1178 | if (con_lst[k] == cfg->input_pins[i]) { |
911 | } | 1179 | index = k; |
912 | imux->items[imux->num_items].index = index; | 1180 | goto found; |
913 | imux->num_items++; | 1181 | } |
914 | } | 1182 | } |
1183 | continue; | ||
1184 | found: | ||
1185 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; | ||
1186 | imux->items[imux->num_items].index = index; | ||
1187 | imux->num_items++; | ||
915 | } | 1188 | } |
916 | 1189 | ||
917 | if (imux->num_items == 1) { | 1190 | if (imux->num_items == 1) { |
@@ -944,11 +1217,20 @@ static void stac92xx_auto_init_multi_out(struct hda_codec *codec) | |||
944 | static void stac92xx_auto_init_hp_out(struct hda_codec *codec) | 1217 | static void stac92xx_auto_init_hp_out(struct hda_codec *codec) |
945 | { | 1218 | { |
946 | struct sigmatel_spec *spec = codec->spec; | 1219 | struct sigmatel_spec *spec = codec->spec; |
947 | hda_nid_t pin; | 1220 | int i; |
948 | 1221 | ||
949 | pin = spec->autocfg.hp_pin; | 1222 | for (i = 0; i < spec->autocfg.hp_outs; i++) { |
950 | if (pin) /* connect to front */ | 1223 | hda_nid_t pin; |
951 | stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); | 1224 | pin = spec->autocfg.hp_pins[i]; |
1225 | if (pin) /* connect to front */ | ||
1226 | stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); | ||
1227 | } | ||
1228 | for (i = 0; i < spec->autocfg.speaker_outs; i++) { | ||
1229 | hda_nid_t pin; | ||
1230 | pin = spec->autocfg.speaker_pins[i]; | ||
1231 | if (pin) /* connect to front */ | ||
1232 | stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN); | ||
1233 | } | ||
952 | } | 1234 | } |
953 | 1235 | ||
954 | static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in) | 1236 | static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in) |
@@ -994,7 +1276,7 @@ static int stac9200_auto_create_hp_ctls(struct hda_codec *codec, | |||
994 | struct auto_pin_cfg *cfg) | 1276 | struct auto_pin_cfg *cfg) |
995 | { | 1277 | { |
996 | struct sigmatel_spec *spec = codec->spec; | 1278 | struct sigmatel_spec *spec = codec->spec; |
997 | hda_nid_t pin = cfg->hp_pin; | 1279 | hda_nid_t pin = cfg->hp_pins[0]; |
998 | unsigned int wid_caps; | 1280 | unsigned int wid_caps; |
999 | 1281 | ||
1000 | if (! pin) | 1282 | if (! pin) |
@@ -1007,6 +1289,57 @@ static int stac9200_auto_create_hp_ctls(struct hda_codec *codec, | |||
1007 | return 0; | 1289 | return 0; |
1008 | } | 1290 | } |
1009 | 1291 | ||
1292 | /* add playback controls for LFE output */ | ||
1293 | static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec, | ||
1294 | struct auto_pin_cfg *cfg) | ||
1295 | { | ||
1296 | struct sigmatel_spec *spec = codec->spec; | ||
1297 | int err; | ||
1298 | hda_nid_t lfe_pin = 0x0; | ||
1299 | int i; | ||
1300 | |||
1301 | /* | ||
1302 | * search speaker outs and line outs for a mono speaker pin | ||
1303 | * with an amp. If one is found, add LFE controls | ||
1304 | * for it. | ||
1305 | */ | ||
1306 | for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) { | ||
1307 | hda_nid_t pin = spec->autocfg.speaker_pins[i]; | ||
1308 | unsigned long wcaps = get_wcaps(codec, pin); | ||
1309 | wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); | ||
1310 | if (wcaps == AC_WCAP_OUT_AMP) | ||
1311 | /* found a mono speaker with an amp, must be lfe */ | ||
1312 | lfe_pin = pin; | ||
1313 | } | ||
1314 | |||
1315 | /* if speaker_outs is 0, then speakers may be in line_outs */ | ||
1316 | if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) { | ||
1317 | for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) { | ||
1318 | hda_nid_t pin = spec->autocfg.line_out_pins[i]; | ||
1319 | unsigned long cfg; | ||
1320 | cfg = snd_hda_codec_read(codec, pin, 0, | ||
1321 | AC_VERB_GET_CONFIG_DEFAULT, | ||
1322 | 0x00); | ||
1323 | if (get_defcfg_device(cfg) == AC_JACK_SPEAKER) { | ||
1324 | unsigned long wcaps = get_wcaps(codec, pin); | ||
1325 | wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); | ||
1326 | if (wcaps == AC_WCAP_OUT_AMP) | ||
1327 | /* found a mono speaker with an amp, | ||
1328 | must be lfe */ | ||
1329 | lfe_pin = pin; | ||
1330 | } | ||
1331 | } | ||
1332 | } | ||
1333 | |||
1334 | if (lfe_pin) { | ||
1335 | err = create_controls(spec, "LFE", lfe_pin, 1); | ||
1336 | if (err < 0) | ||
1337 | return err; | ||
1338 | } | ||
1339 | |||
1340 | return 0; | ||
1341 | } | ||
1342 | |||
1010 | static int stac9200_parse_auto_config(struct hda_codec *codec) | 1343 | static int stac9200_parse_auto_config(struct hda_codec *codec) |
1011 | { | 1344 | { |
1012 | struct sigmatel_spec *spec = codec->spec; | 1345 | struct sigmatel_spec *spec = codec->spec; |
@@ -1021,6 +1354,9 @@ static int stac9200_parse_auto_config(struct hda_codec *codec) | |||
1021 | if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0) | 1354 | if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0) |
1022 | return err; | 1355 | return err; |
1023 | 1356 | ||
1357 | if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0) | ||
1358 | return err; | ||
1359 | |||
1024 | if (spec->autocfg.dig_out_pin) | 1360 | if (spec->autocfg.dig_out_pin) |
1025 | spec->multiout.dig_out_nid = 0x05; | 1361 | spec->multiout.dig_out_nid = 0x05; |
1026 | if (spec->autocfg.dig_in_pin) | 1362 | if (spec->autocfg.dig_in_pin) |
@@ -1073,6 +1409,15 @@ static void stac922x_gpio_mute(struct hda_codec *codec, int pin, int muted) | |||
1073 | AC_VERB_SET_GPIO_DATA, gpiostate); | 1409 | AC_VERB_SET_GPIO_DATA, gpiostate); |
1074 | } | 1410 | } |
1075 | 1411 | ||
1412 | static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, | ||
1413 | unsigned int event) | ||
1414 | { | ||
1415 | if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) | ||
1416 | snd_hda_codec_write(codec, nid, 0, | ||
1417 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
1418 | (AC_USRSP_EN | event)); | ||
1419 | } | ||
1420 | |||
1076 | static int stac92xx_init(struct hda_codec *codec) | 1421 | static int stac92xx_init(struct hda_codec *codec) |
1077 | { | 1422 | { |
1078 | struct sigmatel_spec *spec = codec->spec; | 1423 | struct sigmatel_spec *spec = codec->spec; |
@@ -1084,9 +1429,10 @@ static int stac92xx_init(struct hda_codec *codec) | |||
1084 | /* set up pins */ | 1429 | /* set up pins */ |
1085 | if (spec->hp_detect) { | 1430 | if (spec->hp_detect) { |
1086 | /* Enable unsolicited responses on the HP widget */ | 1431 | /* Enable unsolicited responses on the HP widget */ |
1087 | snd_hda_codec_write(codec, cfg->hp_pin, 0, | 1432 | for (i = 0; i < cfg->hp_outs; i++) |
1088 | AC_VERB_SET_UNSOLICITED_ENABLE, | 1433 | enable_pin_detect(codec, cfg->hp_pins[i], |
1089 | STAC_UNSOL_ENABLE); | 1434 | STAC_HP_EVENT); |
1435 | stac92xx_auto_init_hp_out(codec); | ||
1090 | /* fake event to set up pins */ | 1436 | /* fake event to set up pins */ |
1091 | codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); | 1437 | codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); |
1092 | } else { | 1438 | } else { |
@@ -1131,6 +1477,9 @@ static void stac92xx_free(struct hda_codec *codec) | |||
1131 | kfree(spec->kctl_alloc); | 1477 | kfree(spec->kctl_alloc); |
1132 | } | 1478 | } |
1133 | 1479 | ||
1480 | if (spec->bios_pin_configs) | ||
1481 | kfree(spec->bios_pin_configs); | ||
1482 | |||
1134 | kfree(spec); | 1483 | kfree(spec); |
1135 | } | 1484 | } |
1136 | 1485 | ||
@@ -1139,6 +1488,8 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, | |||
1139 | { | 1488 | { |
1140 | unsigned int pin_ctl = snd_hda_codec_read(codec, nid, | 1489 | unsigned int pin_ctl = snd_hda_codec_read(codec, nid, |
1141 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); | 1490 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); |
1491 | if (flag == AC_PINCTL_OUT_EN && (pin_ctl & AC_PINCTL_IN_EN)) | ||
1492 | return; | ||
1142 | snd_hda_codec_write(codec, nid, 0, | 1493 | snd_hda_codec_write(codec, nid, 0, |
1143 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 1494 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
1144 | pin_ctl | flag); | 1495 | pin_ctl | flag); |
@@ -1154,33 +1505,57 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, | |||
1154 | pin_ctl & ~flag); | 1505 | pin_ctl & ~flag); |
1155 | } | 1506 | } |
1156 | 1507 | ||
1157 | static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) | 1508 | static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) |
1509 | { | ||
1510 | if (!nid) | ||
1511 | return 0; | ||
1512 | if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00) | ||
1513 | & (1 << 31)) | ||
1514 | return 1; | ||
1515 | return 0; | ||
1516 | } | ||
1517 | |||
1518 | static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) | ||
1158 | { | 1519 | { |
1159 | struct sigmatel_spec *spec = codec->spec; | 1520 | struct sigmatel_spec *spec = codec->spec; |
1160 | struct auto_pin_cfg *cfg = &spec->autocfg; | 1521 | struct auto_pin_cfg *cfg = &spec->autocfg; |
1161 | int i, presence; | 1522 | int i, presence; |
1162 | 1523 | ||
1163 | if ((res >> 26) != STAC_HP_EVENT) | 1524 | presence = 0; |
1164 | return; | 1525 | for (i = 0; i < cfg->hp_outs; i++) { |
1165 | 1526 | presence = get_pin_presence(codec, cfg->hp_pins[i]); | |
1166 | presence = snd_hda_codec_read(codec, cfg->hp_pin, 0, | 1527 | if (presence) |
1167 | AC_VERB_GET_PIN_SENSE, 0x00) >> 31; | 1528 | break; |
1529 | } | ||
1168 | 1530 | ||
1169 | if (presence) { | 1531 | if (presence) { |
1170 | /* disable lineouts, enable hp */ | 1532 | /* disable lineouts, enable hp */ |
1171 | for (i = 0; i < cfg->line_outs; i++) | 1533 | for (i = 0; i < cfg->line_outs; i++) |
1172 | stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], | 1534 | stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], |
1173 | AC_PINCTL_OUT_EN); | 1535 | AC_PINCTL_OUT_EN); |
1174 | stac92xx_set_pinctl(codec, cfg->hp_pin, AC_PINCTL_OUT_EN); | 1536 | for (i = 0; i < cfg->speaker_outs; i++) |
1537 | stac92xx_reset_pinctl(codec, cfg->speaker_pins[i], | ||
1538 | AC_PINCTL_OUT_EN); | ||
1175 | } else { | 1539 | } else { |
1176 | /* enable lineouts, disable hp */ | 1540 | /* enable lineouts, disable hp */ |
1177 | for (i = 0; i < cfg->line_outs; i++) | 1541 | for (i = 0; i < cfg->line_outs; i++) |
1178 | stac92xx_set_pinctl(codec, cfg->line_out_pins[i], | 1542 | stac92xx_set_pinctl(codec, cfg->line_out_pins[i], |
1179 | AC_PINCTL_OUT_EN); | 1543 | AC_PINCTL_OUT_EN); |
1180 | stac92xx_reset_pinctl(codec, cfg->hp_pin, AC_PINCTL_OUT_EN); | 1544 | for (i = 0; i < cfg->speaker_outs; i++) |
1545 | stac92xx_set_pinctl(codec, cfg->speaker_pins[i], | ||
1546 | AC_PINCTL_OUT_EN); | ||
1181 | } | 1547 | } |
1182 | } | 1548 | } |
1183 | 1549 | ||
1550 | static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) | ||
1551 | { | ||
1552 | switch (res >> 26) { | ||
1553 | case STAC_HP_EVENT: | ||
1554 | stac92xx_hp_detect(codec, res); | ||
1555 | break; | ||
1556 | } | ||
1557 | } | ||
1558 | |||
1184 | #ifdef CONFIG_PM | 1559 | #ifdef CONFIG_PM |
1185 | static int stac92xx_resume(struct hda_codec *codec) | 1560 | static int stac92xx_resume(struct hda_codec *codec) |
1186 | { | 1561 | { |
@@ -1188,6 +1563,7 @@ static int stac92xx_resume(struct hda_codec *codec) | |||
1188 | int i; | 1563 | int i; |
1189 | 1564 | ||
1190 | stac92xx_init(codec); | 1565 | stac92xx_init(codec); |
1566 | stac92xx_set_config_regs(codec); | ||
1191 | for (i = 0; i < spec->num_mixers; i++) | 1567 | for (i = 0; i < spec->num_mixers; i++) |
1192 | snd_hda_resume_ctls(codec, spec->mixers[i]); | 1568 | snd_hda_resume_ctls(codec, spec->mixers[i]); |
1193 | if (spec->multiout.dig_out_nid) | 1569 | if (spec->multiout.dig_out_nid) |
@@ -1220,12 +1596,18 @@ static int patch_stac9200(struct hda_codec *codec) | |||
1220 | return -ENOMEM; | 1596 | return -ENOMEM; |
1221 | 1597 | ||
1222 | codec->spec = spec; | 1598 | codec->spec = spec; |
1599 | spec->num_pins = 8; | ||
1600 | spec->pin_nids = stac9200_pin_nids; | ||
1223 | spec->board_config = snd_hda_check_board_config(codec, stac9200_cfg_tbl); | 1601 | spec->board_config = snd_hda_check_board_config(codec, stac9200_cfg_tbl); |
1224 | if (spec->board_config < 0) | 1602 | if (spec->board_config < 0) { |
1225 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); | 1603 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); |
1226 | else { | 1604 | err = stac92xx_save_bios_config_regs(codec); |
1227 | spec->num_pins = 8; | 1605 | if (err < 0) { |
1228 | spec->pin_nids = stac9200_pin_nids; | 1606 | stac92xx_free(codec); |
1607 | return err; | ||
1608 | } | ||
1609 | spec->pin_configs = spec->bios_pin_configs; | ||
1610 | } else { | ||
1229 | spec->pin_configs = stac9200_brd_tbl[spec->board_config]; | 1611 | spec->pin_configs = stac9200_brd_tbl[spec->board_config]; |
1230 | stac92xx_set_config_regs(codec); | 1612 | stac92xx_set_config_regs(codec); |
1231 | } | 1613 | } |
@@ -1261,13 +1643,19 @@ static int patch_stac922x(struct hda_codec *codec) | |||
1261 | return -ENOMEM; | 1643 | return -ENOMEM; |
1262 | 1644 | ||
1263 | codec->spec = spec; | 1645 | codec->spec = spec; |
1646 | spec->num_pins = 10; | ||
1647 | spec->pin_nids = stac922x_pin_nids; | ||
1264 | spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl); | 1648 | spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl); |
1265 | if (spec->board_config < 0) | 1649 | if (spec->board_config < 0) { |
1266 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " | 1650 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " |
1267 | "using BIOS defaults\n"); | 1651 | "using BIOS defaults\n"); |
1268 | else if (stac922x_brd_tbl[spec->board_config] != NULL) { | 1652 | err = stac92xx_save_bios_config_regs(codec); |
1269 | spec->num_pins = 10; | 1653 | if (err < 0) { |
1270 | spec->pin_nids = stac922x_pin_nids; | 1654 | stac92xx_free(codec); |
1655 | return err; | ||
1656 | } | ||
1657 | spec->pin_configs = spec->bios_pin_configs; | ||
1658 | } else if (stac922x_brd_tbl[spec->board_config] != NULL) { | ||
1271 | spec->pin_configs = stac922x_brd_tbl[spec->board_config]; | 1659 | spec->pin_configs = stac922x_brd_tbl[spec->board_config]; |
1272 | stac92xx_set_config_regs(codec); | 1660 | stac92xx_set_config_regs(codec); |
1273 | } | 1661 | } |
@@ -1281,25 +1669,6 @@ static int patch_stac922x(struct hda_codec *codec) | |||
1281 | 1669 | ||
1282 | spec->multiout.dac_nids = spec->dac_nids; | 1670 | spec->multiout.dac_nids = spec->dac_nids; |
1283 | 1671 | ||
1284 | switch (spec->board_config) { | ||
1285 | case STAC_D965_2112: | ||
1286 | spec->adc_nids = stac9227_adc_nids; | ||
1287 | spec->mux_nids = stac9227_mux_nids; | ||
1288 | #if 0 | ||
1289 | spec->multiout.dac_nids = d965_2112_dac_nids; | ||
1290 | spec->multiout.num_dacs = ARRAY_SIZE(d965_2112_dac_nids); | ||
1291 | #endif | ||
1292 | spec->init = d965_2112_core_init; | ||
1293 | spec->mixer = stac9227_mixer; | ||
1294 | break; | ||
1295 | case STAC_D965_284B: | ||
1296 | spec->adc_nids = stac9227_adc_nids; | ||
1297 | spec->mux_nids = stac9227_mux_nids; | ||
1298 | spec->init = stac9227_core_init; | ||
1299 | spec->mixer = stac9227_mixer; | ||
1300 | break; | ||
1301 | } | ||
1302 | |||
1303 | err = stac92xx_parse_auto_config(codec, 0x08, 0x09); | 1672 | err = stac92xx_parse_auto_config(codec, 0x08, 0x09); |
1304 | if (err < 0) { | 1673 | if (err < 0) { |
1305 | stac92xx_free(codec); | 1674 | stac92xx_free(codec); |
@@ -1324,26 +1693,94 @@ static int patch_stac927x(struct hda_codec *codec) | |||
1324 | return -ENOMEM; | 1693 | return -ENOMEM; |
1325 | 1694 | ||
1326 | codec->spec = spec; | 1695 | codec->spec = spec; |
1696 | spec->num_pins = 14; | ||
1697 | spec->pin_nids = stac927x_pin_nids; | ||
1327 | spec->board_config = snd_hda_check_board_config(codec, stac927x_cfg_tbl); | 1698 | spec->board_config = snd_hda_check_board_config(codec, stac927x_cfg_tbl); |
1328 | if (spec->board_config < 0) | 1699 | if (spec->board_config < 0) { |
1329 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n"); | 1700 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n"); |
1330 | else { | 1701 | err = stac92xx_save_bios_config_regs(codec); |
1331 | spec->num_pins = 14; | 1702 | if (err < 0) { |
1332 | spec->pin_nids = stac927x_pin_nids; | 1703 | stac92xx_free(codec); |
1704 | return err; | ||
1705 | } | ||
1706 | spec->pin_configs = spec->bios_pin_configs; | ||
1707 | } else if (stac927x_brd_tbl[spec->board_config] != NULL) { | ||
1333 | spec->pin_configs = stac927x_brd_tbl[spec->board_config]; | 1708 | spec->pin_configs = stac927x_brd_tbl[spec->board_config]; |
1334 | stac92xx_set_config_regs(codec); | 1709 | stac92xx_set_config_regs(codec); |
1335 | } | 1710 | } |
1336 | 1711 | ||
1337 | spec->adc_nids = stac927x_adc_nids; | 1712 | switch (spec->board_config) { |
1338 | spec->mux_nids = stac927x_mux_nids; | 1713 | case STAC_D965_3ST: |
1714 | spec->adc_nids = stac927x_adc_nids; | ||
1715 | spec->mux_nids = stac927x_mux_nids; | ||
1716 | spec->num_muxes = 3; | ||
1717 | spec->init = d965_core_init; | ||
1718 | spec->mixer = stac9227_mixer; | ||
1719 | break; | ||
1720 | case STAC_D965_5ST: | ||
1721 | spec->adc_nids = stac927x_adc_nids; | ||
1722 | spec->mux_nids = stac927x_mux_nids; | ||
1723 | spec->num_muxes = 3; | ||
1724 | spec->init = d965_core_init; | ||
1725 | spec->mixer = stac9227_mixer; | ||
1726 | break; | ||
1727 | default: | ||
1728 | spec->adc_nids = stac927x_adc_nids; | ||
1729 | spec->mux_nids = stac927x_mux_nids; | ||
1730 | spec->num_muxes = 3; | ||
1731 | spec->init = stac927x_core_init; | ||
1732 | spec->mixer = stac927x_mixer; | ||
1733 | } | ||
1734 | |||
1735 | spec->multiout.dac_nids = spec->dac_nids; | ||
1736 | |||
1737 | err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); | ||
1738 | if (err < 0) { | ||
1739 | stac92xx_free(codec); | ||
1740 | return err; | ||
1741 | } | ||
1742 | |||
1743 | codec->patch_ops = stac92xx_patch_ops; | ||
1744 | |||
1745 | return 0; | ||
1746 | } | ||
1747 | |||
1748 | static int patch_stac9205(struct hda_codec *codec) | ||
1749 | { | ||
1750 | struct sigmatel_spec *spec; | ||
1751 | int err; | ||
1752 | |||
1753 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
1754 | if (spec == NULL) | ||
1755 | return -ENOMEM; | ||
1756 | |||
1757 | codec->spec = spec; | ||
1758 | spec->num_pins = 14; | ||
1759 | spec->pin_nids = stac9205_pin_nids; | ||
1760 | spec->board_config = snd_hda_check_board_config(codec, stac9205_cfg_tbl); | ||
1761 | if (spec->board_config < 0) { | ||
1762 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); | ||
1763 | err = stac92xx_save_bios_config_regs(codec); | ||
1764 | if (err < 0) { | ||
1765 | stac92xx_free(codec); | ||
1766 | return err; | ||
1767 | } | ||
1768 | spec->pin_configs = spec->bios_pin_configs; | ||
1769 | } else { | ||
1770 | spec->pin_configs = stac9205_brd_tbl[spec->board_config]; | ||
1771 | stac92xx_set_config_regs(codec); | ||
1772 | } | ||
1773 | |||
1774 | spec->adc_nids = stac9205_adc_nids; | ||
1775 | spec->mux_nids = stac9205_mux_nids; | ||
1339 | spec->num_muxes = 3; | 1776 | spec->num_muxes = 3; |
1340 | 1777 | ||
1341 | spec->init = stac927x_core_init; | 1778 | spec->init = stac9205_core_init; |
1342 | spec->mixer = stac927x_mixer; | 1779 | spec->mixer = stac9205_mixer; |
1343 | 1780 | ||
1344 | spec->multiout.dac_nids = spec->dac_nids; | 1781 | spec->multiout.dac_nids = spec->dac_nids; |
1345 | 1782 | ||
1346 | err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); | 1783 | err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); |
1347 | if (err < 0) { | 1784 | if (err < 0) { |
1348 | stac92xx_free(codec); | 1785 | stac92xx_free(codec); |
1349 | return err; | 1786 | return err; |
@@ -1355,10 +1792,10 @@ static int patch_stac927x(struct hda_codec *codec) | |||
1355 | } | 1792 | } |
1356 | 1793 | ||
1357 | /* | 1794 | /* |
1358 | * STAC 7661(?) hack | 1795 | * STAC9872 hack |
1359 | */ | 1796 | */ |
1360 | 1797 | ||
1361 | /* static config for Sony VAIO FE550G */ | 1798 | /* static config for Sony VAIO FE550G and Sony VAIO AR */ |
1362 | static hda_nid_t vaio_dacs[] = { 0x2 }; | 1799 | static hda_nid_t vaio_dacs[] = { 0x2 }; |
1363 | #define VAIO_HP_DAC 0x5 | 1800 | #define VAIO_HP_DAC 0x5 |
1364 | static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ }; | 1801 | static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ }; |
@@ -1389,6 +1826,23 @@ static struct hda_verb vaio_init[] = { | |||
1389 | {} | 1826 | {} |
1390 | }; | 1827 | }; |
1391 | 1828 | ||
1829 | static struct hda_verb vaio_ar_init[] = { | ||
1830 | {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */ | ||
1831 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */ | ||
1832 | {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ | ||
1833 | {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ | ||
1834 | /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */ | ||
1835 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ | ||
1836 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x2}, /* mic-sel: 0a,0d,14,02 */ | ||
1837 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ | ||
1838 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ | ||
1839 | /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */ | ||
1840 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ | ||
1841 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */ | ||
1842 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ | ||
1843 | {} | ||
1844 | }; | ||
1845 | |||
1392 | /* bind volumes of both NID 0x02 and 0x05 */ | 1846 | /* bind volumes of both NID 0x02 and 0x05 */ |
1393 | static int vaio_master_vol_put(struct snd_kcontrol *kcontrol, | 1847 | static int vaio_master_vol_put(struct snd_kcontrol *kcontrol, |
1394 | struct snd_ctl_elem_value *ucontrol) | 1848 | struct snd_ctl_elem_value *ucontrol) |
@@ -1434,6 +1888,38 @@ static struct snd_kcontrol_new vaio_mixer[] = { | |||
1434 | .info = snd_hda_mixer_amp_volume_info, | 1888 | .info = snd_hda_mixer_amp_volume_info, |
1435 | .get = snd_hda_mixer_amp_volume_get, | 1889 | .get = snd_hda_mixer_amp_volume_get, |
1436 | .put = vaio_master_vol_put, | 1890 | .put = vaio_master_vol_put, |
1891 | .tlv = { .c = snd_hda_mixer_amp_tlv }, | ||
1892 | .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), | ||
1893 | }, | ||
1894 | { | ||
1895 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1896 | .name = "Master Playback Switch", | ||
1897 | .info = snd_hda_mixer_amp_switch_info, | ||
1898 | .get = snd_hda_mixer_amp_switch_get, | ||
1899 | .put = vaio_master_sw_put, | ||
1900 | .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), | ||
1901 | }, | ||
1902 | /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ | ||
1903 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), | ||
1904 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), | ||
1905 | { | ||
1906 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1907 | .name = "Capture Source", | ||
1908 | .count = 1, | ||
1909 | .info = stac92xx_mux_enum_info, | ||
1910 | .get = stac92xx_mux_enum_get, | ||
1911 | .put = stac92xx_mux_enum_put, | ||
1912 | }, | ||
1913 | {} | ||
1914 | }; | ||
1915 | |||
1916 | static struct snd_kcontrol_new vaio_ar_mixer[] = { | ||
1917 | { | ||
1918 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1919 | .name = "Master Playback Volume", | ||
1920 | .info = snd_hda_mixer_amp_volume_info, | ||
1921 | .get = snd_hda_mixer_amp_volume_get, | ||
1922 | .put = vaio_master_vol_put, | ||
1437 | .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), | 1923 | .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), |
1438 | }, | 1924 | }, |
1439 | { | 1925 | { |
@@ -1447,6 +1933,8 @@ static struct snd_kcontrol_new vaio_mixer[] = { | |||
1447 | /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ | 1933 | /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ |
1448 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), | 1934 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), |
1449 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), | 1935 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), |
1936 | /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT), | ||
1937 | HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/ | ||
1450 | { | 1938 | { |
1451 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1939 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1452 | .name = "Capture Source", | 1940 | .name = "Capture Source", |
@@ -1458,7 +1946,7 @@ static struct snd_kcontrol_new vaio_mixer[] = { | |||
1458 | {} | 1946 | {} |
1459 | }; | 1947 | }; |
1460 | 1948 | ||
1461 | static struct hda_codec_ops stac7661_patch_ops = { | 1949 | static struct hda_codec_ops stac9872_patch_ops = { |
1462 | .build_controls = stac92xx_build_controls, | 1950 | .build_controls = stac92xx_build_controls, |
1463 | .build_pcms = stac92xx_build_pcms, | 1951 | .build_pcms = stac92xx_build_pcms, |
1464 | .init = stac92xx_init, | 1952 | .init = stac92xx_init, |
@@ -1468,23 +1956,34 @@ static struct hda_codec_ops stac7661_patch_ops = { | |||
1468 | #endif | 1956 | #endif |
1469 | }; | 1957 | }; |
1470 | 1958 | ||
1471 | enum { STAC7661_VAIO }; | 1959 | enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */ |
1472 | 1960 | CXD9872RD_VAIO, | |
1473 | static struct hda_board_config stac7661_cfg_tbl[] = { | 1961 | /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */ |
1474 | { .modelname = "vaio", .config = STAC7661_VAIO }, | 1962 | STAC9872AK_VAIO, |
1963 | /* Unknown. id=0x83847661 and subsys=0x104D1200. */ | ||
1964 | STAC9872K_VAIO, | ||
1965 | /* AR Series. id=0x83847664 and subsys=104D1300 */ | ||
1966 | CXD9872AKD_VAIO | ||
1967 | }; | ||
1968 | |||
1969 | static struct hda_board_config stac9872_cfg_tbl[] = { | ||
1970 | { .modelname = "vaio", .config = CXD9872RD_VAIO }, | ||
1971 | { .modelname = "vaio-ar", .config = CXD9872AKD_VAIO }, | ||
1475 | { .pci_subvendor = 0x104d, .pci_subdevice = 0x81e6, | 1972 | { .pci_subvendor = 0x104d, .pci_subdevice = 0x81e6, |
1476 | .config = STAC7661_VAIO }, | 1973 | .config = CXD9872RD_VAIO }, |
1477 | { .pci_subvendor = 0x104d, .pci_subdevice = 0x81ef, | 1974 | { .pci_subvendor = 0x104d, .pci_subdevice = 0x81ef, |
1478 | .config = STAC7661_VAIO }, | 1975 | .config = CXD9872RD_VAIO }, |
1976 | { .pci_subvendor = 0x104d, .pci_subdevice = 0x81fd, | ||
1977 | .config = CXD9872AKD_VAIO }, | ||
1479 | {} | 1978 | {} |
1480 | }; | 1979 | }; |
1481 | 1980 | ||
1482 | static int patch_stac7661(struct hda_codec *codec) | 1981 | static int patch_stac9872(struct hda_codec *codec) |
1483 | { | 1982 | { |
1484 | struct sigmatel_spec *spec; | 1983 | struct sigmatel_spec *spec; |
1485 | int board_config; | 1984 | int board_config; |
1486 | 1985 | ||
1487 | board_config = snd_hda_check_board_config(codec, stac7661_cfg_tbl); | 1986 | board_config = snd_hda_check_board_config(codec, stac9872_cfg_tbl); |
1488 | if (board_config < 0) | 1987 | if (board_config < 0) |
1489 | /* unknown config, let generic-parser do its job... */ | 1988 | /* unknown config, let generic-parser do its job... */ |
1490 | return snd_hda_parse_generic_codec(codec); | 1989 | return snd_hda_parse_generic_codec(codec); |
@@ -1495,7 +1994,9 @@ static int patch_stac7661(struct hda_codec *codec) | |||
1495 | 1994 | ||
1496 | codec->spec = spec; | 1995 | codec->spec = spec; |
1497 | switch (board_config) { | 1996 | switch (board_config) { |
1498 | case STAC7661_VAIO: | 1997 | case CXD9872RD_VAIO: |
1998 | case STAC9872AK_VAIO: | ||
1999 | case STAC9872K_VAIO: | ||
1499 | spec->mixer = vaio_mixer; | 2000 | spec->mixer = vaio_mixer; |
1500 | spec->init = vaio_init; | 2001 | spec->init = vaio_init; |
1501 | spec->multiout.max_channels = 2; | 2002 | spec->multiout.max_channels = 2; |
@@ -1507,9 +2008,22 @@ static int patch_stac7661(struct hda_codec *codec) | |||
1507 | spec->input_mux = &vaio_mux; | 2008 | spec->input_mux = &vaio_mux; |
1508 | spec->mux_nids = vaio_mux_nids; | 2009 | spec->mux_nids = vaio_mux_nids; |
1509 | break; | 2010 | break; |
2011 | |||
2012 | case CXD9872AKD_VAIO: | ||
2013 | spec->mixer = vaio_ar_mixer; | ||
2014 | spec->init = vaio_ar_init; | ||
2015 | spec->multiout.max_channels = 2; | ||
2016 | spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs); | ||
2017 | spec->multiout.dac_nids = vaio_dacs; | ||
2018 | spec->multiout.hp_nid = VAIO_HP_DAC; | ||
2019 | spec->num_adcs = ARRAY_SIZE(vaio_adcs); | ||
2020 | spec->adc_nids = vaio_adcs; | ||
2021 | spec->input_mux = &vaio_mux; | ||
2022 | spec->mux_nids = vaio_mux_nids; | ||
2023 | break; | ||
1510 | } | 2024 | } |
1511 | 2025 | ||
1512 | codec->patch_ops = stac7661_patch_ops; | 2026 | codec->patch_ops = stac9872_patch_ops; |
1513 | return 0; | 2027 | return 0; |
1514 | } | 2028 | } |
1515 | 2029 | ||
@@ -1525,12 +2039,12 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { | |||
1525 | { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x }, | 2039 | { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x }, |
1526 | { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x }, | 2040 | { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x }, |
1527 | { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x }, | 2041 | { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x }, |
1528 | { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac922x }, | 2042 | { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x }, |
1529 | { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac922x }, | 2043 | { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x }, |
1530 | { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac922x }, | 2044 | { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x }, |
1531 | { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac922x }, | 2045 | { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x }, |
1532 | { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac922x }, | 2046 | { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x }, |
1533 | { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac922x }, | 2047 | { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x }, |
1534 | { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x }, | 2048 | { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x }, |
1535 | { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x }, | 2049 | { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x }, |
1536 | { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x }, | 2050 | { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x }, |
@@ -1541,6 +2055,20 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { | |||
1541 | { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, | 2055 | { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, |
1542 | { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, | 2056 | { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, |
1543 | { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, | 2057 | { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, |
1544 | { .id = 0x83847661, .name = "STAC7661", .patch = patch_stac7661 }, | 2058 | /* The following does not take into account .id=0x83847661 when subsys = |
2059 | * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are | ||
2060 | * currently not fully supported. | ||
2061 | */ | ||
2062 | { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 }, | ||
2063 | { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 }, | ||
2064 | { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 }, | ||
2065 | { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 }, | ||
2066 | { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 }, | ||
2067 | { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 }, | ||
2068 | { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 }, | ||
2069 | { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 }, | ||
2070 | { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 }, | ||
2071 | { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, | ||
2072 | { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, | ||
1545 | {} /* terminator */ | 2073 | {} /* terminator */ |
1546 | }; | 2074 | }; |