aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c1829
1 files changed, 687 insertions, 1142 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 3a8e58c483df..6a899e8fdd0c 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -208,12 +208,6 @@ enum {
208 ALC885_MBP3, 208 ALC885_MBP3,
209 ALC885_MB5, 209 ALC885_MB5,
210 ALC885_IMAC24, 210 ALC885_IMAC24,
211 ALC882_AUTO,
212 ALC882_MODEL_LAST,
213};
214
215/* ALC883 models */
216enum {
217 ALC883_3ST_2ch_DIG, 211 ALC883_3ST_2ch_DIG,
218 ALC883_3ST_6ch_DIG, 212 ALC883_3ST_6ch_DIG,
219 ALC883_3ST_6ch, 213 ALC883_3ST_6ch,
@@ -246,8 +240,8 @@ enum {
246 ALC889A_MB31, 240 ALC889A_MB31,
247 ALC1200_ASUS_P5Q, 241 ALC1200_ASUS_P5Q,
248 ALC883_SONY_VAIO_TT, 242 ALC883_SONY_VAIO_TT,
249 ALC883_AUTO, 243 ALC882_AUTO,
250 ALC883_MODEL_LAST, 244 ALC882_MODEL_LAST,
251}; 245};
252 246
253/* for GPIO Poll */ 247/* for GPIO Poll */
@@ -320,6 +314,8 @@ struct alc_spec {
320 struct snd_array kctls; 314 struct snd_array kctls;
321 struct hda_input_mux private_imux[3]; 315 struct hda_input_mux private_imux[3];
322 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 316 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
317 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
318 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
323 319
324 /* hooks */ 320 /* hooks */
325 void (*init_hook)(struct hda_codec *codec); 321 void (*init_hook)(struct hda_codec *codec);
@@ -6295,7 +6291,7 @@ static int patch_alc260(struct hda_codec *codec)
6295 6291
6296 6292
6297/* 6293/*
6298 * ALC882 support 6294 * ALC882/883/885/888/889 support
6299 * 6295 *
6300 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 6296 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6301 * configuration. Each pin widget can choose any input DACs and a mixer. 6297 * configuration. Each pin widget can choose any input DACs and a mixer.
@@ -6307,22 +6303,35 @@ static int patch_alc260(struct hda_codec *codec)
6307 */ 6303 */
6308#define ALC882_DIGOUT_NID 0x06 6304#define ALC882_DIGOUT_NID 0x06
6309#define ALC882_DIGIN_NID 0x0a 6305#define ALC882_DIGIN_NID 0x0a
6306#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
6307#define ALC883_DIGIN_NID ALC882_DIGIN_NID
6308#define ALC1200_DIGOUT_NID 0x10
6309
6310 6310
6311static struct hda_channel_mode alc882_ch_modes[1] = { 6311static struct hda_channel_mode alc882_ch_modes[1] = {
6312 { 8, NULL } 6312 { 8, NULL }
6313}; 6313};
6314 6314
6315/* DACs */
6315static hda_nid_t alc882_dac_nids[4] = { 6316static hda_nid_t alc882_dac_nids[4] = {
6316 /* front, rear, clfe, rear_surr */ 6317 /* front, rear, clfe, rear_surr */
6317 0x02, 0x03, 0x04, 0x05 6318 0x02, 0x03, 0x04, 0x05
6318}; 6319};
6320#define alc883_dac_nids alc882_dac_nids
6319 6321
6320/* identical with ALC880 */ 6322/* ADCs */
6321#define alc882_adc_nids alc880_adc_nids 6323#define alc882_adc_nids alc880_adc_nids
6322#define alc882_adc_nids_alt alc880_adc_nids_alt 6324#define alc882_adc_nids_alt alc880_adc_nids_alt
6325#define alc883_adc_nids alc882_adc_nids_alt
6326static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
6327static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
6328#define alc889_adc_nids alc880_adc_nids
6323 6329
6324static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; 6330static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6325static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; 6331static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6332#define alc883_capsrc_nids alc882_capsrc_nids_alt
6333static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6334#define alc889_capsrc_nids alc882_capsrc_nids
6326 6335
6327/* input MUX */ 6336/* input MUX */
6328/* FIXME: should be a matrix-type input source selection */ 6337/* FIXME: should be a matrix-type input source selection */
@@ -6337,6 +6346,8 @@ static struct hda_input_mux alc882_capture_source = {
6337 }, 6346 },
6338}; 6347};
6339 6348
6349#define alc883_capture_source alc882_capture_source
6350
6340static struct hda_input_mux mb5_capture_source = { 6351static struct hda_input_mux mb5_capture_source = {
6341 .num_items = 3, 6352 .num_items = 3,
6342 .items = { 6353 .items = {
@@ -6346,6 +6357,77 @@ static struct hda_input_mux mb5_capture_source = {
6346 }, 6357 },
6347}; 6358};
6348 6359
6360static struct hda_input_mux alc883_3stack_6ch_intel = {
6361 .num_items = 4,
6362 .items = {
6363 { "Mic", 0x1 },
6364 { "Front Mic", 0x0 },
6365 { "Line", 0x2 },
6366 { "CD", 0x4 },
6367 },
6368};
6369
6370static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6371 .num_items = 2,
6372 .items = {
6373 { "Mic", 0x1 },
6374 { "Line", 0x2 },
6375 },
6376};
6377
6378static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6379 .num_items = 4,
6380 .items = {
6381 { "Mic", 0x0 },
6382 { "iMic", 0x1 },
6383 { "Line", 0x2 },
6384 { "CD", 0x4 },
6385 },
6386};
6387
6388static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6389 .num_items = 2,
6390 .items = {
6391 { "Mic", 0x0 },
6392 { "Int Mic", 0x1 },
6393 },
6394};
6395
6396static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6397 .num_items = 3,
6398 .items = {
6399 { "Mic", 0x0 },
6400 { "Front Mic", 0x1 },
6401 { "Line", 0x4 },
6402 },
6403};
6404
6405static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6406 .num_items = 2,
6407 .items = {
6408 { "Mic", 0x0 },
6409 { "Line", 0x2 },
6410 },
6411};
6412
6413static struct hda_input_mux alc889A_mb31_capture_source = {
6414 .num_items = 2,
6415 .items = {
6416 { "Mic", 0x0 },
6417 /* Front Mic (0x01) unused */
6418 { "Line", 0x2 },
6419 /* Line 2 (0x03) unused */
6420 /* CD (0x04) unsused? */
6421 },
6422};
6423
6424/*
6425 * 2ch mode
6426 */
6427static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6428 { 2, NULL }
6429};
6430
6349/* 6431/*
6350 * 2ch mode 6432 * 2ch mode
6351 */ 6433 */
@@ -6358,6 +6440,18 @@ static struct hda_verb alc882_3ST_ch2_init[] = {
6358}; 6440};
6359 6441
6360/* 6442/*
6443 * 4ch mode
6444 */
6445static struct hda_verb alc882_3ST_ch4_init[] = {
6446 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6447 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6448 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6449 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6450 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6451 { } /* end */
6452};
6453
6454/*
6361 * 6ch mode 6455 * 6ch mode
6362 */ 6456 */
6363static struct hda_verb alc882_3ST_ch6_init[] = { 6457static struct hda_verb alc882_3ST_ch6_init[] = {
@@ -6370,11 +6464,14 @@ static struct hda_verb alc882_3ST_ch6_init[] = {
6370 { } /* end */ 6464 { } /* end */
6371}; 6465};
6372 6466
6373static struct hda_channel_mode alc882_3ST_6ch_modes[2] = { 6467static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
6374 { 2, alc882_3ST_ch2_init }, 6468 { 2, alc882_3ST_ch2_init },
6469 { 4, alc882_3ST_ch4_init },
6375 { 6, alc882_3ST_ch6_init }, 6470 { 6, alc882_3ST_ch6_init },
6376}; 6471};
6377 6472
6473#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
6474
6378/* 6475/*
6379 * 6ch mode 6476 * 6ch mode
6380 */ 6477 */
@@ -6462,6 +6559,143 @@ static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6462 { 6, alc885_mb5_ch6_init }, 6559 { 6, alc885_mb5_ch6_init },
6463}; 6560};
6464 6561
6562
6563/*
6564 * 2ch mode
6565 */
6566static struct hda_verb alc883_4ST_ch2_init[] = {
6567 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6568 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6569 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6570 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6571 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6572 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6573 { } /* end */
6574};
6575
6576/*
6577 * 4ch mode
6578 */
6579static struct hda_verb alc883_4ST_ch4_init[] = {
6580 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6581 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6582 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6583 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6584 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6585 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6586 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6587 { } /* end */
6588};
6589
6590/*
6591 * 6ch mode
6592 */
6593static struct hda_verb alc883_4ST_ch6_init[] = {
6594 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6595 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6596 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6597 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6598 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6599 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6600 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6601 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6602 { } /* end */
6603};
6604
6605/*
6606 * 8ch mode
6607 */
6608static struct hda_verb alc883_4ST_ch8_init[] = {
6609 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6610 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6611 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6612 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6613 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6614 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6615 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6616 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6617 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6618 { } /* end */
6619};
6620
6621static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
6622 { 2, alc883_4ST_ch2_init },
6623 { 4, alc883_4ST_ch4_init },
6624 { 6, alc883_4ST_ch6_init },
6625 { 8, alc883_4ST_ch8_init },
6626};
6627
6628
6629/*
6630 * 2ch mode
6631 */
6632static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6633 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6634 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6635 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6636 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6637 { } /* end */
6638};
6639
6640/*
6641 * 4ch mode
6642 */
6643static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6644 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6645 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6646 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6647 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6648 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6649 { } /* end */
6650};
6651
6652/*
6653 * 6ch mode
6654 */
6655static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6656 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6657 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6658 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6659 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6660 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6661 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6662 { } /* end */
6663};
6664
6665static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6666 { 2, alc883_3ST_ch2_intel_init },
6667 { 4, alc883_3ST_ch4_intel_init },
6668 { 6, alc883_3ST_ch6_intel_init },
6669};
6670
6671/*
6672 * 6ch mode
6673 */
6674static struct hda_verb alc883_sixstack_ch6_init[] = {
6675 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6676 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6677 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6678 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6679 { } /* end */
6680};
6681
6682/*
6683 * 8ch mode
6684 */
6685static struct hda_verb alc883_sixstack_ch8_init[] = {
6686 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6687 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6688 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6689 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6690 { } /* end */
6691};
6692
6693static struct hda_channel_mode alc883_sixstack_modes[2] = {
6694 { 6, alc883_sixstack_ch6_init },
6695 { 8, alc883_sixstack_ch8_init },
6696};
6697
6698
6465/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 6699/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6466 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 6700 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6467 */ 6701 */
@@ -6597,7 +6831,7 @@ static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6597 { } /* end */ 6831 { } /* end */
6598}; 6832};
6599 6833
6600static struct hda_verb alc882_init_verbs[] = { 6834static struct hda_verb alc882_base_init_verbs[] = {
6601 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 6835 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6602 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6836 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6603 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6837 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -6649,11 +6883,6 @@ static struct hda_verb alc882_init_verbs[] = {
6649 6883
6650 /* FIXME: use matrix-type input source selection */ 6884 /* FIXME: use matrix-type input source selection */
6651 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 6885 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6652 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6653 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6654 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6655 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6656 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6657 /* Input mixer2 */ 6886 /* Input mixer2 */
6658 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6887 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6659 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6888 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
@@ -6664,9 +6893,6 @@ static struct hda_verb alc882_init_verbs[] = {
6664 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6893 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6665 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6894 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6666 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6895 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6667 /* ADC1: mute amp left and right */
6668 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6669 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6670 /* ADC2: mute amp left and right */ 6896 /* ADC2: mute amp left and right */
6671 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6897 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6672 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 6898 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -6677,6 +6903,21 @@ static struct hda_verb alc882_init_verbs[] = {
6677 { } 6903 { }
6678}; 6904};
6679 6905
6906static struct hda_verb alc882_adc1_init_verbs[] = {
6907 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6908 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6909 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6910 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6911 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6912 /* ADC1: mute amp left and right */
6913 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6914 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6915 { }
6916};
6917
6918/* HACK - expand to two elements */
6919#define alc882_init_verbs alc882_base_init_verbs, alc882_adc1_init_verbs
6920
6680static struct hda_verb alc882_eapd_verbs[] = { 6921static struct hda_verb alc882_eapd_verbs[] = {
6681 /* change to EAPD mode */ 6922 /* change to EAPD mode */
6682 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 6923 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
@@ -6684,6 +6925,8 @@ static struct hda_verb alc882_eapd_verbs[] = {
6684 { } 6925 { }
6685}; 6926};
6686 6927
6928#define alc883_init_verbs alc882_base_init_verbs
6929
6687/* Mac Pro test */ 6930/* Mac Pro test */
6688static struct snd_kcontrol_new alc882_macpro_mixer[] = { 6931static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6689 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6932 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -7034,12 +7277,10 @@ static void alc885_imac24_init_hook(struct hda_codec *codec)
7034/* 7277/*
7035 * generic initialization of ADC, input mixers and output mixers 7278 * generic initialization of ADC, input mixers and output mixers
7036 */ 7279 */
7037static struct hda_verb alc882_auto_init_verbs[] = { 7280static struct hda_verb alc883_auto_init_verbs[] = {
7038 /* 7281 /*
7039 * Unmute ADC0-2 and set the default input to mic-in 7282 * Unmute ADC0-2 and set the default input to mic-in
7040 */ 7283 */
7041 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7042 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7043 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7284 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7044 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7285 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7045 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7286 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -7080,11 +7321,6 @@ static struct hda_verb alc882_auto_init_verbs[] = {
7080 7321
7081 /* FIXME: use matrix-type input source selection */ 7322 /* FIXME: use matrix-type input source selection */
7082 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7323 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7083 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7084 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7085 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7086 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7087 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7088 /* Input mixer2 */ 7324 /* Input mixer2 */
7089 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7325 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7090 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7326 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
@@ -7099,819 +7335,6 @@ static struct hda_verb alc882_auto_init_verbs[] = {
7099 { } 7335 { }
7100}; 7336};
7101 7337
7102#ifdef CONFIG_SND_HDA_POWER_SAVE
7103#define alc882_loopbacks alc880_loopbacks
7104#endif
7105
7106/* pcm configuration: identical with ALC880 */
7107#define alc882_pcm_analog_playback alc880_pcm_analog_playback
7108#define alc882_pcm_analog_capture alc880_pcm_analog_capture
7109#define alc882_pcm_digital_playback alc880_pcm_digital_playback
7110#define alc882_pcm_digital_capture alc880_pcm_digital_capture
7111
7112/*
7113 * configuration and preset
7114 */
7115static const char *alc882_models[ALC882_MODEL_LAST] = {
7116 [ALC882_3ST_DIG] = "3stack-dig",
7117 [ALC882_6ST_DIG] = "6stack-dig",
7118 [ALC882_ARIMA] = "arima",
7119 [ALC882_W2JC] = "w2jc",
7120 [ALC882_TARGA] = "targa",
7121 [ALC882_ASUS_A7J] = "asus-a7j",
7122 [ALC882_ASUS_A7M] = "asus-a7m",
7123 [ALC885_MACPRO] = "macpro",
7124 [ALC885_MB5] = "mb5",
7125 [ALC885_MBP3] = "mbp3",
7126 [ALC885_IMAC24] = "imac24",
7127 [ALC882_AUTO] = "auto",
7128};
7129
7130static struct snd_pci_quirk alc882_cfg_tbl[] = {
7131 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
7132 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
7133 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
7134 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
7135 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
7136 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7137 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
7138 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
7139 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
7140 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
7141 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
7142 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
7143 {}
7144};
7145
7146static struct alc_config_preset alc882_presets[] = {
7147 [ALC882_3ST_DIG] = {
7148 .mixers = { alc882_base_mixer },
7149 .init_verbs = { alc882_init_verbs },
7150 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7151 .dac_nids = alc882_dac_nids,
7152 .dig_out_nid = ALC882_DIGOUT_NID,
7153 .dig_in_nid = ALC882_DIGIN_NID,
7154 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7155 .channel_mode = alc882_ch_modes,
7156 .need_dac_fix = 1,
7157 .input_mux = &alc882_capture_source,
7158 },
7159 [ALC882_6ST_DIG] = {
7160 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
7161 .init_verbs = { alc882_init_verbs },
7162 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7163 .dac_nids = alc882_dac_nids,
7164 .dig_out_nid = ALC882_DIGOUT_NID,
7165 .dig_in_nid = ALC882_DIGIN_NID,
7166 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
7167 .channel_mode = alc882_sixstack_modes,
7168 .input_mux = &alc882_capture_source,
7169 },
7170 [ALC882_ARIMA] = {
7171 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
7172 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
7173 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7174 .dac_nids = alc882_dac_nids,
7175 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
7176 .channel_mode = alc882_sixstack_modes,
7177 .input_mux = &alc882_capture_source,
7178 },
7179 [ALC882_W2JC] = {
7180 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
7181 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7182 alc880_gpio1_init_verbs },
7183 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7184 .dac_nids = alc882_dac_nids,
7185 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7186 .channel_mode = alc880_threestack_modes,
7187 .need_dac_fix = 1,
7188 .input_mux = &alc882_capture_source,
7189 .dig_out_nid = ALC882_DIGOUT_NID,
7190 },
7191 [ALC885_MBP3] = {
7192 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
7193 .init_verbs = { alc885_mbp3_init_verbs,
7194 alc880_gpio1_init_verbs },
7195 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7196 .dac_nids = alc882_dac_nids,
7197 .channel_mode = alc885_mbp_6ch_modes,
7198 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
7199 .input_mux = &alc882_capture_source,
7200 .dig_out_nid = ALC882_DIGOUT_NID,
7201 .dig_in_nid = ALC882_DIGIN_NID,
7202 .unsol_event = alc_automute_amp_unsol_event,
7203 .init_hook = alc885_mbp3_init_hook,
7204 },
7205 [ALC885_MB5] = {
7206 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
7207 .init_verbs = { alc885_mb5_init_verbs,
7208 alc880_gpio1_init_verbs },
7209 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7210 .dac_nids = alc882_dac_nids,
7211 .channel_mode = alc885_mb5_6ch_modes,
7212 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
7213 .input_mux = &mb5_capture_source,
7214 .dig_out_nid = ALC882_DIGOUT_NID,
7215 .dig_in_nid = ALC882_DIGIN_NID,
7216 },
7217 [ALC885_MACPRO] = {
7218 .mixers = { alc882_macpro_mixer },
7219 .init_verbs = { alc882_macpro_init_verbs },
7220 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7221 .dac_nids = alc882_dac_nids,
7222 .dig_out_nid = ALC882_DIGOUT_NID,
7223 .dig_in_nid = ALC882_DIGIN_NID,
7224 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7225 .channel_mode = alc882_ch_modes,
7226 .input_mux = &alc882_capture_source,
7227 .init_hook = alc885_macpro_init_hook,
7228 },
7229 [ALC885_IMAC24] = {
7230 .mixers = { alc885_imac24_mixer },
7231 .init_verbs = { alc885_imac24_init_verbs },
7232 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7233 .dac_nids = alc882_dac_nids,
7234 .dig_out_nid = ALC882_DIGOUT_NID,
7235 .dig_in_nid = ALC882_DIGIN_NID,
7236 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7237 .channel_mode = alc882_ch_modes,
7238 .input_mux = &alc882_capture_source,
7239 .unsol_event = alc_automute_amp_unsol_event,
7240 .init_hook = alc885_imac24_init_hook,
7241 },
7242 [ALC882_TARGA] = {
7243 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
7244 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
7245 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7246 .dac_nids = alc882_dac_nids,
7247 .dig_out_nid = ALC882_DIGOUT_NID,
7248 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7249 .adc_nids = alc882_adc_nids,
7250 .capsrc_nids = alc882_capsrc_nids,
7251 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7252 .channel_mode = alc882_3ST_6ch_modes,
7253 .need_dac_fix = 1,
7254 .input_mux = &alc882_capture_source,
7255 .unsol_event = alc882_targa_unsol_event,
7256 .init_hook = alc882_targa_init_hook,
7257 },
7258 [ALC882_ASUS_A7J] = {
7259 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
7260 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
7261 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7262 .dac_nids = alc882_dac_nids,
7263 .dig_out_nid = ALC882_DIGOUT_NID,
7264 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7265 .adc_nids = alc882_adc_nids,
7266 .capsrc_nids = alc882_capsrc_nids,
7267 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7268 .channel_mode = alc882_3ST_6ch_modes,
7269 .need_dac_fix = 1,
7270 .input_mux = &alc882_capture_source,
7271 },
7272 [ALC882_ASUS_A7M] = {
7273 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
7274 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7275 alc880_gpio1_init_verbs,
7276 alc882_asus_a7m_verbs },
7277 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7278 .dac_nids = alc882_dac_nids,
7279 .dig_out_nid = ALC882_DIGOUT_NID,
7280 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7281 .channel_mode = alc880_threestack_modes,
7282 .need_dac_fix = 1,
7283 .input_mux = &alc882_capture_source,
7284 },
7285};
7286
7287
7288/*
7289 * Pin config fixes
7290 */
7291enum {
7292 PINFIX_ABIT_AW9D_MAX
7293};
7294
7295static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
7296 { 0x15, 0x01080104 }, /* side */
7297 { 0x16, 0x01011012 }, /* rear */
7298 { 0x17, 0x01016011 }, /* clfe */
7299 { }
7300};
7301
7302static const struct alc_pincfg *alc882_pin_fixes[] = {
7303 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
7304};
7305
7306static struct snd_pci_quirk alc882_pinfix_tbl[] = {
7307 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
7308 {}
7309};
7310
7311/*
7312 * BIOS auto configuration
7313 */
7314static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
7315 hda_nid_t nid, int pin_type,
7316 int dac_idx)
7317{
7318 /* set as output */
7319 struct alc_spec *spec = codec->spec;
7320 int idx;
7321
7322 alc_set_pin_output(codec, nid, pin_type);
7323 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7324 idx = 4;
7325 else
7326 idx = spec->multiout.dac_nids[dac_idx] - 2;
7327 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7328
7329}
7330
7331static void alc882_auto_init_multi_out(struct hda_codec *codec)
7332{
7333 struct alc_spec *spec = codec->spec;
7334 int i;
7335
7336 for (i = 0; i <= HDA_SIDE; i++) {
7337 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7338 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7339 if (nid)
7340 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
7341 i);
7342 }
7343}
7344
7345static void alc882_auto_init_hp_out(struct hda_codec *codec)
7346{
7347 struct alc_spec *spec = codec->spec;
7348 hda_nid_t pin;
7349
7350 pin = spec->autocfg.hp_pins[0];
7351 if (pin) /* connect to front */
7352 /* use dac 0 */
7353 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7354 pin = spec->autocfg.speaker_pins[0];
7355 if (pin)
7356 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
7357}
7358
7359#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
7360#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
7361
7362static void alc882_auto_init_analog_input(struct hda_codec *codec)
7363{
7364 struct alc_spec *spec = codec->spec;
7365 int i;
7366
7367 for (i = 0; i < AUTO_PIN_LAST; i++) {
7368 hda_nid_t nid = spec->autocfg.input_pins[i];
7369 if (!nid)
7370 continue;
7371 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
7372 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
7373 snd_hda_codec_write(codec, nid, 0,
7374 AC_VERB_SET_AMP_GAIN_MUTE,
7375 AMP_OUT_MUTE);
7376 }
7377}
7378
7379static void alc882_auto_init_input_src(struct hda_codec *codec)
7380{
7381 struct alc_spec *spec = codec->spec;
7382 int c;
7383
7384 for (c = 0; c < spec->num_adc_nids; c++) {
7385 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
7386 hda_nid_t nid = spec->capsrc_nids[c];
7387 unsigned int mux_idx;
7388 const struct hda_input_mux *imux;
7389 int conns, mute, idx, item;
7390
7391 conns = snd_hda_get_connections(codec, nid, conn_list,
7392 ARRAY_SIZE(conn_list));
7393 if (conns < 0)
7394 continue;
7395 mux_idx = c >= spec->num_mux_defs ? 0 : c;
7396 imux = &spec->input_mux[mux_idx];
7397 for (idx = 0; idx < conns; idx++) {
7398 /* if the current connection is the selected one,
7399 * unmute it as default - otherwise mute it
7400 */
7401 mute = AMP_IN_MUTE(idx);
7402 for (item = 0; item < imux->num_items; item++) {
7403 if (imux->items[item].index == idx) {
7404 if (spec->cur_mux[c] == item)
7405 mute = AMP_IN_UNMUTE(idx);
7406 break;
7407 }
7408 }
7409 /* check if we have a selector or mixer
7410 * we could check for the widget type instead, but
7411 * just check for Amp-In presence (in case of mixer
7412 * without amp-in there is something wrong, this
7413 * function shouldn't be used or capsrc nid is wrong)
7414 */
7415 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
7416 snd_hda_codec_write(codec, nid, 0,
7417 AC_VERB_SET_AMP_GAIN_MUTE,
7418 mute);
7419 else if (mute != AMP_IN_MUTE(idx))
7420 snd_hda_codec_write(codec, nid, 0,
7421 AC_VERB_SET_CONNECT_SEL,
7422 idx);
7423 }
7424 }
7425}
7426
7427/* add mic boosts if needed */
7428static int alc_auto_add_mic_boost(struct hda_codec *codec)
7429{
7430 struct alc_spec *spec = codec->spec;
7431 int err;
7432 hda_nid_t nid;
7433
7434 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
7435 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7436 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7437 "Mic Boost",
7438 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7439 if (err < 0)
7440 return err;
7441 }
7442 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
7443 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7444 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7445 "Front Mic Boost",
7446 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7447 if (err < 0)
7448 return err;
7449 }
7450 return 0;
7451}
7452
7453/* almost identical with ALC880 parser... */
7454static int alc882_parse_auto_config(struct hda_codec *codec)
7455{
7456 struct alc_spec *spec = codec->spec;
7457 int err = alc880_parse_auto_config(codec);
7458
7459 if (err < 0)
7460 return err;
7461 else if (!err)
7462 return 0; /* no config found */
7463
7464 err = alc_auto_add_mic_boost(codec);
7465 if (err < 0)
7466 return err;
7467
7468 /* hack - override the init verbs */
7469 spec->init_verbs[0] = alc882_auto_init_verbs;
7470
7471 return 1; /* config found */
7472}
7473
7474/* additional initialization for auto-configuration model */
7475static void alc882_auto_init(struct hda_codec *codec)
7476{
7477 struct alc_spec *spec = codec->spec;
7478 alc882_auto_init_multi_out(codec);
7479 alc882_auto_init_hp_out(codec);
7480 alc882_auto_init_analog_input(codec);
7481 alc882_auto_init_input_src(codec);
7482 if (spec->unsol_event)
7483 alc_inithook(codec);
7484}
7485
7486static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7487
7488static int patch_alc882(struct hda_codec *codec)
7489{
7490 struct alc_spec *spec;
7491 int err, board_config;
7492
7493 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7494 if (spec == NULL)
7495 return -ENOMEM;
7496
7497 codec->spec = spec;
7498
7499 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7500 alc882_models,
7501 alc882_cfg_tbl);
7502
7503 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
7504 /* Pick up systems that don't supply PCI SSID */
7505 switch (codec->subsystem_id) {
7506 case 0x106b0c00: /* Mac Pro */
7507 board_config = ALC885_MACPRO;
7508 break;
7509 case 0x106b1000: /* iMac 24 */
7510 case 0x106b2800: /* AppleTV */
7511 case 0x106b3e00: /* iMac 24 Aluminium */
7512 board_config = ALC885_IMAC24;
7513 break;
7514 case 0x106b00a0: /* MacBookPro3,1 - Another revision */
7515 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7516 case 0x106b00a4: /* MacbookPro4,1 */
7517 case 0x106b2c00: /* Macbook Pro rev3 */
7518 /* Macbook 3.1 (0x106b3600) is handled by patch_alc883() */
7519 case 0x106b3800: /* MacbookPro4,1 - latter revision */
7520 board_config = ALC885_MBP3;
7521 break;
7522 case 0x106b3f00: /* Macbook 5,1 */
7523 case 0x106b4000: /* Macbook Pro 5,1 - FIXME: HP jack sense
7524 * seems not working, so apparently
7525 * no perfect solution yet
7526 */
7527 board_config = ALC885_MB5;
7528 break;
7529 default:
7530 /* ALC889A is handled better as ALC888-compatible */
7531 if (codec->revision_id == 0x100101 ||
7532 codec->revision_id == 0x100103) {
7533 alc_free(codec);
7534 return patch_alc883(codec);
7535 }
7536 printk(KERN_INFO "hda_codec: Unknown model for %s, "
7537 "trying auto-probe from BIOS...\n",
7538 codec->chip_name);
7539 board_config = ALC882_AUTO;
7540 }
7541 }
7542
7543 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7544
7545 if (board_config == ALC882_AUTO) {
7546 /* automatic parse from the BIOS config */
7547 err = alc882_parse_auto_config(codec);
7548 if (err < 0) {
7549 alc_free(codec);
7550 return err;
7551 } else if (!err) {
7552 printk(KERN_INFO
7553 "hda_codec: Cannot set up configuration "
7554 "from BIOS. Using base mode...\n");
7555 board_config = ALC882_3ST_DIG;
7556 }
7557 }
7558
7559 err = snd_hda_attach_beep_device(codec, 0x1);
7560 if (err < 0) {
7561 alc_free(codec);
7562 return err;
7563 }
7564
7565 if (board_config != ALC882_AUTO)
7566 setup_preset(spec, &alc882_presets[board_config]);
7567
7568 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7569 spec->stream_analog_capture = &alc882_pcm_analog_capture;
7570 /* FIXME: setup DAC5 */
7571 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7572 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
7573
7574 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7575 spec->stream_digital_capture = &alc882_pcm_digital_capture;
7576
7577 if (!spec->adc_nids && spec->input_mux) {
7578 /* check whether NID 0x07 is valid */
7579 unsigned int wcap = get_wcaps(codec, 0x07);
7580 /* get type */
7581 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7582 if (wcap != AC_WID_AUD_IN) {
7583 spec->adc_nids = alc882_adc_nids_alt;
7584 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
7585 spec->capsrc_nids = alc882_capsrc_nids_alt;
7586 } else {
7587 spec->adc_nids = alc882_adc_nids;
7588 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
7589 spec->capsrc_nids = alc882_capsrc_nids;
7590 }
7591 }
7592 set_capture_mixer(spec);
7593 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7594
7595 spec->vmaster_nid = 0x0c;
7596
7597 codec->patch_ops = alc_patch_ops;
7598 if (board_config == ALC882_AUTO)
7599 spec->init_hook = alc882_auto_init;
7600#ifdef CONFIG_SND_HDA_POWER_SAVE
7601 if (!spec->loopback.amplist)
7602 spec->loopback.amplist = alc882_loopbacks;
7603#endif
7604 codec->proc_widget_hook = print_realtek_coef;
7605
7606 return 0;
7607}
7608
7609/*
7610 * ALC883 support
7611 *
7612 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7613 * configuration. Each pin widget can choose any input DACs and a mixer.
7614 * Each ADC is connected from a mixer of all inputs. This makes possible
7615 * 6-channel independent captures.
7616 *
7617 * In addition, an independent DAC for the multi-playback (not used in this
7618 * driver yet).
7619 */
7620#define ALC883_DIGOUT_NID 0x06
7621#define ALC883_DIGIN_NID 0x0a
7622
7623#define ALC1200_DIGOUT_NID 0x10
7624
7625static hda_nid_t alc883_dac_nids[4] = {
7626 /* front, rear, clfe, rear_surr */
7627 0x02, 0x03, 0x04, 0x05
7628};
7629
7630static hda_nid_t alc883_adc_nids[2] = {
7631 /* ADC1-2 */
7632 0x08, 0x09,
7633};
7634
7635static hda_nid_t alc883_adc_nids_alt[1] = {
7636 /* ADC1 */
7637 0x08,
7638};
7639
7640static hda_nid_t alc883_adc_nids_rev[2] = {
7641 /* ADC2-1 */
7642 0x09, 0x08
7643};
7644
7645#define alc889_adc_nids alc880_adc_nids
7646
7647static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7648
7649static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7650
7651#define alc889_capsrc_nids alc882_capsrc_nids
7652
7653/* input MUX */
7654/* FIXME: should be a matrix-type input source selection */
7655
7656static struct hda_input_mux alc883_capture_source = {
7657 .num_items = 4,
7658 .items = {
7659 { "Mic", 0x0 },
7660 { "Front Mic", 0x1 },
7661 { "Line", 0x2 },
7662 { "CD", 0x4 },
7663 },
7664};
7665
7666static struct hda_input_mux alc883_3stack_6ch_intel = {
7667 .num_items = 4,
7668 .items = {
7669 { "Mic", 0x1 },
7670 { "Front Mic", 0x0 },
7671 { "Line", 0x2 },
7672 { "CD", 0x4 },
7673 },
7674};
7675
7676static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7677 .num_items = 2,
7678 .items = {
7679 { "Mic", 0x1 },
7680 { "Line", 0x2 },
7681 },
7682};
7683
7684static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7685 .num_items = 4,
7686 .items = {
7687 { "Mic", 0x0 },
7688 { "iMic", 0x1 },
7689 { "Line", 0x2 },
7690 { "CD", 0x4 },
7691 },
7692};
7693
7694static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7695 .num_items = 2,
7696 .items = {
7697 { "Mic", 0x0 },
7698 { "Int Mic", 0x1 },
7699 },
7700};
7701
7702static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7703 .num_items = 3,
7704 .items = {
7705 { "Mic", 0x0 },
7706 { "Front Mic", 0x1 },
7707 { "Line", 0x4 },
7708 },
7709};
7710
7711static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7712 .num_items = 2,
7713 .items = {
7714 { "Mic", 0x0 },
7715 { "Line", 0x2 },
7716 },
7717};
7718
7719static struct hda_input_mux alc889A_mb31_capture_source = {
7720 .num_items = 2,
7721 .items = {
7722 { "Mic", 0x0 },
7723 /* Front Mic (0x01) unused */
7724 { "Line", 0x2 },
7725 /* Line 2 (0x03) unused */
7726 /* CD (0x04) unsused? */
7727 },
7728};
7729
7730/*
7731 * 2ch mode
7732 */
7733static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7734 { 2, NULL }
7735};
7736
7737/*
7738 * 2ch mode
7739 */
7740static struct hda_verb alc883_3ST_ch2_init[] = {
7741 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7742 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7743 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7744 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7745 { } /* end */
7746};
7747
7748/*
7749 * 4ch mode
7750 */
7751static struct hda_verb alc883_3ST_ch4_init[] = {
7752 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7753 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7754 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7755 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7756 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7757 { } /* end */
7758};
7759
7760/*
7761 * 6ch mode
7762 */
7763static struct hda_verb alc883_3ST_ch6_init[] = {
7764 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7765 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7766 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7767 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7768 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7769 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7770 { } /* end */
7771};
7772
7773static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7774 { 2, alc883_3ST_ch2_init },
7775 { 4, alc883_3ST_ch4_init },
7776 { 6, alc883_3ST_ch6_init },
7777};
7778
7779
7780/*
7781 * 2ch mode
7782 */
7783static struct hda_verb alc883_4ST_ch2_init[] = {
7784 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7785 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7786 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7787 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7788 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7789 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7790 { } /* end */
7791};
7792
7793/*
7794 * 4ch mode
7795 */
7796static struct hda_verb alc883_4ST_ch4_init[] = {
7797 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7798 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7799 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7800 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7801 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7802 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7803 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7804 { } /* end */
7805};
7806
7807/*
7808 * 6ch mode
7809 */
7810static struct hda_verb alc883_4ST_ch6_init[] = {
7811 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7812 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7813 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7814 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7815 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7816 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7817 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7818 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7819 { } /* end */
7820};
7821
7822/*
7823 * 8ch mode
7824 */
7825static struct hda_verb alc883_4ST_ch8_init[] = {
7826 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7827 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7828 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7829 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7830 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7831 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7832 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7833 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7834 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7835 { } /* end */
7836};
7837
7838static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7839 { 2, alc883_4ST_ch2_init },
7840 { 4, alc883_4ST_ch4_init },
7841 { 6, alc883_4ST_ch6_init },
7842 { 8, alc883_4ST_ch8_init },
7843};
7844
7845
7846/*
7847 * 2ch mode
7848 */
7849static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7850 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7851 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7852 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7853 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7854 { } /* end */
7855};
7856
7857/*
7858 * 4ch mode
7859 */
7860static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7861 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7862 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7863 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7864 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7865 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7866 { } /* end */
7867};
7868
7869/*
7870 * 6ch mode
7871 */
7872static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7873 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7874 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7875 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7876 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7877 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7878 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7879 { } /* end */
7880};
7881
7882static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7883 { 2, alc883_3ST_ch2_intel_init },
7884 { 4, alc883_3ST_ch4_intel_init },
7885 { 6, alc883_3ST_ch6_intel_init },
7886};
7887
7888/*
7889 * 6ch mode
7890 */
7891static struct hda_verb alc883_sixstack_ch6_init[] = {
7892 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7893 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7894 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7895 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7896 { } /* end */
7897};
7898
7899/*
7900 * 8ch mode
7901 */
7902static struct hda_verb alc883_sixstack_ch8_init[] = {
7903 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7904 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7905 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7906 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7907 { } /* end */
7908};
7909
7910static struct hda_channel_mode alc883_sixstack_modes[2] = {
7911 { 6, alc883_sixstack_ch6_init },
7912 { 8, alc883_sixstack_ch8_init },
7913};
7914
7915/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ 7338/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7916static struct hda_verb alc889A_mb31_ch2_init[] = { 7339static struct hda_verb alc889A_mb31_ch2_init[] = {
7917 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 7340 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
@@ -7962,34 +7385,7 @@ static struct hda_verb alc883_medion_eapd_verbs[] = {
7962 { } 7385 { }
7963}; 7386};
7964 7387
7965/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 7388#define alc883_base_mixer alc882_base_mixer
7966 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7967 */
7968
7969static struct snd_kcontrol_new alc883_base_mixer[] = {
7970 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7971 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7972 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7973 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7974 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7975 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7976 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7977 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7978 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7979 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7980 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7981 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7982 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7983 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7984 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7985 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7986 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7987 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7988 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7989 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7990 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7991 { } /* end */
7992};
7993 7389
7994static struct snd_kcontrol_new alc883_mitac_mixer[] = { 7390static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7995 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7391 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -8340,84 +7736,6 @@ static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8340 { } /* end */ 7736 { } /* end */
8341}; 7737};
8342 7738
8343static struct hda_verb alc883_init_verbs[] = {
8344 /* ADC1: mute amp left and right */
8345 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8346 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8347 /* ADC2: mute amp left and right */
8348 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8349 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8350 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8351 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8352 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8353 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8354 /* Rear mixer */
8355 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8356 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8357 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8358 /* CLFE mixer */
8359 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8360 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8361 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8362 /* Side mixer */
8363 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8364 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8365 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8366
8367 /* mute analog input loopbacks */
8368 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8369 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8370 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8371 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8372 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8373
8374 /* Front Pin: output 0 (0x0c) */
8375 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8376 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8377 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8378 /* Rear Pin: output 1 (0x0d) */
8379 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8380 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8381 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8382 /* CLFE Pin: output 2 (0x0e) */
8383 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8384 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8385 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8386 /* Side Pin: output 3 (0x0f) */
8387 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8388 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8389 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8390 /* Mic (rear) pin: input vref at 80% */
8391 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8392 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8393 /* Front Mic pin: input vref at 80% */
8394 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8395 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8396 /* Line In pin: input */
8397 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8398 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8399 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8400 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8401 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8402 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8403 /* CD pin widget for input */
8404 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8405
8406 /* FIXME: use matrix-type input source selection */
8407 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8408 /* Input mixer2 */
8409 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8410 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8411 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8412 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8413 /* Input mixer3 */
8414 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8415 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8416 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8417 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8418 { }
8419};
8420
8421/* toggle speaker-output according to the hp-jack state */ 7739/* toggle speaker-output according to the hp-jack state */
8422static void alc883_mitac_init_hook(struct hda_codec *codec) 7740static void alc883_mitac_init_hook(struct hda_codec *codec)
8423{ 7741{
@@ -8850,69 +8168,6 @@ static void alc883_vaiott_init_hook(struct hda_codec *codec)
8850 alc_automute_amp(codec); 8168 alc_automute_amp(codec);
8851} 8169}
8852 8170
8853/*
8854 * generic initialization of ADC, input mixers and output mixers
8855 */
8856static struct hda_verb alc883_auto_init_verbs[] = {
8857 /*
8858 * Unmute ADC0-2 and set the default input to mic-in
8859 */
8860 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8861 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8862 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8863 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8864
8865 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8866 * mixer widget
8867 * Note: PASD motherboards uses the Line In 2 as the input for
8868 * front panel mic (mic 2)
8869 */
8870 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8871 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8872 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8873 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8874 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8875 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8876
8877 /*
8878 * Set up output mixers (0x0c - 0x0f)
8879 */
8880 /* set vol=0 to output mixers */
8881 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8882 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8883 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8884 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8885 /* set up input amps for analog loopback */
8886 /* Amp Indices: DAC = 0, mixer = 1 */
8887 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8888 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8889 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8890 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8891 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8892 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8893 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8894 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8895 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8896 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8897
8898 /* FIXME: use matrix-type input source selection */
8899 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8900 /* Input mixer1 */
8901 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8902 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8903 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8904 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8905 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8906 /* Input mixer2 */
8907 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8908 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8909 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8910 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8911 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8912
8913 { }
8914};
8915
8916static struct hda_verb alc888_asus_m90v_verbs[] = { 8171static struct hda_verb alc888_asus_m90v_verbs[] = {
8917 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8172 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8918 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8173 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -9023,25 +8278,44 @@ static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9023 alc889A_mb31_automute(codec); 8278 alc889A_mb31_automute(codec);
9024} 8279}
9025 8280
8281
9026#ifdef CONFIG_SND_HDA_POWER_SAVE 8282#ifdef CONFIG_SND_HDA_POWER_SAVE
9027#define alc883_loopbacks alc880_loopbacks 8283#define alc882_loopbacks alc880_loopbacks
9028#endif 8284#endif
9029 8285
9030/* pcm configuration: identical with ALC880 */ 8286/* pcm configuration: identical with ALC880 */
9031#define alc883_pcm_analog_playback alc880_pcm_analog_playback 8287#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9032#define alc883_pcm_analog_capture alc880_pcm_analog_capture 8288#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9033#define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 8289#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9034#define alc883_pcm_digital_playback alc880_pcm_digital_playback 8290#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9035#define alc883_pcm_digital_capture alc880_pcm_digital_capture 8291
8292static hda_nid_t alc883_slave_dig_outs[] = {
8293 ALC1200_DIGOUT_NID, 0,
8294};
8295
8296static hda_nid_t alc1200_slave_dig_outs[] = {
8297 ALC883_DIGOUT_NID, 0,
8298};
9036 8299
9037/* 8300/*
9038 * configuration and preset 8301 * configuration and preset
9039 */ 8302 */
9040static const char *alc883_models[ALC883_MODEL_LAST] = { 8303static const char *alc882_models[ALC882_MODEL_LAST] = {
9041 [ALC883_3ST_2ch_DIG] = "3stack-dig", 8304 [ALC882_3ST_DIG] = "3stack-dig",
8305 [ALC882_6ST_DIG] = "6stack-dig",
8306 [ALC882_ARIMA] = "arima",
8307 [ALC882_W2JC] = "w2jc",
8308 [ALC882_TARGA] = "targa",
8309 [ALC882_ASUS_A7J] = "asus-a7j",
8310 [ALC882_ASUS_A7M] = "asus-a7m",
8311 [ALC885_MACPRO] = "macpro",
8312 [ALC885_MB5] = "mb5",
8313 [ALC885_MBP3] = "mbp3",
8314 [ALC885_IMAC24] = "imac24",
8315 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
9042 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", 8316 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9043 [ALC883_3ST_6ch] = "3stack-6ch", 8317 [ALC883_3ST_6ch] = "3stack-6ch",
9044 [ALC883_6ST_DIG] = "6stack-dig", 8318 [ALC883_6ST_DIG] = "alc883-6stack-dig",
9045 [ALC883_TARGA_DIG] = "targa-dig", 8319 [ALC883_TARGA_DIG] = "targa-dig",
9046 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 8320 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
9047 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig", 8321 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
@@ -9068,11 +8342,12 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
9068 [ALC1200_ASUS_P5Q] = "asus-p5q", 8342 [ALC1200_ASUS_P5Q] = "asus-p5q",
9069 [ALC889A_MB31] = "mb31", 8343 [ALC889A_MB31] = "mb31",
9070 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt", 8344 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
9071 [ALC883_AUTO] = "auto", 8345 [ALC882_AUTO] = "auto",
9072}; 8346};
9073 8347
9074static struct snd_pci_quirk alc883_cfg_tbl[] = { 8348static struct snd_pci_quirk alc882_cfg_tbl[] = {
9075 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), 8349 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
8350
9076 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 8351 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
9077 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), 8352 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9078 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE), 8353 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
@@ -9087,8 +8362,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
9087 ALC888_ACER_ASPIRE_8930G), 8362 ALC888_ACER_ASPIRE_8930G),
9088 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", 8363 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9089 ALC888_ACER_ASPIRE_8930G), 8364 ALC888_ACER_ASPIRE_8930G),
9090 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO), 8365 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9091 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO), 8366 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
9092 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", 8367 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
9093 ALC888_ACER_ASPIRE_6530G), 8368 ALC888_ACER_ASPIRE_6530G),
9094 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", 8369 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
@@ -9097,30 +8372,44 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
9097 * model=auto should work fine now 8372 * model=auto should work fine now
9098 */ 8373 */
9099 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */ 8374 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
8375
9100 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 8376 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8377
9101 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 8378 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
9102 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 8379 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9103 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 8380 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9104 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), 8381 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
9105 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), 8382 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
9106 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP), 8383 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8384
8385 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
8386 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
8387 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
9107 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), 8388 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8389 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
8390 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
8391 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
9108 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 8392 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
9109 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), 8393 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
9110 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), 8394 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
9111 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), 8395 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8396
8397 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9112 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), 8398 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
9113 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), 8399 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
9114 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), 8400 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
9115 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), 8401 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9116 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), 8402 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
9117 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), 8403 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
9118 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 8404 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
9119 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG), 8405 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
8406
9120 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), 8407 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
9121 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), 8408 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
9122 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 8409 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8410 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
9123 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG), 8411 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8412 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
9124 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 8413 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
9125 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), 8414 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
9126 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), 8415 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
@@ -9142,11 +8431,13 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
9142 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 8431 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
9143 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), 8432 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9144 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), 8433 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8434
9145 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), 8435 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9146 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), 8436 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9147 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), 8437 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
9148 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), 8438 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
9149 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 8439 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8440 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
9150 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 8441 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
9151 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx", 8442 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
9152 ALC883_FUJITSU_PI2515), 8443 ALC883_FUJITSU_PI2515),
@@ -9161,24 +8452,175 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
9161 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), 8452 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9162 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), 8453 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9163 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 8454 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8455
9164 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), 8456 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9165 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), 8457 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
9166 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), 8458 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
9167 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL), 8459 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
9168 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), 8460 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9169 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9170 {}
9171};
9172 8461
9173static hda_nid_t alc883_slave_dig_outs[] = { 8462 {}
9174 ALC1200_DIGOUT_NID, 0,
9175}; 8463};
9176 8464
9177static hda_nid_t alc1200_slave_dig_outs[] = { 8465/* codec SSID table for Intel Mac */
9178 ALC883_DIGOUT_NID, 0, 8466static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
8467 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
8468 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
8469 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
8470 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
8471 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
8472 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
8473 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
8474 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
8475 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
8476 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
8477 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
8478 /* FIXME: HP jack sense seems not working for MBP 5,1, so apparently
8479 * no perfect solution yet
8480 */
8481 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
8482 {} /* terminator */
9179}; 8483};
9180 8484
9181static struct alc_config_preset alc883_presets[] = { 8485static struct alc_config_preset alc882_presets[] = {
8486 [ALC882_3ST_DIG] = {
8487 .mixers = { alc882_base_mixer },
8488 .init_verbs = { alc882_init_verbs },
8489 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8490 .dac_nids = alc882_dac_nids,
8491 .dig_out_nid = ALC882_DIGOUT_NID,
8492 .dig_in_nid = ALC882_DIGIN_NID,
8493 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8494 .channel_mode = alc882_ch_modes,
8495 .need_dac_fix = 1,
8496 .input_mux = &alc882_capture_source,
8497 },
8498 [ALC882_6ST_DIG] = {
8499 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8500 .init_verbs = { alc882_init_verbs },
8501 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8502 .dac_nids = alc882_dac_nids,
8503 .dig_out_nid = ALC882_DIGOUT_NID,
8504 .dig_in_nid = ALC882_DIGIN_NID,
8505 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8506 .channel_mode = alc882_sixstack_modes,
8507 .input_mux = &alc882_capture_source,
8508 },
8509 [ALC882_ARIMA] = {
8510 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8511 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
8512 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8513 .dac_nids = alc882_dac_nids,
8514 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8515 .channel_mode = alc882_sixstack_modes,
8516 .input_mux = &alc882_capture_source,
8517 },
8518 [ALC882_W2JC] = {
8519 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8520 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
8521 alc880_gpio1_init_verbs },
8522 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8523 .dac_nids = alc882_dac_nids,
8524 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
8525 .channel_mode = alc880_threestack_modes,
8526 .need_dac_fix = 1,
8527 .input_mux = &alc882_capture_source,
8528 .dig_out_nid = ALC882_DIGOUT_NID,
8529 },
8530 [ALC885_MBP3] = {
8531 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
8532 .init_verbs = { alc885_mbp3_init_verbs,
8533 alc880_gpio1_init_verbs },
8534 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8535 .dac_nids = alc882_dac_nids,
8536 .channel_mode = alc885_mbp_6ch_modes,
8537 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
8538 .input_mux = &alc882_capture_source,
8539 .dig_out_nid = ALC882_DIGOUT_NID,
8540 .dig_in_nid = ALC882_DIGIN_NID,
8541 .unsol_event = alc_automute_amp_unsol_event,
8542 .init_hook = alc885_mbp3_init_hook,
8543 },
8544 [ALC885_MB5] = {
8545 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
8546 .init_verbs = { alc885_mb5_init_verbs,
8547 alc880_gpio1_init_verbs },
8548 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8549 .dac_nids = alc882_dac_nids,
8550 .channel_mode = alc885_mb5_6ch_modes,
8551 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
8552 .input_mux = &mb5_capture_source,
8553 .dig_out_nid = ALC882_DIGOUT_NID,
8554 .dig_in_nid = ALC882_DIGIN_NID,
8555 },
8556 [ALC885_MACPRO] = {
8557 .mixers = { alc882_macpro_mixer },
8558 .init_verbs = { alc882_macpro_init_verbs },
8559 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8560 .dac_nids = alc882_dac_nids,
8561 .dig_out_nid = ALC882_DIGOUT_NID,
8562 .dig_in_nid = ALC882_DIGIN_NID,
8563 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8564 .channel_mode = alc882_ch_modes,
8565 .input_mux = &alc882_capture_source,
8566 .init_hook = alc885_macpro_init_hook,
8567 },
8568 [ALC885_IMAC24] = {
8569 .mixers = { alc885_imac24_mixer },
8570 .init_verbs = { alc885_imac24_init_verbs },
8571 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8572 .dac_nids = alc882_dac_nids,
8573 .dig_out_nid = ALC882_DIGOUT_NID,
8574 .dig_in_nid = ALC882_DIGIN_NID,
8575 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8576 .channel_mode = alc882_ch_modes,
8577 .input_mux = &alc882_capture_source,
8578 .unsol_event = alc_automute_amp_unsol_event,
8579 .init_hook = alc885_imac24_init_hook,
8580 },
8581 [ALC882_TARGA] = {
8582 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8583 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
8584 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8585 .dac_nids = alc882_dac_nids,
8586 .dig_out_nid = ALC882_DIGOUT_NID,
8587 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
8588 .adc_nids = alc882_adc_nids,
8589 .capsrc_nids = alc882_capsrc_nids,
8590 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
8591 .channel_mode = alc882_3ST_6ch_modes,
8592 .need_dac_fix = 1,
8593 .input_mux = &alc882_capture_source,
8594 .unsol_event = alc882_targa_unsol_event,
8595 .init_hook = alc882_targa_init_hook,
8596 },
8597 [ALC882_ASUS_A7J] = {
8598 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8599 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
8600 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8601 .dac_nids = alc882_dac_nids,
8602 .dig_out_nid = ALC882_DIGOUT_NID,
8603 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
8604 .adc_nids = alc882_adc_nids,
8605 .capsrc_nids = alc882_capsrc_nids,
8606 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
8607 .channel_mode = alc882_3ST_6ch_modes,
8608 .need_dac_fix = 1,
8609 .input_mux = &alc882_capture_source,
8610 },
8611 [ALC882_ASUS_A7M] = {
8612 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8613 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
8614 alc880_gpio1_init_verbs,
8615 alc882_asus_a7m_verbs },
8616 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8617 .dac_nids = alc882_dac_nids,
8618 .dig_out_nid = ALC882_DIGOUT_NID,
8619 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
8620 .channel_mode = alc880_threestack_modes,
8621 .need_dac_fix = 1,
8622 .input_mux = &alc882_capture_source,
8623 },
9182 [ALC883_3ST_2ch_DIG] = { 8624 [ALC883_3ST_2ch_DIG] = {
9183 .mixers = { alc883_3ST_2ch_mixer }, 8625 .mixers = { alc883_3ST_2ch_mixer },
9184 .init_verbs = { alc883_init_verbs }, 8626 .init_verbs = { alc883_init_verbs },
@@ -9613,9 +9055,32 @@ static struct alc_config_preset alc883_presets[] = {
9613 9055
9614 9056
9615/* 9057/*
9058 * Pin config fixes
9059 */
9060enum {
9061 PINFIX_ABIT_AW9D_MAX
9062};
9063
9064static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
9065 { 0x15, 0x01080104 }, /* side */
9066 { 0x16, 0x01011012 }, /* rear */
9067 { 0x17, 0x01016011 }, /* clfe */
9068 { }
9069};
9070
9071static const struct alc_pincfg *alc882_pin_fixes[] = {
9072 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
9073};
9074
9075static struct snd_pci_quirk alc882_pinfix_tbl[] = {
9076 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
9077 {}
9078};
9079
9080/*
9616 * BIOS auto configuration 9081 * BIOS auto configuration
9617 */ 9082 */
9618static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, 9083static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9619 hda_nid_t nid, int pin_type, 9084 hda_nid_t nid, int pin_type,
9620 int dac_idx) 9085 int dac_idx)
9621{ 9086{
@@ -9632,7 +9097,7 @@ static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
9632 9097
9633} 9098}
9634 9099
9635static void alc883_auto_init_multi_out(struct hda_codec *codec) 9100static void alc882_auto_init_multi_out(struct hda_codec *codec)
9636{ 9101{
9637 struct alc_spec *spec = codec->spec; 9102 struct alc_spec *spec = codec->spec;
9638 int i; 9103 int i;
@@ -9641,12 +9106,12 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec)
9641 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 9106 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9642 int pin_type = get_pin_type(spec->autocfg.line_out_type); 9107 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9643 if (nid) 9108 if (nid)
9644 alc883_auto_set_output_and_unmute(codec, nid, pin_type, 9109 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
9645 i); 9110 i);
9646 } 9111 }
9647} 9112}
9648 9113
9649static void alc883_auto_init_hp_out(struct hda_codec *codec) 9114static void alc882_auto_init_hp_out(struct hda_codec *codec)
9650{ 9115{
9651 struct alc_spec *spec = codec->spec; 9116 struct alc_spec *spec = codec->spec;
9652 hda_nid_t pin; 9117 hda_nid_t pin;
@@ -9654,42 +9119,114 @@ static void alc883_auto_init_hp_out(struct hda_codec *codec)
9654 pin = spec->autocfg.hp_pins[0]; 9119 pin = spec->autocfg.hp_pins[0];
9655 if (pin) /* connect to front */ 9120 if (pin) /* connect to front */
9656 /* use dac 0 */ 9121 /* use dac 0 */
9657 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 9122 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9658 pin = spec->autocfg.speaker_pins[0]; 9123 pin = spec->autocfg.speaker_pins[0];
9659 if (pin) 9124 if (pin)
9660 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 9125 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9661} 9126}
9662 9127
9663#define alc883_is_input_pin(nid) alc880_is_input_pin(nid) 9128#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
9664#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID 9129#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
9665 9130
9666static void alc883_auto_init_analog_input(struct hda_codec *codec) 9131static void alc882_auto_init_analog_input(struct hda_codec *codec)
9667{ 9132{
9668 struct alc_spec *spec = codec->spec; 9133 struct alc_spec *spec = codec->spec;
9669 int i; 9134 int i;
9670 9135
9671 for (i = 0; i < AUTO_PIN_LAST; i++) { 9136 for (i = 0; i < AUTO_PIN_LAST; i++) {
9672 hda_nid_t nid = spec->autocfg.input_pins[i]; 9137 hda_nid_t nid = spec->autocfg.input_pins[i];
9673 if (alc883_is_input_pin(nid)) { 9138 if (!nid)
9674 alc_set_input_pin(codec, nid, i); 9139 continue;
9675 if (nid != ALC883_PIN_CD_NID && 9140 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
9676 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 9141 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
9142 snd_hda_codec_write(codec, nid, 0,
9143 AC_VERB_SET_AMP_GAIN_MUTE,
9144 AMP_OUT_MUTE);
9145 }
9146}
9147
9148static void alc882_auto_init_input_src(struct hda_codec *codec)
9149{
9150 struct alc_spec *spec = codec->spec;
9151 int c;
9152
9153 for (c = 0; c < spec->num_adc_nids; c++) {
9154 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
9155 hda_nid_t nid = spec->capsrc_nids[c];
9156 unsigned int mux_idx;
9157 const struct hda_input_mux *imux;
9158 int conns, mute, idx, item;
9159
9160 conns = snd_hda_get_connections(codec, nid, conn_list,
9161 ARRAY_SIZE(conn_list));
9162 if (conns < 0)
9163 continue;
9164 mux_idx = c >= spec->num_mux_defs ? 0 : c;
9165 imux = &spec->input_mux[mux_idx];
9166 for (idx = 0; idx < conns; idx++) {
9167 /* if the current connection is the selected one,
9168 * unmute it as default - otherwise mute it
9169 */
9170 mute = AMP_IN_MUTE(idx);
9171 for (item = 0; item < imux->num_items; item++) {
9172 if (imux->items[item].index == idx) {
9173 if (spec->cur_mux[c] == item)
9174 mute = AMP_IN_UNMUTE(idx);
9175 break;
9176 }
9177 }
9178 /* check if we have a selector or mixer
9179 * we could check for the widget type instead, but
9180 * just check for Amp-In presence (in case of mixer
9181 * without amp-in there is something wrong, this
9182 * function shouldn't be used or capsrc nid is wrong)
9183 */
9184 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9677 snd_hda_codec_write(codec, nid, 0, 9185 snd_hda_codec_write(codec, nid, 0,
9678 AC_VERB_SET_AMP_GAIN_MUTE, 9186 AC_VERB_SET_AMP_GAIN_MUTE,
9679 AMP_OUT_MUTE); 9187 mute);
9188 else if (mute != AMP_IN_MUTE(idx))
9189 snd_hda_codec_write(codec, nid, 0,
9190 AC_VERB_SET_CONNECT_SEL,
9191 idx);
9680 } 9192 }
9681 } 9193 }
9682} 9194}
9683 9195
9684#define alc883_auto_init_input_src alc882_auto_init_input_src 9196/* add mic boosts if needed */
9197static int alc_auto_add_mic_boost(struct hda_codec *codec)
9198{
9199 struct alc_spec *spec = codec->spec;
9200 int err;
9201 hda_nid_t nid;
9202
9203 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
9204 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9205 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9206 "Mic Boost",
9207 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9208 if (err < 0)
9209 return err;
9210 }
9211 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
9212 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9213 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9214 "Front Mic Boost",
9215 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9216 if (err < 0)
9217 return err;
9218 }
9219 return 0;
9220}
9685 9221
9686/* almost identical with ALC880 parser... */ 9222/* almost identical with ALC880 parser... */
9687static int alc883_parse_auto_config(struct hda_codec *codec) 9223static int alc882_parse_auto_config(struct hda_codec *codec)
9688{ 9224{
9689 struct alc_spec *spec = codec->spec; 9225 struct alc_spec *spec = codec->spec;
9690 int err = alc880_parse_auto_config(codec); 9226 struct auto_pin_cfg *autocfg = &spec->autocfg;
9691 struct auto_pin_cfg *cfg = &spec->autocfg; 9227 unsigned int wcap;
9692 int i; 9228 int i;
9229 int err = alc880_parse_auto_config(codec);
9693 9230
9694 if (err < 0) 9231 if (err < 0)
9695 return err; 9232 return err;
@@ -9702,43 +9239,45 @@ static int alc883_parse_auto_config(struct hda_codec *codec)
9702 9239
9703 /* hack - override the init verbs */ 9240 /* hack - override the init verbs */
9704 spec->init_verbs[0] = alc883_auto_init_verbs; 9241 spec->init_verbs[0] = alc883_auto_init_verbs;
9242 /* if ADC 0x07 is available, initialize it, too */
9243 wcap = get_wcaps(codec, 0x07);
9244 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9245 if (wcap == AC_WID_AUD_IN)
9246 add_verb(spec, alc882_adc1_init_verbs);
9705 9247
9706 /* setup input_mux for ALC889 */ 9248 /* digital-mic input pin is excluded in alc880_auto_create..()
9707 if (codec->vendor_id == 0x10ec0889) { 9249 * because it's under 0x18
9708 /* digital-mic input pin is excluded in alc880_auto_create..() 9250 */
9709 * because it's under 0x18 9251 if (autocfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9710 */ 9252 autocfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9711 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 || 9253 struct hda_input_mux *imux = &spec->private_imux[0];
9712 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) { 9254 for (i = 1; i < 3; i++)
9713 struct hda_input_mux *imux = &spec->private_imux[0]; 9255 memcpy(&spec->private_imux[i],
9714 for (i = 1; i < 3; i++) 9256 &spec->private_imux[0],
9715 memcpy(&spec->private_imux[i], 9257 sizeof(spec->private_imux[0]));
9716 &spec->private_imux[0], 9258 imux->items[imux->num_items].label = "Int DMic";
9717 sizeof(spec->private_imux[0])); 9259 imux->items[imux->num_items].index = 0x0b;
9718 imux->items[imux->num_items].label = "Int DMic"; 9260 imux->num_items++;
9719 imux->items[imux->num_items].index = 0x0b; 9261 spec->num_mux_defs = 3;
9720 imux->num_items++; 9262 spec->input_mux = spec->private_imux;
9721 spec->num_mux_defs = 3;
9722 spec->input_mux = spec->private_imux;
9723 }
9724 } 9263 }
9725 9264
9726 return 1; /* config found */ 9265 return 1; /* config found */
9727} 9266}
9728 9267
9729/* additional initialization for auto-configuration model */ 9268/* additional initialization for auto-configuration model */
9730static void alc883_auto_init(struct hda_codec *codec) 9269static void alc882_auto_init(struct hda_codec *codec)
9731{ 9270{
9732 struct alc_spec *spec = codec->spec; 9271 struct alc_spec *spec = codec->spec;
9733 alc883_auto_init_multi_out(codec); 9272 alc882_auto_init_multi_out(codec);
9734 alc883_auto_init_hp_out(codec); 9273 alc882_auto_init_hp_out(codec);
9735 alc883_auto_init_analog_input(codec); 9274 alc882_auto_init_analog_input(codec);
9736 alc883_auto_init_input_src(codec); 9275 alc882_auto_init_input_src(codec);
9737 if (spec->unsol_event) 9276 if (spec->unsol_event)
9738 alc_inithook(codec); 9277 alc_inithook(codec);
9739} 9278}
9740 9279
9741static int patch_alc883(struct hda_codec *codec) 9280static int patch_alc882(struct hda_codec *codec)
9742{ 9281{
9743 struct alc_spec *spec; 9282 struct alc_spec *spec;
9744 int err, board_config; 9283 int err, board_config;
@@ -9749,28 +9288,36 @@ static int patch_alc883(struct hda_codec *codec)
9749 9288
9750 codec->spec = spec; 9289 codec->spec = spec;
9751 9290
9752 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 9291 switch (codec->vendor_id) {
9292 case 0x10ec0882:
9293 case 0x10ec0885:
9294 break;
9295 default:
9296 /* ALC883 and variants */
9297 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9298 break;
9299 }
9753 9300
9754 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, 9301 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
9755 alc883_models, 9302 alc882_models,
9756 alc883_cfg_tbl); 9303 alc882_cfg_tbl);
9757 if (board_config < 0 || board_config >= ALC883_MODEL_LAST) { 9304
9758 /* Pick up systems that don't supply PCI SSID */ 9305 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
9759 switch (codec->subsystem_id) { 9306 board_config = snd_hda_check_board_codec_sid_config(codec,
9760 case 0x106b3600: /* Macbook 3.1 */ 9307 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
9761 board_config = ALC889A_MB31; 9308
9762 break; 9309 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9763 default: 9310 printk(KERN_INFO "hda_codec: Unknown model for %s, "
9764 printk(KERN_INFO 9311 "trying auto-probe from BIOS...\n",
9765 "hda_codec: Unknown model for %s, trying " 9312 codec->chip_name);
9766 "auto-probe from BIOS...\n", codec->chip_name); 9313 board_config = ALC882_AUTO;
9767 board_config = ALC883_AUTO;
9768 }
9769 } 9314 }
9770 9315
9771 if (board_config == ALC883_AUTO) { 9316 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
9317
9318 if (board_config == ALC882_AUTO) {
9772 /* automatic parse from the BIOS config */ 9319 /* automatic parse from the BIOS config */
9773 err = alc883_parse_auto_config(codec); 9320 err = alc882_parse_auto_config(codec);
9774 if (err < 0) { 9321 if (err < 0) {
9775 alc_free(codec); 9322 alc_free(codec);
9776 return err; 9323 return err;
@@ -9778,7 +9325,7 @@ static int patch_alc883(struct hda_codec *codec)
9778 printk(KERN_INFO 9325 printk(KERN_INFO
9779 "hda_codec: Cannot set up configuration " 9326 "hda_codec: Cannot set up configuration "
9780 "from BIOS. Using base mode...\n"); 9327 "from BIOS. Using base mode...\n");
9781 board_config = ALC883_3ST_2ch_DIG; 9328 board_config = ALC882_3ST_DIG;
9782 } 9329 }
9783 } 9330 }
9784 9331
@@ -9788,63 +9335,61 @@ static int patch_alc883(struct hda_codec *codec)
9788 return err; 9335 return err;
9789 } 9336 }
9790 9337
9791 if (board_config != ALC883_AUTO) 9338 if (board_config != ALC882_AUTO)
9792 setup_preset(spec, &alc883_presets[board_config]); 9339 setup_preset(spec, &alc882_presets[board_config]);
9793 9340
9794 switch (codec->vendor_id) { 9341 spec->stream_analog_playback = &alc882_pcm_analog_playback;
9795 case 0x10ec0888: 9342 spec->stream_analog_capture = &alc882_pcm_analog_capture;
9796 if (!spec->num_adc_nids) { 9343 /* FIXME: setup DAC5 */
9797 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 9344 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
9798 spec->adc_nids = alc883_adc_nids; 9345 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
9799 } 9346
9800 if (!spec->capsrc_nids) 9347 spec->stream_digital_playback = &alc882_pcm_digital_playback;
9801 spec->capsrc_nids = alc883_capsrc_nids; 9348 spec->stream_digital_capture = &alc882_pcm_digital_capture;
9349
9350 if (codec->vendor_id == 0x10ec0888)
9802 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */ 9351 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9803 break; 9352
9804 case 0x10ec0889: 9353 if (!spec->adc_nids && spec->input_mux) {
9805 if (!spec->num_adc_nids) { 9354 int i;
9806 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids); 9355 spec->num_adc_nids = 0;
9807 spec->adc_nids = alc889_adc_nids; 9356 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
9808 } 9357 hda_nid_t cap;
9809 if (!spec->capsrc_nids) 9358 hda_nid_t nid = alc882_adc_nids[i];
9810 spec->capsrc_nids = alc889_capsrc_nids; 9359 unsigned int wcap = get_wcaps(codec, nid);
9811 break; 9360 /* get type */
9812 default: 9361 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9813 if (!spec->num_adc_nids) { 9362 if (wcap != AC_WID_AUD_IN)
9814 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 9363 continue;
9815 spec->adc_nids = alc883_adc_nids; 9364 spec->private_adc_nids[spec->num_adc_nids] = nid;
9365 err = snd_hda_get_connections(codec, nid, &cap, 1);
9366 if (err < 0)
9367 continue;
9368 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
9369 spec->num_adc_nids++;
9816 } 9370 }
9817 if (!spec->capsrc_nids) 9371 spec->adc_nids = spec->private_adc_nids;
9818 spec->capsrc_nids = alc883_capsrc_nids; 9372 spec->capsrc_nids = spec->private_capsrc_nids;
9819 break;
9820 } 9373 }
9821 9374
9822 spec->stream_analog_playback = &alc883_pcm_analog_playback; 9375 set_capture_mixer(spec);
9823 spec->stream_analog_capture = &alc883_pcm_analog_capture;
9824 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9825
9826 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9827 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9828
9829 if (!spec->cap_mixer)
9830 set_capture_mixer(spec);
9831 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 9376 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9832 9377
9833 spec->vmaster_nid = 0x0c; 9378 spec->vmaster_nid = 0x0c;
9834 9379
9835 codec->patch_ops = alc_patch_ops; 9380 codec->patch_ops = alc_patch_ops;
9836 if (board_config == ALC883_AUTO) 9381 if (board_config == ALC882_AUTO)
9837 spec->init_hook = alc883_auto_init; 9382 spec->init_hook = alc882_auto_init;
9838
9839#ifdef CONFIG_SND_HDA_POWER_SAVE 9383#ifdef CONFIG_SND_HDA_POWER_SAVE
9840 if (!spec->loopback.amplist) 9384 if (!spec->loopback.amplist)
9841 spec->loopback.amplist = alc883_loopbacks; 9385 spec->loopback.amplist = alc882_loopbacks;
9842#endif 9386#endif
9843 codec->proc_widget_hook = print_realtek_coef; 9387 codec->proc_widget_hook = print_realtek_coef;
9844 9388
9845 return 0; 9389 return 0;
9846} 9390}
9847 9391
9392
9848/* 9393/*
9849 * ALC262 support 9394 * ALC262 support
9850 */ 9395 */
@@ -17546,23 +17091,23 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
17546 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 17091 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17547 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 17092 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17548 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 17093 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17549 .patch = patch_alc883 }, 17094 .patch = patch_alc882 },
17550 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 17095 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17551 .patch = patch_alc662 }, 17096 .patch = patch_alc662 },
17552 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 17097 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17553 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 17098 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17554 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 17099 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17555 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, 17100 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
17556 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", 17101 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17557 .patch = patch_alc882 }, /* should be patch_alc883() in future */ 17102 .patch = patch_alc882 },
17558 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 17103 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17559 .patch = patch_alc882 }, /* should be patch_alc883() in future */ 17104 .patch = patch_alc882 },
17560 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 17105 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17561 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 }, 17106 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
17562 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 17107 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17563 .patch = patch_alc883 }, 17108 .patch = patch_alc882 },
17564 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, 17109 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
17565 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 }, 17110 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
17566 {} /* terminator */ 17111 {} /* terminator */
17567}; 17112};
17568 17113