diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 138 |
1 files changed, 79 insertions, 59 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b4f472157ebd..6df758adff84 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -117,6 +117,7 @@ struct alc_spec { | |||
117 | int codec_variant; /* flag for other variants */ | 117 | int codec_variant; /* flag for other variants */ |
118 | unsigned int has_alc5505_dsp:1; | 118 | unsigned int has_alc5505_dsp:1; |
119 | unsigned int no_depop_delay:1; | 119 | unsigned int no_depop_delay:1; |
120 | unsigned int done_hp_init:1; | ||
120 | 121 | ||
121 | /* for PLL fix */ | 122 | /* for PLL fix */ |
122 | hda_nid_t pll_nid; | 123 | hda_nid_t pll_nid; |
@@ -514,6 +515,15 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) | |||
514 | } | 515 | } |
515 | } | 516 | } |
516 | 517 | ||
518 | /* get a primary headphone pin if available */ | ||
519 | static hda_nid_t alc_get_hp_pin(struct alc_spec *spec) | ||
520 | { | ||
521 | if (spec->gen.autocfg.hp_pins[0]) | ||
522 | return spec->gen.autocfg.hp_pins[0]; | ||
523 | if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) | ||
524 | return spec->gen.autocfg.line_out_pins[0]; | ||
525 | return 0; | ||
526 | } | ||
517 | 527 | ||
518 | /* | 528 | /* |
519 | * Realtek SSID verification | 529 | * Realtek SSID verification |
@@ -724,9 +734,7 @@ do_sku: | |||
724 | * 15 : 1 --> enable the function "Mute internal speaker | 734 | * 15 : 1 --> enable the function "Mute internal speaker |
725 | * when the external headphone out jack is plugged" | 735 | * when the external headphone out jack is plugged" |
726 | */ | 736 | */ |
727 | if (!spec->gen.autocfg.hp_pins[0] && | 737 | if (!alc_get_hp_pin(spec)) { |
728 | !(spec->gen.autocfg.line_out_pins[0] && | ||
729 | spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) { | ||
730 | hda_nid_t nid; | 738 | hda_nid_t nid; |
731 | tmp = (ass >> 11) & 0x3; /* HP to chassis */ | 739 | tmp = (ass >> 11) & 0x3; /* HP to chassis */ |
732 | nid = ports[tmp]; | 740 | nid = ports[tmp]; |
@@ -2958,7 +2966,7 @@ static void alc282_restore_default_value(struct hda_codec *codec) | |||
2958 | static void alc282_init(struct hda_codec *codec) | 2966 | static void alc282_init(struct hda_codec *codec) |
2959 | { | 2967 | { |
2960 | struct alc_spec *spec = codec->spec; | 2968 | struct alc_spec *spec = codec->spec; |
2961 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 2969 | hda_nid_t hp_pin = alc_get_hp_pin(spec); |
2962 | bool hp_pin_sense; | 2970 | bool hp_pin_sense; |
2963 | int coef78; | 2971 | int coef78; |
2964 | 2972 | ||
@@ -2995,7 +3003,7 @@ static void alc282_init(struct hda_codec *codec) | |||
2995 | static void alc282_shutup(struct hda_codec *codec) | 3003 | static void alc282_shutup(struct hda_codec *codec) |
2996 | { | 3004 | { |
2997 | struct alc_spec *spec = codec->spec; | 3005 | struct alc_spec *spec = codec->spec; |
2998 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3006 | hda_nid_t hp_pin = alc_get_hp_pin(spec); |
2999 | bool hp_pin_sense; | 3007 | bool hp_pin_sense; |
3000 | int coef78; | 3008 | int coef78; |
3001 | 3009 | ||
@@ -3073,14 +3081,9 @@ static void alc283_restore_default_value(struct hda_codec *codec) | |||
3073 | static void alc283_init(struct hda_codec *codec) | 3081 | static void alc283_init(struct hda_codec *codec) |
3074 | { | 3082 | { |
3075 | struct alc_spec *spec = codec->spec; | 3083 | struct alc_spec *spec = codec->spec; |
3076 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3084 | hda_nid_t hp_pin = alc_get_hp_pin(spec); |
3077 | bool hp_pin_sense; | 3085 | bool hp_pin_sense; |
3078 | 3086 | ||
3079 | if (!spec->gen.autocfg.hp_outs) { | ||
3080 | if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) | ||
3081 | hp_pin = spec->gen.autocfg.line_out_pins[0]; | ||
3082 | } | ||
3083 | |||
3084 | alc283_restore_default_value(codec); | 3087 | alc283_restore_default_value(codec); |
3085 | 3088 | ||
3086 | if (!hp_pin) | 3089 | if (!hp_pin) |
@@ -3114,14 +3117,9 @@ static void alc283_init(struct hda_codec *codec) | |||
3114 | static void alc283_shutup(struct hda_codec *codec) | 3117 | static void alc283_shutup(struct hda_codec *codec) |
3115 | { | 3118 | { |
3116 | struct alc_spec *spec = codec->spec; | 3119 | struct alc_spec *spec = codec->spec; |
3117 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3120 | hda_nid_t hp_pin = alc_get_hp_pin(spec); |
3118 | bool hp_pin_sense; | 3121 | bool hp_pin_sense; |
3119 | 3122 | ||
3120 | if (!spec->gen.autocfg.hp_outs) { | ||
3121 | if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) | ||
3122 | hp_pin = spec->gen.autocfg.line_out_pins[0]; | ||
3123 | } | ||
3124 | |||
3125 | if (!hp_pin) { | 3123 | if (!hp_pin) { |
3126 | alc269_shutup(codec); | 3124 | alc269_shutup(codec); |
3127 | return; | 3125 | return; |
@@ -3155,7 +3153,7 @@ static void alc283_shutup(struct hda_codec *codec) | |||
3155 | static void alc256_init(struct hda_codec *codec) | 3153 | static void alc256_init(struct hda_codec *codec) |
3156 | { | 3154 | { |
3157 | struct alc_spec *spec = codec->spec; | 3155 | struct alc_spec *spec = codec->spec; |
3158 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3156 | hda_nid_t hp_pin = alc_get_hp_pin(spec); |
3159 | bool hp_pin_sense; | 3157 | bool hp_pin_sense; |
3160 | 3158 | ||
3161 | if (!hp_pin) | 3159 | if (!hp_pin) |
@@ -3191,7 +3189,7 @@ static void alc256_init(struct hda_codec *codec) | |||
3191 | static void alc256_shutup(struct hda_codec *codec) | 3189 | static void alc256_shutup(struct hda_codec *codec) |
3192 | { | 3190 | { |
3193 | struct alc_spec *spec = codec->spec; | 3191 | struct alc_spec *spec = codec->spec; |
3194 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3192 | hda_nid_t hp_pin = alc_get_hp_pin(spec); |
3195 | bool hp_pin_sense; | 3193 | bool hp_pin_sense; |
3196 | 3194 | ||
3197 | if (!hp_pin) { | 3195 | if (!hp_pin) { |
@@ -3227,7 +3225,7 @@ static void alc256_shutup(struct hda_codec *codec) | |||
3227 | static void alc225_init(struct hda_codec *codec) | 3225 | static void alc225_init(struct hda_codec *codec) |
3228 | { | 3226 | { |
3229 | struct alc_spec *spec = codec->spec; | 3227 | struct alc_spec *spec = codec->spec; |
3230 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3228 | hda_nid_t hp_pin = alc_get_hp_pin(spec); |
3231 | bool hp1_pin_sense, hp2_pin_sense; | 3229 | bool hp1_pin_sense, hp2_pin_sense; |
3232 | 3230 | ||
3233 | if (!hp_pin) | 3231 | if (!hp_pin) |
@@ -3270,7 +3268,7 @@ static void alc225_init(struct hda_codec *codec) | |||
3270 | static void alc225_shutup(struct hda_codec *codec) | 3268 | static void alc225_shutup(struct hda_codec *codec) |
3271 | { | 3269 | { |
3272 | struct alc_spec *spec = codec->spec; | 3270 | struct alc_spec *spec = codec->spec; |
3273 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3271 | hda_nid_t hp_pin = alc_get_hp_pin(spec); |
3274 | bool hp1_pin_sense, hp2_pin_sense; | 3272 | bool hp1_pin_sense, hp2_pin_sense; |
3275 | 3273 | ||
3276 | if (!hp_pin) { | 3274 | if (!hp_pin) { |
@@ -3314,7 +3312,7 @@ static void alc225_shutup(struct hda_codec *codec) | |||
3314 | static void alc_default_init(struct hda_codec *codec) | 3312 | static void alc_default_init(struct hda_codec *codec) |
3315 | { | 3313 | { |
3316 | struct alc_spec *spec = codec->spec; | 3314 | struct alc_spec *spec = codec->spec; |
3317 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3315 | hda_nid_t hp_pin = alc_get_hp_pin(spec); |
3318 | bool hp_pin_sense; | 3316 | bool hp_pin_sense; |
3319 | 3317 | ||
3320 | if (!hp_pin) | 3318 | if (!hp_pin) |
@@ -3343,7 +3341,7 @@ static void alc_default_init(struct hda_codec *codec) | |||
3343 | static void alc_default_shutup(struct hda_codec *codec) | 3341 | static void alc_default_shutup(struct hda_codec *codec) |
3344 | { | 3342 | { |
3345 | struct alc_spec *spec = codec->spec; | 3343 | struct alc_spec *spec = codec->spec; |
3346 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3344 | hda_nid_t hp_pin = alc_get_hp_pin(spec); |
3347 | bool hp_pin_sense; | 3345 | bool hp_pin_sense; |
3348 | 3346 | ||
3349 | if (!hp_pin) { | 3347 | if (!hp_pin) { |
@@ -3372,6 +3370,48 @@ static void alc_default_shutup(struct hda_codec *codec) | |||
3372 | snd_hda_shutup_pins(codec); | 3370 | snd_hda_shutup_pins(codec); |
3373 | } | 3371 | } |
3374 | 3372 | ||
3373 | static void alc294_hp_init(struct hda_codec *codec) | ||
3374 | { | ||
3375 | struct alc_spec *spec = codec->spec; | ||
3376 | hda_nid_t hp_pin = alc_get_hp_pin(spec); | ||
3377 | int i, val; | ||
3378 | |||
3379 | if (!hp_pin) | ||
3380 | return; | ||
3381 | |||
3382 | snd_hda_codec_write(codec, hp_pin, 0, | ||
3383 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
3384 | |||
3385 | msleep(100); | ||
3386 | |||
3387 | snd_hda_codec_write(codec, hp_pin, 0, | ||
3388 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | ||
3389 | |||
3390 | alc_update_coef_idx(codec, 0x6f, 0x000f, 0);/* Set HP depop to manual mode */ | ||
3391 | alc_update_coefex_idx(codec, 0x58, 0x00, 0x8000, 0x8000); /* HP depop procedure start */ | ||
3392 | |||
3393 | /* Wait for depop procedure finish */ | ||
3394 | val = alc_read_coefex_idx(codec, 0x58, 0x01); | ||
3395 | for (i = 0; i < 20 && val & 0x0080; i++) { | ||
3396 | msleep(50); | ||
3397 | val = alc_read_coefex_idx(codec, 0x58, 0x01); | ||
3398 | } | ||
3399 | /* Set HP depop to auto mode */ | ||
3400 | alc_update_coef_idx(codec, 0x6f, 0x000f, 0x000b); | ||
3401 | msleep(50); | ||
3402 | } | ||
3403 | |||
3404 | static void alc294_init(struct hda_codec *codec) | ||
3405 | { | ||
3406 | struct alc_spec *spec = codec->spec; | ||
3407 | |||
3408 | if (!spec->done_hp_init) { | ||
3409 | alc294_hp_init(codec); | ||
3410 | spec->done_hp_init = true; | ||
3411 | } | ||
3412 | alc_default_init(codec); | ||
3413 | } | ||
3414 | |||
3375 | static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg, | 3415 | static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg, |
3376 | unsigned int val) | 3416 | unsigned int val) |
3377 | { | 3417 | { |
@@ -4737,7 +4777,7 @@ static void alc_update_headset_mode(struct hda_codec *codec) | |||
4737 | struct alc_spec *spec = codec->spec; | 4777 | struct alc_spec *spec = codec->spec; |
4738 | 4778 | ||
4739 | hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]]; | 4779 | hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]]; |
4740 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 4780 | hda_nid_t hp_pin = alc_get_hp_pin(spec); |
4741 | 4781 | ||
4742 | int new_headset_mode; | 4782 | int new_headset_mode; |
4743 | 4783 | ||
@@ -5016,7 +5056,7 @@ static void alc_fixup_tpt470_dock(struct hda_codec *codec, | |||
5016 | static void alc_shutup_dell_xps13(struct hda_codec *codec) | 5056 | static void alc_shutup_dell_xps13(struct hda_codec *codec) |
5017 | { | 5057 | { |
5018 | struct alc_spec *spec = codec->spec; | 5058 | struct alc_spec *spec = codec->spec; |
5019 | int hp_pin = spec->gen.autocfg.hp_pins[0]; | 5059 | int hp_pin = alc_get_hp_pin(spec); |
5020 | 5060 | ||
5021 | /* Prevent pop noises when headphones are plugged in */ | 5061 | /* Prevent pop noises when headphones are plugged in */ |
5022 | snd_hda_codec_write(codec, hp_pin, 0, | 5062 | snd_hda_codec_write(codec, hp_pin, 0, |
@@ -5109,7 +5149,7 @@ static void alc271_hp_gate_mic_jack(struct hda_codec *codec, | |||
5109 | 5149 | ||
5110 | if (action == HDA_FIXUP_ACT_PROBE) { | 5150 | if (action == HDA_FIXUP_ACT_PROBE) { |
5111 | int mic_pin = find_ext_mic_pin(codec); | 5151 | int mic_pin = find_ext_mic_pin(codec); |
5112 | int hp_pin = spec->gen.autocfg.hp_pins[0]; | 5152 | int hp_pin = alc_get_hp_pin(spec); |
5113 | 5153 | ||
5114 | if (snd_BUG_ON(!mic_pin || !hp_pin)) | 5154 | if (snd_BUG_ON(!mic_pin || !hp_pin)) |
5115 | return; | 5155 | return; |
@@ -5591,6 +5631,7 @@ enum { | |||
5591 | ALC294_FIXUP_ASUS_HEADSET_MIC, | 5631 | ALC294_FIXUP_ASUS_HEADSET_MIC, |
5592 | ALC294_FIXUP_ASUS_SPK, | 5632 | ALC294_FIXUP_ASUS_SPK, |
5593 | ALC225_FIXUP_HEADSET_JACK, | 5633 | ALC225_FIXUP_HEADSET_JACK, |
5634 | ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE, | ||
5594 | }; | 5635 | }; |
5595 | 5636 | ||
5596 | static const struct hda_fixup alc269_fixups[] = { | 5637 | static const struct hda_fixup alc269_fixups[] = { |
@@ -6537,6 +6578,15 @@ static const struct hda_fixup alc269_fixups[] = { | |||
6537 | .type = HDA_FIXUP_FUNC, | 6578 | .type = HDA_FIXUP_FUNC, |
6538 | .v.func = alc_fixup_headset_jack, | 6579 | .v.func = alc_fixup_headset_jack, |
6539 | }, | 6580 | }, |
6581 | [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = { | ||
6582 | .type = HDA_FIXUP_PINS, | ||
6583 | .v.pins = (const struct hda_pintbl[]) { | ||
6584 | { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | ||
6585 | { } | ||
6586 | }, | ||
6587 | .chained = true, | ||
6588 | .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC | ||
6589 | }, | ||
6540 | }; | 6590 | }; |
6541 | 6591 | ||
6542 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 6592 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
@@ -6715,6 +6765,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
6715 | SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), | 6765 | SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), |
6716 | SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC), | 6766 | SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC), |
6717 | SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC), | 6767 | SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC), |
6768 | SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
6718 | SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS), | 6769 | SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS), |
6719 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), | 6770 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), |
6720 | SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), | 6771 | SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), |
@@ -7373,37 +7424,6 @@ static void alc269_fill_coef(struct hda_codec *codec) | |||
7373 | alc_update_coef_idx(codec, 0x4, 0, 1<<11); | 7424 | alc_update_coef_idx(codec, 0x4, 0, 1<<11); |
7374 | } | 7425 | } |
7375 | 7426 | ||
7376 | static void alc294_hp_init(struct hda_codec *codec) | ||
7377 | { | ||
7378 | struct alc_spec *spec = codec->spec; | ||
7379 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | ||
7380 | int i, val; | ||
7381 | |||
7382 | if (!hp_pin) | ||
7383 | return; | ||
7384 | |||
7385 | snd_hda_codec_write(codec, hp_pin, 0, | ||
7386 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
7387 | |||
7388 | msleep(100); | ||
7389 | |||
7390 | snd_hda_codec_write(codec, hp_pin, 0, | ||
7391 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | ||
7392 | |||
7393 | alc_update_coef_idx(codec, 0x6f, 0x000f, 0);/* Set HP depop to manual mode */ | ||
7394 | alc_update_coefex_idx(codec, 0x58, 0x00, 0x8000, 0x8000); /* HP depop procedure start */ | ||
7395 | |||
7396 | /* Wait for depop procedure finish */ | ||
7397 | val = alc_read_coefex_idx(codec, 0x58, 0x01); | ||
7398 | for (i = 0; i < 20 && val & 0x0080; i++) { | ||
7399 | msleep(50); | ||
7400 | val = alc_read_coefex_idx(codec, 0x58, 0x01); | ||
7401 | } | ||
7402 | /* Set HP depop to auto mode */ | ||
7403 | alc_update_coef_idx(codec, 0x6f, 0x000f, 0x000b); | ||
7404 | msleep(50); | ||
7405 | } | ||
7406 | |||
7407 | /* | 7427 | /* |
7408 | */ | 7428 | */ |
7409 | static int patch_alc269(struct hda_codec *codec) | 7429 | static int patch_alc269(struct hda_codec *codec) |
@@ -7529,7 +7549,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
7529 | spec->codec_variant = ALC269_TYPE_ALC294; | 7549 | spec->codec_variant = ALC269_TYPE_ALC294; |
7530 | spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */ | 7550 | spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */ |
7531 | alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */ | 7551 | alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */ |
7532 | alc294_hp_init(codec); | 7552 | spec->init_hook = alc294_init; |
7533 | break; | 7553 | break; |
7534 | case 0x10ec0300: | 7554 | case 0x10ec0300: |
7535 | spec->codec_variant = ALC269_TYPE_ALC300; | 7555 | spec->codec_variant = ALC269_TYPE_ALC300; |
@@ -7541,7 +7561,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
7541 | spec->codec_variant = ALC269_TYPE_ALC700; | 7561 | spec->codec_variant = ALC269_TYPE_ALC700; |
7542 | spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */ | 7562 | spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */ |
7543 | alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */ | 7563 | alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */ |
7544 | alc294_hp_init(codec); | 7564 | spec->init_hook = alc294_init; |
7545 | break; | 7565 | break; |
7546 | 7566 | ||
7547 | } | 7567 | } |