Skip to content

Commit 504c193

Browse files
committed
Backported DELL XPS13 microphone patch
1 parent 7b43b47 commit 504c193

File tree

1 file changed

+162
-0
lines changed

1 file changed

+162
-0
lines changed

sound/pci/hda/patch_realtek.c

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2912,6 +2912,8 @@ static void alc283_init(struct hda_codec *codec)
29122912

29132913
if (!hp_pin)
29142914
return;
2915+
2916+
msleep(30);
29152917
hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
29162918

29172919
/* Index 0x43 Direct Drive HP AMP LPM Control 1 */
@@ -3583,6 +3585,14 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
35833585
WRITE_COEF(0x32, 0x42a3),
35843586
{}
35853587
};
3588+
static struct coef_fw coef0288[] = {
3589+
UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
3590+
UPDATE_COEF(0x50, 0x2000, 0x2000),
3591+
UPDATE_COEF(0x56, 0x0006, 0x0006),
3592+
UPDATE_COEF(0x66, 0x0008, 0),
3593+
UPDATE_COEF(0x67, 0x2000, 0),
3594+
{}
3595+
};
35863596
static struct coef_fw coef0292[] = {
35873597
WRITE_COEF(0x76, 0x000e),
35883598
WRITE_COEF(0x6c, 0x2400),
@@ -3607,12 +3617,17 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
36073617

36083618
switch (codec->vendor_id) {
36093619
case 0x10ec0255:
3620+
case 0x10ec0256:
36103621
alc_process_coef_fw(codec, coef0255);
36113622
break;
36123623
case 0x10ec0233:
36133624
case 0x10ec0283:
36143625
alc_process_coef_fw(codec, coef0233);
36153626
break;
3627+
case 0x10ec0286:
3628+
case 0x10ec0288:
3629+
alc_process_coef_fw(codec, coef0288);
3630+
break;
36163631
case 0x10ec0292:
36173632
alc_process_coef_fw(codec, coef0292);
36183633
break;
@@ -3642,6 +3657,14 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
36423657
WRITE_COEF(0x26, 0x008c),
36433658
{}
36443659
};
3660+
static struct coef_fw coef0288[] = {
3661+
UPDATE_COEF(0x50, 0x2000, 0),
3662+
UPDATE_COEF(0x56, 0x0006, 0),
3663+
UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
3664+
UPDATE_COEF(0x66, 0x0008, 0x0008),
3665+
UPDATE_COEF(0x67, 0x2000, 0x2000),
3666+
{}
3667+
};
36453668
static struct coef_fw coef0292[] = {
36463669
WRITE_COEF(0x19, 0xa208),
36473670
WRITE_COEF(0x2e, 0xacf0),
@@ -3662,6 +3685,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
36623685

36633686
switch (codec->vendor_id) {
36643687
case 0x10ec0255:
3688+
case 0x10ec0256:
36653689
alc_write_coef_idx(codec, 0x45, 0xc489);
36663690
snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
36673691
alc_process_coef_fw(codec, coef0255);
@@ -3674,6 +3698,13 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
36743698
alc_process_coef_fw(codec, coef0233);
36753699
snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
36763700
break;
3701+
case 0x10ec0286:
3702+
case 0x10ec0288:
3703+
alc_update_coef_idx(codec, 0x4f, 0x000c, 0);
3704+
snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3705+
alc_process_coef_fw(codec, coef0288);
3706+
snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3707+
break;
36773708
case 0x10ec0292:
36783709
snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
36793710
alc_process_coef_fw(codec, coef0292);
@@ -3709,6 +3740,14 @@ static void alc_headset_mode_default(struct hda_codec *codec)
37093740
WRITE_COEF(0x32, 0x4ea3),
37103741
{}
37113742
};
3743+
static struct coef_fw coef0288[] = {
3744+
UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
3745+
UPDATE_COEF(0x50, 0x2000, 0x2000),
3746+
UPDATE_COEF(0x56, 0x0006, 0x0006),
3747+
UPDATE_COEF(0x66, 0x0008, 0),
3748+
UPDATE_COEF(0x67, 0x2000, 0),
3749+
{}
3750+
};
37123751
static struct coef_fw coef0292[] = {
37133752
WRITE_COEF(0x76, 0x000e),
37143753
WRITE_COEF(0x6c, 0x2400),
@@ -3731,12 +3770,18 @@ static void alc_headset_mode_default(struct hda_codec *codec)
37313770

37323771
switch (codec->vendor_id) {
37333772
case 0x10ec0255:
3773+
case 0x10ec0256:
37343774
alc_process_coef_fw(codec, coef0255);
37353775
break;
37363776
case 0x10ec0233:
37373777
case 0x10ec0283:
37383778
alc_process_coef_fw(codec, coef0233);
37393779
break;
3780+
case 0x10ec0286:
3781+
case 0x10ec0288:
3782+
alc_process_coef_fw(codec, coef0288);
3783+
break;
3784+
break;
37403785
case 0x10ec0292:
37413786
alc_process_coef_fw(codec, coef0292);
37423787
break;
@@ -3765,6 +3810,13 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
37653810
WRITE_COEF(0x32, 0x4ea3),
37663811
{}
37673812
};
3813+
static struct coef_fw coef0288[] = {
3814+
UPDATE_COEF(0x50, 0x2000, 0x2000),
3815+
UPDATE_COEF(0x56, 0x0006, 0x0006),
3816+
UPDATE_COEF(0x66, 0x0008, 0),
3817+
UPDATE_COEF(0x67, 0x2000, 0),
3818+
{}
3819+
};
37683820
static struct coef_fw coef0292[] = {
37693821
WRITE_COEF(0x6b, 0xd429),
37703822
WRITE_COEF(0x76, 0x0008),
@@ -3785,12 +3837,19 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
37853837

37863838
switch (codec->vendor_id) {
37873839
case 0x10ec0255:
3840+
case 0x10ec0256:
37883841
alc_process_coef_fw(codec, coef0255);
37893842
break;
37903843
case 0x10ec0233:
37913844
case 0x10ec0283:
37923845
alc_process_coef_fw(codec, coef0233);
37933846
break;
3847+
case 0x10ec0286:
3848+
case 0x10ec0288:
3849+
alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
3850+
msleep(300);
3851+
alc_process_coef_fw(codec, coef0288);
3852+
break;
37943853
case 0x10ec0292:
37953854
alc_process_coef_fw(codec, coef0292);
37963855
break;
@@ -3819,6 +3878,13 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
38193878
WRITE_COEF(0x32, 0x4ea3),
38203879
{}
38213880
};
3881+
static struct coef_fw coef0288[] = {
3882+
UPDATE_COEF(0x50, 0x2000, 0x2000),
3883+
UPDATE_COEF(0x56, 0x0006, 0x0006),
3884+
UPDATE_COEF(0x66, 0x0008, 0),
3885+
UPDATE_COEF(0x67, 0x2000, 0),
3886+
{}
3887+
};
38223888
static struct coef_fw coef0292[] = {
38233889
WRITE_COEF(0x6b, 0xe429),
38243890
WRITE_COEF(0x76, 0x0008),
@@ -3839,12 +3905,19 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
38393905

38403906
switch (codec->vendor_id) {
38413907
case 0x10ec0255:
3908+
case 0x10ec0256:
38423909
alc_process_coef_fw(codec, coef0255);
38433910
break;
38443911
case 0x10ec0233:
38453912
case 0x10ec0283:
38463913
alc_process_coef_fw(codec, coef0233);
38473914
break;
3915+
case 0x10ec0286:
3916+
case 0x10ec0288:
3917+
alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
3918+
msleep(300);
3919+
alc_process_coef_fw(codec, coef0288);
3920+
break;
38483921
case 0x10ec0292:
38493922
alc_process_coef_fw(codec, coef0292);
38503923
break;
@@ -3869,6 +3942,10 @@ static void alc_determine_headset_type(struct hda_codec *codec)
38693942
conteol) */
38703943
{}
38713944
};
3945+
static struct coef_fw coef0288[] = {
3946+
UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
3947+
{}
3948+
};
38723949
static struct coef_fw coef0293[] = {
38733950
UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
38743951
WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
@@ -3884,6 +3961,7 @@ static void alc_determine_headset_type(struct hda_codec *codec)
38843961

38853962
switch (codec->vendor_id) {
38863963
case 0x10ec0255:
3964+
case 0x10ec0256:
38873965
alc_process_coef_fw(codec, coef0255);
38883966
msleep(300);
38893967
val = alc_read_coef_idx(codec, 0x46);
@@ -3896,6 +3974,13 @@ static void alc_determine_headset_type(struct hda_codec *codec)
38963974
val = alc_read_coef_idx(codec, 0x46);
38973975
is_ctia = (val & 0x0070) == 0x0070;
38983976
break;
3977+
case 0x10ec0286:
3978+
case 0x10ec0288:
3979+
alc_process_coef_fw(codec, coef0288);
3980+
msleep(350);
3981+
val = alc_read_coef_idx(codec, 0x50);
3982+
is_ctia = (val & 0x0070) == 0x0070;
3983+
break;
38993984
case 0x10ec0292:
39003985
alc_write_coef_idx(codec, 0x6b, 0xd429);
39013986
msleep(300);
@@ -4079,6 +4164,29 @@ static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
40794164
alc_fixup_headset_mode(codec, fix, action);
40804165
}
40814166

4167+
static void alc288_update_headset_jack_cb(struct hda_codec *codec,
4168+
struct hda_jack_callback *jack)
4169+
{
4170+
struct alc_spec *spec = codec->spec;
4171+
int present;
4172+
4173+
alc_update_headset_jack_cb(codec, jack);
4174+
/* Headset Mic enable or disable, only for Dell Dino */
4175+
present = spec->gen.hp_jack_present ? 0x40 : 0;
4176+
snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4177+
present);
4178+
}
4179+
4180+
static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
4181+
const struct hda_fixup *fix, int action)
4182+
{
4183+
alc_fixup_headset_mode(codec, fix, action);
4184+
if (action == HDA_FIXUP_ACT_PROBE) {
4185+
struct alc_spec *spec = codec->spec;
4186+
spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
4187+
}
4188+
}
4189+
40824190
static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
40834191
const struct hda_fixup *fix, int action)
40844192
{
@@ -4418,6 +4526,9 @@ enum {
44184526
ALC286_FIXUP_HP_GPIO_LED,
44194527
ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
44204528
ALC280_FIXUP_HP_DOCK_PINS,
4529+
ALC288_FIXUP_DELL_HEADSET_MODE,
4530+
ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
4531+
ALC288_FIXUP_DELL_XPS_13_GPIO6,
44214532
};
44224533

44234534
static const struct hda_fixup alc269_fixups[] = {
@@ -4906,6 +5017,33 @@ static const struct hda_fixup alc269_fixups[] = {
49065017
.chained = true,
49075018
.chain_id = ALC280_FIXUP_HP_GPIO4
49085019
},
5020+
[ALC288_FIXUP_DELL_HEADSET_MODE] = {
5021+
.type = HDA_FIXUP_FUNC,
5022+
.v.func = alc_fixup_headset_mode_dell_alc288,
5023+
.chained = true,
5024+
.chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
5025+
},
5026+
[ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5027+
.type = HDA_FIXUP_PINS,
5028+
.v.pins = (const struct hda_pintbl[]) {
5029+
{ 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5030+
{ 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5031+
{ }
5032+
},
5033+
.chained = true,
5034+
.chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
5035+
},
5036+
[ALC288_FIXUP_DELL_XPS_13_GPIO6] = {
5037+
.type = HDA_FIXUP_VERBS,
5038+
.v.verbs = (const struct hda_verb[]) {
5039+
{0x01, AC_VERB_SET_GPIO_MASK, 0x40},
5040+
{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x40},
5041+
{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5042+
{ }
5043+
},
5044+
.chained = true,
5045+
.chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
5046+
},
49095047
};
49105048

49115049
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -5132,6 +5270,13 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
51325270
{0x1b, 0x411111f0}, \
51335271
{0x1e, 0x411111f0}
51345272

5273+
#define ALC288_STANDARD_PINS \
5274+
{0x17, 0x411111f0}, \
5275+
{0x18, 0x411111f0}, \
5276+
{0x19, 0x411111f0}, \
5277+
{0x1a, 0x411111f0}, \
5278+
{0x1e, 0x411111f0}
5279+
51355280
#define ALC290_STANDARD_PINS \
51365281
{0x12, 0x99a30130}, \
51375282
{0x13, 0x40000000}, \
@@ -5217,6 +5362,16 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
52175362
{0x17, 0x40000000},
52185363
{0x1d, 0x40700001},
52195364
{0x21, 0x02211050}),
5365+
SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5366+
{0x12, 0x90a60140},
5367+
{0x13, 0x40000000},
5368+
{0x14, 0x90170110},
5369+
{0x19, 0x411111f0},
5370+
{0x1a, 0x411111f0},
5371+
{0x1b, 0x411111f0},
5372+
{0x1d, 0x40700001},
5373+
{0x1e, 0x411111f0},
5374+
{0x21, 0x02211020}),
52205375
SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
52215376
{0x12, 0x90a60130},
52225377
{0x13, 0x40000000},
@@ -5317,6 +5472,13 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
53175472
{0x19, 0x03a11020},
53185473
{0x1d, 0x40e00001},
53195474
{0x21, 0x0321101f}),
5475+
SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL_XPS_13_GPIO6,
5476+
ALC288_STANDARD_PINS,
5477+
{0x12, 0x90a60120},
5478+
{0x13, 0x40000000},
5479+
{0x14, 0x90170110},
5480+
{0x1d, 0x4076832d},
5481+
{0x21, 0x0321101f}),
53205482
SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
53215483
ALC290_STANDARD_PINS,
53225484
{0x14, 0x411111f0},

0 commit comments

Comments
 (0)