diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
| -rw-r--r-- | sound/pci/hda/patch_realtek.c | 1570 |
1 files changed, 1479 insertions, 91 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index bc07d369fac..b60824e9040 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -118,7 +118,8 @@ struct alc_spec { int init_amp; int codec_variant; /* flag for other variants */ - bool has_alc5505_dsp; + unsigned int has_alc5505_dsp:1; + unsigned int no_depop_delay:1; /* for PLL fix */ hda_nid_t pll_nid; @@ -280,8 +281,11 @@ static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) */ static void alc_eapd_shutup(struct hda_codec *codec) { + struct alc_spec *spec = codec->spec; + alc_auto_setup_eapd(codec, false); - msleep(200); + if (!spec->no_depop_delay) + msleep(200); snd_hda_shutup_pins(codec); } @@ -365,6 +369,17 @@ static void alc_fixup_sku_ignore(struct hda_codec *codec, } } +static void alc_fixup_no_depop_delay(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + + if (action == HDA_FIXUP_ACT_PROBE) { + spec->no_depop_delay = 1; + codec->depop_delay = 0; + } +} + static int alc_auto_parse_customize_define(struct hda_codec *codec) { unsigned int ass, tmp, i; @@ -380,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; @@ -390,8 +407,8 @@ static int alc_auto_parse_customize_define(struct hda_codec *codec) ass = snd_hda_codec_get_pincfg(codec, nid); if (!(ass & 1)) { - printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n", - codec->chip_name, ass); + codec_info(codec, "%s: SKU not ready 0x%08x\n", + codec->chip_name, ass); return -1; } @@ -415,17 +432,17 @@ do_sku: spec->cdefine.swap = (ass & 0x2) >> 1; spec->cdefine.override = ass & 0x1; - snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n", + codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n", nid, spec->cdefine.sku_cfg); - snd_printd("SKU: port_connectivity=0x%x\n", + codec_dbg(codec, "SKU: port_connectivity=0x%x\n", spec->cdefine.port_connectivity); - snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep); - snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum); - snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization); - snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp); - snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type); - snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap); - snd_printd("SKU: override=0x%x\n", spec->cdefine.override); + codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep); + codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum); + codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization); + codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp); + codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type); + codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap); + codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override); return 0; } @@ -454,9 +471,7 @@ static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) * 7 ~ 0 : Assembly ID * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 */ -static int alc_subsystem_id(struct hda_codec *codec, - hda_nid_t porta, hda_nid_t porte, - hda_nid_t portd, hda_nid_t porti) +static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports) { unsigned int ass, tmp, i; unsigned nid; @@ -470,7 +485,8 @@ static int alc_subsystem_id(struct hda_codec *codec, } 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 */ @@ -486,8 +502,8 @@ static int alc_subsystem_id(struct hda_codec *codec, if (codec->vendor_id == 0x10ec0260) nid = 0x17; ass = snd_hda_codec_get_pincfg(codec, nid); - snd_printd("realtek: No valid SSID, " - "checking pincfg 0x%08x for NID 0x%x\n", + codec_dbg(codec, + "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n", ass, nid); if (!(ass & 1)) return 0; @@ -503,7 +519,7 @@ static int alc_subsystem_id(struct hda_codec *codec, if (((ass >> 16) & 0xf) != tmp) return 0; do_sku: - snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", + codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", ass & 0xffff, codec->vendor_id); /* * 0 : override @@ -546,16 +562,7 @@ do_sku: spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) { hda_nid_t nid; tmp = (ass >> 11) & 0x3; /* HP to chassis */ - if (tmp == 0) - nid = porta; - else if (tmp == 1) - nid = porte; - else if (tmp == 2) - nid = portd; - else if (tmp == 3) - nid = porti; - else - return 1; + nid = ports[tmp]; if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins, spec->gen.autocfg.line_outs)) return 1; @@ -568,10 +575,10 @@ do_sku: * ports contains an array of 4 pin NIDs for port-A, E, D and I */ static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports) { - if (!alc_subsystem_id(codec, ports[0], ports[1], ports[2], ports[3])) { + if (!alc_subsystem_id(codec, ports)) { struct alc_spec *spec = codec->spec; - snd_printd("realtek: " - "Enable default setup for auto mode as fallback\n"); + codec_dbg(codec, + "realtek: Enable default setup for auto mode as fallback\n"); spec->init_amp = ALC_INIT_DEFAULT; } } @@ -579,26 +586,35 @@ static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports) /* * COEF access helper functions */ -static int alc_read_coef_idx(struct hda_codec *codec, - unsigned int coef_idx) + +static int alc_read_coefex_idx(struct hda_codec *codec, + hda_nid_t nid, + unsigned int coef_idx) { unsigned int val; - snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx); - val = snd_hda_codec_read(codec, 0x20, 0, + val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0); return val; } -static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx, +#define alc_read_coef_idx(codec, coef_idx) \ + alc_read_coefex_idx(codec, 0x20, coef_idx) + +static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid, + unsigned int coef_idx, unsigned int coef_val) { - snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx); - snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val); } +#define alc_write_coef_idx(codec, coef_idx, coef_val) \ + alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val) + /* a special bypass for COEF 0; read the cached value at the second time */ static unsigned int alc_get_coef0(struct hda_codec *codec) { @@ -695,7 +711,8 @@ static void alc_inv_dmic_sync(struct hda_codec *codec, bool force) } static void alc_inv_dmic_hook(struct hda_codec *codec, - struct snd_ctl_elem_value *ucontrol) + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { alc_inv_dmic_sync(codec, false); } @@ -852,7 +869,10 @@ static int alc_suspend(struct hda_codec *codec) #ifdef CONFIG_PM static int alc_resume(struct hda_codec *codec) { - msleep(150); /* to avoid pop noise */ + struct alc_spec *spec = codec->spec; + + if (!spec->no_depop_delay) + msleep(150); /* to avoid pop noise */ codec->patch_ops.init(codec); snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); @@ -892,7 +912,7 @@ static int alc_codec_rename(struct hda_codec *codec, const char *name) } /* - * Rename codecs appropriately from COEF value + * Rename codecs appropriately from COEF value or subvendor id */ struct alc_codec_rename_table { unsigned int vendor_id; @@ -901,7 +921,15 @@ struct alc_codec_rename_table { const char *name; }; +struct alc_codec_rename_pci_table { + unsigned int codec_vendor_id; + unsigned short pci_subvendor; + unsigned short pci_subdevice; + const char *name; +}; + static struct alc_codec_rename_table rename_tbl[] = { + { 0x10ec0221, 0xf00f, 0x1003, "ALC231" }, { 0x10ec0269, 0xfff0, 0x3010, "ALC277" }, { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" }, { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" }, @@ -910,6 +938,7 @@ static struct alc_codec_rename_table rename_tbl[] = { { 0x10ec0269, 0xffff, 0x6023, "ALC281X" }, { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" }, { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" }, + { 0x10ec0662, 0xffff, 0x4020, "ALC656" }, { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" }, { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" }, { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" }, @@ -920,9 +949,35 @@ static struct alc_codec_rename_table rename_tbl[] = { { } /* terminator */ }; +static struct alc_codec_rename_pci_table rename_pci_tbl[] = { + { 0x10ec0280, 0x1028, 0, "ALC3220" }, + { 0x10ec0282, 0x1028, 0, "ALC3221" }, + { 0x10ec0283, 0x1028, 0, "ALC3223" }, + { 0x10ec0288, 0x1028, 0, "ALC3263" }, + { 0x10ec0292, 0x1028, 0, "ALC3226" }, + { 0x10ec0293, 0x1028, 0, "ALC3235" }, + { 0x10ec0255, 0x1028, 0, "ALC3234" }, + { 0x10ec0668, 0x1028, 0, "ALC3661" }, + { 0x10ec0275, 0x1028, 0, "ALC3260" }, + { 0x10ec0899, 0x1028, 0, "ALC3861" }, + { 0x10ec0670, 0x1025, 0, "ALC669X" }, + { 0x10ec0676, 0x1025, 0, "ALC679X" }, + { 0x10ec0282, 0x1043, 0, "ALC3229" }, + { 0x10ec0233, 0x1043, 0, "ALC3236" }, + { 0x10ec0280, 0x103c, 0, "ALC3228" }, + { 0x10ec0282, 0x103c, 0, "ALC3227" }, + { 0x10ec0286, 0x103c, 0, "ALC3242" }, + { 0x10ec0290, 0x103c, 0, "ALC3241" }, + { 0x10ec0668, 0x103c, 0, "ALC3662" }, + { 0x10ec0283, 0x17aa, 0, "ALC3239" }, + { 0x10ec0292, 0x17aa, 0, "ALC3232" }, + { } /* terminator */ +}; + static int alc_codec_rename_from_preset(struct hda_codec *codec) { const struct alc_codec_rename_table *p; + const struct alc_codec_rename_pci_table *q; for (p = rename_tbl; p->vendor_id; p++) { if (p->vendor_id != codec->vendor_id) @@ -930,6 +985,19 @@ static int alc_codec_rename_from_preset(struct hda_codec *codec) if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits) 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; + if (q->pci_subvendor != codec->bus->pci->subsystem_vendor) + continue; + if (!q->pci_subdevice || + q->pci_subdevice == codec->bus->pci->subsystem_device) + return alc_codec_rename(codec, q->name); + } + return 0; } @@ -943,6 +1011,7 @@ static int alc_codec_rename_from_preset(struct hda_codec *codec) static const struct snd_pci_quirk beep_white_list[] = { SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1), + SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1), SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1), SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), @@ -1043,6 +1112,7 @@ enum { ALC880_FIXUP_UNIWILL, ALC880_FIXUP_UNIWILL_DIG, ALC880_FIXUP_Z71V, + ALC880_FIXUP_ASUS_W5A, ALC880_FIXUP_3ST_BASE, ALC880_FIXUP_3ST, ALC880_FIXUP_3ST_DIG, @@ -1213,6 +1283,26 @@ static const struct hda_fixup alc880_fixups[] = { { } } }, + [ALC880_FIXUP_ASUS_W5A] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + /* set up the whole pins as BIOS is utterly broken */ + { 0x14, 0x0121411f }, /* HP */ + { 0x15, 0x411111f0 }, /* N/A */ + { 0x16, 0x411111f0 }, /* N/A */ + { 0x17, 0x411111f0 }, /* N/A */ + { 0x18, 0x90a60160 }, /* mic */ + { 0x19, 0x411111f0 }, /* N/A */ + { 0x1a, 0x411111f0 }, /* N/A */ + { 0x1b, 0x411111f0 }, /* N/A */ + { 0x1c, 0x411111f0 }, /* N/A */ + { 0x1d, 0x411111f0 }, /* N/A */ + { 0x1e, 0xb743111e }, /* SPDIF out */ + { } + }, + .chained = true, + .chain_id = ALC880_FIXUP_GPIO1, + }, [ALC880_FIXUP_3ST_BASE] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -1334,8 +1424,10 @@ static const struct hda_fixup alc880_fixups[] = { static const struct snd_pci_quirk alc880_fixup_tbl[] = { SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810), + SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A), SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V), SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1), + SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE), SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2), SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF), SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG), @@ -1479,6 +1571,7 @@ enum { ALC260_FIXUP_KN1, ALC260_FIXUP_FSC_S7020, ALC260_FIXUP_FSC_S7020_JWSE, + ALC260_FIXUP_VAIO_PINS, }; static void alc260_gpio1_automute(struct hda_codec *codec) @@ -1572,12 +1665,10 @@ static const struct hda_fixup alc260_fixups[] = { [ALC260_FIXUP_COEF] = { .type = HDA_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { - { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, - { 0x20, AC_VERB_SET_PROC_COEF, 0x3040 }, + { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 }, + { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 }, { } }, - .chained = true, - .chain_id = ALC260_FIXUP_HP_PIN_0F, }, [ALC260_FIXUP_GPIO1] = { .type = HDA_FIXUP_VERBS, @@ -1592,8 +1683,8 @@ static const struct hda_fixup alc260_fixups[] = { [ALC260_FIXUP_REPLACER] = { .type = HDA_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { - { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, - { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, + { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 }, + { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 }, { } }, .chained = true, @@ -1619,6 +1710,24 @@ static const struct hda_fixup alc260_fixups[] = { .chained = true, .chain_id = ALC260_FIXUP_FSC_S7020, }, + [ALC260_FIXUP_VAIO_PINS] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + /* Pin configs are missing completely on some VAIOs */ + { 0x0f, 0x01211020 }, + { 0x10, 0x0001003f }, + { 0x11, 0x411111f0 }, + { 0x12, 0x01a15930 }, + { 0x13, 0x411111f0 }, + { 0x14, 0x411111f0 }, + { 0x15, 0x411111f0 }, + { 0x16, 0x411111f0 }, + { 0x17, 0x411111f0 }, + { 0x18, 0x411111f0 }, + { 0x19, 0x411111f0 }, + { } + } + }, }; static const struct snd_pci_quirk alc260_fixup_tbl[] = { @@ -1627,6 +1736,8 @@ static const struct snd_pci_quirk alc260_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1), SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900), + SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS), + SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F), SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020), SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1), @@ -1709,6 +1820,7 @@ enum { ALC882_FIXUP_ACER_ASPIRE_7736, ALC882_FIXUP_ASUS_W90V, ALC889_FIXUP_CD, + ALC889_FIXUP_FRONT_HP_NO_PRESENCE, ALC889_FIXUP_VAIO_TT, ALC888_FIXUP_EEE1601, ALC882_FIXUP_EAPD, @@ -1726,8 +1838,13 @@ enum { ALC889_FIXUP_DAC_ROUTE, ALC889_FIXUP_MBP_VREF, ALC889_FIXUP_IMAC91_VREF, + ALC889_FIXUP_MBA11_VREF, + ALC889_FIXUP_MBA21_VREF, + ALC889_FIXUP_MP11_VREF, ALC882_FIXUP_INV_DMIC, ALC882_FIXUP_NO_PRIMARY_HP, + ALC887_FIXUP_ASUS_BASS, + ALC887_FIXUP_BASS_CHMAP, }; static void alc889_fixup_coef(struct hda_codec *codec, @@ -1828,17 +1945,13 @@ static void alc889_fixup_mbp_vref(struct hda_codec *codec, } } -/* Set VREF on speaker pins on imac91 */ -static void alc889_fixup_imac91_vref(struct hda_codec *codec, - const struct hda_fixup *fix, int action) +static void alc889_fixup_mac_pins(struct hda_codec *codec, + const hda_nid_t *nids, int num_nids) { struct alc_spec *spec = codec->spec; - static hda_nid_t nids[2] = { 0x18, 0x1a }; int i; - if (action != HDA_FIXUP_ACT_INIT) - return; - for (i = 0; i < ARRAY_SIZE(nids); i++) { + for (i = 0; i < num_nids; i++) { unsigned int val; val = snd_hda_codec_get_pin_target(codec, nids[i]); val |= AC_PINCTL_VREF_50; @@ -1847,6 +1960,36 @@ static void alc889_fixup_imac91_vref(struct hda_codec *codec, spec->gen.keep_vref_in_automute = 1; } +/* Set VREF on speaker pins on imac91 */ +static void alc889_fixup_imac91_vref(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + static hda_nid_t nids[2] = { 0x18, 0x1a }; + + if (action == HDA_FIXUP_ACT_INIT) + alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); +} + +/* Set VREF on speaker pins on mba11 */ +static void alc889_fixup_mba11_vref(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + static hda_nid_t nids[1] = { 0x18 }; + + if (action == HDA_FIXUP_ACT_INIT) + alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); +} + +/* Set VREF on speaker pins on mba21 */ +static void alc889_fixup_mba21_vref(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + static hda_nid_t nids[2] = { 0x18, 0x19 }; + + if (action == HDA_FIXUP_ACT_INIT) + alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); +} + /* Don't take HP output as primary * Strangely, the speaker output doesn't work on Vaio Z and some Vaio * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05 @@ -1861,6 +2004,9 @@ static void alc882_fixup_no_primary_hp(struct hda_codec *codec, } } +static void alc_fixup_bass_chmap(struct hda_codec *codec, + const struct hda_fixup *fix, int action); + static const struct hda_fixup alc882_fixups[] = { [ALC882_FIXUP_ABIT_AW9D_MAX] = { .type = HDA_FIXUP_PINS, @@ -1904,6 +2050,15 @@ static const struct hda_fixup alc882_fixups[] = { { } } }, + [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */ + { } + }, + .chained = true, + .chain_id = ALC889_FIXUP_CD, + }, [ALC889_FIXUP_VAIO_TT] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -2043,6 +2198,24 @@ static const struct hda_fixup alc882_fixups[] = { .chained = true, .chain_id = ALC882_FIXUP_GPIO1, }, + [ALC889_FIXUP_MBA11_VREF] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc889_fixup_mba11_vref, + .chained = true, + .chain_id = ALC889_FIXUP_MBP_VREF, + }, + [ALC889_FIXUP_MBA21_VREF] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc889_fixup_mba21_vref, + .chained = true, + .chain_id = ALC889_FIXUP_MBP_VREF, + }, + [ALC889_FIXUP_MP11_VREF] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc889_fixup_mba11_vref, + .chained = true, + .chain_id = ALC885_FIXUP_MACPRO_GPIO, + }, [ALC882_FIXUP_INV_DMIC] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_inv_dmic_0x12, @@ -2051,6 +2224,19 @@ static const struct hda_fixup alc882_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc882_fixup_no_primary_hp, }, + [ALC887_FIXUP_ASUS_BASS] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + {0x16, 0x99130130}, /* bass speaker */ + {} + }, + .chained = true, + .chain_id = ALC887_FIXUP_BASS_CHMAP, + }, + [ALC887_FIXUP_BASS_CHMAP] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_bass_chmap, + }, }; static const struct snd_pci_quirk alc882_fixup_tbl[] = { @@ -2084,6 +2270,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC), SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601), + SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS), SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP), SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP), @@ -2092,14 +2279,14 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF), SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), - SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO), + SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF), SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF), SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF), SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), - SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBP_VREF), - SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBP_VREF), + SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF), + SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF), SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF), SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), @@ -2115,7 +2302,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), - SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3", ALC889_FIXUP_CD), + SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), @@ -2218,6 +2405,7 @@ enum { ALC262_FIXUP_BENQ, ALC262_FIXUP_BENQ_T31, ALC262_FIXUP_INV_DMIC, + ALC262_FIXUP_INTEL_BAYLEYBAY, }; static const struct hda_fixup alc262_fixups[] = { @@ -2282,6 +2470,10 @@ static const struct hda_fixup alc262_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_inv_dmic_0x12, }, + [ALC262_FIXUP_INTEL_BAYLEYBAY] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_no_depop_delay, + }, }; static const struct snd_pci_quirk alc262_fixup_tbl[] = { @@ -2293,6 +2485,7 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31), + SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY), {} }; @@ -2388,6 +2581,7 @@ static const struct hda_verb alc268_beep_init_verbs[] = { enum { ALC268_FIXUP_INV_DMIC, ALC268_FIXUP_HP_EAPD, + ALC268_FIXUP_SPDIF, }; static const struct hda_fixup alc268_fixups[] = { @@ -2402,6 +2596,13 @@ static const struct hda_fixup alc268_fixups[] = { {} } }, + [ALC268_FIXUP_SPDIF] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x1e, 0x014b1180 }, /* enable SPDIF out */ + {} + } + }, }; static const struct hda_model_fixup alc268_fixup_models[] = { @@ -2411,6 +2612,7 @@ static const struct hda_model_fixup alc268_fixup_models[] = { }; static const struct snd_pci_quirk alc268_fixup_tbl[] = { + SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF), SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC), /* below is codec SSID since multiple Toshiba laptops have the * same PCI SSID 1179:ff00 @@ -2539,7 +2741,9 @@ enum { ALC269_TYPE_ALC282, ALC269_TYPE_ALC283, ALC269_TYPE_ALC284, + ALC269_TYPE_ALC285, ALC269_TYPE_ALC286, + ALC269_TYPE_ALC255, }; /* @@ -2558,6 +2762,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) case ALC269_TYPE_ALC269VC: case ALC269_TYPE_ALC280: case ALC269_TYPE_ALC284: + case ALC269_TYPE_ALC285: ssids = alc269va_ssids; break; case ALC269_TYPE_ALC269VB: @@ -2565,6 +2770,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) case ALC269_TYPE_ALC282: case ALC269_TYPE_ALC283: case ALC269_TYPE_ALC286: + case ALC269_TYPE_ALC255: ssids = alc269_ssids; break; default: @@ -2598,6 +2804,237 @@ static void alc269_shutup(struct hda_codec *codec) snd_hda_shutup_pins(codec); } +static void alc282_restore_default_value(struct hda_codec *codec) +{ + int val; + + /* Power Down Control */ + alc_write_coef_idx(codec, 0x03, 0x0002); + /* FIFO and filter clock */ + alc_write_coef_idx(codec, 0x05, 0x0700); + /* DMIC control */ + alc_write_coef_idx(codec, 0x07, 0x0200); + /* Analog clock */ + val = alc_read_coef_idx(codec, 0x06); + alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); + /* JD */ + val = alc_read_coef_idx(codec, 0x08); + alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); + /* JD offset1 */ + alc_write_coef_idx(codec, 0x0a, 0xcccc); + /* JD offset2 */ + alc_write_coef_idx(codec, 0x0b, 0xcccc); + /* LDO1/2/3, DAC/ADC */ + alc_write_coef_idx(codec, 0x0e, 0x6e00); + /* JD */ + val = alc_read_coef_idx(codec, 0x0f); + alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); + /* Capless */ + val = alc_read_coef_idx(codec, 0x10); + alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); + /* Class D test 4 */ + alc_write_coef_idx(codec, 0x6f, 0x0); + /* IO power down directly */ + val = alc_read_coef_idx(codec, 0x0c); + alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); + /* ANC */ + alc_write_coef_idx(codec, 0x34, 0xa0c0); + /* AGC MUX */ + val = alc_read_coef_idx(codec, 0x16); + alc_write_coef_idx(codec, 0x16, (val & ~0x0008) | 0x0); + /* DAC simple content protection */ + val = alc_read_coef_idx(codec, 0x1d); + alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); + /* ADC simple content protection */ + val = alc_read_coef_idx(codec, 0x1f); + alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); + /* DAC ADC Zero Detection */ + alc_write_coef_idx(codec, 0x21, 0x8804); + /* PLL */ + alc_write_coef_idx(codec, 0x63, 0x2902); + /* capless control 2 */ + alc_write_coef_idx(codec, 0x68, 0xa080); + /* capless control 3 */ + alc_write_coef_idx(codec, 0x69, 0x3400); + /* capless control 4 */ + alc_write_coef_idx(codec, 0x6a, 0x2f3e); + /* capless control 5 */ + alc_write_coef_idx(codec, 0x6b, 0x0); + /* class D test 2 */ + val = alc_read_coef_idx(codec, 0x6d); + alc_write_coef_idx(codec, 0x6d, (val & ~0x0fff) | 0x0900); + /* class D test 3 */ + alc_write_coef_idx(codec, 0x6e, 0x110a); + /* class D test 5 */ + val = alc_read_coef_idx(codec, 0x70); + alc_write_coef_idx(codec, 0x70, (val & ~0x00f8) | 0x00d8); + /* class D test 6 */ + alc_write_coef_idx(codec, 0x71, 0x0014); + /* classD OCP */ + alc_write_coef_idx(codec, 0x72, 0xc2ba); + /* classD pure DC test */ + val = alc_read_coef_idx(codec, 0x77); + alc_write_coef_idx(codec, 0x77, (val & ~0x0f80) | 0x0); + /* Class D amp control */ + alc_write_coef_idx(codec, 0x6c, 0xfc06); +} + +static void alc282_init(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; + bool hp_pin_sense; + int coef78; + + alc282_restore_default_value(codec); + + if (!hp_pin) + return; + hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); + coef78 = alc_read_coef_idx(codec, 0x78); + + /* Index 0x78 Direct Drive HP AMP LPM Control 1 */ + /* Headphone capless set to high power mode */ + alc_write_coef_idx(codec, 0x78, 0x9004); + + if (hp_pin_sense) + msleep(2); + + snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); + + if (hp_pin_sense) + msleep(85); + + snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + + if (hp_pin_sense) + msleep(100); + + /* Headphone capless set to normal mode */ + alc_write_coef_idx(codec, 0x78, coef78); +} + +static void alc282_shutup(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; + bool hp_pin_sense; + int coef78; + + if (!hp_pin) { + alc269_shutup(codec); + return; + } + + hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); + coef78 = alc_read_coef_idx(codec, 0x78); + alc_write_coef_idx(codec, 0x78, 0x9004); + + if (hp_pin_sense) + msleep(2); + + snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); + + if (hp_pin_sense) + msleep(85); + + snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); + + if (hp_pin_sense) + msleep(100); + + alc_auto_setup_eapd(codec, false); + snd_hda_shutup_pins(codec); + alc_write_coef_idx(codec, 0x78, coef78); +} + +static void alc283_restore_default_value(struct hda_codec *codec) +{ + int val; + + /* Power Down Control */ + alc_write_coef_idx(codec, 0x03, 0x0002); + /* FIFO and filter clock */ + alc_write_coef_idx(codec, 0x05, 0x0700); + /* DMIC control */ + alc_write_coef_idx(codec, 0x07, 0x0200); + /* Analog clock */ + val = alc_read_coef_idx(codec, 0x06); + alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); + /* JD */ + val = alc_read_coef_idx(codec, 0x08); + alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); + /* JD offset1 */ + alc_write_coef_idx(codec, 0x0a, 0xcccc); + /* JD offset2 */ + alc_write_coef_idx(codec, 0x0b, 0xcccc); + /* LDO1/2/3, DAC/ADC */ + alc_write_coef_idx(codec, 0x0e, 0x6fc0); + /* JD */ + val = alc_read_coef_idx(codec, 0x0f); + alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); + /* Capless */ + val = alc_read_coef_idx(codec, 0x10); + alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); + /* Class D test 4 */ + alc_write_coef_idx(codec, 0x3a, 0x0); + /* IO power down directly */ + val = alc_read_coef_idx(codec, 0x0c); + alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); + /* ANC */ + alc_write_coef_idx(codec, 0x22, 0xa0c0); + /* AGC MUX */ + val = alc_read_coefex_idx(codec, 0x53, 0x01); + alc_write_coefex_idx(codec, 0x53, 0x01, (val & ~0x000f) | 0x0008); + /* DAC simple content protection */ + val = alc_read_coef_idx(codec, 0x1d); + alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); + /* ADC simple content protection */ + val = alc_read_coef_idx(codec, 0x1f); + alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); + /* DAC ADC Zero Detection */ + alc_write_coef_idx(codec, 0x21, 0x8804); + /* PLL */ + alc_write_coef_idx(codec, 0x2e, 0x2902); + /* capless control 2 */ + alc_write_coef_idx(codec, 0x33, 0xa080); + /* capless control 3 */ + alc_write_coef_idx(codec, 0x34, 0x3400); + /* capless control 4 */ + alc_write_coef_idx(codec, 0x35, 0x2f3e); + /* capless control 5 */ + alc_write_coef_idx(codec, 0x36, 0x0); + /* class D test 2 */ + val = alc_read_coef_idx(codec, 0x38); + alc_write_coef_idx(codec, 0x38, (val & ~0x0fff) | 0x0900); + /* class D test 3 */ + alc_write_coef_idx(codec, 0x39, 0x110a); + /* class D test 5 */ + val = alc_read_coef_idx(codec, 0x3b); + alc_write_coef_idx(codec, 0x3b, (val & ~0x00f8) | 0x00d8); + /* class D test 6 */ + alc_write_coef_idx(codec, 0x3c, 0x0014); + /* classD OCP */ + alc_write_coef_idx(codec, 0x3d, 0xc2ba); + /* classD pure DC test */ + val = alc_read_coef_idx(codec, 0x42); + alc_write_coef_idx(codec, 0x42, (val & ~0x0f80) | 0x0); + /* test mode */ + alc_write_coef_idx(codec, 0x49, 0x0); + /* Class D DC enable */ + val = alc_read_coef_idx(codec, 0x40); + alc_write_coef_idx(codec, 0x40, (val & ~0xf800) | 0x9800); + /* DC offset */ + val = alc_read_coef_idx(codec, 0x42); + alc_write_coef_idx(codec, 0x42, (val & ~0xf000) | 0x2000); + /* Class D amp control */ + alc_write_coef_idx(codec, 0x37, 0xfc06); +} + static void alc283_init(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -2605,6 +3042,13 @@ static void alc283_init(struct hda_codec *codec) bool hp_pin_sense; int val; + if (!spec->gen.autocfg.hp_outs) { + if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) + hp_pin = spec->gen.autocfg.line_out_pins[0]; + } + + alc283_restore_default_value(codec); + if (!hp_pin) return; hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); @@ -2639,6 +3083,11 @@ static void alc283_shutup(struct hda_codec *codec) bool hp_pin_sense; int val; + if (!spec->gen.autocfg.hp_outs) { + if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) + hp_pin = spec->gen.autocfg.line_out_pins[0]; + } + if (!hp_pin) { alc269_shutup(codec); return; @@ -2652,7 +3101,7 @@ static void alc283_shutup(struct hda_codec *codec) AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); if (hp_pin_sense) - msleep(85); + msleep(100); snd_hda_codec_write(codec, hp_pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); @@ -2661,7 +3110,8 @@ static void alc283_shutup(struct hda_codec *codec) alc_write_coef_idx(codec, 0x46, val | (3 << 12)); if (hp_pin_sense) - msleep(85); + msleep(100); + alc_auto_setup_eapd(codec, false); snd_hda_shutup_pins(codec); alc_write_coef_idx(codec, 0x43, 0x9614); } @@ -2819,6 +3269,15 @@ static void alc269_fixup_hweq(struct hda_codec *codec, alc_write_coef_idx(codec, 0x1e, coef | 0x80); } +static void alc269_fixup_headset_mic(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + + if (action == HDA_FIXUP_ACT_PRE_PROBE) + spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; +} + static void alc271_fixup_dmic(struct hda_codec *codec, const struct hda_fixup *fix, int action) { @@ -2929,12 +3388,30 @@ static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) if (spec->mute_led_polarity) enabled = !enabled; - pinval = AC_PINCTL_IN_EN | - (enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80); + pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid); + pinval &= ~AC_PINCTL_VREFEN; + pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80; if (spec->mute_led_nid) snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval); } +/* Make sure the led works even in runtime suspend */ +static unsigned int led_power_filter(struct hda_codec *codec, + hda_nid_t nid, + unsigned int power_state) +{ + struct alc_spec *spec = codec->spec; + + if (power_state != AC_PWRST_D3 || nid != spec->mute_led_nid) + return power_state; + + /* Set pin ctl again, it might have just been set to 0 */ + snd_hda_set_pin_ctl(codec, nid, + snd_hda_codec_get_pin_target(codec, nid)); + + return AC_PWRST_D0; +} + static void alc269_fixup_hp_mute_led(struct hda_codec *codec, const struct hda_fixup *fix, int action) { @@ -2954,7 +3431,9 @@ static void alc269_fixup_hp_mute_led(struct hda_codec *codec, spec->mute_led_nid = pin - 0x0a + 0x18; spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; spec->gen.vmaster_mute_enum = 1; - snd_printd("Detected mute LED for %x:%d\n", spec->mute_led_nid, + codec->power_filter = led_power_filter; + codec_dbg(codec, + "Detected mute LED for %x:%d\n", spec->mute_led_nid, spec->mute_led_polarity); break; } @@ -2969,6 +3448,7 @@ static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec, spec->mute_led_nid = 0x18; spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; spec->gen.vmaster_mute_enum = 1; + codec->power_filter = led_power_filter; } } @@ -2981,6 +3461,7 @@ static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec, spec->mute_led_nid = 0x19; spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; spec->gen.vmaster_mute_enum = 1; + codec->power_filter = led_power_filter; } } @@ -3002,7 +3483,8 @@ static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled) /* turn on/off mic-mute LED per capture hook */ static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec, - struct snd_ctl_elem_value *ucontrol) + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct alc_spec *spec = codec->spec; unsigned int oldval = spec->gpio_led; @@ -3043,6 +3525,20 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) int val; switch (codec->vendor_id) { + case 0x10ec0255: + /* LDO and MISC control */ + alc_write_coef_idx(codec, 0x1b, 0x0c0b); + /* UAJ function set to menual mode */ + alc_write_coef_idx(codec, 0x45, 0xd089); + /* Direct Drive HP Amp control(Set to verb control)*/ + val = alc_read_coefex_idx(codec, 0x57, 0x05); + alc_write_coefex_idx(codec, 0x57, 0x05, val & ~(1<<14)); + /* Set MIC2 Vref gate with HP */ + alc_write_coef_idx(codec, 0x06, 0x6104); + /* Direct Drive HP Amp control */ + alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); + break; + case 0x10ec0233: case 0x10ec0283: alc_write_coef_idx(codec, 0x1b, 0x0c0b); alc_write_coef_idx(codec, 0x45, 0xc429); @@ -3059,12 +3555,31 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) alc_write_coef_idx(codec, 0x18, 0x7308); alc_write_coef_idx(codec, 0x6b, 0xc429); break; + case 0x10ec0293: + /* SET Line1 JD to 0 */ + val = alc_read_coef_idx(codec, 0x10); + alc_write_coef_idx(codec, 0x10, (val & ~(7<<8)) | 6<<8); + /* SET charge pump by verb */ + val = alc_read_coefex_idx(codec, 0x57, 0x05); + alc_write_coefex_idx(codec, 0x57, 0x05, (val & ~(1<<15|1<<13)) | 0x0); + /* SET EN_OSW to 1 */ + val = alc_read_coefex_idx(codec, 0x57, 0x03); + alc_write_coefex_idx(codec, 0x57, 0x03, (val & ~(1<<10)) | (1<<10) ); + /* Combo JD gating with LINE1-VREFO */ + val = alc_read_coef_idx(codec, 0x1a); + alc_write_coef_idx(codec, 0x1a, (val & ~(1<<3)) | (1<<3)); + /* Set to TRS type */ + alc_write_coef_idx(codec, 0x45, 0xc429); + /* Combo Jack auto detect */ + val = alc_read_coef_idx(codec, 0x4a); + alc_write_coef_idx(codec, 0x4a, (val & 0xfff0) | 0x000e); + break; case 0x10ec0668: alc_write_coef_idx(codec, 0x15, 0x0d40); alc_write_coef_idx(codec, 0xb7, 0x802b); break; } - snd_printdd("Headset jack set to unplugged mode.\n"); + codec_dbg(codec, "Headset jack set to unplugged mode.\n"); } @@ -3074,6 +3589,15 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, int val; switch (codec->vendor_id) { + case 0x10ec0255: + alc_write_coef_idx(codec, 0x45, 0xc489); + snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); + alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); + /* Set MIC2 Vref gate to normal */ + alc_write_coef_idx(codec, 0x06, 0x6100); + snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); + break; + case 0x10ec0233: case 0x10ec0283: alc_write_coef_idx(codec, 0x45, 0xc429); snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); @@ -3089,6 +3613,21 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, alc_write_coef_idx(codec, 0x19, 0xa208); alc_write_coef_idx(codec, 0x2e, 0xacf0); break; + case 0x10ec0293: + /* Set to TRS mode */ + alc_write_coef_idx(codec, 0x45, 0xc429); + snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); + /* SET charge pump by verb */ + val = alc_read_coefex_idx(codec, 0x57, 0x05); + alc_write_coefex_idx(codec, 0x57, 0x05, (val & ~(1<<15|1<<13)) | (1<<15|1<<13)); + /* SET EN_OSW to 0 */ + val = alc_read_coefex_idx(codec, 0x57, 0x03); + alc_write_coefex_idx(codec, 0x57, 0x03, (val & ~(1<<10)) | 0x0); + /* Combo JD gating without LINE1-VREFO */ + val = alc_read_coef_idx(codec, 0x1a); + alc_write_coef_idx(codec, 0x1a, (val & ~(1<<3)) | 0x0); + snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); + break; case 0x10ec0668: alc_write_coef_idx(codec, 0x11, 0x0001); snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); @@ -3099,12 +3638,21 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); break; } - snd_printdd("Headset jack set to mic-in mode.\n"); + codec_dbg(codec, "Headset jack set to mic-in mode.\n"); } static void alc_headset_mode_default(struct hda_codec *codec) { + int val; + switch (codec->vendor_id) { + case 0x10ec0255: + alc_write_coef_idx(codec, 0x45, 0xc089); + alc_write_coef_idx(codec, 0x45, 0xc489); + alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); + alc_write_coef_idx(codec, 0x49, 0x0049); + break; + case 0x10ec0233: case 0x10ec0283: alc_write_coef_idx(codec, 0x06, 0x2100); alc_write_coef_idx(codec, 0x32, 0x4ea3); @@ -3115,19 +3663,38 @@ static void alc_headset_mode_default(struct hda_codec *codec) alc_write_coef_idx(codec, 0x6b, 0xc429); alc_write_coef_idx(codec, 0x18, 0x7308); break; + case 0x10ec0293: + /* Combo Jack auto detect */ + val = alc_read_coef_idx(codec, 0x4a); + alc_write_coef_idx(codec, 0x4a, (val & 0xfff0) | 0x000e); + /* Set to TRS type */ + alc_write_coef_idx(codec, 0x45, 0xC429); + /* Combo JD gating without LINE1-VREFO */ + val = alc_read_coef_idx(codec, 0x1a); + alc_write_coef_idx(codec, 0x1a, (val & ~(1<<3)) | 0x0); + break; case 0x10ec0668: alc_write_coef_idx(codec, 0x11, 0x0041); alc_write_coef_idx(codec, 0x15, 0x0d40); alc_write_coef_idx(codec, 0xb7, 0x802b); break; } - snd_printdd("Headset jack set to headphone (default) mode.\n"); + codec_dbg(codec, "Headset jack set to headphone (default) mode.\n"); } /* Iphone type */ static void alc_headset_mode_ctia(struct hda_codec *codec) { + int val; + switch (codec->vendor_id) { + case 0x10ec0255: + /* Set to CTIA type */ + alc_write_coef_idx(codec, 0x45, 0xd489); + alc_write_coef_idx(codec, 0x1b, 0x0c2b); + alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); + break; + case 0x10ec0233: case 0x10ec0283: alc_write_coef_idx(codec, 0x45, 0xd429); alc_write_coef_idx(codec, 0x1b, 0x0c2b); @@ -3138,18 +3705,35 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) alc_write_coef_idx(codec, 0x76, 0x0008); alc_write_coef_idx(codec, 0x18, 0x7388); break; + case 0x10ec0293: + /* Set to ctia type */ + alc_write_coef_idx(codec, 0x45, 0xd429); + /* SET Line1 JD to 1 */ + val = alc_read_coef_idx(codec, 0x10); + alc_write_coef_idx(codec, 0x10, (val & ~(7<<8)) | 7<<8); + break; case 0x10ec0668: + alc_write_coef_idx(codec, 0x11, 0x0001); alc_write_coef_idx(codec, 0x15, 0x0d60); alc_write_coef_idx(codec, 0xc3, 0x0000); break; } - snd_printdd("Headset jack set to iPhone-style headset mode.\n"); + codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n"); } /* Nokia type */ static void alc_headset_mode_omtp(struct hda_codec *codec) { + int val; + switch (codec->vendor_id) { + case 0x10ec0255: + /* Set to OMTP Type */ + alc_write_coef_idx(codec, 0x45, 0xe489); + alc_write_coef_idx(codec, 0x1b, 0x0c2b); + alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); + break; + case 0x10ec0233: case 0x10ec0283: alc_write_coef_idx(codec, 0x45, 0xe429); alc_write_coef_idx(codec, 0x1b, 0x0c2b); @@ -3160,12 +3744,20 @@ static void alc_headset_mode_omtp(struct hda_codec *codec) alc_write_coef_idx(codec, 0x76, 0x0008); alc_write_coef_idx(codec, 0x18, 0x7388); break; + case 0x10ec0293: + /* Set to omtp type */ + alc_write_coef_idx(codec, 0x45, 0xe429); + /* SET Line1 JD to 1 */ + val = alc_read_coef_idx(codec, 0x10); + alc_write_coef_idx(codec, 0x10, (val & ~(7<<8)) | 7<<8); + break; case 0x10ec0668: + alc_write_coef_idx(codec, 0x11, 0x0001); alc_write_coef_idx(codec, 0x15, 0x0d50); alc_write_coef_idx(codec, 0xc3, 0x0000); break; } - snd_printdd("Headset jack set to Nokia-style headset mode.\n"); + codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n"); } static void alc_determine_headset_type(struct hda_codec *codec) @@ -3175,6 +3767,16 @@ static void alc_determine_headset_type(struct hda_codec *codec) struct alc_spec *spec = codec->spec; switch (codec->vendor_id) { + case 0x10ec0255: + /* combo jack auto switch control(Check type)*/ + alc_write_coef_idx(codec, 0x45, 0xd089); + /* combo jack auto switch control(Vref conteol) */ + alc_write_coef_idx(codec, 0x49, 0x0149); + msleep(300); + val = alc_read_coef_idx(codec, 0x46); + is_ctia = (val & 0x0070) == 0x0070; + break; + case 0x10ec0233: case 0x10ec0283: alc_write_coef_idx(codec, 0x45, 0xd029); msleep(300); @@ -3187,6 +3789,16 @@ static void alc_determine_headset_type(struct hda_codec *codec) val = alc_read_coef_idx(codec, 0x6c); is_ctia = (val & 0x001c) == 0x001c; break; + case 0x10ec0293: + /* Combo Jack auto detect */ + val = alc_read_coef_idx(codec, 0x4a); + alc_write_coef_idx(codec, 0x4a, (val & 0xfff0) | 0x0008); + /* Set to ctia type */ + alc_write_coef_idx(codec, 0x45, 0xD429); + msleep(300); + val = alc_read_coef_idx(codec, 0x46); + is_ctia = (val & 0x0070) == 0x0070; + break; case 0x10ec0668: alc_write_coef_idx(codec, 0x11, 0x0001); alc_write_coef_idx(codec, 0xb7, 0x802b); @@ -3198,7 +3810,7 @@ static void alc_determine_headset_type(struct hda_codec *codec) break; } - snd_printdd("Headset jack detected iPhone-style headset: %s\n", + codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n", is_ctia ? "yes" : "no"); spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP; } @@ -3221,8 +3833,10 @@ static void alc_update_headset_mode(struct hda_codec *codec) else new_headset_mode = ALC_HEADSET_MODE_HEADPHONE; - if (new_headset_mode == spec->current_headset_mode) + if (new_headset_mode == spec->current_headset_mode) { + snd_hda_gen_update_outputs(codec); return; + } switch (new_headset_mode) { case ALC_HEADSET_MODE_UNPLUGGED: @@ -3260,7 +3874,8 @@ static void alc_update_headset_mode(struct hda_codec *codec) } static void alc_update_headset_mode_hook(struct hda_codec *codec, - struct snd_ctl_elem_value *ucontrol) + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { alc_update_headset_mode(codec); } @@ -3268,7 +3883,7 @@ static void alc_update_headset_mode_hook(struct hda_codec *codec, static void alc_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_tbl *jack) { struct alc_spec *spec = codec->spec; - spec->current_headset_type = ALC_HEADSET_MODE_UNKNOWN; + spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN; snd_hda_gen_hp_automute(codec, jack); } @@ -3321,6 +3936,93 @@ static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, alc_fixup_headset_mode(codec, fix, action); } +static void alc255_set_default_jack_type(struct hda_codec *codec) +{ + /* Set to iphone type */ + alc_write_coef_idx(codec, 0x1b, 0x880b); + alc_write_coef_idx(codec, 0x45, 0xd089); + alc_write_coef_idx(codec, 0x1b, 0x080b); + alc_write_coef_idx(codec, 0x46, 0x0004); + alc_write_coef_idx(codec, 0x1b, 0x0c0b); + msleep(30); +} + +static void alc_fixup_headset_mode_alc255(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + alc255_set_default_jack_type(codec); + } + alc_fixup_headset_mode(codec, fix, action); +} + +static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + struct alc_spec *spec = codec->spec; + spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; + alc255_set_default_jack_type(codec); + } + else + alc_fixup_headset_mode(codec, fix, action); +} + +static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + struct alc_spec *spec = codec->spec; + spec->gen.auto_mute_via_amp = 1; + } +} + +static void alc_no_shutup(struct hda_codec *codec) +{ +} + +static void alc_fixup_no_shutup(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + struct alc_spec *spec = codec->spec; + spec->shutup = alc_no_shutup; + } +} + +static void alc_fixup_disable_aamix(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + struct alc_spec *spec = codec->spec; + /* Disable AA-loopback as it causes white noise */ + spec->gen.mixer_nid = 0; + } +} + +static unsigned int alc_power_filter_xps13(struct hda_codec *codec, + hda_nid_t nid, + unsigned int power_state) +{ + struct alc_spec *spec = codec->spec; + + /* Avoid pop noises when headphones are plugged in */ + if (spec->gen.hp_jack_present) + if (nid == codec->afg || nid == 0x02) + return AC_PWRST_D0; + return power_state; +} + +static void alc_fixup_dell_xps13(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action == HDA_FIXUP_ACT_PROBE) { + struct alc_spec *spec = codec->spec; + spec->shutup = alc_no_shutup; + codec->power_filter = alc_power_filter_xps13; + } +} + static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, const struct hda_fixup *fix, int action) { @@ -3420,12 +4122,31 @@ static void alc283_hp_automute_hook(struct hda_codec *codec, vref); } -static void alc283_chromebook_caps(struct hda_codec *codec) +static void alc283_fixup_chromebook(struct hda_codec *codec, + const struct hda_fixup *fix, int action) { - snd_hda_override_wcaps(codec, 0x03, 0); + struct alc_spec *spec = codec->spec; + int val; + + switch (action) { + case HDA_FIXUP_ACT_PRE_PROBE: + snd_hda_override_wcaps(codec, 0x03, 0); + /* Disable AA-loopback as it causes white noise */ + spec->gen.mixer_nid = 0; + break; + case HDA_FIXUP_ACT_INIT: + /* MIC2-VREF control */ + /* Set to manual mode */ + val = alc_read_coef_idx(codec, 0x06); + alc_write_coef_idx(codec, 0x06, val & ~0x000c); + /* Enable Line1 input control by verb */ + val = alc_read_coef_idx(codec, 0x1a); + alc_write_coef_idx(codec, 0x1a, val | (1 << 4)); + break; + } } -static void alc283_fixup_chromebook(struct hda_codec *codec, +static void alc283_fixup_sense_combo_jack(struct hda_codec *codec, const struct hda_fixup *fix, int action) { struct alc_spec *spec = codec->spec; @@ -3433,8 +4154,9 @@ static void alc283_fixup_chromebook(struct hda_codec *codec, switch (action) { case HDA_FIXUP_ACT_PRE_PROBE: - alc283_chromebook_caps(codec); spec->gen.hp_automute_hook = alc283_hp_automute_hook; + break; + case HDA_FIXUP_ACT_INIT: /* MIC2-VREF control */ /* Set to manual mode */ val = alc_read_coef_idx(codec, 0x06); @@ -3493,6 +4215,22 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec, } } +static void alc290_fixup_mono_speakers(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + /* DAC node 0x03 is giving mono output. We therefore want to + make sure 0x14 (front speaker) and 0x15 (headphones) use the + stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */ + hda_nid_t conn1[2] = { 0x0c }; + snd_hda_override_conn_list(codec, 0x14, 1, conn1); + snd_hda_override_conn_list(codec, 0x15, 1, conn1); + } +} + +/* for hda_fixup_thinkpad_acpi() */ +#include "thinkpad_helper.c" + enum { ALC269_FIXUP_SONY_VAIO, ALC275_FIXUP_SONY_VAIO_GPIO2, @@ -3501,11 +4239,14 @@ enum { ALC269_FIXUP_ASUS_G73JW, ALC269_FIXUP_LENOVO_EAPD, ALC275_FIXUP_SONY_HWEQ, + ALC275_FIXUP_SONY_DISABLE_AAMIX, ALC271_FIXUP_DMIC, ALC269_FIXUP_PCM_44K, ALC269_FIXUP_STEREO_DMIC, + ALC269_FIXUP_HEADSET_MIC, ALC269_FIXUP_QUANTA_MUTE, ALC269_FIXUP_LIFEBOOK, + ALC269_FIXUP_LIFEBOOK_EXTMIC, ALC269_FIXUP_AMIC, ALC269_FIXUP_DMIC, ALC269VB_FIXUP_AMIC, @@ -3516,9 +4257,12 @@ enum { ALC269_FIXUP_HP_GPIO_LED, ALC269_FIXUP_INV_DMIC, ALC269_FIXUP_LENOVO_DOCK, + ALC269_FIXUP_NO_SHUTUP, + ALC286_FIXUP_SONY_MIC_NO_PRESENCE, ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, + ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, ALC269_FIXUP_HEADSET_MODE, ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, ALC269_FIXUP_ASUS_X101_FUNC, @@ -3526,11 +4270,28 @@ enum { ALC269_FIXUP_ASUS_X101, ALC271_FIXUP_AMIC_MIC2, ALC271_FIXUP_HP_GATE_MIC_JACK, + ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, ALC269_FIXUP_ACER_AC700, ALC269_FIXUP_LIMIT_INT_MIC_BOOST, + ALC269VB_FIXUP_ASUS_ZENBOOK, + ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, + ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED, ALC269VB_FIXUP_ORDISSIMO_EVE2, ALC283_FIXUP_CHROME_BOOK, + ALC283_FIXUP_SENSE_COMBO_JACK, ALC282_FIXUP_ASUS_TX300, + ALC283_FIXUP_INT_MIC, + ALC290_FIXUP_MONO_SPEAKERS, + ALC290_FIXUP_MONO_SPEAKERS_HSJACK, + ALC290_FIXUP_SUBWOOFER, + ALC290_FIXUP_SUBWOOFER_HSJACK, + ALC269_FIXUP_THINKPAD_ACPI, + ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, + ALC255_FIXUP_HEADSET_MODE, + ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC, + ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, + ALC292_FIXUP_TPT440_DOCK, }; static const struct hda_fixup alc269_fixups[] = { @@ -3585,6 +4346,12 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 }, + [ALC275_FIXUP_SONY_DISABLE_AAMIX] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_disable_aamix, + .chained = true, + .chain_id = ALC269_FIXUP_SONY_VAIO + }, [ALC271_FIXUP_DMIC] = { .type = HDA_FIXUP_FUNC, .v.func = alc271_fixup_dmic, @@ -3599,6 +4366,10 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc269_fixup_stereo_dmic, }, + [ALC269_FIXUP_HEADSET_MIC] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc269_fixup_headset_mic, + }, [ALC269_FIXUP_QUANTA_MUTE] = { .type = HDA_FIXUP_FUNC, .v.func = alc269_fixup_quanta_mute, @@ -3613,6 +4384,13 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC269_FIXUP_QUANTA_MUTE }, + [ALC269_FIXUP_LIFEBOOK_EXTMIC] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x19, 0x01a1903c }, /* headset mic, with jack detect */ + { } + }, + }, [ALC269_FIXUP_AMIC] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -3673,6 +4451,10 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_inv_dmic_0x12, }, + [ALC269_FIXUP_NO_SHUTUP] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_no_shutup, + }, [ALC269_FIXUP_LENOVO_DOCK] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -3686,6 +4468,8 @@ static const struct hda_fixup alc269_fixups[] = { [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = { .type = HDA_FIXUP_FUNC, .v.func = alc269_fixup_pincfg_no_hp_to_lineout, + .chained = true, + .chain_id = ALC269_FIXUP_THINKPAD_ACPI, }, [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = { .type = HDA_FIXUP_PINS, @@ -3708,6 +4492,15 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC }, + [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ + { } + }, + .chained = true, + .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC + }, [ALC269_FIXUP_HEADSET_MODE] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_headset_mode, @@ -3716,6 +4509,15 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_headset_mode_no_hp_mic, }, + [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */ + { } + }, + .chained = true, + .chain_id = ALC269_FIXUP_HEADSET_MIC + }, [ALC269_FIXUP_ASUS_X101_FUNC] = { .type = HDA_FIXUP_FUNC, .v.func = alc269_fixup_x101_headset_mic, @@ -3756,6 +4558,12 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC271_FIXUP_AMIC_MIC2, }, + [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc269_fixup_limit_int_mic_boost, + .chained = true, + .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK, + }, [ALC269_FIXUP_ACER_AC700] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -3772,6 +4580,31 @@ static const struct hda_fixup alc269_fixups[] = { [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = { .type = HDA_FIXUP_FUNC, .v.func = alc269_fixup_limit_int_mic_boost, + .chained = true, + .chain_id = ALC269_FIXUP_THINKPAD_ACPI, + }, + [ALC269VB_FIXUP_ASUS_ZENBOOK] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc269_fixup_limit_int_mic_boost, + .chained = true, + .chain_id = ALC269VB_FIXUP_DMIC, + }, + [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = { + .type = HDA_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + /* class-D output amp +5dB */ + { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 }, + {} + }, + .chained = true, + .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK, + }, + [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc269_fixup_limit_int_mic_boost, + .chained = true, + .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1, }, [ALC269VB_FIXUP_ORDISSIMO_EVE2] = { .type = HDA_FIXUP_PINS, @@ -3786,19 +4619,116 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc283_fixup_chromebook, }, + [ALC283_FIXUP_SENSE_COMBO_JACK] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc283_fixup_sense_combo_jack, + .chained = true, + .chain_id = ALC283_FIXUP_CHROME_BOOK, + }, [ALC282_FIXUP_ASUS_TX300] = { .type = HDA_FIXUP_FUNC, .v.func = alc282_fixup_asus_tx300, }, + [ALC283_FIXUP_INT_MIC] = { + .type = HDA_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + {0x20, AC_VERB_SET_COEF_INDEX, 0x1a}, + {0x20, AC_VERB_SET_PROC_COEF, 0x0011}, + { } + }, + .chained = true, + .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST + }, + [ALC290_FIXUP_SUBWOOFER_HSJACK] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x17, 0x90170112 }, /* subwoofer */ + { } + }, + .chained = true, + .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, + }, + [ALC290_FIXUP_SUBWOOFER] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x17, 0x90170112 }, /* subwoofer */ + { } + }, + .chained = true, + .chain_id = ALC290_FIXUP_MONO_SPEAKERS, + }, + [ALC290_FIXUP_MONO_SPEAKERS] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc290_fixup_mono_speakers, + }, + [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc290_fixup_mono_speakers, + .chained = true, + .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, + }, + [ALC269_FIXUP_THINKPAD_ACPI] = { + .type = HDA_FIXUP_FUNC, + .v.func = hda_fixup_thinkpad_acpi, + }, + [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x19, 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 = ALC255_FIXUP_HEADSET_MODE + }, + [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ + { } + }, + .chained = true, + .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC + }, + [ALC255_FIXUP_HEADSET_MODE] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_headset_mode_alc255, + }, + [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_headset_mode_alc255_no_hp_mic, + }, + [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ + { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ + { } + }, + .chained = true, + .chain_id = ALC269_FIXUP_HEADSET_MODE + }, + [ALC292_FIXUP_TPT440_DOCK] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x16, 0x21211010 }, /* dock headphone */ + { 0x19, 0x21a11010 }, /* dock mic */ + { } + }, + .chained = true, + .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700), SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), + SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), @@ -3812,6 +4742,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER), SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), @@ -3831,19 +4762,93 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), + SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), + SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK), + SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0684, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), - SND_PCI_QUIRK(0x103c, 0x21ed, "HP Falco Chromebook", ALC283_FIXUP_CHROME_BOOK), + SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED), + /* ALC282 */ + SND_PCI_QUIRK(0x103c, 0x220d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x220e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x220f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2211, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2212, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2213, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2266, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2267, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2269, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x226c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x226d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x226f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x227a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x227b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22a0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22c0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22c1, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22c2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22cd, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22ce, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22d0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + /* ALC290 */ + SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2261, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2262, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x227d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x227e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2280, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2281, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2289, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x228a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x228c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x228d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22c6, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22c3, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), - SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), - SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_DMIC), + SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), + SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), @@ -3853,11 +4858,15 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), + SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), + SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX), SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), + SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC), SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), @@ -3869,16 +4878,20 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK), - SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440_DOCK), + SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK), + SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK), SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), - SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC), SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), + SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI), SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ #if 0 @@ -3938,13 +4951,155 @@ static const struct hda_model_fixup alc269_fixup_models[] = { {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"}, {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"}, {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, + {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"}, {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"}, + {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"}, + {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"}, + {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"}, {} }; +static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x90a60140}, + {0x14, 0x90170110}, + {0x17, 0x40000000}, + {0x18, 0x411111f0}, + {0x19, 0x411111f0}, + {0x1a, 0x411111f0}, + {0x1b, 0x411111f0}, + {0x1d, 0x40700001}, + {0x1e, 0x411111f0}, + {0x21, 0x02211020}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x90a60160}, + {0x14, 0x90170120}, + {0x17, 0x40000000}, + {0x18, 0x411111f0}, + {0x19, 0x411111f0}, + {0x1a, 0x411111f0}, + {0x1b, 0x411111f0}, + {0x1d, 0x40700001}, + {0x1e, 0x411111f0}, + {0x21, 0x02211030}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x90a60160}, + {0x14, 0x90170120}, + {0x17, 0x90170140}, + {0x18, 0x40000000}, + {0x19, 0x411111f0}, + {0x1a, 0x411111f0}, + {0x1b, 0x411111f0}, + {0x1d, 0x41163b05}, + {0x1e, 0x411111f0}, + {0x21, 0x0321102f}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x90a60160}, + {0x14, 0x90170130}, + {0x17, 0x40000000}, + {0x18, 0x411111f0}, + {0x19, 0x411111f0}, + {0x1a, 0x411111f0}, + {0x1b, 0x411111f0}, + {0x1d, 0x40700001}, + {0x1e, 0x411111f0}, + {0x21, 0x02211040}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x90a60160}, + {0x14, 0x90170140}, + {0x17, 0x40000000}, + {0x18, 0x411111f0}, + {0x19, 0x411111f0}, + {0x1a, 0x411111f0}, + {0x1b, 0x411111f0}, + {0x1d, 0x40700001}, + {0x1e, 0x411111f0}, + {0x21, 0x02211050}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x90a60170}, + {0x14, 0x90170120}, + {0x17, 0x40000000}, + {0x18, 0x411111f0}, + {0x19, 0x411111f0}, + {0x1a, 0x411111f0}, + {0x1b, 0x411111f0}, + {0x1d, 0x40700001}, + {0x1e, 0x411111f0}, + {0x21, 0x02211030}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x90a60170}, + {0x14, 0x90170130}, + {0x17, 0x40000000}, + {0x18, 0x411111f0}, + {0x19, 0x411111f0}, + {0x1a, 0x411111f0}, + {0x1b, 0x411111f0}, + {0x1d, 0x40700001}, + {0x1e, 0x411111f0}, + {0x21, 0x02211040}), + SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x90a60130}, + {0x14, 0x90170110}, + {0x17, 0x40020008}, + {0x18, 0x411111f0}, + {0x19, 0x411111f0}, + {0x1a, 0x411111f0}, + {0x1b, 0x411111f0}, + {0x1d, 0x40e00001}, + {0x1e, 0x411111f0}, + {0x21, 0x0321101f}), + SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x90a60160}, + {0x14, 0x90170120}, + {0x17, 0x40000000}, + {0x18, 0x411111f0}, + {0x19, 0x411111f0}, + {0x1a, 0x411111f0}, + {0x1b, 0x411111f0}, + {0x1d, 0x40700001}, + {0x1e, 0x411111f0}, + {0x21, 0x02211030}), + SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, + {0x12, 0x90a60140}, + {0x13, 0x411111f0}, + {0x14, 0x90170110}, + {0x15, 0x0221401f}, + {0x16, 0x411111f0}, + {0x18, 0x411111f0}, + {0x19, 0x411111f0}, + {0x1a, 0x411111f0}, + {0x1b, 0x411111f0}, + {0x1d, 0x40700001}, + {0x1e, 0x411111f0}), + SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x40000000}, + {0x13, 0x90a60140}, + {0x14, 0x90170110}, + {0x15, 0x0221401f}, + {0x16, 0x21014020}, + {0x18, 0x411111f0}, + {0x19, 0x21a19030}, + {0x1a, 0x411111f0}, + {0x1b, 0x411111f0}, + {0x1d, 0x40700001}, + {0x1e, 0x411111f0}), + SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x40000000}, + {0x13, 0x90a60140}, + {0x14, 0x90170110}, + {0x15, 0x0221401f}, + {0x16, 0x411111f0}, + {0x18, 0x411111f0}, + {0x19, 0x411111f0}, + {0x1a, 0x411111f0}, + {0x1b, 0x411111f0}, + {0x1d, 0x40700001}, + {0x1e, 0x411111f0}), + {} +}; static void alc269_fill_coef(struct hda_codec *codec) { @@ -4006,6 +5161,7 @@ static int patch_alc269(struct hda_codec *codec) snd_hda_pick_fixup(codec, alc269_fixup_models, alc269_fixup_tbl, alc269_fixups); + snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups); snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); alc_auto_parse_customize_define(codec); @@ -4018,13 +5174,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; @@ -4047,6 +5205,8 @@ static int patch_alc269(struct hda_codec *codec) break; case 0x10ec0282: spec->codec_variant = ALC269_TYPE_ALC282; + spec->shutup = alc282_shutup; + spec->init_hook = alc282_init; break; case 0x10ec0233: case 0x10ec0283: @@ -4058,13 +5218,21 @@ static int patch_alc269(struct hda_codec *codec) case 0x10ec0292: spec->codec_variant = ALC269_TYPE_ALC284; break; + case 0x10ec0285: + case 0x10ec0293: + spec->codec_variant = ALC269_TYPE_ALC285; + break; case 0x10ec0286: + case 0x10ec0288: spec->codec_variant = ALC269_TYPE_ALC286; break; + case 0x10ec0255: + spec->codec_variant = ALC269_TYPE_ALC255; + break; } if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) { - spec->has_alc5505_dsp = true; + spec->has_alc5505_dsp = 1; spec->init_hook = alc5505_dsp_init; } @@ -4110,6 +5278,7 @@ enum { ALC861_FIXUP_AMP_VREF_0F, ALC861_FIXUP_NO_JACK_DETECT, ALC861_FIXUP_ASUS_A6RP, + ALC660_FIXUP_ASUS_W7J, }; /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ @@ -4159,10 +5328,22 @@ static const struct hda_fixup alc861_fixups[] = { .v.func = alc861_fixup_asus_amp_vref_0f, .chained = true, .chain_id = ALC861_FIXUP_NO_JACK_DETECT, + }, + [ALC660_FIXUP_ASUS_W7J] = { + .type = HDA_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + /* ASUS W7J needs a magic pin setup on unused NID 0x10 + * for enabling outputs + */ + {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, + { } + }, } }; static const struct snd_pci_quirk alc861_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J), + SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J), SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP), SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F), SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT), @@ -4344,12 +5525,76 @@ static void alc272_fixup_mario(struct hda_codec *codec, (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) | (0 << AC_AMPCAP_MUTE_SHIFT))) - printk(KERN_WARNING - "hda_codec: failed to override amp caps for NID 0x2\n"); + codec_warn(codec, "failed to override amp caps for NID 0x2\n"); +} + +static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = { + { .channels = 2, + .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, + { .channels = 4, + .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, + SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */ + { } +}; + +/* override the 2.1 chmap */ +static void alc_fixup_bass_chmap(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action == HDA_FIXUP_ACT_BUILD) { + struct alc_spec *spec = codec->spec; + spec->gen.pcm_rec[0].stream[0].chmap = asus_pcm_2_1_chmaps; + } +} + +/* 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, @@ -4368,6 +5613,13 @@ enum { ALC662_FIXUP_INV_DMIC, ALC668_FIXUP_DELL_MIC_NO_PRESENCE, ALC668_FIXUP_HEADSET_MODE, + ALC662_FIXUP_BASS_MODE4_CHMAP, + ALC662_FIXUP_BASS_16, + ALC662_FIXUP_BASS_1A, + ALC662_FIXUP_BASS_CHMAP, + ALC668_FIXUP_AUTO_MUTE, + ALC668_FIXUP_DELL_DISABLE_AAMIX, + ALC668_FIXUP_DELL_XPS13, }; static const struct hda_fixup alc662_fixups[] = { @@ -4378,12 +5630,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, @@ -4528,6 +5786,24 @@ static const struct hda_fixup alc662_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_inv_dmic_0x12, }, + [ALC668_FIXUP_DELL_XPS13] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_dell_xps13, + .chained = true, + .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX + }, + [ALC668_FIXUP_DELL_DISABLE_AAMIX] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_disable_aamix, + .chained = true, + .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE + }, + [ALC668_FIXUP_AUTO_MUTE] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_auto_mute_via_amp, + .chained = true, + .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE + }, [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -4542,6 +5818,34 @@ static const struct hda_fixup alc662_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_headset_mode_alc668, }, + [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_CHMAP] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_bass_chmap, + }, }; static const struct snd_pci_quirk alc662_fixup_tbl[] = { @@ -4554,7 +5858,17 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13), + SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0698, "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), + 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), @@ -4638,6 +5952,70 @@ static const struct hda_model_fixup alc662_fixup_models[] = { {} }; +static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = { + SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE, + {0x12, 0x99a30130}, + {0x14, 0x90170110}, + {0x15, 0x0321101f}, + {0x16, 0x03011020}, + {0x18, 0x40000008}, + {0x19, 0x411111f0}, + {0x1a, 0x411111f0}, + {0x1b, 0x411111f0}, + {0x1d, 0x41000001}, + {0x1e, 0x411111f0}, + {0x1f, 0x411111f0}), + SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE, + {0x12, 0x99a30140}, + {0x14, 0x90170110}, + {0x15, 0x0321101f}, + {0x16, 0x03011020}, + {0x18, 0x40000008}, + {0x19, 0x411111f0}, + {0x1a, 0x411111f0}, + {0x1b, 0x411111f0}, + {0x1d, 0x41000001}, + {0x1e, 0x411111f0}, + {0x1f, 0x411111f0}), + SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE, + {0x12, 0x99a30150}, + {0x14, 0x90170110}, + {0x15, 0x0321101f}, + {0x16, 0x03011020}, + {0x18, 0x40000008}, + {0x19, 0x411111f0}, + {0x1a, 0x411111f0}, + {0x1b, 0x411111f0}, + {0x1d, 0x41000001}, + {0x1e, 0x411111f0}, + {0x1f, 0x411111f0}), + SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE, + {0x12, 0x411111f0}, + {0x14, 0x90170110}, + {0x15, 0x0321101f}, + {0x16, 0x03011020}, + {0x18, 0x40000008}, + {0x19, 0x411111f0}, + {0x1a, 0x411111f0}, + {0x1b, 0x411111f0}, + {0x1d, 0x41000001}, + {0x1e, 0x411111f0}, + {0x1f, 0x411111f0}), + SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE, + {0x12, 0x90a60130}, + {0x14, 0x90170110}, + {0x15, 0x0321101f}, + {0x16, 0x40000000}, + {0x18, 0x411111f0}, + {0x19, 0x411111f0}, + {0x1a, 0x411111f0}, + {0x1b, 0x411111f0}, + {0x1d, 0x40d6832d}, + {0x1e, 0x411111f0}, + {0x1f, 0x411111f0}), + {} +}; + static void alc662_fill_coef(struct hda_codec *codec) { int val, coef; @@ -4687,6 +6065,7 @@ static int patch_alc662(struct hda_codec *codec) snd_hda_pick_fixup(codec, alc662_fixup_models, alc662_fixup_tbl, alc662_fixups); + snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups); snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); alc_auto_parse_customize_define(codec); @@ -4695,7 +6074,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) @@ -4715,6 +6094,7 @@ static int patch_alc662(struct hda_codec *codec) case 0x10ec0272: case 0x10ec0663: case 0x10ec0665: + case 0x10ec0668: set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); break; case 0x10ec0273: @@ -4772,7 +6152,10 @@ static int patch_alc680(struct hda_codec *codec) */ static const struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 }, + { .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 }, { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 }, + { .id = 0x10ec0235, .name = "ALC233", .patch = patch_alc269 }, + { .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 }, { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, @@ -4786,9 +6169,12 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 }, + { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 }, { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 }, + { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 }, { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, + { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 }, { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", .patch = patch_alc861 }, { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, @@ -4802,10 +6188,12 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { .patch = patch_alc662 }, { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, + { .id = 0x10ec0667, .name = "ALC667", .patch = patch_alc662 }, { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 }, { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, + { .id = 0x10ec0867, .name = "ALC891", .patch = patch_alc882 }, { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, |
