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.c138
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 */
519static 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)
2958static void alc282_init(struct hda_codec *codec) 2966static 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)
2995static void alc282_shutup(struct hda_codec *codec) 3003static 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)
3073static void alc283_init(struct hda_codec *codec) 3081static 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)
3114static void alc283_shutup(struct hda_codec *codec) 3117static 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)
3155static void alc256_init(struct hda_codec *codec) 3153static 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)
3191static void alc256_shutup(struct hda_codec *codec) 3189static 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)
3227static void alc225_init(struct hda_codec *codec) 3225static 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)
3270static void alc225_shutup(struct hda_codec *codec) 3268static 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)
3314static void alc_default_init(struct hda_codec *codec) 3312static 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)
3343static void alc_default_shutup(struct hda_codec *codec) 3341static 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
3373static 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
3404static 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
3375static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg, 3415static 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,
5016static void alc_shutup_dell_xps13(struct hda_codec *codec) 5056static 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
5596static const struct hda_fixup alc269_fixups[] = { 5637static 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
6542static const struct snd_pci_quirk alc269_fixup_tbl[] = { 6592static 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
7376static 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 */
7409static int patch_alc269(struct hda_codec *codec) 7429static 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 }