From patchwork Fri Nov 22 14:30:47 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Henningsson X-Patchwork-Id: 293465 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id D5E2E2C00EF for ; Sat, 23 Nov 2013 01:31:34 +1100 (EST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1VjrlY-00062S-5B; Fri, 22 Nov 2013 14:31:28 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1Vjrky-0005pm-Rl for kernel-team@lists.ubuntu.com; Fri, 22 Nov 2013 14:30:52 +0000 Received: from hd9483857.selulk5.dyn.perspektivbredband.net ([217.72.56.87] helo=localhost.localdomain) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1Vjrky-0003Le-Hf; Fri, 22 Nov 2013 14:30:52 +0000 From: David Henningsson To: kernel-team@lists.ubuntu.com Subject: [PATCH 03/15] ALSA: hda - Implement headset jack functionality for some Dell hw Date: Fri, 22 Nov 2013 15:30:47 +0100 Message-Id: <1385130659-29870-4-git-send-email-david.henningsson@canonical.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1385130659-29870-1-git-send-email-david.henningsson@canonical.com> References: <1385130659-29870-1-git-send-email-david.henningsson@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com On some machines, there is a headset jack that can support both headphone, headsets (of both CTIA and OMTP type) and mic-in. On other machines, the headset jack supports headphone, headsets (both CTIA and OMTP), but not mic-in. This patch implements that functionality as different capture sources. Buglink: https://bugs.launchpad.net/bugs/1169143 Tested-by: David Chen Co-authored-by: Kailang Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai (backport from commit 73bdd597823e2231dc882577dbbaf8df92fe1775) Conflicts: sound/pci/hda/patch_realtek.c Signed-off-by: David Henningsson --- sound/pci/hda/patch_realtek.c | 381 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 380 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 73d3c8f..2cced2c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -54,6 +54,20 @@ enum { ALC_INIT_GPIO3, }; +enum { + ALC_HEADSET_MODE_UNKNOWN, + ALC_HEADSET_MODE_UNPLUGGED, + ALC_HEADSET_MODE_HEADSET, + ALC_HEADSET_MODE_MIC, + ALC_HEADSET_MODE_HEADPHONE, +}; + +enum { + ALC_HEADSET_TYPE_UNKNOWN, + ALC_HEADSET_TYPE_CTIA, + ALC_HEADSET_TYPE_OMTP, +}; + struct alc_customize_define { unsigned int sku_cfg; unsigned char port_connectivity; @@ -172,6 +186,11 @@ struct alc_spec { int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */ hda_nid_t inv_dmic_pin; + hda_nid_t headset_mic_pin; + hda_nid_t headphone_mic_pin; + int current_headset_mode; + int current_headset_type; + /* hooks */ void (*init_hook)(struct hda_codec *codec); #ifdef CONFIG_PM @@ -335,6 +354,8 @@ static void update_shared_mic_hp(struct hda_codec *codec, bool set_as_mic) call_update_outputs(codec); } +static void alc_update_headset_mode(struct hda_codec *codec); + /* select the given imux item; either unmute exclusively or select the route */ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, unsigned int idx, bool force) @@ -392,6 +413,10 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, imux->items[idx].index); } alc_inv_dmic_sync(codec, true); + + if (spec->headset_mic_pin || spec->headphone_mic_pin) + alc_update_headset_mode(codec); + return 1; } @@ -558,7 +583,7 @@ static void update_outputs(struct hda_codec *codec) * in general, HP pins/amps control should be enabled in all cases, * but currently set only for master_mute, just to be safe */ - if (!spec->shared_mic_hp) /* don't change HP-pin when shared with mic */ + if (!spec->shared_mic_hp && (spec->current_headset_mode != ALC_HEADSET_MODE_MIC)) /* don't change HP-pin when shared with mic */ do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), spec->autocfg.hp_pins, spec->master_mute, true); @@ -601,6 +626,8 @@ static void alc_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) spec->hp_jack_present = detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins), spec->autocfg.hp_pins); + spec->current_headset_type = ALC_HEADSET_MODE_UNKNOWN; + if (!spec->detect_hp || (!spec->automute_speaker && !spec->automute_lo)) return; call_update_outputs(codec); @@ -6050,6 +6077,287 @@ static void alc269_fixup_mic2_mute(struct hda_codec *codec, } } +static void alc_headset_mode_unplugged(struct hda_codec *codec) +{ + int val; + + switch (codec->vendor_id) { + case 0x10ec0283: + alc_write_coef_idx(codec, 0x1b, 0x0c0b); + alc_write_coef_idx(codec, 0x45, 0xc429); + val = alc_read_coef_idx(codec, 0x35); + alc_write_coef_idx(codec, 0x35, val & 0xbfff); + alc_write_coef_idx(codec, 0x06, 0x2104); + alc_write_coef_idx(codec, 0x1a, 0x0001); + alc_write_coef_idx(codec, 0x26, 0x0004); + alc_write_coef_idx(codec, 0x32, 0x42a3); + break; + case 0x10ec0292: + alc_write_coef_idx(codec, 0x76, 0x000e); + alc_write_coef_idx(codec, 0x6c, 0x2400); + alc_write_coef_idx(codec, 0x18, 0x7308); + alc_write_coef_idx(codec, 0x6b, 0xc429); + 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"); +} + + +static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, + hda_nid_t mic_pin) +{ + int val; + + switch (codec->vendor_id) { + case 0x10ec0283: + alc_write_coef_idx(codec, 0x45, 0xc429); + snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); + val = alc_read_coef_idx(codec, 0x35); + alc_write_coef_idx(codec, 0x35, val | 1<<14); + alc_write_coef_idx(codec, 0x06, 0x2100); + alc_write_coef_idx(codec, 0x1a, 0x0021); + alc_write_coef_idx(codec, 0x26, 0x008c); + snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); + break; + case 0x10ec0292: + snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); + alc_write_coef_idx(codec, 0x19, 0xa208); + alc_write_coef_idx(codec, 0x2e, 0xacf0); + break; + case 0x10ec0668: + alc_write_coef_idx(codec, 0x11, 0x0001); + snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); + alc_write_coef_idx(codec, 0xb7, 0x802b); + alc_write_coef_idx(codec, 0xb5, 0x1040); + val = alc_read_coef_idx(codec, 0xc3); + alc_write_coef_idx(codec, 0xc3, val | 1<<12); + snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); + break; + } + snd_printdd("Headset jack set to mic-in mode.\n"); +} + +static void alc_headset_mode_default(struct hda_codec *codec) +{ + switch (codec->vendor_id) { + case 0x10ec0283: + alc_write_coef_idx(codec, 0x06, 0x2100); + alc_write_coef_idx(codec, 0x32, 0x4ea3); + break; + case 0x10ec0292: + alc_write_coef_idx(codec, 0x76, 0x000e); + alc_write_coef_idx(codec, 0x6c, 0x2400); + alc_write_coef_idx(codec, 0x6b, 0xc429); + alc_write_coef_idx(codec, 0x18, 0x7308); + 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"); +} + +/* Iphone type */ +static void alc_headset_mode_ctia(struct hda_codec *codec) +{ + switch (codec->vendor_id) { + case 0x10ec0283: + alc_write_coef_idx(codec, 0x45, 0xd429); + alc_write_coef_idx(codec, 0x1b, 0x0c2b); + alc_write_coef_idx(codec, 0x32, 0x4ea3); + break; + case 0x10ec0292: + alc_write_coef_idx(codec, 0x6b, 0xd429); + alc_write_coef_idx(codec, 0x76, 0x0008); + alc_write_coef_idx(codec, 0x18, 0x7388); + break; + case 0x10ec0668: + 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"); +} + +/* Nokia type */ +static void alc_headset_mode_omtp(struct hda_codec *codec) +{ + switch (codec->vendor_id) { + case 0x10ec0283: + alc_write_coef_idx(codec, 0x45, 0xe429); + alc_write_coef_idx(codec, 0x1b, 0x0c2b); + alc_write_coef_idx(codec, 0x32, 0x4ea3); + break; + case 0x10ec0292: + alc_write_coef_idx(codec, 0x6b, 0xe429); + alc_write_coef_idx(codec, 0x76, 0x0008); + alc_write_coef_idx(codec, 0x18, 0x7388); + break; + case 0x10ec0668: + 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"); +} + +static void alc_determine_headset_type(struct hda_codec *codec) +{ + int val; + bool is_ctia = false; + struct alc_spec *spec = codec->spec; + + switch (codec->vendor_id) { + case 0x10ec0283: + alc_write_coef_idx(codec, 0x45, 0xd029); + msleep(300); + val = alc_read_coef_idx(codec, 0x46); + is_ctia = (val & 0x0070) == 0x0070; + break; + case 0x10ec0292: + alc_write_coef_idx(codec, 0x6b, 0xd429); + msleep(300); + val = alc_read_coef_idx(codec, 0x6c); + is_ctia = (val & 0x001c) == 0x001c; + break; + case 0x10ec0668: + alc_write_coef_idx(codec, 0x11, 0x0001); + alc_write_coef_idx(codec, 0xb7, 0x802b); + alc_write_coef_idx(codec, 0x15, 0x0d60); + alc_write_coef_idx(codec, 0xc3, 0x0c00); + msleep(300); + val = alc_read_coef_idx(codec, 0xbe); + is_ctia = (val & 0x1c02) == 0x1c02; + break; + } + + snd_printdd("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; +} + +static void alc_update_headset_mode(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + + hda_nid_t mux_pin = spec->imux_pins[spec->cur_mux[0]]; + hda_nid_t hp_pin = spec->autocfg.hp_pins[0]; + + int new_headset_mode; + + if (!snd_hda_jack_detect(codec, hp_pin)) + new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED; + else if (mux_pin == spec->headset_mic_pin) + new_headset_mode = ALC_HEADSET_MODE_HEADSET; + else if (mux_pin == spec->headphone_mic_pin) + new_headset_mode = ALC_HEADSET_MODE_MIC; + else + new_headset_mode = ALC_HEADSET_MODE_HEADPHONE; + + if (new_headset_mode == spec->current_headset_mode) + return; + + switch (new_headset_mode) { + case ALC_HEADSET_MODE_UNPLUGGED: + alc_headset_mode_unplugged(codec); + spec->hp_jack_present = false; + break; + case ALC_HEADSET_MODE_HEADSET: + if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN) + alc_determine_headset_type(codec); + if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA) + alc_headset_mode_ctia(codec); + else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP) + alc_headset_mode_omtp(codec); + spec->hp_jack_present = true; + break; + case ALC_HEADSET_MODE_MIC: + alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin); + spec->hp_jack_present = false; + break; + case ALC_HEADSET_MODE_HEADPHONE: + alc_headset_mode_default(codec); + spec->hp_jack_present = true; + break; + } + if (new_headset_mode != ALC_HEADSET_MODE_MIC) { + snd_hda_set_pin_ctl_cache(codec, hp_pin, + AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); + if (spec->headphone_mic_pin) + snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin, + PIN_VREFHIZ); + } + spec->current_headset_mode = new_headset_mode; + + update_outputs(codec); +} + +static void alc_probe_headset_mode(struct hda_codec *codec) +{ + int i; + struct alc_spec *spec = codec->spec; + struct auto_pin_cfg *cfg = &spec->autocfg; + + /* Find mic pins */ + for (i = 0; i < cfg->num_inputs; i++) { + if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin) + spec->headset_mic_pin = cfg->inputs[i].pin; + if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin) + spec->headphone_mic_pin = cfg->inputs[i].pin; + } + + spec->automute_hook = alc_update_headset_mode; +} + +static void alc_fixup_headset_mode(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + + switch (action) { + case HDA_FIXUP_ACT_PRE_PROBE: + spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC; + break; + case HDA_FIXUP_ACT_PROBE: + alc_probe_headset_mode(codec); + break; + case HDA_FIXUP_ACT_INIT: + spec->current_headset_mode = 0; + alc_update_headset_mode(codec); + break; + } +} + +static void alc_fixup_headset_mode_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; + } + else + alc_fixup_headset_mode(codec, fix, action); +} + +static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + int val; + alc_write_coef_idx(codec, 0xc4, 0x8000); + val = alc_read_coef_idx(codec, 0xc2); + alc_write_coef_idx(codec, 0xc2, val & 0xfe); + snd_hda_set_pin_ctl_cache(codec, 0x18, 0); + } + alc_fixup_headset_mode(codec, fix, action); +} + static void alc271_hp_gate_mic_jack(struct hda_codec *codec, const struct alc_fixup *fix, int action) @@ -6084,6 +6392,10 @@ enum { ALC269_FIXUP_LENOVO_DOCK, 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_HEADSET_MODE, + ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, ALC271_FIXUP_AMIC_MIC2, ALC271_FIXUP_HP_GATE_MIC_JACK, }; @@ -6241,6 +6553,35 @@ static const struct alc_fixup alc269_fixups[] = { { } }, }, + [ALC269_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 = ALC269_FIXUP_HEADSET_MODE + }, + [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x16, 0x21014020 }, /* dock line out */ + { 0x19, 0x21a19030 }, /* dock mic */ + { 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, + }, + [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_headset_mode_no_hp_mic, + }, [ALC271_FIXUP_AMIC_MIC2] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { @@ -6262,6 +6603,26 @@ static const struct alc_fixup alc269_fixups[] = { static const struct snd_pci_quirk alc269_fixup_tbl[] = { 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(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05c5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05c6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05c7, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05c8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05ec, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05ed, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05ee, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05f3, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x1972, "HP Pavilion 17", ALC269_FIXUP_MIC1_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x1977, "HP Pavilion 14", ALC269_FIXUP_MIC1_MUTE_LED), @@ -6774,6 +7135,8 @@ enum { ALC662_FIXUP_NO_JACK_DETECT, ALC662_FIXUP_ZOTAC_Z68, ALC662_FIXUP_INV_DMIC, + ALC668_FIXUP_DELL_MIC_NO_PRESENCE, + ALC668_FIXUP_HEADSET_MODE, }; static const struct alc_fixup alc662_fixups[] = { @@ -6934,6 +7297,20 @@ static const struct alc_fixup alc662_fixups[] = { .type = ALC_FIXUP_FUNC, .v.func = alc_fixup_inv_dmic_0x12, }, + [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ + { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ + { } + }, + .chained = true, + .chain_id = ALC668_FIXUP_HEADSET_MODE + }, + [ALC668_FIXUP_HEADSET_MODE] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_headset_mode_alc668, + }, }; static const struct snd_pci_quirk alc662_fixup_tbl[] = { @@ -6944,6 +7321,8 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC), 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(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_ASUS_MODE4), SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),