diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 758 |
1 files changed, 566 insertions, 192 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cbde019d3d5..5e82acf77c5 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "hda_codec.h" | 33 | #include "hda_codec.h" |
34 | #include "hda_local.h" | 34 | #include "hda_local.h" |
35 | #include "hda_beep.h" | 35 | #include "hda_beep.h" |
36 | #include "hda_jack.h" | ||
36 | 37 | ||
37 | /* unsol event tags */ | 38 | /* unsol event tags */ |
38 | #define ALC_FRONT_EVENT 0x01 | 39 | #define ALC_FRONT_EVENT 0x01 |
@@ -183,6 +184,8 @@ struct alc_spec { | |||
183 | unsigned int single_input_src:1; | 184 | unsigned int single_input_src:1; |
184 | unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ | 185 | unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ |
185 | unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ | 186 | unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ |
187 | unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ | ||
188 | unsigned int use_jack_tbl:1; /* 1 for model=auto */ | ||
186 | 189 | ||
187 | /* auto-mute control */ | 190 | /* auto-mute control */ |
188 | int automute_mode; | 191 | int automute_mode; |
@@ -283,6 +286,8 @@ static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx) | |||
283 | spec->capsrc_nids[idx] : spec->adc_nids[idx]; | 286 | spec->capsrc_nids[idx] : spec->adc_nids[idx]; |
284 | } | 287 | } |
285 | 288 | ||
289 | static void call_update_outputs(struct hda_codec *codec); | ||
290 | |||
286 | /* select the given imux item; either unmute exclusively or select the route */ | 291 | /* select the given imux item; either unmute exclusively or select the route */ |
287 | static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | 292 | static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, |
288 | unsigned int idx, bool force) | 293 | unsigned int idx, bool force) |
@@ -297,6 +302,8 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
297 | imux = &spec->input_mux[mux_idx]; | 302 | imux = &spec->input_mux[mux_idx]; |
298 | if (!imux->num_items && mux_idx > 0) | 303 | if (!imux->num_items && mux_idx > 0) |
299 | imux = &spec->input_mux[0]; | 304 | imux = &spec->input_mux[0]; |
305 | if (!imux->num_items) | ||
306 | return 0; | ||
300 | 307 | ||
301 | if (idx >= imux->num_items) | 308 | if (idx >= imux->num_items) |
302 | idx = imux->num_items - 1; | 309 | idx = imux->num_items - 1; |
@@ -304,6 +311,19 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
304 | return 0; | 311 | return 0; |
305 | spec->cur_mux[adc_idx] = idx; | 312 | spec->cur_mux[adc_idx] = idx; |
306 | 313 | ||
314 | /* for shared I/O, change the pin-control accordingly */ | ||
315 | if (spec->shared_mic_hp) { | ||
316 | /* NOTE: this assumes that there are only two inputs, the | ||
317 | * first is the real internal mic and the second is HP jack. | ||
318 | */ | ||
319 | snd_hda_codec_write(codec, spec->autocfg.inputs[1].pin, 0, | ||
320 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
321 | spec->cur_mux[adc_idx] ? | ||
322 | PIN_VREF80 : PIN_HP); | ||
323 | spec->automute_speaker = !spec->cur_mux[adc_idx]; | ||
324 | call_update_outputs(codec); | ||
325 | } | ||
326 | |||
307 | if (spec->dyn_adc_switch) { | 327 | if (spec->dyn_adc_switch) { |
308 | alc_dyn_adc_pcm_resetup(codec, idx); | 328 | alc_dyn_adc_pcm_resetup(codec, idx); |
309 | adc_idx = spec->dyn_adc_idx[idx]; | 329 | adc_idx = spec->dyn_adc_idx[idx]; |
@@ -448,46 +468,6 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, | |||
448 | } | 468 | } |
449 | 469 | ||
450 | /* | 470 | /* |
451 | * Jack-reporting via input-jack layer | ||
452 | */ | ||
453 | |||
454 | /* initialization of jacks; currently checks only a few known pins */ | ||
455 | static int alc_init_jacks(struct hda_codec *codec) | ||
456 | { | ||
457 | #ifdef CONFIG_SND_HDA_INPUT_JACK | ||
458 | struct alc_spec *spec = codec->spec; | ||
459 | int err; | ||
460 | unsigned int hp_nid = spec->autocfg.hp_pins[0]; | ||
461 | unsigned int mic_nid = spec->ext_mic_pin; | ||
462 | unsigned int dock_nid = spec->dock_mic_pin; | ||
463 | |||
464 | if (hp_nid) { | ||
465 | err = snd_hda_input_jack_add(codec, hp_nid, | ||
466 | SND_JACK_HEADPHONE, NULL); | ||
467 | if (err < 0) | ||
468 | return err; | ||
469 | snd_hda_input_jack_report(codec, hp_nid); | ||
470 | } | ||
471 | |||
472 | if (mic_nid) { | ||
473 | err = snd_hda_input_jack_add(codec, mic_nid, | ||
474 | SND_JACK_MICROPHONE, NULL); | ||
475 | if (err < 0) | ||
476 | return err; | ||
477 | snd_hda_input_jack_report(codec, mic_nid); | ||
478 | } | ||
479 | if (dock_nid) { | ||
480 | err = snd_hda_input_jack_add(codec, dock_nid, | ||
481 | SND_JACK_MICROPHONE, NULL); | ||
482 | if (err < 0) | ||
483 | return err; | ||
484 | snd_hda_input_jack_report(codec, dock_nid); | ||
485 | } | ||
486 | #endif /* CONFIG_SND_HDA_INPUT_JACK */ | ||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | /* | ||
491 | * Jack detections for HP auto-mute and mic-switch | 471 | * Jack detections for HP auto-mute and mic-switch |
492 | */ | 472 | */ |
493 | 473 | ||
@@ -500,7 +480,6 @@ static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) | |||
500 | hda_nid_t nid = pins[i]; | 480 | hda_nid_t nid = pins[i]; |
501 | if (!nid) | 481 | if (!nid) |
502 | break; | 482 | break; |
503 | snd_hda_input_jack_report(codec, nid); | ||
504 | present |= snd_hda_jack_detect(codec, nid); | 483 | present |= snd_hda_jack_detect(codec, nid); |
505 | } | 484 | } |
506 | return present; | 485 | return present; |
@@ -552,7 +531,8 @@ static void update_outputs(struct hda_codec *codec) | |||
552 | * in general, HP pins/amps control should be enabled in all cases, | 531 | * in general, HP pins/amps control should be enabled in all cases, |
553 | * but currently set only for master_mute, just to be safe | 532 | * but currently set only for master_mute, just to be safe |
554 | */ | 533 | */ |
555 | do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), | 534 | if (!spec->shared_mic_hp) /* don't change HP-pin when shared with mic */ |
535 | do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), | ||
556 | spec->autocfg.hp_pins, spec->master_mute, true); | 536 | spec->autocfg.hp_pins, spec->master_mute, true); |
557 | 537 | ||
558 | if (!spec->automute_speaker) | 538 | if (!spec->automute_speaker) |
@@ -639,19 +619,18 @@ static void alc_mic_automute(struct hda_codec *codec) | |||
639 | alc_mux_select(codec, 0, spec->dock_mic_idx, false); | 619 | alc_mux_select(codec, 0, spec->dock_mic_idx, false); |
640 | else | 620 | else |
641 | alc_mux_select(codec, 0, spec->int_mic_idx, false); | 621 | alc_mux_select(codec, 0, spec->int_mic_idx, false); |
642 | |||
643 | snd_hda_input_jack_report(codec, pins[spec->ext_mic_idx]); | ||
644 | if (spec->dock_mic_idx >= 0) | ||
645 | snd_hda_input_jack_report(codec, pins[spec->dock_mic_idx]); | ||
646 | } | 622 | } |
647 | 623 | ||
648 | /* unsolicited event for HP jack sensing */ | 624 | /* unsolicited event for HP jack sensing */ |
649 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | 625 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) |
650 | { | 626 | { |
627 | struct alc_spec *spec = codec->spec; | ||
651 | if (codec->vendor_id == 0x10ec0880) | 628 | if (codec->vendor_id == 0x10ec0880) |
652 | res >>= 28; | 629 | res >>= 28; |
653 | else | 630 | else |
654 | res >>= 26; | 631 | res >>= 26; |
632 | if (spec->use_jack_tbl) | ||
633 | res = snd_hda_jack_get_action(codec, res); | ||
655 | switch (res) { | 634 | switch (res) { |
656 | case ALC_HP_EVENT: | 635 | case ALC_HP_EVENT: |
657 | alc_hp_automute(codec); | 636 | alc_hp_automute(codec); |
@@ -663,6 +642,7 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | |||
663 | alc_mic_automute(codec); | 642 | alc_mic_automute(codec); |
664 | break; | 643 | break; |
665 | } | 644 | } |
645 | snd_hda_jack_report_sync(codec); | ||
666 | } | 646 | } |
667 | 647 | ||
668 | /* call init functions of standard auto-mute helpers */ | 648 | /* call init functions of standard auto-mute helpers */ |
@@ -952,9 +932,7 @@ static void alc_init_automute(struct hda_codec *codec) | |||
952 | continue; | 932 | continue; |
953 | snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", | 933 | snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", |
954 | nid); | 934 | nid); |
955 | snd_hda_codec_write_cache(codec, nid, 0, | 935 | snd_hda_jack_detect_enable(codec, nid, ALC_HP_EVENT); |
956 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
957 | AC_USRSP_EN | ALC_HP_EVENT); | ||
958 | spec->detect_hp = 1; | 936 | spec->detect_hp = 1; |
959 | } | 937 | } |
960 | 938 | ||
@@ -966,9 +944,8 @@ static void alc_init_automute(struct hda_codec *codec) | |||
966 | continue; | 944 | continue; |
967 | snd_printdd("realtek: Enable Line-Out " | 945 | snd_printdd("realtek: Enable Line-Out " |
968 | "auto-muting on NID 0x%x\n", nid); | 946 | "auto-muting on NID 0x%x\n", nid); |
969 | snd_hda_codec_write_cache(codec, nid, 0, | 947 | snd_hda_jack_detect_enable(codec, nid, |
970 | AC_VERB_SET_UNSOLICITED_ENABLE, | 948 | ALC_FRONT_EVENT); |
971 | AC_USRSP_EN | ALC_FRONT_EVENT); | ||
972 | spec->detect_lo = 1; | 949 | spec->detect_lo = 1; |
973 | } | 950 | } |
974 | spec->automute_lo_possible = spec->detect_hp; | 951 | spec->automute_lo_possible = spec->detect_hp; |
@@ -1107,13 +1084,10 @@ static bool alc_auto_mic_check_imux(struct hda_codec *codec) | |||
1107 | return false; /* no corresponding imux */ | 1084 | return false; /* no corresponding imux */ |
1108 | } | 1085 | } |
1109 | 1086 | ||
1110 | snd_hda_codec_write_cache(codec, spec->ext_mic_pin, 0, | 1087 | snd_hda_jack_detect_enable(codec, spec->ext_mic_pin, ALC_MIC_EVENT); |
1111 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
1112 | AC_USRSP_EN | ALC_MIC_EVENT); | ||
1113 | if (spec->dock_mic_pin) | 1088 | if (spec->dock_mic_pin) |
1114 | snd_hda_codec_write_cache(codec, spec->dock_mic_pin, 0, | 1089 | snd_hda_jack_detect_enable(codec, spec->dock_mic_pin, |
1115 | AC_VERB_SET_UNSOLICITED_ENABLE, | 1090 | ALC_MIC_EVENT); |
1116 | AC_USRSP_EN | ALC_MIC_EVENT); | ||
1117 | 1091 | ||
1118 | spec->auto_mic_valid_imux = 1; | 1092 | spec->auto_mic_valid_imux = 1; |
1119 | spec->auto_mic = 1; | 1093 | spec->auto_mic = 1; |
@@ -1131,6 +1105,9 @@ static void alc_init_auto_mic(struct hda_codec *codec) | |||
1131 | hda_nid_t fixed, ext, dock; | 1105 | hda_nid_t fixed, ext, dock; |
1132 | int i; | 1106 | int i; |
1133 | 1107 | ||
1108 | if (spec->shared_mic_hp) | ||
1109 | return; /* no auto-mic for the shared I/O */ | ||
1110 | |||
1134 | spec->ext_mic_idx = spec->int_mic_idx = spec->dock_mic_idx = -1; | 1111 | spec->ext_mic_idx = spec->int_mic_idx = spec->dock_mic_idx = -1; |
1135 | 1112 | ||
1136 | fixed = ext = dock = 0; | 1113 | fixed = ext = dock = 0; |
@@ -1522,6 +1499,7 @@ static void alc_pick_fixup(struct hda_codec *codec, | |||
1522 | const struct alc_fixup *fixlist) | 1499 | const struct alc_fixup *fixlist) |
1523 | { | 1500 | { |
1524 | struct alc_spec *spec = codec->spec; | 1501 | struct alc_spec *spec = codec->spec; |
1502 | const struct snd_pci_quirk *q; | ||
1525 | int id = -1; | 1503 | int id = -1; |
1526 | const char *name = NULL; | 1504 | const char *name = NULL; |
1527 | 1505 | ||
@@ -1536,12 +1514,25 @@ static void alc_pick_fixup(struct hda_codec *codec, | |||
1536 | } | 1514 | } |
1537 | } | 1515 | } |
1538 | if (id < 0) { | 1516 | if (id < 0) { |
1539 | quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); | 1517 | q = snd_pci_quirk_lookup(codec->bus->pci, quirk); |
1540 | if (quirk) { | 1518 | if (q) { |
1541 | id = quirk->value; | 1519 | id = q->value; |
1520 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
1521 | name = q->name; | ||
1522 | #endif | ||
1523 | } | ||
1524 | } | ||
1525 | if (id < 0) { | ||
1526 | for (q = quirk; q->subvendor; q++) { | ||
1527 | unsigned int vendorid = | ||
1528 | q->subdevice | (q->subvendor << 16); | ||
1529 | if (vendorid == codec->subsystem_id) { | ||
1530 | id = q->value; | ||
1542 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 1531 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
1543 | name = quirk->name; | 1532 | name = q->name; |
1544 | #endif | 1533 | #endif |
1534 | break; | ||
1535 | } | ||
1545 | } | 1536 | } |
1546 | } | 1537 | } |
1547 | 1538 | ||
@@ -2038,6 +2029,10 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2038 | 2029 | ||
2039 | alc_free_kctls(codec); /* no longer needed */ | 2030 | alc_free_kctls(codec); /* no longer needed */ |
2040 | 2031 | ||
2032 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | ||
2033 | if (err < 0) | ||
2034 | return err; | ||
2035 | |||
2041 | return 0; | 2036 | return 0; |
2042 | } | 2037 | } |
2043 | 2038 | ||
@@ -2065,6 +2060,8 @@ static int alc_init(struct hda_codec *codec) | |||
2065 | 2060 | ||
2066 | alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); | 2061 | alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); |
2067 | 2062 | ||
2063 | snd_hda_jack_report_sync(codec); | ||
2064 | |||
2068 | hda_call_check_power_status(codec, 0x01); | 2065 | hda_call_check_power_status(codec, 0x01); |
2069 | return 0; | 2066 | return 0; |
2070 | } | 2067 | } |
@@ -2448,7 +2445,6 @@ static void alc_free(struct hda_codec *codec) | |||
2448 | return; | 2445 | return; |
2449 | 2446 | ||
2450 | alc_shutup(codec); | 2447 | alc_shutup(codec); |
2451 | snd_hda_input_jack_free(codec); | ||
2452 | alc_free_kctls(codec); | 2448 | alc_free_kctls(codec); |
2453 | alc_free_bind_ctls(codec); | 2449 | alc_free_bind_ctls(codec); |
2454 | kfree(spec); | 2450 | kfree(spec); |
@@ -2629,6 +2625,8 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, | |||
2629 | case AUTO_PIN_SPEAKER_OUT: | 2625 | case AUTO_PIN_SPEAKER_OUT: |
2630 | if (cfg->line_outs == 1) | 2626 | if (cfg->line_outs == 1) |
2631 | return "Speaker"; | 2627 | return "Speaker"; |
2628 | if (cfg->line_outs == 2) | ||
2629 | return ch ? "Bass Speaker" : "Speaker"; | ||
2632 | break; | 2630 | break; |
2633 | case AUTO_PIN_HP_OUT: | 2631 | case AUTO_PIN_HP_OUT: |
2634 | /* for multi-io case, only the primary out */ | 2632 | /* for multi-io case, only the primary out */ |
@@ -2681,6 +2679,9 @@ static int alc_auto_fill_adc_caps(struct hda_codec *codec) | |||
2681 | int max_nums = ARRAY_SIZE(spec->private_adc_nids); | 2679 | int max_nums = ARRAY_SIZE(spec->private_adc_nids); |
2682 | int i, nums = 0; | 2680 | int i, nums = 0; |
2683 | 2681 | ||
2682 | if (spec->shared_mic_hp) | ||
2683 | max_nums = 1; /* no multi streams with the shared HP/mic */ | ||
2684 | |||
2684 | nid = codec->start_nid; | 2685 | nid = codec->start_nid; |
2685 | for (i = 0; i < codec->num_nodes; i++, nid++) { | 2686 | for (i = 0; i < codec->num_nodes; i++, nid++) { |
2686 | hda_nid_t src; | 2687 | hda_nid_t src; |
@@ -2743,6 +2744,8 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec) | |||
2743 | continue; | 2744 | continue; |
2744 | 2745 | ||
2745 | label = hda_get_autocfg_input_label(codec, cfg, i); | 2746 | label = hda_get_autocfg_input_label(codec, cfg, i); |
2747 | if (spec->shared_mic_hp && !strcmp(label, "Misc")) | ||
2748 | label = "Headphone Mic"; | ||
2746 | if (prev_label && !strcmp(label, prev_label)) | 2749 | if (prev_label && !strcmp(label, prev_label)) |
2747 | type_idx++; | 2750 | type_idx++; |
2748 | else | 2751 | else |
@@ -2777,6 +2780,39 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec) | |||
2777 | return 0; | 2780 | return 0; |
2778 | } | 2781 | } |
2779 | 2782 | ||
2783 | /* create a shared input with the headphone out */ | ||
2784 | static int alc_auto_create_shared_input(struct hda_codec *codec) | ||
2785 | { | ||
2786 | struct alc_spec *spec = codec->spec; | ||
2787 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
2788 | unsigned int defcfg; | ||
2789 | hda_nid_t nid; | ||
2790 | |||
2791 | /* only one internal input pin? */ | ||
2792 | if (cfg->num_inputs != 1) | ||
2793 | return 0; | ||
2794 | defcfg = snd_hda_codec_get_pincfg(codec, cfg->inputs[0].pin); | ||
2795 | if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT) | ||
2796 | return 0; | ||
2797 | |||
2798 | if (cfg->hp_outs == 1 && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
2799 | nid = cfg->hp_pins[0]; /* OK, we have a single HP-out */ | ||
2800 | else if (cfg->line_outs == 1 && cfg->line_out_type == AUTO_PIN_HP_OUT) | ||
2801 | nid = cfg->line_out_pins[0]; /* OK, we have a single line-out */ | ||
2802 | else | ||
2803 | return 0; /* both not available */ | ||
2804 | |||
2805 | if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_IN)) | ||
2806 | return 0; /* no input */ | ||
2807 | |||
2808 | cfg->inputs[1].pin = nid; | ||
2809 | cfg->inputs[1].type = AUTO_PIN_MIC; | ||
2810 | cfg->num_inputs = 2; | ||
2811 | spec->shared_mic_hp = 1; | ||
2812 | snd_printdd("realtek: Enable shared I/O jack on NID 0x%x\n", nid); | ||
2813 | return 0; | ||
2814 | } | ||
2815 | |||
2780 | static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, | 2816 | static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, |
2781 | unsigned int pin_type) | 2817 | unsigned int pin_type) |
2782 | { | 2818 | { |
@@ -2902,7 +2938,7 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) | |||
2902 | if (!nid) | 2938 | if (!nid) |
2903 | continue; | 2939 | continue; |
2904 | if (found_in_nid_list(nid, spec->multiout.dac_nids, | 2940 | if (found_in_nid_list(nid, spec->multiout.dac_nids, |
2905 | spec->multiout.num_dacs)) | 2941 | ARRAY_SIZE(spec->private_dac_nids))) |
2906 | continue; | 2942 | continue; |
2907 | if (found_in_nid_list(nid, spec->multiout.hp_out_nid, | 2943 | if (found_in_nid_list(nid, spec->multiout.hp_out_nid, |
2908 | ARRAY_SIZE(spec->multiout.hp_out_nid))) | 2944 | ARRAY_SIZE(spec->multiout.hp_out_nid))) |
@@ -2915,6 +2951,23 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) | |||
2915 | return 0; | 2951 | return 0; |
2916 | } | 2952 | } |
2917 | 2953 | ||
2954 | /* check whether the DAC is reachable from the pin */ | ||
2955 | static bool alc_auto_is_dac_reachable(struct hda_codec *codec, | ||
2956 | hda_nid_t pin, hda_nid_t dac) | ||
2957 | { | ||
2958 | hda_nid_t srcs[5]; | ||
2959 | int i, num; | ||
2960 | |||
2961 | pin = alc_go_down_to_selector(codec, pin); | ||
2962 | num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); | ||
2963 | for (i = 0; i < num; i++) { | ||
2964 | hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]); | ||
2965 | if (nid == dac) | ||
2966 | return true; | ||
2967 | } | ||
2968 | return false; | ||
2969 | } | ||
2970 | |||
2918 | static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) | 2971 | static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) |
2919 | { | 2972 | { |
2920 | hda_nid_t sel = alc_go_down_to_selector(codec, pin); | 2973 | hda_nid_t sel = alc_go_down_to_selector(codec, pin); |
@@ -2923,6 +2976,7 @@ static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) | |||
2923 | return 0; | 2976 | return 0; |
2924 | } | 2977 | } |
2925 | 2978 | ||
2979 | /* return 0 if no possible DAC is found, 1 if one or more found */ | ||
2926 | static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, | 2980 | static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, |
2927 | const hda_nid_t *pins, hda_nid_t *dacs) | 2981 | const hda_nid_t *pins, hda_nid_t *dacs) |
2928 | { | 2982 | { |
@@ -2940,17 +2994,21 @@ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, | |||
2940 | if (!dacs[i]) | 2994 | if (!dacs[i]) |
2941 | dacs[i] = alc_auto_look_for_dac(codec, pins[i]); | 2995 | dacs[i] = alc_auto_look_for_dac(codec, pins[i]); |
2942 | } | 2996 | } |
2943 | return 0; | 2997 | return 1; |
2944 | } | 2998 | } |
2945 | 2999 | ||
2946 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, | 3000 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, |
2947 | unsigned int location); | 3001 | unsigned int location, int offset); |
3002 | static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec, | ||
3003 | hda_nid_t pin, hda_nid_t dac); | ||
2948 | 3004 | ||
2949 | /* fill in the dac_nids table from the parsed pin configuration */ | 3005 | /* fill in the dac_nids table from the parsed pin configuration */ |
2950 | static int alc_auto_fill_dac_nids(struct hda_codec *codec) | 3006 | static int alc_auto_fill_dac_nids(struct hda_codec *codec) |
2951 | { | 3007 | { |
2952 | struct alc_spec *spec = codec->spec; | 3008 | struct alc_spec *spec = codec->spec; |
2953 | const struct auto_pin_cfg *cfg = &spec->autocfg; | 3009 | struct auto_pin_cfg *cfg = &spec->autocfg; |
3010 | unsigned int location, defcfg; | ||
3011 | int num_pins; | ||
2954 | bool redone = false; | 3012 | bool redone = false; |
2955 | int i; | 3013 | int i; |
2956 | 3014 | ||
@@ -2961,6 +3019,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
2961 | spec->multiout.extra_out_nid[0] = 0; | 3019 | spec->multiout.extra_out_nid[0] = 0; |
2962 | memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); | 3020 | memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); |
2963 | spec->multiout.dac_nids = spec->private_dac_nids; | 3021 | spec->multiout.dac_nids = spec->private_dac_nids; |
3022 | spec->multi_ios = 0; | ||
2964 | 3023 | ||
2965 | /* fill hard-wired DACs first */ | 3024 | /* fill hard-wired DACs first */ |
2966 | if (!redone) { | 3025 | if (!redone) { |
@@ -2994,21 +3053,20 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
2994 | for (i = 0; i < cfg->line_outs; i++) { | 3053 | for (i = 0; i < cfg->line_outs; i++) { |
2995 | if (spec->private_dac_nids[i]) | 3054 | if (spec->private_dac_nids[i]) |
2996 | spec->multiout.num_dacs++; | 3055 | spec->multiout.num_dacs++; |
2997 | else | 3056 | else { |
2998 | memmove(spec->private_dac_nids + i, | 3057 | memmove(spec->private_dac_nids + i, |
2999 | spec->private_dac_nids + i + 1, | 3058 | spec->private_dac_nids + i + 1, |
3000 | sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); | 3059 | sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); |
3060 | spec->private_dac_nids[cfg->line_outs - 1] = 0; | ||
3061 | } | ||
3001 | } | 3062 | } |
3002 | 3063 | ||
3003 | if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | 3064 | if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
3004 | /* try to fill multi-io first */ | 3065 | /* try to fill multi-io first */ |
3005 | unsigned int location, defcfg; | ||
3006 | int num_pins; | ||
3007 | |||
3008 | defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]); | 3066 | defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]); |
3009 | location = get_defcfg_location(defcfg); | 3067 | location = get_defcfg_location(defcfg); |
3010 | 3068 | ||
3011 | num_pins = alc_auto_fill_multi_ios(codec, location); | 3069 | num_pins = alc_auto_fill_multi_ios(codec, location, 0); |
3012 | if (num_pins > 0) { | 3070 | if (num_pins > 0) { |
3013 | spec->multi_ios = num_pins; | 3071 | spec->multi_ios = num_pins; |
3014 | spec->ext_channel_count = 2; | 3072 | spec->ext_channel_count = 2; |
@@ -3019,10 +3077,48 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
3019 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) | 3077 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) |
3020 | alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, | 3078 | alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, |
3021 | spec->multiout.hp_out_nid); | 3079 | spec->multiout.hp_out_nid); |
3022 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) | 3080 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
3023 | alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, cfg->speaker_pins, | 3081 | int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, |
3024 | spec->multiout.extra_out_nid); | 3082 | cfg->speaker_pins, |
3083 | spec->multiout.extra_out_nid); | ||
3084 | /* if no speaker volume is assigned, try again as the primary | ||
3085 | * output | ||
3086 | */ | ||
3087 | if (!err && cfg->speaker_outs > 0 && | ||
3088 | cfg->line_out_type == AUTO_PIN_HP_OUT) { | ||
3089 | cfg->hp_outs = cfg->line_outs; | ||
3090 | memcpy(cfg->hp_pins, cfg->line_out_pins, | ||
3091 | sizeof(cfg->hp_pins)); | ||
3092 | cfg->line_outs = cfg->speaker_outs; | ||
3093 | memcpy(cfg->line_out_pins, cfg->speaker_pins, | ||
3094 | sizeof(cfg->speaker_pins)); | ||
3095 | cfg->speaker_outs = 0; | ||
3096 | memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); | ||
3097 | cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; | ||
3098 | redone = false; | ||
3099 | goto again; | ||
3100 | } | ||
3101 | } | ||
3102 | |||
3103 | if (!spec->multi_ios && | ||
3104 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && | ||
3105 | cfg->hp_outs) { | ||
3106 | /* try multi-ios with HP + inputs */ | ||
3107 | defcfg = snd_hda_codec_get_pincfg(codec, cfg->hp_pins[0]); | ||
3108 | location = get_defcfg_location(defcfg); | ||
3025 | 3109 | ||
3110 | num_pins = alc_auto_fill_multi_ios(codec, location, 1); | ||
3111 | if (num_pins > 0) { | ||
3112 | spec->multi_ios = num_pins; | ||
3113 | spec->ext_channel_count = 2; | ||
3114 | spec->multiout.num_dacs = num_pins + 1; | ||
3115 | } | ||
3116 | } | ||
3117 | |||
3118 | if (cfg->line_out_pins[0]) | ||
3119 | spec->vmaster_nid = | ||
3120 | alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0], | ||
3121 | spec->multiout.dac_nids[0]); | ||
3026 | return 0; | 3122 | return 0; |
3027 | } | 3123 | } |
3028 | 3124 | ||
@@ -3054,8 +3150,15 @@ static int alc_auto_add_vol_ctl(struct hda_codec *codec, | |||
3054 | val); | 3150 | val); |
3055 | } | 3151 | } |
3056 | 3152 | ||
3057 | #define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \ | 3153 | static int alc_auto_add_stereo_vol(struct hda_codec *codec, |
3058 | alc_auto_add_vol_ctl(codec, pfx, cidx, nid, 3) | 3154 | const char *pfx, int cidx, |
3155 | hda_nid_t nid) | ||
3156 | { | ||
3157 | int chs = 1; | ||
3158 | if (get_wcaps(codec, nid) & AC_WCAP_STEREO) | ||
3159 | chs = 3; | ||
3160 | return alc_auto_add_vol_ctl(codec, pfx, cidx, nid, chs); | ||
3161 | } | ||
3059 | 3162 | ||
3060 | /* create a mute-switch for the given mixer widget; | 3163 | /* create a mute-switch for the given mixer widget; |
3061 | * if it has multiple sources (e.g. DAC and loopback), create a bind-mute | 3164 | * if it has multiple sources (e.g. DAC and loopback), create a bind-mute |
@@ -3087,8 +3190,14 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec, | |||
3087 | return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val); | 3190 | return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val); |
3088 | } | 3191 | } |
3089 | 3192 | ||
3090 | #define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \ | 3193 | static int alc_auto_add_stereo_sw(struct hda_codec *codec, const char *pfx, |
3091 | alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3) | 3194 | int cidx, hda_nid_t nid) |
3195 | { | ||
3196 | int chs = 1; | ||
3197 | if (get_wcaps(codec, nid) & AC_WCAP_STEREO) | ||
3198 | chs = 3; | ||
3199 | return alc_auto_add_sw_ctl(codec, pfx, cidx, nid, chs); | ||
3200 | } | ||
3092 | 3201 | ||
3093 | static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec, | 3202 | static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec, |
3094 | hda_nid_t pin, hda_nid_t dac) | 3203 | hda_nid_t pin, hda_nid_t dac) |
@@ -3171,7 +3280,8 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
3171 | } | 3280 | } |
3172 | 3281 | ||
3173 | static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | 3282 | static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, |
3174 | hda_nid_t dac, const char *pfx) | 3283 | hda_nid_t dac, const char *pfx, |
3284 | int cidx) | ||
3175 | { | 3285 | { |
3176 | struct alc_spec *spec = codec->spec; | 3286 | struct alc_spec *spec = codec->spec; |
3177 | hda_nid_t sw, vol; | 3287 | hda_nid_t sw, vol; |
@@ -3187,15 +3297,15 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | |||
3187 | if (is_ctl_used(spec->sw_ctls, val)) | 3297 | if (is_ctl_used(spec->sw_ctls, val)) |
3188 | return 0; /* already created */ | 3298 | return 0; /* already created */ |
3189 | mark_ctl_usage(spec->sw_ctls, val); | 3299 | mark_ctl_usage(spec->sw_ctls, val); |
3190 | return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val); | 3300 | return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val); |
3191 | } | 3301 | } |
3192 | 3302 | ||
3193 | sw = alc_look_for_out_mute_nid(codec, pin, dac); | 3303 | sw = alc_look_for_out_mute_nid(codec, pin, dac); |
3194 | vol = alc_look_for_out_vol_nid(codec, pin, dac); | 3304 | vol = alc_look_for_out_vol_nid(codec, pin, dac); |
3195 | err = alc_auto_add_stereo_vol(codec, pfx, 0, vol); | 3305 | err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol); |
3196 | if (err < 0) | 3306 | if (err < 0) |
3197 | return err; | 3307 | return err; |
3198 | err = alc_auto_add_stereo_sw(codec, pfx, 0, sw); | 3308 | err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw); |
3199 | if (err < 0) | 3309 | if (err < 0) |
3200 | return err; | 3310 | return err; |
3201 | return 0; | 3311 | return 0; |
@@ -3236,16 +3346,21 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins, | |||
3236 | hda_nid_t dac = *dacs; | 3346 | hda_nid_t dac = *dacs; |
3237 | if (!dac) | 3347 | if (!dac) |
3238 | dac = spec->multiout.dac_nids[0]; | 3348 | dac = spec->multiout.dac_nids[0]; |
3239 | return alc_auto_create_extra_out(codec, *pins, dac, pfx); | 3349 | return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0); |
3240 | } | 3350 | } |
3241 | 3351 | ||
3242 | if (dacs[num_pins - 1]) { | 3352 | if (dacs[num_pins - 1]) { |
3243 | /* OK, we have a multi-output system with individual volumes */ | 3353 | /* OK, we have a multi-output system with individual volumes */ |
3244 | for (i = 0; i < num_pins; i++) { | 3354 | for (i = 0; i < num_pins; i++) { |
3245 | snprintf(name, sizeof(name), "%s %s", | 3355 | if (num_pins >= 3) { |
3246 | pfx, channel_name[i]); | 3356 | snprintf(name, sizeof(name), "%s %s", |
3247 | err = alc_auto_create_extra_out(codec, pins[i], dacs[i], | 3357 | pfx, channel_name[i]); |
3248 | name); | 3358 | err = alc_auto_create_extra_out(codec, pins[i], dacs[i], |
3359 | name, 0); | ||
3360 | } else { | ||
3361 | err = alc_auto_create_extra_out(codec, pins[i], dacs[i], | ||
3362 | pfx, i); | ||
3363 | } | ||
3249 | if (err < 0) | 3364 | if (err < 0) |
3250 | return err; | 3365 | return err; |
3251 | } | 3366 | } |
@@ -3408,17 +3523,19 @@ static void alc_auto_init_extra_out(struct hda_codec *codec) | |||
3408 | * multi-io helper | 3523 | * multi-io helper |
3409 | */ | 3524 | */ |
3410 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, | 3525 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, |
3411 | unsigned int location) | 3526 | unsigned int location, |
3527 | int offset) | ||
3412 | { | 3528 | { |
3413 | struct alc_spec *spec = codec->spec; | 3529 | struct alc_spec *spec = codec->spec; |
3414 | struct auto_pin_cfg *cfg = &spec->autocfg; | 3530 | struct auto_pin_cfg *cfg = &spec->autocfg; |
3415 | hda_nid_t prime_dac = spec->private_dac_nids[0]; | 3531 | hda_nid_t prime_dac = spec->private_dac_nids[0]; |
3416 | int type, i, num_pins = 0; | 3532 | int type, i, dacs, num_pins = 0; |
3417 | 3533 | ||
3534 | dacs = spec->multiout.num_dacs; | ||
3418 | for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { | 3535 | for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { |
3419 | for (i = 0; i < cfg->num_inputs; i++) { | 3536 | for (i = 0; i < cfg->num_inputs; i++) { |
3420 | hda_nid_t nid = cfg->inputs[i].pin; | 3537 | hda_nid_t nid = cfg->inputs[i].pin; |
3421 | hda_nid_t dac; | 3538 | hda_nid_t dac = 0; |
3422 | unsigned int defcfg, caps; | 3539 | unsigned int defcfg, caps; |
3423 | if (cfg->inputs[i].type != type) | 3540 | if (cfg->inputs[i].type != type) |
3424 | continue; | 3541 | continue; |
@@ -3430,7 +3547,13 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec, | |||
3430 | caps = snd_hda_query_pin_caps(codec, nid); | 3547 | caps = snd_hda_query_pin_caps(codec, nid); |
3431 | if (!(caps & AC_PINCAP_OUT)) | 3548 | if (!(caps & AC_PINCAP_OUT)) |
3432 | continue; | 3549 | continue; |
3433 | dac = alc_auto_look_for_dac(codec, nid); | 3550 | if (offset && offset + num_pins < dacs) { |
3551 | dac = spec->private_dac_nids[offset + num_pins]; | ||
3552 | if (!alc_auto_is_dac_reachable(codec, nid, dac)) | ||
3553 | dac = 0; | ||
3554 | } | ||
3555 | if (!dac) | ||
3556 | dac = alc_auto_look_for_dac(codec, nid); | ||
3434 | if (!dac) | 3557 | if (!dac) |
3435 | continue; | 3558 | continue; |
3436 | spec->multi_io[num_pins].pin = nid; | 3559 | spec->multi_io[num_pins].pin = nid; |
@@ -3439,11 +3562,11 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec, | |||
3439 | spec->private_dac_nids[spec->multiout.num_dacs++] = dac; | 3562 | spec->private_dac_nids[spec->multiout.num_dacs++] = dac; |
3440 | } | 3563 | } |
3441 | } | 3564 | } |
3442 | spec->multiout.num_dacs = 1; | 3565 | spec->multiout.num_dacs = dacs; |
3443 | if (num_pins < 2) { | 3566 | if (num_pins < 2) { |
3444 | /* clear up again */ | 3567 | /* clear up again */ |
3445 | memset(spec->private_dac_nids, 0, | 3568 | memset(spec->private_dac_nids + dacs, 0, |
3446 | sizeof(spec->private_dac_nids)); | 3569 | sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - dacs)); |
3447 | spec->private_dac_nids[0] = prime_dac; | 3570 | spec->private_dac_nids[0] = prime_dac; |
3448 | return 0; | 3571 | return 0; |
3449 | } | 3572 | } |
@@ -3667,6 +3790,8 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec) | |||
3667 | char boost_label[32]; | 3790 | char boost_label[32]; |
3668 | 3791 | ||
3669 | label = hda_get_autocfg_input_label(codec, cfg, i); | 3792 | label = hda_get_autocfg_input_label(codec, cfg, i); |
3793 | if (spec->shared_mic_hp && !strcmp(label, "Misc")) | ||
3794 | label = "Headphone Mic"; | ||
3670 | if (prev_label && !strcmp(label, prev_label)) | 3795 | if (prev_label && !strcmp(label, prev_label)) |
3671 | type_idx++; | 3796 | type_idx++; |
3672 | else | 3797 | else |
@@ -3779,6 +3904,7 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
3779 | static void alc_auto_init_std(struct hda_codec *codec) | 3904 | static void alc_auto_init_std(struct hda_codec *codec) |
3780 | { | 3905 | { |
3781 | struct alc_spec *spec = codec->spec; | 3906 | struct alc_spec *spec = codec->spec; |
3907 | spec->use_jack_tbl = 1; | ||
3782 | alc_auto_init_multi_out(codec); | 3908 | alc_auto_init_multi_out(codec); |
3783 | alc_auto_init_extra_out(codec); | 3909 | alc_auto_init_extra_out(codec); |
3784 | alc_auto_init_analog_input(codec); | 3910 | alc_auto_init_analog_input(codec); |
@@ -3871,6 +3997,9 @@ static int alc_parse_auto_config(struct hda_codec *codec, | |||
3871 | err = alc_auto_create_speaker_out(codec); | 3997 | err = alc_auto_create_speaker_out(codec); |
3872 | if (err < 0) | 3998 | if (err < 0) |
3873 | return err; | 3999 | return err; |
4000 | err = alc_auto_create_shared_input(codec); | ||
4001 | if (err < 0) | ||
4002 | return err; | ||
3874 | err = alc_auto_create_input_ctls(codec); | 4003 | err = alc_auto_create_input_ctls(codec); |
3875 | if (err < 0) | 4004 | if (err < 0) |
3876 | return err; | 4005 | return err; |
@@ -3918,6 +4047,37 @@ static const struct hda_amp_list alc880_loopbacks[] = { | |||
3918 | #endif | 4047 | #endif |
3919 | 4048 | ||
3920 | /* | 4049 | /* |
4050 | * ALC880 fix-ups | ||
4051 | */ | ||
4052 | enum { | ||
4053 | ALC880_FIXUP_GPIO2, | ||
4054 | ALC880_FIXUP_MEDION_RIM, | ||
4055 | }; | ||
4056 | |||
4057 | static const struct alc_fixup alc880_fixups[] = { | ||
4058 | [ALC880_FIXUP_GPIO2] = { | ||
4059 | .type = ALC_FIXUP_VERBS, | ||
4060 | .v.verbs = alc_gpio2_init_verbs, | ||
4061 | }, | ||
4062 | [ALC880_FIXUP_MEDION_RIM] = { | ||
4063 | .type = ALC_FIXUP_VERBS, | ||
4064 | .v.verbs = (const struct hda_verb[]) { | ||
4065 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | ||
4066 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, | ||
4067 | { } | ||
4068 | }, | ||
4069 | .chained = true, | ||
4070 | .chain_id = ALC880_FIXUP_GPIO2, | ||
4071 | }, | ||
4072 | }; | ||
4073 | |||
4074 | static const struct snd_pci_quirk alc880_fixup_tbl[] = { | ||
4075 | SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), | ||
4076 | {} | ||
4077 | }; | ||
4078 | |||
4079 | |||
4080 | /* | ||
3921 | * board setups | 4081 | * board setups |
3922 | */ | 4082 | */ |
3923 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | 4083 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS |
@@ -3963,6 +4123,11 @@ static int patch_alc880(struct hda_codec *codec) | |||
3963 | } | 4123 | } |
3964 | 4124 | ||
3965 | if (board_config == ALC_MODEL_AUTO) { | 4125 | if (board_config == ALC_MODEL_AUTO) { |
4126 | alc_pick_fixup(codec, NULL, alc880_fixup_tbl, alc880_fixups); | ||
4127 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | ||
4128 | } | ||
4129 | |||
4130 | if (board_config == ALC_MODEL_AUTO) { | ||
3966 | /* automatic parse from the BIOS config */ | 4131 | /* automatic parse from the BIOS config */ |
3967 | err = alc880_parse_auto_config(codec); | 4132 | err = alc880_parse_auto_config(codec); |
3968 | if (err < 0) | 4133 | if (err < 0) |
@@ -3977,8 +4142,10 @@ static int patch_alc880(struct hda_codec *codec) | |||
3977 | #endif | 4142 | #endif |
3978 | } | 4143 | } |
3979 | 4144 | ||
3980 | if (board_config != ALC_MODEL_AUTO) | 4145 | if (board_config != ALC_MODEL_AUTO) { |
4146 | spec->vmaster_nid = 0x0c; | ||
3981 | setup_preset(codec, &alc880_presets[board_config]); | 4147 | setup_preset(codec, &alc880_presets[board_config]); |
4148 | } | ||
3982 | 4149 | ||
3983 | if (!spec->no_analog && !spec->adc_nids) { | 4150 | if (!spec->no_analog && !spec->adc_nids) { |
3984 | alc_auto_fill_adc_caps(codec); | 4151 | alc_auto_fill_adc_caps(codec); |
@@ -3996,7 +4163,7 @@ static int patch_alc880(struct hda_codec *codec) | |||
3996 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 4163 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
3997 | } | 4164 | } |
3998 | 4165 | ||
3999 | spec->vmaster_nid = 0x0c; | 4166 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
4000 | 4167 | ||
4001 | codec->patch_ops = alc_patch_ops; | 4168 | codec->patch_ops = alc_patch_ops; |
4002 | if (board_config == ALC_MODEL_AUTO) | 4169 | if (board_config == ALC_MODEL_AUTO) |
@@ -4104,8 +4271,10 @@ static int patch_alc260(struct hda_codec *codec) | |||
4104 | #endif | 4271 | #endif |
4105 | } | 4272 | } |
4106 | 4273 | ||
4107 | if (board_config != ALC_MODEL_AUTO) | 4274 | if (board_config != ALC_MODEL_AUTO) { |
4108 | setup_preset(codec, &alc260_presets[board_config]); | 4275 | setup_preset(codec, &alc260_presets[board_config]); |
4276 | spec->vmaster_nid = 0x08; | ||
4277 | } | ||
4109 | 4278 | ||
4110 | if (!spec->no_analog && !spec->adc_nids) { | 4279 | if (!spec->no_analog && !spec->adc_nids) { |
4111 | alc_auto_fill_adc_caps(codec); | 4280 | alc_auto_fill_adc_caps(codec); |
@@ -4125,8 +4294,6 @@ static int patch_alc260(struct hda_codec *codec) | |||
4125 | 4294 | ||
4126 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 4295 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
4127 | 4296 | ||
4128 | spec->vmaster_nid = 0x08; | ||
4129 | |||
4130 | codec->patch_ops = alc_patch_ops; | 4297 | codec->patch_ops = alc_patch_ops; |
4131 | if (board_config == ALC_MODEL_AUTO) | 4298 | if (board_config == ALC_MODEL_AUTO) |
4132 | spec->init_hook = alc_auto_init_std; | 4299 | spec->init_hook = alc_auto_init_std; |
@@ -4163,15 +4330,78 @@ static int patch_alc260(struct hda_codec *codec) | |||
4163 | * Pin config fixes | 4330 | * Pin config fixes |
4164 | */ | 4331 | */ |
4165 | enum { | 4332 | enum { |
4166 | PINFIX_ABIT_AW9D_MAX, | 4333 | ALC882_FIXUP_ABIT_AW9D_MAX, |
4167 | PINFIX_LENOVO_Y530, | 4334 | ALC882_FIXUP_LENOVO_Y530, |
4168 | PINFIX_PB_M5210, | 4335 | ALC882_FIXUP_PB_M5210, |
4169 | PINFIX_ACER_ASPIRE_7736, | 4336 | ALC882_FIXUP_ACER_ASPIRE_7736, |
4170 | PINFIX_ASUS_W90V, | 4337 | ALC882_FIXUP_ASUS_W90V, |
4338 | ALC889_FIXUP_VAIO_TT, | ||
4339 | ALC888_FIXUP_EEE1601, | ||
4340 | ALC882_FIXUP_EAPD, | ||
4341 | ALC883_FIXUP_EAPD, | ||
4342 | ALC883_FIXUP_ACER_EAPD, | ||
4343 | ALC882_FIXUP_GPIO3, | ||
4344 | ALC889_FIXUP_COEF, | ||
4345 | ALC882_FIXUP_ASUS_W2JC, | ||
4346 | ALC882_FIXUP_ACER_ASPIRE_4930G, | ||
4347 | ALC882_FIXUP_ACER_ASPIRE_8930G, | ||
4348 | ALC882_FIXUP_ASPIRE_8930G_VERBS, | ||
4349 | ALC885_FIXUP_MACPRO_GPIO, | ||
4171 | }; | 4350 | }; |
4172 | 4351 | ||
4352 | static void alc889_fixup_coef(struct hda_codec *codec, | ||
4353 | const struct alc_fixup *fix, int action) | ||
4354 | { | ||
4355 | if (action != ALC_FIXUP_ACT_INIT) | ||
4356 | return; | ||
4357 | alc889_coef_init(codec); | ||
4358 | } | ||
4359 | |||
4360 | /* toggle speaker-output according to the hp-jack state */ | ||
4361 | static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) | ||
4362 | { | ||
4363 | unsigned int gpiostate, gpiomask, gpiodir; | ||
4364 | |||
4365 | gpiostate = snd_hda_codec_read(codec, codec->afg, 0, | ||
4366 | AC_VERB_GET_GPIO_DATA, 0); | ||
4367 | |||
4368 | if (!muted) | ||
4369 | gpiostate |= (1 << pin); | ||
4370 | else | ||
4371 | gpiostate &= ~(1 << pin); | ||
4372 | |||
4373 | gpiomask = snd_hda_codec_read(codec, codec->afg, 0, | ||
4374 | AC_VERB_GET_GPIO_MASK, 0); | ||
4375 | gpiomask |= (1 << pin); | ||
4376 | |||
4377 | gpiodir = snd_hda_codec_read(codec, codec->afg, 0, | ||
4378 | AC_VERB_GET_GPIO_DIRECTION, 0); | ||
4379 | gpiodir |= (1 << pin); | ||
4380 | |||
4381 | |||
4382 | snd_hda_codec_write(codec, codec->afg, 0, | ||
4383 | AC_VERB_SET_GPIO_MASK, gpiomask); | ||
4384 | snd_hda_codec_write(codec, codec->afg, 0, | ||
4385 | AC_VERB_SET_GPIO_DIRECTION, gpiodir); | ||
4386 | |||
4387 | msleep(1); | ||
4388 | |||
4389 | snd_hda_codec_write(codec, codec->afg, 0, | ||
4390 | AC_VERB_SET_GPIO_DATA, gpiostate); | ||
4391 | } | ||
4392 | |||
4393 | /* set up GPIO at initialization */ | ||
4394 | static void alc885_fixup_macpro_gpio(struct hda_codec *codec, | ||
4395 | const struct alc_fixup *fix, int action) | ||
4396 | { | ||
4397 | if (action != ALC_FIXUP_ACT_INIT) | ||
4398 | return; | ||
4399 | alc882_gpio_mute(codec, 0, 0); | ||
4400 | alc882_gpio_mute(codec, 1, 0); | ||
4401 | } | ||
4402 | |||
4173 | static const struct alc_fixup alc882_fixups[] = { | 4403 | static const struct alc_fixup alc882_fixups[] = { |
4174 | [PINFIX_ABIT_AW9D_MAX] = { | 4404 | [ALC882_FIXUP_ABIT_AW9D_MAX] = { |
4175 | .type = ALC_FIXUP_PINS, | 4405 | .type = ALC_FIXUP_PINS, |
4176 | .v.pins = (const struct alc_pincfg[]) { | 4406 | .v.pins = (const struct alc_pincfg[]) { |
4177 | { 0x15, 0x01080104 }, /* side */ | 4407 | { 0x15, 0x01080104 }, /* side */ |
@@ -4180,7 +4410,7 @@ static const struct alc_fixup alc882_fixups[] = { | |||
4180 | { } | 4410 | { } |
4181 | } | 4411 | } |
4182 | }, | 4412 | }, |
4183 | [PINFIX_LENOVO_Y530] = { | 4413 | [ALC882_FIXUP_LENOVO_Y530] = { |
4184 | .type = ALC_FIXUP_PINS, | 4414 | .type = ALC_FIXUP_PINS, |
4185 | .v.pins = (const struct alc_pincfg[]) { | 4415 | .v.pins = (const struct alc_pincfg[]) { |
4186 | { 0x15, 0x99130112 }, /* rear int speakers */ | 4416 | { 0x15, 0x99130112 }, /* rear int speakers */ |
@@ -4188,32 +4418,180 @@ static const struct alc_fixup alc882_fixups[] = { | |||
4188 | { } | 4418 | { } |
4189 | } | 4419 | } |
4190 | }, | 4420 | }, |
4191 | [PINFIX_PB_M5210] = { | 4421 | [ALC882_FIXUP_PB_M5210] = { |
4192 | .type = ALC_FIXUP_VERBS, | 4422 | .type = ALC_FIXUP_VERBS, |
4193 | .v.verbs = (const struct hda_verb[]) { | 4423 | .v.verbs = (const struct hda_verb[]) { |
4194 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, | 4424 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, |
4195 | {} | 4425 | {} |
4196 | } | 4426 | } |
4197 | }, | 4427 | }, |
4198 | [PINFIX_ACER_ASPIRE_7736] = { | 4428 | [ALC882_FIXUP_ACER_ASPIRE_7736] = { |
4199 | .type = ALC_FIXUP_SKU, | 4429 | .type = ALC_FIXUP_SKU, |
4200 | .v.sku = ALC_FIXUP_SKU_IGNORE, | 4430 | .v.sku = ALC_FIXUP_SKU_IGNORE, |
4201 | }, | 4431 | }, |
4202 | [PINFIX_ASUS_W90V] = { | 4432 | [ALC882_FIXUP_ASUS_W90V] = { |
4203 | .type = ALC_FIXUP_PINS, | 4433 | .type = ALC_FIXUP_PINS, |
4204 | .v.pins = (const struct alc_pincfg[]) { | 4434 | .v.pins = (const struct alc_pincfg[]) { |
4205 | { 0x16, 0x99130110 }, /* fix sequence for CLFE */ | 4435 | { 0x16, 0x99130110 }, /* fix sequence for CLFE */ |
4206 | { } | 4436 | { } |
4207 | } | 4437 | } |
4208 | }, | 4438 | }, |
4439 | [ALC889_FIXUP_VAIO_TT] = { | ||
4440 | .type = ALC_FIXUP_PINS, | ||
4441 | .v.pins = (const struct alc_pincfg[]) { | ||
4442 | { 0x17, 0x90170111 }, /* hidden surround speaker */ | ||
4443 | { } | ||
4444 | } | ||
4445 | }, | ||
4446 | [ALC888_FIXUP_EEE1601] = { | ||
4447 | .type = ALC_FIXUP_VERBS, | ||
4448 | .v.verbs = (const struct hda_verb[]) { | ||
4449 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, | ||
4450 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 }, | ||
4451 | { } | ||
4452 | } | ||
4453 | }, | ||
4454 | [ALC882_FIXUP_EAPD] = { | ||
4455 | .type = ALC_FIXUP_VERBS, | ||
4456 | .v.verbs = (const struct hda_verb[]) { | ||
4457 | /* change to EAPD mode */ | ||
4458 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | ||
4459 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, | ||
4460 | { } | ||
4461 | } | ||
4462 | }, | ||
4463 | [ALC883_FIXUP_EAPD] = { | ||
4464 | .type = ALC_FIXUP_VERBS, | ||
4465 | .v.verbs = (const struct hda_verb[]) { | ||
4466 | /* change to EAPD mode */ | ||
4467 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | ||
4468 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, | ||
4469 | { } | ||
4470 | } | ||
4471 | }, | ||
4472 | [ALC883_FIXUP_ACER_EAPD] = { | ||
4473 | .type = ALC_FIXUP_VERBS, | ||
4474 | .v.verbs = (const struct hda_verb[]) { | ||
4475 | /* eanable EAPD on Acer laptops */ | ||
4476 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | ||
4477 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | ||
4478 | { } | ||
4479 | } | ||
4480 | }, | ||
4481 | [ALC882_FIXUP_GPIO3] = { | ||
4482 | .type = ALC_FIXUP_VERBS, | ||
4483 | .v.verbs = alc_gpio3_init_verbs, | ||
4484 | }, | ||
4485 | [ALC882_FIXUP_ASUS_W2JC] = { | ||
4486 | .type = ALC_FIXUP_VERBS, | ||
4487 | .v.verbs = alc_gpio1_init_verbs, | ||
4488 | .chained = true, | ||
4489 | .chain_id = ALC882_FIXUP_EAPD, | ||
4490 | }, | ||
4491 | [ALC889_FIXUP_COEF] = { | ||
4492 | .type = ALC_FIXUP_FUNC, | ||
4493 | .v.func = alc889_fixup_coef, | ||
4494 | }, | ||
4495 | [ALC882_FIXUP_ACER_ASPIRE_4930G] = { | ||
4496 | .type = ALC_FIXUP_PINS, | ||
4497 | .v.pins = (const struct alc_pincfg[]) { | ||
4498 | { 0x16, 0x99130111 }, /* CLFE speaker */ | ||
4499 | { 0x17, 0x99130112 }, /* surround speaker */ | ||
4500 | { } | ||
4501 | } | ||
4502 | }, | ||
4503 | [ALC882_FIXUP_ACER_ASPIRE_8930G] = { | ||
4504 | .type = ALC_FIXUP_PINS, | ||
4505 | .v.pins = (const struct alc_pincfg[]) { | ||
4506 | { 0x16, 0x99130111 }, /* CLFE speaker */ | ||
4507 | { 0x1b, 0x99130112 }, /* surround speaker */ | ||
4508 | { } | ||
4509 | }, | ||
4510 | .chained = true, | ||
4511 | .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS, | ||
4512 | }, | ||
4513 | [ALC882_FIXUP_ASPIRE_8930G_VERBS] = { | ||
4514 | /* additional init verbs for Acer Aspire 8930G */ | ||
4515 | .type = ALC_FIXUP_VERBS, | ||
4516 | .v.verbs = (const struct hda_verb[]) { | ||
4517 | /* Enable all DACs */ | ||
4518 | /* DAC DISABLE/MUTE 1? */ | ||
4519 | /* setting bits 1-5 disables DAC nids 0x02-0x06 | ||
4520 | * apparently. Init=0x38 */ | ||
4521 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 }, | ||
4522 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, | ||
4523 | /* DAC DISABLE/MUTE 2? */ | ||
4524 | /* some bit here disables the other DACs. | ||
4525 | * Init=0x4900 */ | ||
4526 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 }, | ||
4527 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, | ||
4528 | /* DMIC fix | ||
4529 | * This laptop has a stereo digital microphone. | ||
4530 | * The mics are only 1cm apart which makes the stereo | ||
4531 | * useless. However, either the mic or the ALC889 | ||
4532 | * makes the signal become a difference/sum signal | ||
4533 | * instead of standard stereo, which is annoying. | ||
4534 | * So instead we flip this bit which makes the | ||
4535 | * codec replicate the sum signal to both channels, | ||
4536 | * turning it into a normal mono mic. | ||
4537 | */ | ||
4538 | /* DMIC_CONTROL? Init value = 0x0001 */ | ||
4539 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, | ||
4540 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 }, | ||
4541 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | ||
4542 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | ||
4543 | { } | ||
4544 | } | ||
4545 | }, | ||
4546 | [ALC885_FIXUP_MACPRO_GPIO] = { | ||
4547 | .type = ALC_FIXUP_FUNC, | ||
4548 | .v.func = alc885_fixup_macpro_gpio, | ||
4549 | }, | ||
4209 | }; | 4550 | }; |
4210 | 4551 | ||
4211 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { | 4552 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { |
4212 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), | 4553 | SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD), |
4213 | SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", PINFIX_ASUS_W90V), | 4554 | SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), |
4214 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530), | 4555 | SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD), |
4215 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), | 4556 | SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), |
4216 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), | 4557 | SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD), |
4558 | SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD), | ||
4559 | SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", | ||
4560 | ALC882_FIXUP_ACER_ASPIRE_4930G), | ||
4561 | SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", | ||
4562 | ALC882_FIXUP_ACER_ASPIRE_4930G), | ||
4563 | SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", | ||
4564 | ALC882_FIXUP_ACER_ASPIRE_8930G), | ||
4565 | SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", | ||
4566 | ALC882_FIXUP_ACER_ASPIRE_8930G), | ||
4567 | SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", | ||
4568 | ALC882_FIXUP_ACER_ASPIRE_4930G), | ||
4569 | SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", | ||
4570 | ALC882_FIXUP_ACER_ASPIRE_4930G), | ||
4571 | SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", | ||
4572 | ALC882_FIXUP_ACER_ASPIRE_4930G), | ||
4573 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), | ||
4574 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), | ||
4575 | SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), | ||
4576 | SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), | ||
4577 | SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC), | ||
4578 | SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601), | ||
4579 | SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), | ||
4580 | |||
4581 | /* All Apple entries are in codec SSIDs */ | ||
4582 | SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO), | ||
4583 | SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), | ||
4584 | SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), | ||
4585 | SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), | ||
4586 | SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), | ||
4587 | |||
4588 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), | ||
4589 | SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), | ||
4590 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), | ||
4591 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), | ||
4592 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), | ||
4593 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), | ||
4594 | SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF), | ||
4217 | {} | 4595 | {} |
4218 | }; | 4596 | }; |
4219 | 4597 | ||
@@ -4262,8 +4640,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
4262 | goto error; | 4640 | goto error; |
4263 | 4641 | ||
4264 | board_config = alc_board_config(codec, ALC882_MODEL_LAST, | 4642 | board_config = alc_board_config(codec, ALC882_MODEL_LAST, |
4265 | alc882_models, alc882_cfg_tbl); | 4643 | alc882_models, NULL); |
4266 | |||
4267 | if (board_config < 0) | 4644 | if (board_config < 0) |
4268 | board_config = alc_board_codec_sid_config(codec, | 4645 | board_config = alc_board_codec_sid_config(codec, |
4269 | ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); | 4646 | ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); |
@@ -4286,18 +4663,12 @@ static int patch_alc882(struct hda_codec *codec) | |||
4286 | err = alc882_parse_auto_config(codec); | 4663 | err = alc882_parse_auto_config(codec); |
4287 | if (err < 0) | 4664 | if (err < 0) |
4288 | goto error; | 4665 | goto error; |
4289 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
4290 | else if (!err) { | ||
4291 | printk(KERN_INFO | ||
4292 | "hda_codec: Cannot set up configuration " | ||
4293 | "from BIOS. Using base mode...\n"); | ||
4294 | board_config = ALC882_3ST_DIG; | ||
4295 | } | ||
4296 | #endif | ||
4297 | } | 4666 | } |
4298 | 4667 | ||
4299 | if (board_config != ALC_MODEL_AUTO) | 4668 | if (board_config != ALC_MODEL_AUTO) { |
4300 | setup_preset(codec, &alc882_presets[board_config]); | 4669 | setup_preset(codec, &alc882_presets[board_config]); |
4670 | spec->vmaster_nid = 0x0c; | ||
4671 | } | ||
4301 | 4672 | ||
4302 | if (!spec->no_analog && !spec->adc_nids) { | 4673 | if (!spec->no_analog && !spec->adc_nids) { |
4303 | alc_auto_fill_adc_caps(codec); | 4674 | alc_auto_fill_adc_caps(codec); |
@@ -4317,13 +4688,10 @@ static int patch_alc882(struct hda_codec *codec) | |||
4317 | 4688 | ||
4318 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 4689 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
4319 | 4690 | ||
4320 | spec->vmaster_nid = 0x0c; | ||
4321 | |||
4322 | codec->patch_ops = alc_patch_ops; | 4691 | codec->patch_ops = alc_patch_ops; |
4323 | if (board_config == ALC_MODEL_AUTO) | 4692 | if (board_config == ALC_MODEL_AUTO) |
4324 | spec->init_hook = alc_auto_init_std; | 4693 | spec->init_hook = alc_auto_init_std; |
4325 | 4694 | ||
4326 | alc_init_jacks(codec); | ||
4327 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4695 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4328 | if (!spec->loopback.amplist) | 4696 | if (!spec->loopback.amplist) |
4329 | spec->loopback.amplist = alc882_loopbacks; | 4697 | spec->loopback.amplist = alc882_loopbacks; |
@@ -4351,12 +4719,17 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
4351 | * Pin config fixes | 4719 | * Pin config fixes |
4352 | */ | 4720 | */ |
4353 | enum { | 4721 | enum { |
4354 | PINFIX_FSC_H270, | 4722 | ALC262_FIXUP_FSC_H270, |
4355 | PINFIX_HP_Z200, | 4723 | ALC262_FIXUP_HP_Z200, |
4724 | ALC262_FIXUP_TYAN, | ||
4725 | ALC262_FIXUP_TOSHIBA_RX1, | ||
4726 | ALC262_FIXUP_LENOVO_3000, | ||
4727 | ALC262_FIXUP_BENQ, | ||
4728 | ALC262_FIXUP_BENQ_T31, | ||
4356 | }; | 4729 | }; |
4357 | 4730 | ||
4358 | static const struct alc_fixup alc262_fixups[] = { | 4731 | static const struct alc_fixup alc262_fixups[] = { |
4359 | [PINFIX_FSC_H270] = { | 4732 | [ALC262_FIXUP_FSC_H270] = { |
4360 | .type = ALC_FIXUP_PINS, | 4733 | .type = ALC_FIXUP_PINS, |
4361 | .v.pins = (const struct alc_pincfg[]) { | 4734 | .v.pins = (const struct alc_pincfg[]) { |
4362 | { 0x14, 0x99130110 }, /* speaker */ | 4735 | { 0x14, 0x99130110 }, /* speaker */ |
@@ -4365,18 +4738,68 @@ static const struct alc_fixup alc262_fixups[] = { | |||
4365 | { } | 4738 | { } |
4366 | } | 4739 | } |
4367 | }, | 4740 | }, |
4368 | [PINFIX_HP_Z200] = { | 4741 | [ALC262_FIXUP_HP_Z200] = { |
4369 | .type = ALC_FIXUP_PINS, | 4742 | .type = ALC_FIXUP_PINS, |
4370 | .v.pins = (const struct alc_pincfg[]) { | 4743 | .v.pins = (const struct alc_pincfg[]) { |
4371 | { 0x16, 0x99130120 }, /* internal speaker */ | 4744 | { 0x16, 0x99130120 }, /* internal speaker */ |
4372 | { } | 4745 | { } |
4373 | } | 4746 | } |
4374 | }, | 4747 | }, |
4748 | [ALC262_FIXUP_TYAN] = { | ||
4749 | .type = ALC_FIXUP_PINS, | ||
4750 | .v.pins = (const struct alc_pincfg[]) { | ||
4751 | { 0x14, 0x1993e1f0 }, /* int AUX */ | ||
4752 | { } | ||
4753 | } | ||
4754 | }, | ||
4755 | [ALC262_FIXUP_TOSHIBA_RX1] = { | ||
4756 | .type = ALC_FIXUP_PINS, | ||
4757 | .v.pins = (const struct alc_pincfg[]) { | ||
4758 | { 0x14, 0x90170110 }, /* speaker */ | ||
4759 | { 0x15, 0x0421101f }, /* HP */ | ||
4760 | { 0x1a, 0x40f000f0 }, /* N/A */ | ||
4761 | { 0x1b, 0x40f000f0 }, /* N/A */ | ||
4762 | { 0x1e, 0x40f000f0 }, /* N/A */ | ||
4763 | } | ||
4764 | }, | ||
4765 | [ALC262_FIXUP_LENOVO_3000] = { | ||
4766 | .type = ALC_FIXUP_VERBS, | ||
4767 | .v.verbs = (const struct hda_verb[]) { | ||
4768 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, | ||
4769 | {} | ||
4770 | }, | ||
4771 | .chained = true, | ||
4772 | .chain_id = ALC262_FIXUP_BENQ, | ||
4773 | }, | ||
4774 | [ALC262_FIXUP_BENQ] = { | ||
4775 | .type = ALC_FIXUP_VERBS, | ||
4776 | .v.verbs = (const struct hda_verb[]) { | ||
4777 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | ||
4778 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, | ||
4779 | {} | ||
4780 | } | ||
4781 | }, | ||
4782 | [ALC262_FIXUP_BENQ_T31] = { | ||
4783 | .type = ALC_FIXUP_VERBS, | ||
4784 | .v.verbs = (const struct hda_verb[]) { | ||
4785 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | ||
4786 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | ||
4787 | {} | ||
4788 | } | ||
4789 | }, | ||
4375 | }; | 4790 | }; |
4376 | 4791 | ||
4377 | static const struct snd_pci_quirk alc262_fixup_tbl[] = { | 4792 | static const struct snd_pci_quirk alc262_fixup_tbl[] = { |
4378 | SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200), | 4793 | SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200), |
4379 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270), | 4794 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ), |
4795 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), | ||
4796 | SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), | ||
4797 | SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", | ||
4798 | ALC262_FIXUP_TOSHIBA_RX1), | ||
4799 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), | ||
4800 | SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), | ||
4801 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), | ||
4802 | SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31), | ||
4380 | {} | 4803 | {} |
4381 | }; | 4804 | }; |
4382 | 4805 | ||
@@ -4387,14 +4810,9 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = { | |||
4387 | 4810 | ||
4388 | /* | 4811 | /* |
4389 | */ | 4812 | */ |
4390 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
4391 | #include "alc262_quirks.c" | ||
4392 | #endif | ||
4393 | |||
4394 | static int patch_alc262(struct hda_codec *codec) | 4813 | static int patch_alc262(struct hda_codec *codec) |
4395 | { | 4814 | { |
4396 | struct alc_spec *spec; | 4815 | struct alc_spec *spec; |
4397 | int board_config; | ||
4398 | int err; | 4816 | int err; |
4399 | 4817 | ||
4400 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4818 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
@@ -4421,37 +4839,13 @@ static int patch_alc262(struct hda_codec *codec) | |||
4421 | 4839 | ||
4422 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); | 4840 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); |
4423 | 4841 | ||
4424 | board_config = alc_board_config(codec, ALC262_MODEL_LAST, | 4842 | alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); |
4425 | alc262_models, alc262_cfg_tbl); | 4843 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); |
4426 | |||
4427 | if (board_config < 0) { | ||
4428 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
4429 | codec->chip_name); | ||
4430 | board_config = ALC_MODEL_AUTO; | ||
4431 | } | ||
4432 | |||
4433 | if (board_config == ALC_MODEL_AUTO) { | ||
4434 | alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); | ||
4435 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | ||
4436 | } | ||
4437 | |||
4438 | if (board_config == ALC_MODEL_AUTO) { | ||
4439 | /* automatic parse from the BIOS config */ | ||
4440 | err = alc262_parse_auto_config(codec); | ||
4441 | if (err < 0) | ||
4442 | goto error; | ||
4443 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
4444 | else if (!err) { | ||
4445 | printk(KERN_INFO | ||
4446 | "hda_codec: Cannot set up configuration " | ||
4447 | "from BIOS. Using base mode...\n"); | ||
4448 | board_config = ALC262_BASIC; | ||
4449 | } | ||
4450 | #endif | ||
4451 | } | ||
4452 | 4844 | ||
4453 | if (board_config != ALC_MODEL_AUTO) | 4845 | /* automatic parse from the BIOS config */ |
4454 | setup_preset(codec, &alc262_presets[board_config]); | 4846 | err = alc262_parse_auto_config(codec); |
4847 | if (err < 0) | ||
4848 | goto error; | ||
4455 | 4849 | ||
4456 | if (!spec->no_analog && !spec->adc_nids) { | 4850 | if (!spec->no_analog && !spec->adc_nids) { |
4457 | alc_auto_fill_adc_caps(codec); | 4851 | alc_auto_fill_adc_caps(codec); |
@@ -4471,14 +4865,10 @@ static int patch_alc262(struct hda_codec *codec) | |||
4471 | 4865 | ||
4472 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 4866 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
4473 | 4867 | ||
4474 | spec->vmaster_nid = 0x0c; | ||
4475 | |||
4476 | codec->patch_ops = alc_patch_ops; | 4868 | codec->patch_ops = alc_patch_ops; |
4477 | if (board_config == ALC_MODEL_AUTO) | 4869 | spec->init_hook = alc_auto_init_std; |
4478 | spec->init_hook = alc_auto_init_std; | ||
4479 | spec->shutup = alc_eapd_shutup; | 4870 | spec->shutup = alc_eapd_shutup; |
4480 | 4871 | ||
4481 | alc_init_jacks(codec); | ||
4482 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4872 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4483 | if (!spec->loopback.amplist) | 4873 | if (!spec->loopback.amplist) |
4484 | spec->loopback.amplist = alc262_loopbacks; | 4874 | spec->loopback.amplist = alc262_loopbacks; |
@@ -4585,14 +4975,10 @@ static int patch_alc268(struct hda_codec *codec) | |||
4585 | if (!spec->no_analog && !spec->cap_mixer) | 4975 | if (!spec->no_analog && !spec->cap_mixer) |
4586 | set_capture_mixer(codec); | 4976 | set_capture_mixer(codec); |
4587 | 4977 | ||
4588 | spec->vmaster_nid = 0x02; | ||
4589 | |||
4590 | codec->patch_ops = alc_patch_ops; | 4978 | codec->patch_ops = alc_patch_ops; |
4591 | spec->init_hook = alc_auto_init_std; | 4979 | spec->init_hook = alc_auto_init_std; |
4592 | spec->shutup = alc_eapd_shutup; | 4980 | spec->shutup = alc_eapd_shutup; |
4593 | 4981 | ||
4594 | alc_init_jacks(codec); | ||
4595 | |||
4596 | return 0; | 4982 | return 0; |
4597 | 4983 | ||
4598 | error: | 4984 | error: |
@@ -4934,7 +5320,7 @@ static const struct alc_fixup alc269_fixups[] = { | |||
4934 | { } | 5320 | { } |
4935 | }, | 5321 | }, |
4936 | }, | 5322 | }, |
4937 | [ALC269_FIXUP_DMIC] = { | 5323 | [ALC269VB_FIXUP_DMIC] = { |
4938 | .type = ALC_FIXUP_PINS, | 5324 | .type = ALC_FIXUP_PINS, |
4939 | .v.pins = (const struct alc_pincfg[]) { | 5325 | .v.pins = (const struct alc_pincfg[]) { |
4940 | { 0x12, 0x99a3092f }, /* int-mic */ | 5326 | { 0x12, 0x99a3092f }, /* int-mic */ |
@@ -5141,8 +5527,6 @@ static int patch_alc269(struct hda_codec *codec) | |||
5141 | 5527 | ||
5142 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 5528 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
5143 | 5529 | ||
5144 | spec->vmaster_nid = 0x02; | ||
5145 | |||
5146 | codec->patch_ops = alc_patch_ops; | 5530 | codec->patch_ops = alc_patch_ops; |
5147 | #ifdef CONFIG_PM | 5531 | #ifdef CONFIG_PM |
5148 | codec->patch_ops.resume = alc269_resume; | 5532 | codec->patch_ops.resume = alc269_resume; |
@@ -5150,7 +5534,6 @@ static int patch_alc269(struct hda_codec *codec) | |||
5150 | spec->init_hook = alc_auto_init_std; | 5534 | spec->init_hook = alc_auto_init_std; |
5151 | spec->shutup = alc269_shutup; | 5535 | spec->shutup = alc269_shutup; |
5152 | 5536 | ||
5153 | alc_init_jacks(codec); | ||
5154 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5537 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
5155 | if (!spec->loopback.amplist) | 5538 | if (!spec->loopback.amplist) |
5156 | spec->loopback.amplist = alc269_loopbacks; | 5539 | spec->loopback.amplist = alc269_loopbacks; |
@@ -5247,8 +5630,6 @@ static int patch_alc861(struct hda_codec *codec) | |||
5247 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); | 5630 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); |
5248 | } | 5631 | } |
5249 | 5632 | ||
5250 | spec->vmaster_nid = 0x03; | ||
5251 | |||
5252 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 5633 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
5253 | 5634 | ||
5254 | codec->patch_ops = alc_patch_ops; | 5635 | codec->patch_ops = alc_patch_ops; |
@@ -5373,8 +5754,6 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
5373 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 5754 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
5374 | } | 5755 | } |
5375 | 5756 | ||
5376 | spec->vmaster_nid = 0x02; | ||
5377 | |||
5378 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 5757 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
5379 | 5758 | ||
5380 | codec->patch_ops = alc_patch_ops; | 5759 | codec->patch_ops = alc_patch_ops; |
@@ -5757,7 +6136,6 @@ static int patch_alc662(struct hda_codec *codec) | |||
5757 | break; | 6136 | break; |
5758 | } | 6137 | } |
5759 | } | 6138 | } |
5760 | spec->vmaster_nid = 0x02; | ||
5761 | 6139 | ||
5762 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 6140 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
5763 | 6141 | ||
@@ -5765,8 +6143,6 @@ static int patch_alc662(struct hda_codec *codec) | |||
5765 | spec->init_hook = alc_auto_init_std; | 6143 | spec->init_hook = alc_auto_init_std; |
5766 | spec->shutup = alc_eapd_shutup; | 6144 | spec->shutup = alc_eapd_shutup; |
5767 | 6145 | ||
5768 | alc_init_jacks(codec); | ||
5769 | |||
5770 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 6146 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
5771 | if (!spec->loopback.amplist) | 6147 | if (!spec->loopback.amplist) |
5772 | spec->loopback.amplist = alc662_loopbacks; | 6148 | spec->loopback.amplist = alc662_loopbacks; |
@@ -5813,8 +6189,6 @@ static int patch_alc680(struct hda_codec *codec) | |||
5813 | if (!spec->no_analog && !spec->cap_mixer) | 6189 | if (!spec->no_analog && !spec->cap_mixer) |
5814 | set_capture_mixer(codec); | 6190 | set_capture_mixer(codec); |
5815 | 6191 | ||
5816 | spec->vmaster_nid = 0x02; | ||
5817 | |||
5818 | codec->patch_ops = alc_patch_ops; | 6192 | codec->patch_ops = alc_patch_ops; |
5819 | spec->init_hook = alc_auto_init_std; | 6193 | spec->init_hook = alc_auto_init_std; |
5820 | 6194 | ||