This is a cherry pick of:
e1e62b98ebddc3234f3259019d3236f66fc667f8
and
f3b703326541d0c1ce85f5e570f6d2b6bd4296ec

With some minor refactoring to apply to v3.19.y.

Signed-off-by: Mario Limonciello <[email protected]>
---
 sound/pci/hda/patch_realtek.c | 144 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 144 insertions(+)

diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 172c899..61a64c8 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -3510,6 +3510,14 @@ static void alc_headset_mode_unplugged(struct hda_codec 
*codec)
                WRITE_COEF(0x32, 0x42a3),
                {}
        };
+       static struct coef_fw coef0288[] = {
+               UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
+               UPDATE_COEF(0x50, 0x2000, 0x2000),
+               UPDATE_COEF(0x56, 0x0006, 0x0006),
+               UPDATE_COEF(0x66, 0x0008, 0),
+               UPDATE_COEF(0x67, 0x2000, 0),
+               {}
+       };
        static struct coef_fw coef0292[] = {
                WRITE_COEF(0x76, 0x000e),
                WRITE_COEF(0x6c, 0x2400),
@@ -3540,6 +3548,10 @@ static void alc_headset_mode_unplugged(struct hda_codec 
*codec)
        case 0x10ec0283:
                alc_process_coef_fw(codec, coef0233);
                break;
+       case 0x10ec0286:
+       case 0x10ec0288:
+               alc_process_coef_fw(codec, coef0288);
+               break;
        case 0x10ec0292:
                alc_process_coef_fw(codec, coef0292);
                break;
@@ -3569,6 +3581,14 @@ static void alc_headset_mode_mic_in(struct hda_codec 
*codec, hda_nid_t hp_pin,
                WRITE_COEF(0x26, 0x008c),
                {}
        };
+       static struct coef_fw coef0288[] = {
+               UPDATE_COEF(0x50, 0x2000, 0),
+               UPDATE_COEF(0x56, 0x0006, 0),
+               UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
+               UPDATE_COEF(0x66, 0x0008, 0x0008),
+               UPDATE_COEF(0x67, 0x2000, 0x2000),
+               {}
+       };
        static struct coef_fw coef0292[] = {
                WRITE_COEF(0x19, 0xa208),
                WRITE_COEF(0x2e, 0xacf0),
@@ -3601,6 +3621,13 @@ static void alc_headset_mode_mic_in(struct hda_codec 
*codec, hda_nid_t hp_pin,
                alc_process_coef_fw(codec, coef0233);
                snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
                break;
+       case 0x10ec0286:
+       case 0x10ec0288:
+               alc_update_coef_idx(codec, 0x4f, 0x000c, 0);
+               snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
+               alc_process_coef_fw(codec, coef0288);
+               snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
+               break;
        case 0x10ec0292:
                snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
                alc_process_coef_fw(codec, coef0292);
@@ -3636,6 +3663,14 @@ static void alc_headset_mode_default(struct hda_codec 
*codec)
                WRITE_COEF(0x32, 0x4ea3),
                {}
        };
+       static struct coef_fw coef0288[] = {
+               UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
+               UPDATE_COEF(0x50, 0x2000, 0x2000),
+               UPDATE_COEF(0x56, 0x0006, 0x0006),
+               UPDATE_COEF(0x66, 0x0008, 0),
+               UPDATE_COEF(0x67, 0x2000, 0),
+               {}
+       };
        static struct coef_fw coef0292[] = {
                WRITE_COEF(0x76, 0x000e),
                WRITE_COEF(0x6c, 0x2400),
@@ -3664,6 +3699,11 @@ static void alc_headset_mode_default(struct hda_codec 
*codec)
        case 0x10ec0283:
                alc_process_coef_fw(codec, coef0233);
                break;
+       case 0x10ec0286:
+       case 0x10ec0288:
+               alc_process_coef_fw(codec, coef0288);
+               break;
+               break;
        case 0x10ec0292:
                alc_process_coef_fw(codec, coef0292);
                break;
@@ -3692,6 +3732,13 @@ static void alc_headset_mode_ctia(struct hda_codec 
*codec)
                WRITE_COEF(0x32, 0x4ea3),
                {}
        };
+       static struct coef_fw coef0288[] = {
+               UPDATE_COEF(0x50, 0x2000, 0x2000),
+               UPDATE_COEF(0x56, 0x0006, 0x0006),
+               UPDATE_COEF(0x66, 0x0008, 0),
+               UPDATE_COEF(0x67, 0x2000, 0),
+               {}
+       };
        static struct coef_fw coef0292[] = {
                WRITE_COEF(0x6b, 0xd429),
                WRITE_COEF(0x76, 0x0008),
@@ -3718,6 +3765,12 @@ static void alc_headset_mode_ctia(struct hda_codec 
*codec)
        case 0x10ec0283:
                alc_process_coef_fw(codec, coef0233);
                break;
+       case 0x10ec0286:
+       case 0x10ec0288:
+               alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
+               msleep(300);
+               alc_process_coef_fw(codec, coef0288);
+               break;
        case 0x10ec0292:
                alc_process_coef_fw(codec, coef0292);
                break;
@@ -3746,6 +3799,13 @@ static void alc_headset_mode_omtp(struct hda_codec 
*codec)
                WRITE_COEF(0x32, 0x4ea3),
                {}
        };
+       static struct coef_fw coef0288[] = {
+               UPDATE_COEF(0x50, 0x2000, 0x2000),
+               UPDATE_COEF(0x56, 0x0006, 0x0006),
+               UPDATE_COEF(0x66, 0x0008, 0),
+               UPDATE_COEF(0x67, 0x2000, 0),
+               {}
+       };
        static struct coef_fw coef0292[] = {
                WRITE_COEF(0x6b, 0xe429),
                WRITE_COEF(0x76, 0x0008),
@@ -3772,6 +3832,12 @@ static void alc_headset_mode_omtp(struct hda_codec 
*codec)
        case 0x10ec0283:
                alc_process_coef_fw(codec, coef0233);
                break;
+       case 0x10ec0286:
+       case 0x10ec0288:
+               alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
+               msleep(300);
+               alc_process_coef_fw(codec, coef0288);
+               break;
        case 0x10ec0292:
                alc_process_coef_fw(codec, coef0292);
                break;
@@ -3796,6 +3862,10 @@ static void alc_determine_headset_type(struct hda_codec 
*codec)
  conteol) */
                {}
        };
+       static struct coef_fw coef0288[] = {
+               UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
+               {}
+       };
        static struct coef_fw coef0293[] = {
                UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
                WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
@@ -3823,6 +3893,13 @@ static void alc_determine_headset_type(struct hda_codec 
*codec)
                val = alc_read_coef_idx(codec, 0x46);
                is_ctia = (val & 0x0070) == 0x0070;
                break;
+       case 0x10ec0286:
+       case 0x10ec0288:
+               alc_process_coef_fw(codec, coef0288);
+               msleep(350);
+               val = alc_read_coef_idx(codec, 0x50);
+               is_ctia = (val & 0x0070) == 0x0070;
+               break;
        case 0x10ec0292:
                alc_write_coef_idx(codec, 0x6b, 0xd429);
                msleep(300);
@@ -4006,6 +4083,29 @@ static void 
alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
                alc_fixup_headset_mode(codec, fix, action);
 }
 
+static void alc288_update_headset_jack_cb(struct hda_codec *codec,
+                                      struct hda_jack_callback *jack)
+{
+       struct alc_spec *spec = codec->spec;
+       int present;
+
+       alc_update_headset_jack_cb(codec, jack);
+       /* Headset Mic enable or disable, only for Dell Dino */
+       present = spec->gen.hp_jack_present ? 0x40 : 0;
+       snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
+                               present);
+}
+
+static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
+                               const struct hda_fixup *fix, int action)
+{
+       alc_fixup_headset_mode(codec, fix, action);
+       if (action == HDA_FIXUP_ACT_PROBE) {
+               struct alc_spec *spec = codec->spec;
+               spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
+       }
+}
+
 static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
                                        const struct hda_fixup *fix, int action)
 {
@@ -4344,6 +4444,9 @@ enum {
        ALC282_FIXUP_ASPIRE_V5_PINS,
        ALC280_FIXUP_HP_GPIO4,
        ALC286_FIXUP_HP_GPIO_LED,
+       ALC288_FIXUP_DELL_HEADSET_MODE,
+       ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
+       ALC288_FIXUP_DELL_XPS_13_GPIO6,
 };
 
 static const struct hda_fixup alc269_fixups[] = {
@@ -4824,6 +4927,33 @@ static const struct hda_fixup alc269_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc286_fixup_hp_gpio_led,
        },
+       [ALC288_FIXUP_DELL_HEADSET_MODE] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc_fixup_headset_mode_dell_alc288,
+               .chained = true,
+               .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
+       },
+       [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       { 0x18, 0x01a1913c }, /* use as headset mic, without 
its own jack detect */
+                       { 0x1a, 0x01a1913d }, /* use as headphone mic, without 
its own jack detect */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
+       },
+       [ALC288_FIXUP_DELL_XPS_13_GPIO6] = {
+               .type = HDA_FIXUP_VERBS,
+               .v.verbs = (const struct hda_verb[]) {
+                       {0x01, AC_VERB_SET_GPIO_MASK, 0x40},
+                       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x40},
+                       {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -5048,6 +5178,13 @@ static const struct hda_model_fixup 
alc269_fixup_models[] = {
        {0x1b, 0x411111f0}, \
        {0x1e, 0x411111f0}
 
+#define ALC288_STANDARD_PINS \
+       {0x17, 0x411111f0}, \
+       {0x18, 0x411111f0}, \
+       {0x19, 0x411111f0}, \
+       {0x1a, 0x411111f0}, \
+       {0x1e, 0x411111f0}
+
 #define ALC290_STANDARD_PINS \
        {0x12, 0x99a30130}, \
        {0x13, 0x40000000}, \
@@ -5233,6 +5370,13 @@ static const struct snd_hda_pin_quirk 
alc269_pin_fixup_tbl[] = {
                {0x19, 0x03a11020},
                {0x1d, 0x40e00001},
                {0x21, 0x0321101f}),
+       SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", 
ALC288_FIXUP_DELL_XPS_13_GPIO6,
+               ALC288_STANDARD_PINS,
+               {0x12, 0x90a60120},
+               {0x13, 0x40000000},
+               {0x14, 0x90170110},
+               {0x1d, 0x4076832d},
+               {0x21, 0x0321101f}),
        SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", 
ALC269_FIXUP_HP_MUTE_LED_MIC1,
                ALC290_STANDARD_PINS,
                {0x14, 0x411111f0},
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to