]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - sound/pci/hda/patch_realtek.c
Merge branch 'for-linus' into HEAD
[mirror_ubuntu-bionic-kernel.git] / sound / pci / hda / patch_realtek.c
index 0b4ea6c7eca9b8f23692b10186daad2e11e3e96b..ee1ba2293b236145b29a2566328b883d836cb094 100644 (file)
@@ -395,6 +395,8 @@ static int alc_auto_parse_customize_define(struct hda_codec *codec)
                goto do_sku;
        }
 
+       if (!codec->bus->pci)
+               return -1;
        ass = codec->subsystem_id & 0xffff;
        if (ass != codec->bus->pci->subsystem_device && (ass & 1))
                goto do_sku;
@@ -483,7 +485,8 @@ static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
        }
 
        ass = codec->subsystem_id & 0xffff;
-       if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
+       if (codec->bus->pci &&
+           ass != codec->bus->pci->subsystem_device && (ass & 1))
                goto do_sku;
 
        /* invalid SSID, check the special NID pin defcfg instead */
@@ -845,11 +848,7 @@ static inline void alc_shutup(struct hda_codec *codec)
                snd_hda_shutup_pins(codec);
 }
 
-static void alc_free(struct hda_codec *codec)
-{
-       snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_FREE);
-       snd_hda_gen_free(codec);
-}
+#define alc_free       snd_hda_gen_free
 
 #ifdef CONFIG_PM
 static void alc_power_eapd(struct hda_codec *codec)
@@ -970,6 +969,8 @@ static int alc_codec_rename_from_preset(struct hda_codec *codec)
                        return alc_codec_rename(codec, p->name);
        }
 
+       if (!codec->bus->pci)
+               return 0;
        for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
                if (q->codec_vendor_id != codec->vendor_id)
                        continue;
@@ -4552,13 +4553,15 @@ static int patch_alc269(struct hda_codec *codec)
                spec->codec_variant = ALC269_TYPE_ALC269VA;
                switch (alc_get_coef0(codec) & 0x00f0) {
                case 0x0010:
-                       if (codec->bus->pci->subsystem_vendor == 0x1025 &&
+                       if (codec->bus->pci &&
+                           codec->bus->pci->subsystem_vendor == 0x1025 &&
                            spec->cdefine.platform_type == 1)
                                err = alc_codec_rename(codec, "ALC271X");
                        spec->codec_variant = ALC269_TYPE_ALC269VB;
                        break;
                case 0x0020:
-                       if (codec->bus->pci->subsystem_vendor == 0x17aa &&
+                       if (codec->bus->pci &&
+                           codec->bus->pci->subsystem_vendor == 0x17aa &&
                            codec->bus->pci->subsystem_device == 0x21f3)
                                err = alc_codec_rename(codec, "ALC3202");
                        spec->codec_variant = ALC269_TYPE_ALC269VC;
@@ -4921,8 +4924,54 @@ static void alc_fixup_bass_chmap(struct hda_codec *codec,
        }
 }
 
+/* turn on/off mute LED per vmaster hook */
+static void alc662_led_gpio1_mute_hook(void *private_data, int enabled)
+{
+       struct hda_codec *codec = private_data;
+       struct alc_spec *spec = codec->spec;
+       unsigned int oldval = spec->gpio_led;
+
+       if (enabled)
+               spec->gpio_led &= ~0x01;
+       else
+               spec->gpio_led |= 0x01;
+       if (spec->gpio_led != oldval)
+               snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
+                                   spec->gpio_led);
+}
+
+/* avoid D3 for keeping GPIO up */
+static unsigned int gpio_led_power_filter(struct hda_codec *codec,
+                                         hda_nid_t nid,
+                                         unsigned int power_state)
+{
+       struct alc_spec *spec = codec->spec;
+       if (nid == codec->afg && power_state == AC_PWRST_D3 && spec->gpio_led)
+               return AC_PWRST_D0;
+       return power_state;
+}
+
+static void alc662_fixup_led_gpio1(struct hda_codec *codec,
+                                  const struct hda_fixup *fix, int action)
+{
+       struct alc_spec *spec = codec->spec;
+       static const struct hda_verb gpio_init[] = {
+               { 0x01, AC_VERB_SET_GPIO_MASK, 0x01 },
+               { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 },
+               {}
+       };
+
+       if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+               spec->gen.vmaster_mute.hook = alc662_led_gpio1_mute_hook;
+               spec->gpio_led = 0;
+               snd_hda_add_verbs(codec, gpio_init);
+               codec->power_filter = gpio_led_power_filter;
+       }
+}
+
 enum {
        ALC662_FIXUP_ASPIRE,
+       ALC662_FIXUP_LED_GPIO1,
        ALC662_FIXUP_IDEAPAD,
        ALC272_FIXUP_MARIO,
        ALC662_FIXUP_CZC_P10T,
@@ -4941,9 +4990,10 @@ enum {
        ALC662_FIXUP_INV_DMIC,
        ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
        ALC668_FIXUP_HEADSET_MODE,
-       ALC662_FIXUP_BASS_CHMAP,
+       ALC662_FIXUP_BASS_MODE4_CHMAP,
+       ALC662_FIXUP_BASS_16,
        ALC662_FIXUP_BASS_1A,
-       ALC662_FIXUP_BASS_1A_CHMAP,
+       ALC662_FIXUP_BASS_CHMAP,
        ALC668_FIXUP_AUTO_MUTE,
 };
 
@@ -4955,12 +5005,18 @@ static const struct hda_fixup alc662_fixups[] = {
                        { }
                }
        },
+       [ALC662_FIXUP_LED_GPIO1] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc662_fixup_led_gpio1,
+       },
        [ALC662_FIXUP_IDEAPAD] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = (const struct hda_pintbl[]) {
                        { 0x17, 0x99130112 }, /* subwoofer */
                        { }
-               }
+               },
+               .chained = true,
+               .chain_id = ALC662_FIXUP_LED_GPIO1,
        },
        [ALC272_FIXUP_MARIO] = {
                .type = HDA_FIXUP_FUNC,
@@ -5125,24 +5181,33 @@ static const struct hda_fixup alc662_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc_fixup_headset_mode_alc668,
        },
-       [ALC662_FIXUP_BASS_CHMAP] = {
+       [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc_fixup_bass_chmap,
                .chained = true,
                .chain_id = ALC662_FIXUP_ASUS_MODE4
        },
+       [ALC662_FIXUP_BASS_16] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       {0x16, 0x80106111}, /* bass speaker */
+                       {}
+               },
+               .chained = true,
+               .chain_id = ALC662_FIXUP_BASS_CHMAP,
+       },
        [ALC662_FIXUP_BASS_1A] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = (const struct hda_pintbl[]) {
                        {0x1a, 0x80106111}, /* bass speaker */
                        {}
                },
+               .chained = true,
+               .chain_id = ALC662_FIXUP_BASS_CHMAP,
        },
-       [ALC662_FIXUP_BASS_1A_CHMAP] = {
+       [ALC662_FIXUP_BASS_CHMAP] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc_fixup_bass_chmap,
-               .chained = true,
-               .chain_id = ALC662_FIXUP_BASS_1A,
        },
 };
 
@@ -5164,9 +5229,11 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE),
        SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
-       SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A_CHMAP),
-       SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_CHMAP),
-       SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_CHMAP),
+       SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A),
+       SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
+       SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
+       SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
+       SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
        SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
        SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
        SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
@@ -5307,7 +5374,7 @@ static int patch_alc662(struct hda_codec *codec)
                spec->gen.beep_nid = 0x01;
 
        if ((alc_get_coef0(codec) & (1 << 14)) &&
-           codec->bus->pci->subsystem_vendor == 0x1025 &&
+           codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
            spec->cdefine.platform_type == 1) {
                err = alc_codec_rename(codec, "ALC272X");
                if (err < 0)