2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for Realtek ALC codecs
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@just42.net>
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <linux/dmi.h>
31 #include <linux/module.h>
32 #include <sound/core.h>
33 #include <sound/jack.h>
34 #include "hda_codec.h"
35 #include "hda_local.h"
36 #include "hda_auto_parser.h"
38 #include "hda_generic.h"
40 /* keep halting ALC5505 DSP, for power saving */
41 #define HALT_REALTEK_ALC5505
43 /* unsol event tags */
44 #define ALC_DCVOL_EVENT 0x08
47 #define GPIO_MASK 0x03
49 /* extra amp-initialization sequence types */
59 ALC_HEADSET_MODE_UNKNOWN,
60 ALC_HEADSET_MODE_UNPLUGGED,
61 ALC_HEADSET_MODE_HEADSET,
63 ALC_HEADSET_MODE_HEADPHONE,
67 ALC_HEADSET_TYPE_UNKNOWN,
68 ALC_HEADSET_TYPE_CTIA,
69 ALC_HEADSET_TYPE_OMTP,
72 struct alc_customize_define {
74 unsigned char port_connectivity;
75 unsigned char check_sum;
76 unsigned char customization;
77 unsigned char external_amp;
78 unsigned int enable_pcbeep:1;
79 unsigned int platform_type:1;
81 unsigned int override:1;
82 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
86 struct hda_gen_spec gen; /* must be at head */
88 /* codec parameterization */
89 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
90 unsigned int num_mixers;
91 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
93 struct alc_customize_define cdefine;
94 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
96 /* inverted dmic fix */
97 unsigned int inv_dmic_fixup:1; /* has inverted digital-mic workaround */
98 unsigned int inv_dmic_muted:1; /* R-ch of inv d-mic is muted? */
99 hda_nid_t inv_dmic_pin;
101 /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
102 int mute_led_polarity;
103 hda_nid_t mute_led_nid;
105 unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */
107 hda_nid_t headset_mic_pin;
108 hda_nid_t headphone_mic_pin;
109 int current_headset_mode;
110 int current_headset_type;
113 void (*init_hook)(struct hda_codec *codec);
115 void (*power_hook)(struct hda_codec *codec);
117 void (*shutup)(struct hda_codec *codec);
120 int codec_variant; /* flag for other variants */
121 unsigned int has_alc5505_dsp:1;
122 unsigned int no_depop_delay:1;
126 unsigned int pll_coef_idx, pll_coef_bit;
131 * Append the given mixer and verb elements for the later use
132 * The mixer array is referred in build_controls(), and init_verbs are
135 static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
137 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
139 spec->mixers[spec->num_mixers++] = mix;
143 * GPIO setup tables, used in initialization
145 /* Enable GPIO mask and set output */
146 static const struct hda_verb alc_gpio1_init_verbs[] = {
147 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
148 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
149 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
153 static const struct hda_verb alc_gpio2_init_verbs[] = {
154 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
155 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
156 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
160 static const struct hda_verb alc_gpio3_init_verbs[] = {
161 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
162 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
163 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
168 * Fix hardware PLL issue
169 * On some codecs, the analog PLL gating control must be off while
170 * the default value is 1.
172 static void alc_fix_pll(struct hda_codec *codec)
174 struct alc_spec *spec = codec->spec;
179 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
181 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
182 AC_VERB_GET_PROC_COEF, 0);
185 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
187 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
188 val & ~(1 << spec->pll_coef_bit));
191 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
192 unsigned int coef_idx, unsigned int coef_bit)
194 struct alc_spec *spec = codec->spec;
196 spec->pll_coef_idx = coef_idx;
197 spec->pll_coef_bit = coef_bit;
201 /* update the master volume per volume-knob's unsol event */
202 static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl *jack)
205 struct snd_kcontrol *kctl;
206 struct snd_ctl_elem_value *uctl;
208 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
211 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
214 val = snd_hda_codec_read(codec, jack->nid, 0,
215 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
216 val &= HDA_AMP_VOLMASK;
217 uctl->value.integer.value[0] = val;
218 uctl->value.integer.value[1] = val;
219 kctl->put(kctl, uctl);
223 static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
225 /* For some reason, the res given from ALC880 is broken.
226 Here we adjust it properly. */
227 snd_hda_jack_unsol_event(codec, res >> 2);
230 /* additional initialization for ALC888 variants */
231 static void alc888_coef_init(struct hda_codec *codec)
235 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
236 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
237 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
238 if ((tmp & 0xf0) == 0x20)
240 snd_hda_codec_read(codec, 0x20, 0,
241 AC_VERB_SET_PROC_COEF, 0x830);
244 snd_hda_codec_read(codec, 0x20, 0,
245 AC_VERB_SET_PROC_COEF, 0x3030);
248 /* additional initialization for ALC889 variants */
249 static void alc889_coef_init(struct hda_codec *codec)
253 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
254 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
255 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
256 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
259 /* turn on/off EAPD control (only if available) */
260 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
262 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
264 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
265 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
269 /* turn on/off EAPD controls of the codec */
270 static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
272 /* We currently only handle front, HP */
273 static hda_nid_t pins[] = {
274 0x0f, 0x10, 0x14, 0x15, 0
277 for (p = pins; *p; p++)
278 set_eapd(codec, *p, on);
281 /* generic shutup callback;
282 * just turning off EPAD and a little pause for avoiding pop-noise
284 static void alc_eapd_shutup(struct hda_codec *codec)
286 struct alc_spec *spec = codec->spec;
288 alc_auto_setup_eapd(codec, false);
289 if (!spec->no_depop_delay)
291 snd_hda_shutup_pins(codec);
294 /* generic EAPD initialization */
295 static void alc_auto_init_amp(struct hda_codec *codec, int type)
299 alc_auto_setup_eapd(codec, true);
302 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
305 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
308 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
310 case ALC_INIT_DEFAULT:
311 switch (codec->vendor_id) {
313 snd_hda_codec_write(codec, 0x1a, 0,
314 AC_VERB_SET_COEF_INDEX, 7);
315 tmp = snd_hda_codec_read(codec, 0x1a, 0,
316 AC_VERB_GET_PROC_COEF, 0);
317 snd_hda_codec_write(codec, 0x1a, 0,
318 AC_VERB_SET_COEF_INDEX, 7);
319 snd_hda_codec_write(codec, 0x1a, 0,
320 AC_VERB_SET_PROC_COEF,
329 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
330 alc889_coef_init(codec);
333 alc888_coef_init(codec);
335 #if 0 /* XXX: This may cause the silent output on speaker on some machines */
338 snd_hda_codec_write(codec, 0x20, 0,
339 AC_VERB_SET_COEF_INDEX, 7);
340 tmp = snd_hda_codec_read(codec, 0x20, 0,
341 AC_VERB_GET_PROC_COEF, 0);
342 snd_hda_codec_write(codec, 0x20, 0,
343 AC_VERB_SET_COEF_INDEX, 7);
344 snd_hda_codec_write(codec, 0x20, 0,
345 AC_VERB_SET_PROC_COEF,
356 * Realtek SSID verification
359 /* Could be any non-zero and even value. When used as fixup, tells
360 * the driver to ignore any present sku defines.
362 #define ALC_FIXUP_SKU_IGNORE (2)
364 static void alc_fixup_sku_ignore(struct hda_codec *codec,
365 const struct hda_fixup *fix, int action)
367 struct alc_spec *spec = codec->spec;
368 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
369 spec->cdefine.fixup = 1;
370 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
374 static void alc_fixup_no_depop_delay(struct hda_codec *codec,
375 const struct hda_fixup *fix, int action)
377 struct alc_spec *spec = codec->spec;
379 if (action == HDA_FIXUP_ACT_PROBE) {
380 spec->no_depop_delay = 1;
381 codec->depop_delay = 0;
385 static int alc_auto_parse_customize_define(struct hda_codec *codec)
387 unsigned int ass, tmp, i;
389 struct alc_spec *spec = codec->spec;
391 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
393 if (spec->cdefine.fixup) {
394 ass = spec->cdefine.sku_cfg;
395 if (ass == ALC_FIXUP_SKU_IGNORE)
400 ass = codec->subsystem_id & 0xffff;
401 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
405 if (codec->vendor_id == 0x10ec0260)
407 ass = snd_hda_codec_get_pincfg(codec, nid);
410 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
411 codec->chip_name, ass);
417 for (i = 1; i < 16; i++) {
421 if (((ass >> 16) & 0xf) != tmp)
424 spec->cdefine.port_connectivity = ass >> 30;
425 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
426 spec->cdefine.check_sum = (ass >> 16) & 0xf;
427 spec->cdefine.customization = ass >> 8;
429 spec->cdefine.sku_cfg = ass;
430 spec->cdefine.external_amp = (ass & 0x38) >> 3;
431 spec->cdefine.platform_type = (ass & 0x4) >> 2;
432 spec->cdefine.swap = (ass & 0x2) >> 1;
433 spec->cdefine.override = ass & 0x1;
435 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
436 nid, spec->cdefine.sku_cfg);
437 snd_printd("SKU: port_connectivity=0x%x\n",
438 spec->cdefine.port_connectivity);
439 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
440 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
441 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
442 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
443 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
444 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
445 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
450 /* return the position of NID in the list, or -1 if not found */
451 static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
454 for (i = 0; i < nums; i++)
459 /* return true if the given NID is found in the list */
460 static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
462 return find_idx_in_nid_list(nid, list, nums) >= 0;
465 /* check subsystem ID and set up device-specific initialization;
466 * return 1 if initialized, 0 if invalid SSID
468 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
469 * 31 ~ 16 : Manufacture ID
471 * 7 ~ 0 : Assembly ID
472 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
474 static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
476 unsigned int ass, tmp, i;
478 struct alc_spec *spec = codec->spec;
480 if (spec->cdefine.fixup) {
481 ass = spec->cdefine.sku_cfg;
482 if (ass == ALC_FIXUP_SKU_IGNORE)
487 ass = codec->subsystem_id & 0xffff;
488 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
491 /* invalid SSID, check the special NID pin defcfg instead */
493 * 31~30 : port connectivity
496 * 19~16 : Check sum (15:1)
501 if (codec->vendor_id == 0x10ec0260)
503 ass = snd_hda_codec_get_pincfg(codec, nid);
504 snd_printd("realtek: No valid SSID, "
505 "checking pincfg 0x%08x for NID 0x%x\n",
509 if ((ass >> 30) != 1) /* no physical connection */
514 for (i = 1; i < 16; i++) {
518 if (((ass >> 16) & 0xf) != tmp)
521 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
522 ass & 0xffff, codec->vendor_id);
526 * 2 : 0 --> Desktop, 1 --> Laptop
527 * 3~5 : External Amplifier control
530 tmp = (ass & 0x38) >> 3; /* external Amp control */
533 spec->init_amp = ALC_INIT_GPIO1;
536 spec->init_amp = ALC_INIT_GPIO2;
539 spec->init_amp = ALC_INIT_GPIO3;
543 spec->init_amp = ALC_INIT_DEFAULT;
547 /* is laptop or Desktop and enable the function "Mute internal speaker
548 * when the external headphone out jack is plugged"
553 * 10~8 : Jack location
554 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
556 * 15 : 1 --> enable the function "Mute internal speaker
557 * when the external headphone out jack is plugged"
559 if (!spec->gen.autocfg.hp_pins[0] &&
560 !(spec->gen.autocfg.line_out_pins[0] &&
561 spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) {
563 tmp = (ass >> 11) & 0x3; /* HP to chassis */
565 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
566 spec->gen.autocfg.line_outs))
568 spec->gen.autocfg.hp_pins[0] = nid;
573 /* Check the validity of ALC subsystem-id
574 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
575 static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
577 if (!alc_subsystem_id(codec, ports)) {
578 struct alc_spec *spec = codec->spec;
579 snd_printd("realtek: "
580 "Enable default setup for auto mode as fallback\n");
581 spec->init_amp = ALC_INIT_DEFAULT;
586 * COEF access helper functions
589 static int alc_read_coefex_idx(struct hda_codec *codec,
591 unsigned int coef_idx)
594 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX,
596 val = snd_hda_codec_read(codec, nid, 0,
597 AC_VERB_GET_PROC_COEF, 0);
601 #define alc_read_coef_idx(codec, coef_idx) \
602 alc_read_coefex_idx(codec, 0x20, coef_idx)
604 static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
605 unsigned int coef_idx,
606 unsigned int coef_val)
608 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX,
610 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF,
614 #define alc_write_coef_idx(codec, coef_idx, coef_val) \
615 alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
617 /* a special bypass for COEF 0; read the cached value at the second time */
618 static unsigned int alc_get_coef0(struct hda_codec *codec)
620 struct alc_spec *spec = codec->spec;
622 spec->coef0 = alc_read_coef_idx(codec, 0);
629 static hda_nid_t get_adc_nid(struct hda_codec *codec, int adc_idx, int imux_idx)
631 struct hda_gen_spec *spec = codec->spec;
632 if (spec->dyn_adc_switch)
633 adc_idx = spec->dyn_adc_idx[imux_idx];
634 return spec->adc_nids[adc_idx];
637 static void alc_inv_dmic_sync_adc(struct hda_codec *codec, int adc_idx)
639 struct alc_spec *spec = codec->spec;
640 struct hda_input_mux *imux = &spec->gen.input_mux;
641 struct nid_path *path;
646 for (i = 0; i < imux->num_items; i++) {
647 if (spec->gen.imux_pins[i] == spec->inv_dmic_pin)
650 if (i >= imux->num_items)
653 path = snd_hda_get_nid_path(codec, spec->inv_dmic_pin,
654 get_adc_nid(codec, adc_idx, i));
655 val = path->ctls[NID_PATH_MUTE_CTL];
658 nid = get_amp_nid_(val);
659 dir = get_amp_direction_(val);
660 parm = AC_AMP_SET_RIGHT |
661 (dir == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT);
663 /* flush all cached amps at first */
664 snd_hda_codec_flush_cache(codec);
666 /* we care only right channel */
667 val = snd_hda_codec_amp_read(codec, nid, 1, dir, 0);
668 if (val & 0x80) /* if already muted, we don't need to touch */
671 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
676 * Inverted digital-mic handling
678 * First off, it's a bit tricky. The "Inverted Internal Mic Capture Switch"
679 * gives the additional mute only to the right channel of the digital mic
680 * capture stream. This is a workaround for avoiding the almost silence
681 * by summing the stereo stream from some (known to be ForteMedia)
684 * The logic is to call alc_inv_dmic_sync() after each action (possibly)
685 * modifying ADC amp. When the mute flag is set, it mutes the R-channel
686 * without caching so that the cache can still keep the original value.
687 * The cached value is then restored when the flag is set off or any other
688 * than d-mic is used as the current input source.
690 static void alc_inv_dmic_sync(struct hda_codec *codec, bool force)
692 struct alc_spec *spec = codec->spec;
695 if (!spec->inv_dmic_fixup)
697 if (!spec->inv_dmic_muted && !force)
699 nums = spec->gen.dyn_adc_switch ? 1 : spec->gen.num_adc_nids;
700 for (src = 0; src < nums; src++) {
701 bool dmic_fixup = false;
703 if (spec->inv_dmic_muted &&
704 spec->gen.imux_pins[spec->gen.cur_mux[src]] == spec->inv_dmic_pin)
706 if (!dmic_fixup && !force)
708 alc_inv_dmic_sync_adc(codec, src);
712 static void alc_inv_dmic_hook(struct hda_codec *codec,
713 struct snd_kcontrol *kcontrol,
714 struct snd_ctl_elem_value *ucontrol)
716 alc_inv_dmic_sync(codec, false);
719 static int alc_inv_dmic_sw_get(struct snd_kcontrol *kcontrol,
720 struct snd_ctl_elem_value *ucontrol)
722 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
723 struct alc_spec *spec = codec->spec;
725 ucontrol->value.integer.value[0] = !spec->inv_dmic_muted;
729 static int alc_inv_dmic_sw_put(struct snd_kcontrol *kcontrol,
730 struct snd_ctl_elem_value *ucontrol)
732 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
733 struct alc_spec *spec = codec->spec;
734 unsigned int val = !ucontrol->value.integer.value[0];
736 if (val == spec->inv_dmic_muted)
738 spec->inv_dmic_muted = val;
739 alc_inv_dmic_sync(codec, true);
743 static const struct snd_kcontrol_new alc_inv_dmic_sw = {
744 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
745 .name = "Inverted Internal Mic Capture Switch",
746 .info = snd_ctl_boolean_mono_info,
747 .get = alc_inv_dmic_sw_get,
748 .put = alc_inv_dmic_sw_put,
751 static int alc_add_inv_dmic_mixer(struct hda_codec *codec, hda_nid_t nid)
753 struct alc_spec *spec = codec->spec;
755 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &alc_inv_dmic_sw))
757 spec->inv_dmic_fixup = 1;
758 spec->inv_dmic_muted = 0;
759 spec->inv_dmic_pin = nid;
760 spec->gen.cap_sync_hook = alc_inv_dmic_hook;
764 /* typically the digital mic is put at node 0x12 */
765 static void alc_fixup_inv_dmic_0x12(struct hda_codec *codec,
766 const struct hda_fixup *fix, int action)
768 if (action == HDA_FIXUP_ACT_PROBE)
769 alc_add_inv_dmic_mixer(codec, 0x12);
773 #ifdef CONFIG_SND_HDA_INPUT_BEEP
774 /* additional beep mixers; the actual parameters are overwritten at build */
775 static const struct snd_kcontrol_new alc_beep_mixer[] = {
776 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
777 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
782 static int alc_build_controls(struct hda_codec *codec)
784 struct alc_spec *spec = codec->spec;
787 err = snd_hda_gen_build_controls(codec);
791 for (i = 0; i < spec->num_mixers; i++) {
792 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
797 #ifdef CONFIG_SND_HDA_INPUT_BEEP
798 /* create beep controls if needed */
799 if (spec->beep_amp) {
800 const struct snd_kcontrol_new *knew;
801 for (knew = alc_beep_mixer; knew->name; knew++) {
802 struct snd_kcontrol *kctl;
803 kctl = snd_ctl_new1(knew, codec);
806 kctl->private_value = spec->beep_amp;
807 err = snd_hda_ctl_add(codec, 0, kctl);
814 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
823 static int alc_init(struct hda_codec *codec)
825 struct alc_spec *spec = codec->spec;
828 spec->init_hook(codec);
831 alc_auto_init_amp(codec, spec->init_amp);
833 snd_hda_gen_init(codec);
835 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
840 static inline void alc_shutup(struct hda_codec *codec)
842 struct alc_spec *spec = codec->spec;
844 if (spec && spec->shutup)
847 snd_hda_shutup_pins(codec);
850 static void alc_free(struct hda_codec *codec)
852 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_FREE);
853 snd_hda_gen_free(codec);
857 static void alc_power_eapd(struct hda_codec *codec)
859 alc_auto_setup_eapd(codec, false);
862 static int alc_suspend(struct hda_codec *codec)
864 struct alc_spec *spec = codec->spec;
866 if (spec && spec->power_hook)
867 spec->power_hook(codec);
873 static int alc_resume(struct hda_codec *codec)
875 struct alc_spec *spec = codec->spec;
877 if (!spec->no_depop_delay)
878 msleep(150); /* to avoid pop noise */
879 codec->patch_ops.init(codec);
880 snd_hda_codec_resume_amp(codec);
881 snd_hda_codec_resume_cache(codec);
882 alc_inv_dmic_sync(codec, true);
883 hda_call_check_power_status(codec, 0x01);
890 static const struct hda_codec_ops alc_patch_ops = {
891 .build_controls = alc_build_controls,
892 .build_pcms = snd_hda_gen_build_pcms,
895 .unsol_event = snd_hda_jack_unsol_event,
897 .resume = alc_resume,
898 .suspend = alc_suspend,
899 .check_power_status = snd_hda_gen_check_power_status,
901 .reboot_notify = alc_shutup,
905 /* replace the codec chip_name with the given string */
906 static int alc_codec_rename(struct hda_codec *codec, const char *name)
908 kfree(codec->chip_name);
909 codec->chip_name = kstrdup(name, GFP_KERNEL);
910 if (!codec->chip_name) {
918 * Rename codecs appropriately from COEF value or subvendor id
920 struct alc_codec_rename_table {
921 unsigned int vendor_id;
922 unsigned short coef_mask;
923 unsigned short coef_bits;
927 struct alc_codec_rename_pci_table {
928 unsigned int codec_vendor_id;
929 unsigned short pci_subvendor;
930 unsigned short pci_subdevice;
934 static struct alc_codec_rename_table rename_tbl[] = {
935 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
936 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
937 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
938 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
939 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
940 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
941 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
942 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
943 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
944 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
945 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
946 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
947 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
948 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
949 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
953 static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
954 { 0x10ec0280, 0x1028, 0, "ALC3220" },
955 { 0x10ec0282, 0x1028, 0, "ALC3221" },
956 { 0x10ec0283, 0x1028, 0, "ALC3223" },
957 { 0x10ec0292, 0x1028, 0, "ALC3226" },
958 { 0x10ec0255, 0x1028, 0, "ALC3234" },
959 { 0x10ec0668, 0x1028, 0, "ALC3661" },
963 static int alc_codec_rename_from_preset(struct hda_codec *codec)
965 const struct alc_codec_rename_table *p;
966 const struct alc_codec_rename_pci_table *q;
968 for (p = rename_tbl; p->vendor_id; p++) {
969 if (p->vendor_id != codec->vendor_id)
971 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
972 return alc_codec_rename(codec, p->name);
975 for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
976 if (q->codec_vendor_id != codec->vendor_id)
978 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
980 if (!q->pci_subdevice ||
981 q->pci_subdevice == codec->bus->pci->subsystem_device)
982 return alc_codec_rename(codec, q->name);
990 * Digital-beep handlers
992 #ifdef CONFIG_SND_HDA_INPUT_BEEP
993 #define set_beep_amp(spec, nid, idx, dir) \
994 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
996 static const struct snd_pci_quirk beep_white_list[] = {
997 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
998 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
999 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
1000 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
1001 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
1002 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
1003 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
1004 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
1005 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
1009 static inline int has_cdefine_beep(struct hda_codec *codec)
1011 struct alc_spec *spec = codec->spec;
1012 const struct snd_pci_quirk *q;
1013 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
1016 return spec->cdefine.enable_pcbeep;
1019 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
1020 #define has_cdefine_beep(codec) 0
1023 /* parse the BIOS configuration and set up the alc_spec */
1024 /* return 1 if successful, 0 if the proper config is not found,
1025 * or a negative error code
1027 static int alc_parse_auto_config(struct hda_codec *codec,
1028 const hda_nid_t *ignore_nids,
1029 const hda_nid_t *ssid_nids)
1031 struct alc_spec *spec = codec->spec;
1032 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
1035 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
1041 alc_ssid_check(codec, ssid_nids);
1043 err = snd_hda_gen_parse_auto_config(codec, cfg);
1050 /* common preparation job for alc_spec */
1051 static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1053 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1059 snd_hda_gen_spec_init(&spec->gen);
1060 spec->gen.mixer_nid = mixer_nid;
1061 spec->gen.own_eapd_ctl = 1;
1062 codec->single_adc_amp = 1;
1063 /* FIXME: do we need this for all Realtek codec models? */
1064 codec->spdif_status_reset = 1;
1066 err = alc_codec_rename_from_preset(codec);
1074 static int alc880_parse_auto_config(struct hda_codec *codec)
1076 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
1077 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
1078 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1087 ALC880_FIXUP_MEDION_RIM,
1089 ALC880_FIXUP_LG_LW25,
1091 ALC880_FIXUP_EAPD_COEF,
1092 ALC880_FIXUP_TCL_S700,
1093 ALC880_FIXUP_VOL_KNOB,
1094 ALC880_FIXUP_FUJITSU,
1096 ALC880_FIXUP_UNIWILL,
1097 ALC880_FIXUP_UNIWILL_DIG,
1099 ALC880_FIXUP_ASUS_W5A,
1100 ALC880_FIXUP_3ST_BASE,
1102 ALC880_FIXUP_3ST_DIG,
1103 ALC880_FIXUP_5ST_BASE,
1105 ALC880_FIXUP_5ST_DIG,
1106 ALC880_FIXUP_6ST_BASE,
1108 ALC880_FIXUP_6ST_DIG,
1109 ALC880_FIXUP_6ST_AUTOMUTE,
1112 /* enable the volume-knob widget support on NID 0x21 */
1113 static void alc880_fixup_vol_knob(struct hda_codec *codec,
1114 const struct hda_fixup *fix, int action)
1116 if (action == HDA_FIXUP_ACT_PROBE)
1117 snd_hda_jack_detect_enable_callback(codec, 0x21, ALC_DCVOL_EVENT, alc_update_knob_master);
1120 static const struct hda_fixup alc880_fixups[] = {
1121 [ALC880_FIXUP_GPIO1] = {
1122 .type = HDA_FIXUP_VERBS,
1123 .v.verbs = alc_gpio1_init_verbs,
1125 [ALC880_FIXUP_GPIO2] = {
1126 .type = HDA_FIXUP_VERBS,
1127 .v.verbs = alc_gpio2_init_verbs,
1129 [ALC880_FIXUP_MEDION_RIM] = {
1130 .type = HDA_FIXUP_VERBS,
1131 .v.verbs = (const struct hda_verb[]) {
1132 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1133 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1137 .chain_id = ALC880_FIXUP_GPIO2,
1139 [ALC880_FIXUP_LG] = {
1140 .type = HDA_FIXUP_PINS,
1141 .v.pins = (const struct hda_pintbl[]) {
1142 /* disable bogus unused pins */
1143 { 0x16, 0x411111f0 },
1144 { 0x18, 0x411111f0 },
1145 { 0x1a, 0x411111f0 },
1149 [ALC880_FIXUP_LG_LW25] = {
1150 .type = HDA_FIXUP_PINS,
1151 .v.pins = (const struct hda_pintbl[]) {
1152 { 0x1a, 0x0181344f }, /* line-in */
1153 { 0x1b, 0x0321403f }, /* headphone */
1157 [ALC880_FIXUP_W810] = {
1158 .type = HDA_FIXUP_PINS,
1159 .v.pins = (const struct hda_pintbl[]) {
1160 /* disable bogus unused pins */
1161 { 0x17, 0x411111f0 },
1165 .chain_id = ALC880_FIXUP_GPIO2,
1167 [ALC880_FIXUP_EAPD_COEF] = {
1168 .type = HDA_FIXUP_VERBS,
1169 .v.verbs = (const struct hda_verb[]) {
1170 /* change to EAPD mode */
1171 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1172 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1176 [ALC880_FIXUP_TCL_S700] = {
1177 .type = HDA_FIXUP_VERBS,
1178 .v.verbs = (const struct hda_verb[]) {
1179 /* change to EAPD mode */
1180 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1181 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
1185 .chain_id = ALC880_FIXUP_GPIO2,
1187 [ALC880_FIXUP_VOL_KNOB] = {
1188 .type = HDA_FIXUP_FUNC,
1189 .v.func = alc880_fixup_vol_knob,
1191 [ALC880_FIXUP_FUJITSU] = {
1192 /* override all pins as BIOS on old Amilo is broken */
1193 .type = HDA_FIXUP_PINS,
1194 .v.pins = (const struct hda_pintbl[]) {
1195 { 0x14, 0x0121411f }, /* HP */
1196 { 0x15, 0x99030120 }, /* speaker */
1197 { 0x16, 0x99030130 }, /* bass speaker */
1198 { 0x17, 0x411111f0 }, /* N/A */
1199 { 0x18, 0x411111f0 }, /* N/A */
1200 { 0x19, 0x01a19950 }, /* mic-in */
1201 { 0x1a, 0x411111f0 }, /* N/A */
1202 { 0x1b, 0x411111f0 }, /* N/A */
1203 { 0x1c, 0x411111f0 }, /* N/A */
1204 { 0x1d, 0x411111f0 }, /* N/A */
1205 { 0x1e, 0x01454140 }, /* SPDIF out */
1209 .chain_id = ALC880_FIXUP_VOL_KNOB,
1211 [ALC880_FIXUP_F1734] = {
1212 /* almost compatible with FUJITSU, but no bass and SPDIF */
1213 .type = HDA_FIXUP_PINS,
1214 .v.pins = (const struct hda_pintbl[]) {
1215 { 0x14, 0x0121411f }, /* HP */
1216 { 0x15, 0x99030120 }, /* speaker */
1217 { 0x16, 0x411111f0 }, /* N/A */
1218 { 0x17, 0x411111f0 }, /* N/A */
1219 { 0x18, 0x411111f0 }, /* N/A */
1220 { 0x19, 0x01a19950 }, /* mic-in */
1221 { 0x1a, 0x411111f0 }, /* N/A */
1222 { 0x1b, 0x411111f0 }, /* N/A */
1223 { 0x1c, 0x411111f0 }, /* N/A */
1224 { 0x1d, 0x411111f0 }, /* N/A */
1225 { 0x1e, 0x411111f0 }, /* N/A */
1229 .chain_id = ALC880_FIXUP_VOL_KNOB,
1231 [ALC880_FIXUP_UNIWILL] = {
1232 /* need to fix HP and speaker pins to be parsed correctly */
1233 .type = HDA_FIXUP_PINS,
1234 .v.pins = (const struct hda_pintbl[]) {
1235 { 0x14, 0x0121411f }, /* HP */
1236 { 0x15, 0x99030120 }, /* speaker */
1237 { 0x16, 0x99030130 }, /* bass speaker */
1241 [ALC880_FIXUP_UNIWILL_DIG] = {
1242 .type = HDA_FIXUP_PINS,
1243 .v.pins = (const struct hda_pintbl[]) {
1244 /* disable bogus unused pins */
1245 { 0x17, 0x411111f0 },
1246 { 0x19, 0x411111f0 },
1247 { 0x1b, 0x411111f0 },
1248 { 0x1f, 0x411111f0 },
1252 [ALC880_FIXUP_Z71V] = {
1253 .type = HDA_FIXUP_PINS,
1254 .v.pins = (const struct hda_pintbl[]) {
1255 /* set up the whole pins as BIOS is utterly broken */
1256 { 0x14, 0x99030120 }, /* speaker */
1257 { 0x15, 0x0121411f }, /* HP */
1258 { 0x16, 0x411111f0 }, /* N/A */
1259 { 0x17, 0x411111f0 }, /* N/A */
1260 { 0x18, 0x01a19950 }, /* mic-in */
1261 { 0x19, 0x411111f0 }, /* N/A */
1262 { 0x1a, 0x01813031 }, /* line-in */
1263 { 0x1b, 0x411111f0 }, /* N/A */
1264 { 0x1c, 0x411111f0 }, /* N/A */
1265 { 0x1d, 0x411111f0 }, /* N/A */
1266 { 0x1e, 0x0144111e }, /* SPDIF */
1270 [ALC880_FIXUP_ASUS_W5A] = {
1271 .type = HDA_FIXUP_PINS,
1272 .v.pins = (const struct hda_pintbl[]) {
1273 /* set up the whole pins as BIOS is utterly broken */
1274 { 0x14, 0x0121411f }, /* HP */
1275 { 0x15, 0x411111f0 }, /* N/A */
1276 { 0x16, 0x411111f0 }, /* N/A */
1277 { 0x17, 0x411111f0 }, /* N/A */
1278 { 0x18, 0x90a60160 }, /* mic */
1279 { 0x19, 0x411111f0 }, /* N/A */
1280 { 0x1a, 0x411111f0 }, /* N/A */
1281 { 0x1b, 0x411111f0 }, /* N/A */
1282 { 0x1c, 0x411111f0 }, /* N/A */
1283 { 0x1d, 0x411111f0 }, /* N/A */
1284 { 0x1e, 0xb743111e }, /* SPDIF out */
1288 .chain_id = ALC880_FIXUP_GPIO1,
1290 [ALC880_FIXUP_3ST_BASE] = {
1291 .type = HDA_FIXUP_PINS,
1292 .v.pins = (const struct hda_pintbl[]) {
1293 { 0x14, 0x01014010 }, /* line-out */
1294 { 0x15, 0x411111f0 }, /* N/A */
1295 { 0x16, 0x411111f0 }, /* N/A */
1296 { 0x17, 0x411111f0 }, /* N/A */
1297 { 0x18, 0x01a19c30 }, /* mic-in */
1298 { 0x19, 0x0121411f }, /* HP */
1299 { 0x1a, 0x01813031 }, /* line-in */
1300 { 0x1b, 0x02a19c40 }, /* front-mic */
1301 { 0x1c, 0x411111f0 }, /* N/A */
1302 { 0x1d, 0x411111f0 }, /* N/A */
1303 /* 0x1e is filled in below */
1304 { 0x1f, 0x411111f0 }, /* N/A */
1308 [ALC880_FIXUP_3ST] = {
1309 .type = HDA_FIXUP_PINS,
1310 .v.pins = (const struct hda_pintbl[]) {
1311 { 0x1e, 0x411111f0 }, /* N/A */
1315 .chain_id = ALC880_FIXUP_3ST_BASE,
1317 [ALC880_FIXUP_3ST_DIG] = {
1318 .type = HDA_FIXUP_PINS,
1319 .v.pins = (const struct hda_pintbl[]) {
1320 { 0x1e, 0x0144111e }, /* SPDIF */
1324 .chain_id = ALC880_FIXUP_3ST_BASE,
1326 [ALC880_FIXUP_5ST_BASE] = {
1327 .type = HDA_FIXUP_PINS,
1328 .v.pins = (const struct hda_pintbl[]) {
1329 { 0x14, 0x01014010 }, /* front */
1330 { 0x15, 0x411111f0 }, /* N/A */
1331 { 0x16, 0x01011411 }, /* CLFE */
1332 { 0x17, 0x01016412 }, /* surr */
1333 { 0x18, 0x01a19c30 }, /* mic-in */
1334 { 0x19, 0x0121411f }, /* HP */
1335 { 0x1a, 0x01813031 }, /* line-in */
1336 { 0x1b, 0x02a19c40 }, /* front-mic */
1337 { 0x1c, 0x411111f0 }, /* N/A */
1338 { 0x1d, 0x411111f0 }, /* N/A */
1339 /* 0x1e is filled in below */
1340 { 0x1f, 0x411111f0 }, /* N/A */
1344 [ALC880_FIXUP_5ST] = {
1345 .type = HDA_FIXUP_PINS,
1346 .v.pins = (const struct hda_pintbl[]) {
1347 { 0x1e, 0x411111f0 }, /* N/A */
1351 .chain_id = ALC880_FIXUP_5ST_BASE,
1353 [ALC880_FIXUP_5ST_DIG] = {
1354 .type = HDA_FIXUP_PINS,
1355 .v.pins = (const struct hda_pintbl[]) {
1356 { 0x1e, 0x0144111e }, /* SPDIF */
1360 .chain_id = ALC880_FIXUP_5ST_BASE,
1362 [ALC880_FIXUP_6ST_BASE] = {
1363 .type = HDA_FIXUP_PINS,
1364 .v.pins = (const struct hda_pintbl[]) {
1365 { 0x14, 0x01014010 }, /* front */
1366 { 0x15, 0x01016412 }, /* surr */
1367 { 0x16, 0x01011411 }, /* CLFE */
1368 { 0x17, 0x01012414 }, /* side */
1369 { 0x18, 0x01a19c30 }, /* mic-in */
1370 { 0x19, 0x02a19c40 }, /* front-mic */
1371 { 0x1a, 0x01813031 }, /* line-in */
1372 { 0x1b, 0x0121411f }, /* HP */
1373 { 0x1c, 0x411111f0 }, /* N/A */
1374 { 0x1d, 0x411111f0 }, /* N/A */
1375 /* 0x1e is filled in below */
1376 { 0x1f, 0x411111f0 }, /* N/A */
1380 [ALC880_FIXUP_6ST] = {
1381 .type = HDA_FIXUP_PINS,
1382 .v.pins = (const struct hda_pintbl[]) {
1383 { 0x1e, 0x411111f0 }, /* N/A */
1387 .chain_id = ALC880_FIXUP_6ST_BASE,
1389 [ALC880_FIXUP_6ST_DIG] = {
1390 .type = HDA_FIXUP_PINS,
1391 .v.pins = (const struct hda_pintbl[]) {
1392 { 0x1e, 0x0144111e }, /* SPDIF */
1396 .chain_id = ALC880_FIXUP_6ST_BASE,
1398 [ALC880_FIXUP_6ST_AUTOMUTE] = {
1399 .type = HDA_FIXUP_PINS,
1400 .v.pins = (const struct hda_pintbl[]) {
1401 { 0x1b, 0x0121401f }, /* HP with jack detect */
1404 .chained_before = true,
1405 .chain_id = ALC880_FIXUP_6ST_BASE,
1409 static const struct snd_pci_quirk alc880_fixup_tbl[] = {
1410 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
1411 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
1412 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
1413 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
1414 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
1415 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
1416 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
1417 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
1418 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
1419 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
1420 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
1421 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
1422 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
1423 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734),
1424 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
1425 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
1426 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
1427 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1428 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1429 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
1430 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
1431 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
1433 /* Below is the copied entries from alc880_quirks.c.
1434 * It's not quite sure whether BIOS sets the correct pin-config table
1435 * on these machines, thus they are kept to be compatible with
1436 * the old static quirks. Once when it's confirmed to work without
1437 * these overrides, it'd be better to remove.
1439 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1440 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1441 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1442 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1443 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1444 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1445 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1446 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1447 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1448 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1449 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1450 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1451 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1452 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1453 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1454 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1455 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1456 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1457 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1458 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1459 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1460 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1461 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1462 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1463 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1464 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1465 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1466 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1467 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1468 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1469 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1470 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1471 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1473 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1474 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1475 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1479 static const struct hda_model_fixup alc880_fixup_models[] = {
1480 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1481 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1482 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1483 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1484 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1485 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
1486 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
1492 * OK, here we have finally the patch for ALC880
1494 static int patch_alc880(struct hda_codec *codec)
1496 struct alc_spec *spec;
1499 err = alc_alloc_spec(codec, 0x0b);
1504 spec->gen.need_dac_fix = 1;
1505 spec->gen.beep_nid = 0x01;
1507 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
1509 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1511 /* automatic parse from the BIOS config */
1512 err = alc880_parse_auto_config(codec);
1516 if (!spec->gen.no_analog)
1517 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1519 codec->patch_ops = alc_patch_ops;
1520 codec->patch_ops.unsol_event = alc880_unsol_event;
1523 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1536 static int alc260_parse_auto_config(struct hda_codec *codec)
1538 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
1539 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1540 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
1547 ALC260_FIXUP_HP_DC5750,
1548 ALC260_FIXUP_HP_PIN_0F,
1551 ALC260_FIXUP_GPIO1_TOGGLE,
1552 ALC260_FIXUP_REPLACER,
1553 ALC260_FIXUP_HP_B1900,
1555 ALC260_FIXUP_FSC_S7020,
1556 ALC260_FIXUP_FSC_S7020_JWSE,
1557 ALC260_FIXUP_VAIO_PINS,
1560 static void alc260_gpio1_automute(struct hda_codec *codec)
1562 struct alc_spec *spec = codec->spec;
1563 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
1564 spec->gen.hp_jack_present);
1567 static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
1568 const struct hda_fixup *fix, int action)
1570 struct alc_spec *spec = codec->spec;
1571 if (action == HDA_FIXUP_ACT_PROBE) {
1572 /* although the machine has only one output pin, we need to
1573 * toggle GPIO1 according to the jack state
1575 spec->gen.automute_hook = alc260_gpio1_automute;
1576 spec->gen.detect_hp = 1;
1577 spec->gen.automute_speaker = 1;
1578 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
1579 snd_hda_jack_detect_enable_callback(codec, 0x0f, HDA_GEN_HP_EVENT,
1580 snd_hda_gen_hp_automute);
1581 snd_hda_add_verbs(codec, alc_gpio1_init_verbs);
1585 static void alc260_fixup_kn1(struct hda_codec *codec,
1586 const struct hda_fixup *fix, int action)
1588 struct alc_spec *spec = codec->spec;
1589 static const struct hda_pintbl pincfgs[] = {
1590 { 0x0f, 0x02214000 }, /* HP/speaker */
1591 { 0x12, 0x90a60160 }, /* int mic */
1592 { 0x13, 0x02a19000 }, /* ext mic */
1593 { 0x18, 0x01446000 }, /* SPDIF out */
1594 /* disable bogus I/O pins */
1595 { 0x10, 0x411111f0 },
1596 { 0x11, 0x411111f0 },
1597 { 0x14, 0x411111f0 },
1598 { 0x15, 0x411111f0 },
1599 { 0x16, 0x411111f0 },
1600 { 0x17, 0x411111f0 },
1601 { 0x19, 0x411111f0 },
1606 case HDA_FIXUP_ACT_PRE_PROBE:
1607 snd_hda_apply_pincfgs(codec, pincfgs);
1609 case HDA_FIXUP_ACT_PROBE:
1610 spec->init_amp = ALC_INIT_NONE;
1615 static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1616 const struct hda_fixup *fix, int action)
1618 struct alc_spec *spec = codec->spec;
1619 if (action == HDA_FIXUP_ACT_PROBE)
1620 spec->init_amp = ALC_INIT_NONE;
1623 static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1624 const struct hda_fixup *fix, int action)
1626 struct alc_spec *spec = codec->spec;
1627 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1628 spec->gen.add_jack_modes = 1;
1629 spec->gen.hp_mic = 1;
1633 static const struct hda_fixup alc260_fixups[] = {
1634 [ALC260_FIXUP_HP_DC5750] = {
1635 .type = HDA_FIXUP_PINS,
1636 .v.pins = (const struct hda_pintbl[]) {
1637 { 0x11, 0x90130110 }, /* speaker */
1641 [ALC260_FIXUP_HP_PIN_0F] = {
1642 .type = HDA_FIXUP_PINS,
1643 .v.pins = (const struct hda_pintbl[]) {
1644 { 0x0f, 0x01214000 }, /* HP */
1648 [ALC260_FIXUP_COEF] = {
1649 .type = HDA_FIXUP_VERBS,
1650 .v.verbs = (const struct hda_verb[]) {
1651 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1652 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
1656 [ALC260_FIXUP_GPIO1] = {
1657 .type = HDA_FIXUP_VERBS,
1658 .v.verbs = alc_gpio1_init_verbs,
1660 [ALC260_FIXUP_GPIO1_TOGGLE] = {
1661 .type = HDA_FIXUP_FUNC,
1662 .v.func = alc260_fixup_gpio1_toggle,
1664 .chain_id = ALC260_FIXUP_HP_PIN_0F,
1666 [ALC260_FIXUP_REPLACER] = {
1667 .type = HDA_FIXUP_VERBS,
1668 .v.verbs = (const struct hda_verb[]) {
1669 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1670 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
1674 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1676 [ALC260_FIXUP_HP_B1900] = {
1677 .type = HDA_FIXUP_FUNC,
1678 .v.func = alc260_fixup_gpio1_toggle,
1680 .chain_id = ALC260_FIXUP_COEF,
1682 [ALC260_FIXUP_KN1] = {
1683 .type = HDA_FIXUP_FUNC,
1684 .v.func = alc260_fixup_kn1,
1686 [ALC260_FIXUP_FSC_S7020] = {
1687 .type = HDA_FIXUP_FUNC,
1688 .v.func = alc260_fixup_fsc_s7020,
1690 [ALC260_FIXUP_FSC_S7020_JWSE] = {
1691 .type = HDA_FIXUP_FUNC,
1692 .v.func = alc260_fixup_fsc_s7020_jwse,
1694 .chain_id = ALC260_FIXUP_FSC_S7020,
1696 [ALC260_FIXUP_VAIO_PINS] = {
1697 .type = HDA_FIXUP_PINS,
1698 .v.pins = (const struct hda_pintbl[]) {
1699 /* Pin configs are missing completely on some VAIOs */
1700 { 0x0f, 0x01211020 },
1701 { 0x10, 0x0001003f },
1702 { 0x11, 0x411111f0 },
1703 { 0x12, 0x01a15930 },
1704 { 0x13, 0x411111f0 },
1705 { 0x14, 0x411111f0 },
1706 { 0x15, 0x411111f0 },
1707 { 0x16, 0x411111f0 },
1708 { 0x17, 0x411111f0 },
1709 { 0x18, 0x411111f0 },
1710 { 0x19, 0x411111f0 },
1716 static const struct snd_pci_quirk alc260_fixup_tbl[] = {
1717 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
1718 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
1719 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
1720 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
1721 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
1722 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
1723 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
1724 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
1725 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
1726 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
1727 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
1728 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
1732 static const struct hda_model_fixup alc260_fixup_models[] = {
1733 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1734 {.id = ALC260_FIXUP_COEF, .name = "coef"},
1735 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1736 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1742 static int patch_alc260(struct hda_codec *codec)
1744 struct alc_spec *spec;
1747 err = alc_alloc_spec(codec, 0x07);
1752 /* as quite a few machines require HP amp for speaker outputs,
1753 * it's easier to enable it unconditionally; even if it's unneeded,
1754 * it's almost harmless.
1756 spec->gen.prefer_hp_amp = 1;
1757 spec->gen.beep_nid = 0x01;
1759 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1761 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1763 /* automatic parse from the BIOS config */
1764 err = alc260_parse_auto_config(codec);
1768 if (!spec->gen.no_analog)
1769 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
1771 codec->patch_ops = alc_patch_ops;
1772 spec->shutup = alc_eapd_shutup;
1774 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1785 * ALC882/883/885/888/889 support
1787 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1788 * configuration. Each pin widget can choose any input DACs and a mixer.
1789 * Each ADC is connected from a mixer of all inputs. This makes possible
1790 * 6-channel independent captures.
1792 * In addition, an independent DAC for the multi-playback (not used in this
1800 ALC882_FIXUP_ABIT_AW9D_MAX,
1801 ALC882_FIXUP_LENOVO_Y530,
1802 ALC882_FIXUP_PB_M5210,
1803 ALC882_FIXUP_ACER_ASPIRE_7736,
1804 ALC882_FIXUP_ASUS_W90V,
1806 ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
1807 ALC889_FIXUP_VAIO_TT,
1808 ALC888_FIXUP_EEE1601,
1811 ALC883_FIXUP_ACER_EAPD,
1816 ALC882_FIXUP_ASUS_W2JC,
1817 ALC882_FIXUP_ACER_ASPIRE_4930G,
1818 ALC882_FIXUP_ACER_ASPIRE_8930G,
1819 ALC882_FIXUP_ASPIRE_8930G_VERBS,
1820 ALC885_FIXUP_MACPRO_GPIO,
1821 ALC889_FIXUP_DAC_ROUTE,
1822 ALC889_FIXUP_MBP_VREF,
1823 ALC889_FIXUP_IMAC91_VREF,
1824 ALC889_FIXUP_MBA11_VREF,
1825 ALC889_FIXUP_MBA21_VREF,
1826 ALC889_FIXUP_MP11_VREF,
1827 ALC882_FIXUP_INV_DMIC,
1828 ALC882_FIXUP_NO_PRIMARY_HP,
1829 ALC887_FIXUP_ASUS_BASS,
1830 ALC887_FIXUP_BASS_CHMAP,
1833 static void alc889_fixup_coef(struct hda_codec *codec,
1834 const struct hda_fixup *fix, int action)
1836 if (action != HDA_FIXUP_ACT_INIT)
1838 alc889_coef_init(codec);
1841 /* toggle speaker-output according to the hp-jack state */
1842 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
1844 unsigned int gpiostate, gpiomask, gpiodir;
1846 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
1847 AC_VERB_GET_GPIO_DATA, 0);
1850 gpiostate |= (1 << pin);
1852 gpiostate &= ~(1 << pin);
1854 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
1855 AC_VERB_GET_GPIO_MASK, 0);
1856 gpiomask |= (1 << pin);
1858 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
1859 AC_VERB_GET_GPIO_DIRECTION, 0);
1860 gpiodir |= (1 << pin);
1863 snd_hda_codec_write(codec, codec->afg, 0,
1864 AC_VERB_SET_GPIO_MASK, gpiomask);
1865 snd_hda_codec_write(codec, codec->afg, 0,
1866 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
1870 snd_hda_codec_write(codec, codec->afg, 0,
1871 AC_VERB_SET_GPIO_DATA, gpiostate);
1874 /* set up GPIO at initialization */
1875 static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
1876 const struct hda_fixup *fix, int action)
1878 if (action != HDA_FIXUP_ACT_INIT)
1880 alc882_gpio_mute(codec, 0, 0);
1881 alc882_gpio_mute(codec, 1, 0);
1884 /* Fix the connection of some pins for ALC889:
1885 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1886 * work correctly (bko#42740)
1888 static void alc889_fixup_dac_route(struct hda_codec *codec,
1889 const struct hda_fixup *fix, int action)
1891 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1892 /* fake the connections during parsing the tree */
1893 hda_nid_t conn1[2] = { 0x0c, 0x0d };
1894 hda_nid_t conn2[2] = { 0x0e, 0x0f };
1895 snd_hda_override_conn_list(codec, 0x14, 2, conn1);
1896 snd_hda_override_conn_list(codec, 0x15, 2, conn1);
1897 snd_hda_override_conn_list(codec, 0x18, 2, conn2);
1898 snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
1899 } else if (action == HDA_FIXUP_ACT_PROBE) {
1900 /* restore the connections */
1901 hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1902 snd_hda_override_conn_list(codec, 0x14, 5, conn);
1903 snd_hda_override_conn_list(codec, 0x15, 5, conn);
1904 snd_hda_override_conn_list(codec, 0x18, 5, conn);
1905 snd_hda_override_conn_list(codec, 0x1a, 5, conn);
1909 /* Set VREF on HP pin */
1910 static void alc889_fixup_mbp_vref(struct hda_codec *codec,
1911 const struct hda_fixup *fix, int action)
1913 struct alc_spec *spec = codec->spec;
1914 static hda_nid_t nids[2] = { 0x14, 0x15 };
1917 if (action != HDA_FIXUP_ACT_INIT)
1919 for (i = 0; i < ARRAY_SIZE(nids); i++) {
1920 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1921 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1923 val = snd_hda_codec_get_pin_target(codec, nids[i]);
1924 val |= AC_PINCTL_VREF_80;
1925 snd_hda_set_pin_ctl(codec, nids[i], val);
1926 spec->gen.keep_vref_in_automute = 1;
1931 static void alc889_fixup_mac_pins(struct hda_codec *codec,
1932 const hda_nid_t *nids, int num_nids)
1934 struct alc_spec *spec = codec->spec;
1937 for (i = 0; i < num_nids; i++) {
1939 val = snd_hda_codec_get_pin_target(codec, nids[i]);
1940 val |= AC_PINCTL_VREF_50;
1941 snd_hda_set_pin_ctl(codec, nids[i], val);
1943 spec->gen.keep_vref_in_automute = 1;
1946 /* Set VREF on speaker pins on imac91 */
1947 static void alc889_fixup_imac91_vref(struct hda_codec *codec,
1948 const struct hda_fixup *fix, int action)
1950 static hda_nid_t nids[2] = { 0x18, 0x1a };
1952 if (action == HDA_FIXUP_ACT_INIT)
1953 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1956 /* Set VREF on speaker pins on mba11 */
1957 static void alc889_fixup_mba11_vref(struct hda_codec *codec,
1958 const struct hda_fixup *fix, int action)
1960 static hda_nid_t nids[1] = { 0x18 };
1962 if (action == HDA_FIXUP_ACT_INIT)
1963 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1966 /* Set VREF on speaker pins on mba21 */
1967 static void alc889_fixup_mba21_vref(struct hda_codec *codec,
1968 const struct hda_fixup *fix, int action)
1970 static hda_nid_t nids[2] = { 0x18, 0x19 };
1972 if (action == HDA_FIXUP_ACT_INIT)
1973 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1976 /* Don't take HP output as primary
1977 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
1978 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
1980 static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
1981 const struct hda_fixup *fix, int action)
1983 struct alc_spec *spec = codec->spec;
1984 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1985 spec->gen.no_primary_hp = 1;
1986 spec->gen.no_multi_io = 1;
1990 static void alc_fixup_bass_chmap(struct hda_codec *codec,
1991 const struct hda_fixup *fix, int action);
1993 static const struct hda_fixup alc882_fixups[] = {
1994 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
1995 .type = HDA_FIXUP_PINS,
1996 .v.pins = (const struct hda_pintbl[]) {
1997 { 0x15, 0x01080104 }, /* side */
1998 { 0x16, 0x01011012 }, /* rear */
1999 { 0x17, 0x01016011 }, /* clfe */
2003 [ALC882_FIXUP_LENOVO_Y530] = {
2004 .type = HDA_FIXUP_PINS,
2005 .v.pins = (const struct hda_pintbl[]) {
2006 { 0x15, 0x99130112 }, /* rear int speakers */
2007 { 0x16, 0x99130111 }, /* subwoofer */
2011 [ALC882_FIXUP_PB_M5210] = {
2012 .type = HDA_FIXUP_PINCTLS,
2013 .v.pins = (const struct hda_pintbl[]) {
2014 { 0x19, PIN_VREF50 },
2018 [ALC882_FIXUP_ACER_ASPIRE_7736] = {
2019 .type = HDA_FIXUP_FUNC,
2020 .v.func = alc_fixup_sku_ignore,
2022 [ALC882_FIXUP_ASUS_W90V] = {
2023 .type = HDA_FIXUP_PINS,
2024 .v.pins = (const struct hda_pintbl[]) {
2025 { 0x16, 0x99130110 }, /* fix sequence for CLFE */
2029 [ALC889_FIXUP_CD] = {
2030 .type = HDA_FIXUP_PINS,
2031 .v.pins = (const struct hda_pintbl[]) {
2032 { 0x1c, 0x993301f0 }, /* CD */
2036 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2037 .type = HDA_FIXUP_PINS,
2038 .v.pins = (const struct hda_pintbl[]) {
2039 { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
2043 .chain_id = ALC889_FIXUP_CD,
2045 [ALC889_FIXUP_VAIO_TT] = {
2046 .type = HDA_FIXUP_PINS,
2047 .v.pins = (const struct hda_pintbl[]) {
2048 { 0x17, 0x90170111 }, /* hidden surround speaker */
2052 [ALC888_FIXUP_EEE1601] = {
2053 .type = HDA_FIXUP_VERBS,
2054 .v.verbs = (const struct hda_verb[]) {
2055 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2056 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
2060 [ALC882_FIXUP_EAPD] = {
2061 .type = HDA_FIXUP_VERBS,
2062 .v.verbs = (const struct hda_verb[]) {
2063 /* change to EAPD mode */
2064 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2065 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2069 [ALC883_FIXUP_EAPD] = {
2070 .type = HDA_FIXUP_VERBS,
2071 .v.verbs = (const struct hda_verb[]) {
2072 /* change to EAPD mode */
2073 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2074 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2078 [ALC883_FIXUP_ACER_EAPD] = {
2079 .type = HDA_FIXUP_VERBS,
2080 .v.verbs = (const struct hda_verb[]) {
2081 /* eanable EAPD on Acer laptops */
2082 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2083 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2087 [ALC882_FIXUP_GPIO1] = {
2088 .type = HDA_FIXUP_VERBS,
2089 .v.verbs = alc_gpio1_init_verbs,
2091 [ALC882_FIXUP_GPIO2] = {
2092 .type = HDA_FIXUP_VERBS,
2093 .v.verbs = alc_gpio2_init_verbs,
2095 [ALC882_FIXUP_GPIO3] = {
2096 .type = HDA_FIXUP_VERBS,
2097 .v.verbs = alc_gpio3_init_verbs,
2099 [ALC882_FIXUP_ASUS_W2JC] = {
2100 .type = HDA_FIXUP_VERBS,
2101 .v.verbs = alc_gpio1_init_verbs,
2103 .chain_id = ALC882_FIXUP_EAPD,
2105 [ALC889_FIXUP_COEF] = {
2106 .type = HDA_FIXUP_FUNC,
2107 .v.func = alc889_fixup_coef,
2109 [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
2110 .type = HDA_FIXUP_PINS,
2111 .v.pins = (const struct hda_pintbl[]) {
2112 { 0x16, 0x99130111 }, /* CLFE speaker */
2113 { 0x17, 0x99130112 }, /* surround speaker */
2117 .chain_id = ALC882_FIXUP_GPIO1,
2119 [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
2120 .type = HDA_FIXUP_PINS,
2121 .v.pins = (const struct hda_pintbl[]) {
2122 { 0x16, 0x99130111 }, /* CLFE speaker */
2123 { 0x1b, 0x99130112 }, /* surround speaker */
2127 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2129 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2130 /* additional init verbs for Acer Aspire 8930G */
2131 .type = HDA_FIXUP_VERBS,
2132 .v.verbs = (const struct hda_verb[]) {
2133 /* Enable all DACs */
2134 /* DAC DISABLE/MUTE 1? */
2135 /* setting bits 1-5 disables DAC nids 0x02-0x06
2136 * apparently. Init=0x38 */
2137 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2138 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2139 /* DAC DISABLE/MUTE 2? */
2140 /* some bit here disables the other DACs.
2142 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2143 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2145 * This laptop has a stereo digital microphone.
2146 * The mics are only 1cm apart which makes the stereo
2147 * useless. However, either the mic or the ALC889
2148 * makes the signal become a difference/sum signal
2149 * instead of standard stereo, which is annoying.
2150 * So instead we flip this bit which makes the
2151 * codec replicate the sum signal to both channels,
2152 * turning it into a normal mono mic.
2154 /* DMIC_CONTROL? Init value = 0x0001 */
2155 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2156 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2157 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2158 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2162 .chain_id = ALC882_FIXUP_GPIO1,
2164 [ALC885_FIXUP_MACPRO_GPIO] = {
2165 .type = HDA_FIXUP_FUNC,
2166 .v.func = alc885_fixup_macpro_gpio,
2168 [ALC889_FIXUP_DAC_ROUTE] = {
2169 .type = HDA_FIXUP_FUNC,
2170 .v.func = alc889_fixup_dac_route,
2172 [ALC889_FIXUP_MBP_VREF] = {
2173 .type = HDA_FIXUP_FUNC,
2174 .v.func = alc889_fixup_mbp_vref,
2176 .chain_id = ALC882_FIXUP_GPIO1,
2178 [ALC889_FIXUP_IMAC91_VREF] = {
2179 .type = HDA_FIXUP_FUNC,
2180 .v.func = alc889_fixup_imac91_vref,
2182 .chain_id = ALC882_FIXUP_GPIO1,
2184 [ALC889_FIXUP_MBA11_VREF] = {
2185 .type = HDA_FIXUP_FUNC,
2186 .v.func = alc889_fixup_mba11_vref,
2188 .chain_id = ALC889_FIXUP_MBP_VREF,
2190 [ALC889_FIXUP_MBA21_VREF] = {
2191 .type = HDA_FIXUP_FUNC,
2192 .v.func = alc889_fixup_mba21_vref,
2194 .chain_id = ALC889_FIXUP_MBP_VREF,
2196 [ALC889_FIXUP_MP11_VREF] = {
2197 .type = HDA_FIXUP_FUNC,
2198 .v.func = alc889_fixup_mba11_vref,
2200 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2202 [ALC882_FIXUP_INV_DMIC] = {
2203 .type = HDA_FIXUP_FUNC,
2204 .v.func = alc_fixup_inv_dmic_0x12,
2206 [ALC882_FIXUP_NO_PRIMARY_HP] = {
2207 .type = HDA_FIXUP_FUNC,
2208 .v.func = alc882_fixup_no_primary_hp,
2210 [ALC887_FIXUP_ASUS_BASS] = {
2211 .type = HDA_FIXUP_PINS,
2212 .v.pins = (const struct hda_pintbl[]) {
2213 {0x16, 0x99130130}, /* bass speaker */
2217 .chain_id = ALC887_FIXUP_BASS_CHMAP,
2219 [ALC887_FIXUP_BASS_CHMAP] = {
2220 .type = HDA_FIXUP_FUNC,
2221 .v.func = alc_fixup_bass_chmap,
2225 static const struct snd_pci_quirk alc882_fixup_tbl[] = {
2226 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2227 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2228 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2229 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2230 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2231 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
2232 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2233 ALC882_FIXUP_ACER_ASPIRE_4930G),
2234 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2235 ALC882_FIXUP_ACER_ASPIRE_4930G),
2236 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2237 ALC882_FIXUP_ACER_ASPIRE_8930G),
2238 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2239 ALC882_FIXUP_ACER_ASPIRE_8930G),
2240 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2241 ALC882_FIXUP_ACER_ASPIRE_4930G),
2242 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2243 ALC882_FIXUP_ACER_ASPIRE_4930G),
2244 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2245 ALC882_FIXUP_ACER_ASPIRE_4930G),
2246 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
2247 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2248 ALC882_FIXUP_ACER_ASPIRE_4930G),
2249 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
2250 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
2251 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
2252 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
2253 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
2254 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
2255 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
2256 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
2257 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
2258 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
2259 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
2261 /* All Apple entries are in codec SSIDs */
2262 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2263 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2264 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
2265 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
2266 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2267 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
2268 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2269 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
2270 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
2271 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
2272 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
2273 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2274 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
2275 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
2276 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2277 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2278 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
2279 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO),
2280 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
2281 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2282 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
2283 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF),
2285 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
2286 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
2287 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
2288 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
2289 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
2290 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2291 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
2292 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
2293 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
2297 static const struct hda_model_fixup alc882_fixup_models[] = {
2298 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2299 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2300 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
2301 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
2302 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
2307 * BIOS auto configuration
2309 /* almost identical with ALC880 parser... */
2310 static int alc882_parse_auto_config(struct hda_codec *codec)
2312 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
2313 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2314 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
2319 static int patch_alc882(struct hda_codec *codec)
2321 struct alc_spec *spec;
2324 err = alc_alloc_spec(codec, 0x0b);
2330 switch (codec->vendor_id) {
2335 /* ALC883 and variants */
2336 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2340 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
2342 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2344 alc_auto_parse_customize_define(codec);
2346 if (has_cdefine_beep(codec))
2347 spec->gen.beep_nid = 0x01;
2349 /* automatic parse from the BIOS config */
2350 err = alc882_parse_auto_config(codec);
2354 if (!spec->gen.no_analog && spec->gen.beep_nid)
2355 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2357 codec->patch_ops = alc_patch_ops;
2359 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2372 static int alc262_parse_auto_config(struct hda_codec *codec)
2374 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
2375 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2376 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
2383 ALC262_FIXUP_FSC_H270,
2384 ALC262_FIXUP_FSC_S7110,
2385 ALC262_FIXUP_HP_Z200,
2387 ALC262_FIXUP_LENOVO_3000,
2389 ALC262_FIXUP_BENQ_T31,
2390 ALC262_FIXUP_INV_DMIC,
2391 ALC262_FIXUP_INTEL_BAYLEYBAY,
2394 static const struct hda_fixup alc262_fixups[] = {
2395 [ALC262_FIXUP_FSC_H270] = {
2396 .type = HDA_FIXUP_PINS,
2397 .v.pins = (const struct hda_pintbl[]) {
2398 { 0x14, 0x99130110 }, /* speaker */
2399 { 0x15, 0x0221142f }, /* front HP */
2400 { 0x1b, 0x0121141f }, /* rear HP */
2404 [ALC262_FIXUP_FSC_S7110] = {
2405 .type = HDA_FIXUP_PINS,
2406 .v.pins = (const struct hda_pintbl[]) {
2407 { 0x15, 0x90170110 }, /* speaker */
2411 .chain_id = ALC262_FIXUP_BENQ,
2413 [ALC262_FIXUP_HP_Z200] = {
2414 .type = HDA_FIXUP_PINS,
2415 .v.pins = (const struct hda_pintbl[]) {
2416 { 0x16, 0x99130120 }, /* internal speaker */
2420 [ALC262_FIXUP_TYAN] = {
2421 .type = HDA_FIXUP_PINS,
2422 .v.pins = (const struct hda_pintbl[]) {
2423 { 0x14, 0x1993e1f0 }, /* int AUX */
2427 [ALC262_FIXUP_LENOVO_3000] = {
2428 .type = HDA_FIXUP_PINCTLS,
2429 .v.pins = (const struct hda_pintbl[]) {
2430 { 0x19, PIN_VREF50 },
2434 .chain_id = ALC262_FIXUP_BENQ,
2436 [ALC262_FIXUP_BENQ] = {
2437 .type = HDA_FIXUP_VERBS,
2438 .v.verbs = (const struct hda_verb[]) {
2439 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2440 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2444 [ALC262_FIXUP_BENQ_T31] = {
2445 .type = HDA_FIXUP_VERBS,
2446 .v.verbs = (const struct hda_verb[]) {
2447 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2448 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2452 [ALC262_FIXUP_INV_DMIC] = {
2453 .type = HDA_FIXUP_FUNC,
2454 .v.func = alc_fixup_inv_dmic_0x12,
2456 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2457 .type = HDA_FIXUP_FUNC,
2458 .v.func = alc_fixup_no_depop_delay,
2462 static const struct snd_pci_quirk alc262_fixup_tbl[] = {
2463 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
2464 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
2465 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
2466 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
2467 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
2468 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
2469 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2470 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
2471 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
2475 static const struct hda_model_fixup alc262_fixup_models[] = {
2476 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
2482 static int patch_alc262(struct hda_codec *codec)
2484 struct alc_spec *spec;
2487 err = alc_alloc_spec(codec, 0x0b);
2492 spec->gen.shared_mic_vref_pin = 0x18;
2495 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
2500 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
2501 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
2502 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
2503 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
2506 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2508 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
2510 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2512 alc_auto_parse_customize_define(codec);
2514 if (has_cdefine_beep(codec))
2515 spec->gen.beep_nid = 0x01;
2517 /* automatic parse from the BIOS config */
2518 err = alc262_parse_auto_config(codec);
2522 if (!spec->gen.no_analog && spec->gen.beep_nid)
2523 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2525 codec->patch_ops = alc_patch_ops;
2526 spec->shutup = alc_eapd_shutup;
2528 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2540 /* bind Beep switches of both NID 0x0f and 0x10 */
2541 static const struct hda_bind_ctls alc268_bind_beep_sw = {
2542 .ops = &snd_hda_bind_sw,
2544 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
2545 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
2550 static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2551 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
2552 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
2556 /* set PCBEEP vol = 0, mute connections */
2557 static const struct hda_verb alc268_beep_init_verbs[] = {
2558 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2559 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2560 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2565 ALC268_FIXUP_INV_DMIC,
2566 ALC268_FIXUP_HP_EAPD,
2570 static const struct hda_fixup alc268_fixups[] = {
2571 [ALC268_FIXUP_INV_DMIC] = {
2572 .type = HDA_FIXUP_FUNC,
2573 .v.func = alc_fixup_inv_dmic_0x12,
2575 [ALC268_FIXUP_HP_EAPD] = {
2576 .type = HDA_FIXUP_VERBS,
2577 .v.verbs = (const struct hda_verb[]) {
2578 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2582 [ALC268_FIXUP_SPDIF] = {
2583 .type = HDA_FIXUP_PINS,
2584 .v.pins = (const struct hda_pintbl[]) {
2585 { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2591 static const struct hda_model_fixup alc268_fixup_models[] = {
2592 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
2593 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
2597 static const struct snd_pci_quirk alc268_fixup_tbl[] = {
2598 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
2599 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
2600 /* below is codec SSID since multiple Toshiba laptops have the
2601 * same PCI SSID 1179:ff00
2603 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
2608 * BIOS auto configuration
2610 static int alc268_parse_auto_config(struct hda_codec *codec)
2612 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2613 return alc_parse_auto_config(codec, NULL, alc268_ssids);
2618 static int patch_alc268(struct hda_codec *codec)
2620 struct alc_spec *spec;
2623 /* ALC268 has no aa-loopback mixer */
2624 err = alc_alloc_spec(codec, 0);
2629 spec->gen.beep_nid = 0x01;
2631 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2632 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2634 /* automatic parse from the BIOS config */
2635 err = alc268_parse_auto_config(codec);
2639 if (err > 0 && !spec->gen.no_analog &&
2640 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
2641 add_mixer(spec, alc268_beep_mixer);
2642 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
2643 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2644 /* override the amp caps for beep generator */
2645 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2646 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2647 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2648 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2649 (0 << AC_AMPCAP_MUTE_SHIFT));
2652 codec->patch_ops = alc_patch_ops;
2653 spec->shutup = alc_eapd_shutup;
2655 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2668 static int playback_pcm_open(struct hda_pcm_stream *hinfo,
2669 struct hda_codec *codec,
2670 struct snd_pcm_substream *substream)
2672 struct hda_gen_spec *spec = codec->spec;
2673 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2677 static int playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2678 struct hda_codec *codec,
2679 unsigned int stream_tag,
2680 unsigned int format,
2681 struct snd_pcm_substream *substream)
2683 struct hda_gen_spec *spec = codec->spec;
2684 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2685 stream_tag, format, substream);
2688 static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2689 struct hda_codec *codec,
2690 struct snd_pcm_substream *substream)
2692 struct hda_gen_spec *spec = codec->spec;
2693 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2696 static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
2700 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
2701 /* NID is set in alc_build_pcms */
2703 .open = playback_pcm_open,
2704 .prepare = playback_pcm_prepare,
2705 .cleanup = playback_pcm_cleanup
2709 static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
2713 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
2714 /* NID is set in alc_build_pcms */
2717 /* different alc269-variants */
2719 ALC269_TYPE_ALC269VA,
2720 ALC269_TYPE_ALC269VB,
2721 ALC269_TYPE_ALC269VC,
2722 ALC269_TYPE_ALC269VD,
2733 * BIOS auto configuration
2735 static int alc269_parse_auto_config(struct hda_codec *codec)
2737 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
2738 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2739 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2740 struct alc_spec *spec = codec->spec;
2741 const hda_nid_t *ssids;
2743 switch (spec->codec_variant) {
2744 case ALC269_TYPE_ALC269VA:
2745 case ALC269_TYPE_ALC269VC:
2746 case ALC269_TYPE_ALC280:
2747 case ALC269_TYPE_ALC284:
2748 case ALC269_TYPE_ALC285:
2749 ssids = alc269va_ssids;
2751 case ALC269_TYPE_ALC269VB:
2752 case ALC269_TYPE_ALC269VD:
2753 case ALC269_TYPE_ALC282:
2754 case ALC269_TYPE_ALC283:
2755 case ALC269_TYPE_ALC286:
2756 case ALC269_TYPE_ALC255:
2757 ssids = alc269_ssids;
2760 ssids = alc269_ssids;
2764 return alc_parse_auto_config(codec, alc269_ignore, ssids);
2767 static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
2769 int val = alc_read_coef_idx(codec, 0x04);
2776 alc_write_coef_idx(codec, 0x04, val);
2779 static void alc269_shutup(struct hda_codec *codec)
2781 struct alc_spec *spec = codec->spec;
2783 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2784 alc269vb_toggle_power_output(codec, 0);
2785 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2786 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
2789 snd_hda_shutup_pins(codec);
2792 static void alc283_restore_default_value(struct hda_codec *codec)
2796 /* Power Down Control */
2797 alc_write_coef_idx(codec, 0x03, 0x0002);
2798 /* FIFO and filter clock */
2799 alc_write_coef_idx(codec, 0x05, 0x0700);
2801 alc_write_coef_idx(codec, 0x07, 0x0200);
2803 val = alc_read_coef_idx(codec, 0x06);
2804 alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0);
2806 val = alc_read_coef_idx(codec, 0x08);
2807 alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c);
2809 alc_write_coef_idx(codec, 0x0a, 0xcccc);
2811 alc_write_coef_idx(codec, 0x0b, 0xcccc);
2812 /* LDO1/2/3, DAC/ADC */
2813 alc_write_coef_idx(codec, 0x0e, 0x6fc0);
2815 val = alc_read_coef_idx(codec, 0x0f);
2816 alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000);
2818 val = alc_read_coef_idx(codec, 0x10);
2819 alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00);
2820 /* Class D test 4 */
2821 alc_write_coef_idx(codec, 0x3a, 0x0);
2822 /* IO power down directly */
2823 val = alc_read_coef_idx(codec, 0x0c);
2824 alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0);
2826 alc_write_coef_idx(codec, 0x22, 0xa0c0);
2828 val = alc_read_coefex_idx(codec, 0x53, 0x01);
2829 alc_write_coefex_idx(codec, 0x53, 0x01, (val & ~0x000f) | 0x0008);
2830 /* DAC simple content protection */
2831 val = alc_read_coef_idx(codec, 0x1d);
2832 alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0);
2833 /* ADC simple content protection */
2834 val = alc_read_coef_idx(codec, 0x1f);
2835 alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0);
2836 /* DAC ADC Zero Detection */
2837 alc_write_coef_idx(codec, 0x21, 0x8804);
2839 alc_write_coef_idx(codec, 0x2e, 0x2902);
2840 /* capless control 2 */
2841 alc_write_coef_idx(codec, 0x33, 0xa080);
2842 /* capless control 3 */
2843 alc_write_coef_idx(codec, 0x34, 0x3400);
2844 /* capless control 4 */
2845 alc_write_coef_idx(codec, 0x35, 0x2f3e);
2846 /* capless control 5 */
2847 alc_write_coef_idx(codec, 0x36, 0x0);
2848 /* class D test 2 */
2849 val = alc_read_coef_idx(codec, 0x38);
2850 alc_write_coef_idx(codec, 0x38, (val & ~0x0fff) | 0x0900);
2851 /* class D test 3 */
2852 alc_write_coef_idx(codec, 0x39, 0x110a);
2853 /* class D test 5 */
2854 val = alc_read_coef_idx(codec, 0x3b);
2855 alc_write_coef_idx(codec, 0x3b, (val & ~0x00f8) | 0x00d8);
2856 /* class D test 6 */
2857 alc_write_coef_idx(codec, 0x3c, 0x0014);
2859 alc_write_coef_idx(codec, 0x3d, 0xc2ba);
2860 /* classD pure DC test */
2861 val = alc_read_coef_idx(codec, 0x42);
2862 alc_write_coef_idx(codec, 0x42, (val & ~0x0f80) | 0x0);
2864 alc_write_coef_idx(codec, 0x49, 0x0);
2865 /* Class D DC enable */
2866 val = alc_read_coef_idx(codec, 0x40);
2867 alc_write_coef_idx(codec, 0x40, (val & ~0xf800) | 0x9800);
2869 val = alc_read_coef_idx(codec, 0x42);
2870 alc_write_coef_idx(codec, 0x42, (val & ~0xf000) | 0x2000);
2871 /* Class D amp control */
2872 alc_write_coef_idx(codec, 0x37, 0xfc06);
2875 static void alc283_init(struct hda_codec *codec)
2877 struct alc_spec *spec = codec->spec;
2878 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2882 alc283_restore_default_value(codec);
2886 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2888 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
2889 /* Headphone capless set to high power mode */
2890 alc_write_coef_idx(codec, 0x43, 0x9004);
2892 snd_hda_codec_write(codec, hp_pin, 0,
2893 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2898 snd_hda_codec_write(codec, hp_pin, 0,
2899 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2903 /* Index 0x46 Combo jack auto switch control 2 */
2904 /* 3k pull low control for Headset jack. */
2905 val = alc_read_coef_idx(codec, 0x46);
2906 alc_write_coef_idx(codec, 0x46, val & ~(3 << 12));
2907 /* Headphone capless set to normal mode */
2908 alc_write_coef_idx(codec, 0x43, 0x9614);
2911 static void alc283_shutup(struct hda_codec *codec)
2913 struct alc_spec *spec = codec->spec;
2914 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2919 alc269_shutup(codec);
2923 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2925 alc_write_coef_idx(codec, 0x43, 0x9004);
2927 snd_hda_codec_write(codec, hp_pin, 0,
2928 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2933 snd_hda_codec_write(codec, hp_pin, 0,
2934 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
2936 val = alc_read_coef_idx(codec, 0x46);
2937 alc_write_coef_idx(codec, 0x46, val | (3 << 12));
2941 snd_hda_shutup_pins(codec);
2942 alc_write_coef_idx(codec, 0x43, 0x9614);
2945 static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
2948 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
2949 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
2950 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
2953 static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
2957 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
2958 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
2960 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
2965 static void alc5505_dsp_halt(struct hda_codec *codec)
2969 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
2970 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
2971 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
2972 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
2973 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
2974 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
2975 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
2976 val = alc5505_coef_get(codec, 0x6220);
2977 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
2980 static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
2982 alc5505_coef_set(codec, 0x61b8, 0x04133302);
2983 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
2984 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
2985 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
2986 alc5505_coef_set(codec, 0x6220, 0x2002010f);
2987 alc5505_coef_set(codec, 0x880c, 0x00000004);
2990 static void alc5505_dsp_init(struct hda_codec *codec)
2994 alc5505_dsp_halt(codec);
2995 alc5505_dsp_back_from_halt(codec);
2996 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
2997 alc5505_coef_set(codec, 0x61b0, 0x5b16);
2998 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
2999 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3000 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3001 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3002 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3003 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3004 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3005 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3006 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3007 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3008 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3010 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3012 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3014 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3016 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3017 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3018 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3019 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3020 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3021 alc5505_coef_set(codec, 0x880c, 0x00000003);
3022 alc5505_coef_set(codec, 0x880c, 0x00000010);
3024 #ifdef HALT_REALTEK_ALC5505
3025 alc5505_dsp_halt(codec);
3029 #ifdef HALT_REALTEK_ALC5505
3030 #define alc5505_dsp_suspend(codec) /* NOP */
3031 #define alc5505_dsp_resume(codec) /* NOP */
3033 #define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3034 #define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3038 static int alc269_suspend(struct hda_codec *codec)
3040 struct alc_spec *spec = codec->spec;
3042 if (spec->has_alc5505_dsp)
3043 alc5505_dsp_suspend(codec);
3044 return alc_suspend(codec);
3047 static int alc269_resume(struct hda_codec *codec)
3049 struct alc_spec *spec = codec->spec;
3051 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3052 alc269vb_toggle_power_output(codec, 0);
3053 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3054 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
3058 codec->patch_ops.init(codec);
3060 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3061 alc269vb_toggle_power_output(codec, 1);
3062 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3063 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
3067 snd_hda_codec_resume_amp(codec);
3068 snd_hda_codec_resume_cache(codec);
3069 alc_inv_dmic_sync(codec, true);
3070 hda_call_check_power_status(codec, 0x01);
3072 /* on some machine, the BIOS will clear the codec gpio data when enter
3073 * suspend, and won't restore the data after resume, so we restore it
3077 snd_hda_codec_write(codec, codec->afg, 0, AC_VERB_SET_GPIO_DATA,
3080 if (spec->has_alc5505_dsp)
3081 alc5505_dsp_resume(codec);
3085 #endif /* CONFIG_PM */
3087 static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
3088 const struct hda_fixup *fix, int action)
3090 struct alc_spec *spec = codec->spec;
3092 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3093 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3096 static void alc269_fixup_hweq(struct hda_codec *codec,
3097 const struct hda_fixup *fix, int action)
3101 if (action != HDA_FIXUP_ACT_INIT)
3103 coef = alc_read_coef_idx(codec, 0x1e);
3104 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
3107 static void alc269_fixup_headset_mic(struct hda_codec *codec,
3108 const struct hda_fixup *fix, int action)
3110 struct alc_spec *spec = codec->spec;
3112 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3113 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3116 static void alc271_fixup_dmic(struct hda_codec *codec,
3117 const struct hda_fixup *fix, int action)
3119 static const struct hda_verb verbs[] = {
3120 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3121 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3126 if (strcmp(codec->chip_name, "ALC271X") &&
3127 strcmp(codec->chip_name, "ALC269VB"))
3129 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3130 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3131 snd_hda_sequence_write(codec, verbs);
3134 static void alc269_fixup_pcm_44k(struct hda_codec *codec,
3135 const struct hda_fixup *fix, int action)
3137 struct alc_spec *spec = codec->spec;
3139 if (action != HDA_FIXUP_ACT_PROBE)
3142 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3143 * fix the sample rate of analog I/O to 44.1kHz
3145 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3146 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
3149 static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
3150 const struct hda_fixup *fix, int action)
3154 if (action != HDA_FIXUP_ACT_INIT)
3156 /* The digital-mic unit sends PDM (differential signal) instead of
3157 * the standard PCM, thus you can't record a valid mono stream as is.
3158 * Below is a workaround specific to ALC269 to control the dmic
3159 * signal source as mono.
3161 coef = alc_read_coef_idx(codec, 0x07);
3162 alc_write_coef_idx(codec, 0x07, coef | 0x80);
3165 static void alc269_quanta_automute(struct hda_codec *codec)
3167 snd_hda_gen_update_outputs(codec);
3169 snd_hda_codec_write(codec, 0x20, 0,
3170 AC_VERB_SET_COEF_INDEX, 0x0c);
3171 snd_hda_codec_write(codec, 0x20, 0,
3172 AC_VERB_SET_PROC_COEF, 0x680);
3174 snd_hda_codec_write(codec, 0x20, 0,
3175 AC_VERB_SET_COEF_INDEX, 0x0c);
3176 snd_hda_codec_write(codec, 0x20, 0,
3177 AC_VERB_SET_PROC_COEF, 0x480);
3180 static void alc269_fixup_quanta_mute(struct hda_codec *codec,
3181 const struct hda_fixup *fix, int action)
3183 struct alc_spec *spec = codec->spec;
3184 if (action != HDA_FIXUP_ACT_PROBE)
3186 spec->gen.automute_hook = alc269_quanta_automute;
3189 static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
3190 struct hda_jack_tbl *jack)
3192 struct alc_spec *spec = codec->spec;
3195 snd_hda_gen_hp_automute(codec, jack);
3197 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3199 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3202 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3206 static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3207 const struct hda_fixup *fix, int action)
3209 struct alc_spec *spec = codec->spec;
3210 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3211 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3212 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3217 /* update mute-LED according to the speaker mute state via mic VREF pin */
3218 static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
3220 struct hda_codec *codec = private_data;
3221 struct alc_spec *spec = codec->spec;
3222 unsigned int pinval;
3224 if (spec->mute_led_polarity)
3226 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3227 pinval &= ~AC_PINCTL_VREFEN;
3228 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
3229 if (spec->mute_led_nid)
3230 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
3233 /* Make sure the led works even in runtime suspend */
3234 static unsigned int led_power_filter(struct hda_codec *codec,
3236 unsigned int power_state)
3238 struct alc_spec *spec = codec->spec;
3240 if (power_state != AC_PWRST_D3 || nid != spec->mute_led_nid)
3243 /* Set pin ctl again, it might have just been set to 0 */
3244 snd_hda_set_pin_ctl(codec, nid,
3245 snd_hda_codec_get_pin_target(codec, nid));
3250 static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
3251 const struct hda_fixup *fix, int action)
3253 struct alc_spec *spec = codec->spec;
3254 const struct dmi_device *dev = NULL;
3256 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3259 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
3261 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
3263 if (pin < 0x0a || pin >= 0x10)
3265 spec->mute_led_polarity = pol;
3266 spec->mute_led_nid = pin - 0x0a + 0x18;
3267 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3268 spec->gen.vmaster_mute_enum = 1;
3269 codec->power_filter = led_power_filter;
3270 snd_printd("Detected mute LED for %x:%d\n", spec->mute_led_nid,
3271 spec->mute_led_polarity);
3276 static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
3277 const struct hda_fixup *fix, int action)
3279 struct alc_spec *spec = codec->spec;
3280 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3281 spec->mute_led_polarity = 0;
3282 spec->mute_led_nid = 0x18;
3283 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3284 spec->gen.vmaster_mute_enum = 1;
3285 codec->power_filter = led_power_filter;
3289 static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
3290 const struct hda_fixup *fix, int action)
3292 struct alc_spec *spec = codec->spec;
3293 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3294 spec->mute_led_polarity = 0;
3295 spec->mute_led_nid = 0x19;
3296 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3297 spec->gen.vmaster_mute_enum = 1;
3298 codec->power_filter = led_power_filter;
3302 /* turn on/off mute LED per vmaster hook */
3303 static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled)
3305 struct hda_codec *codec = private_data;
3306 struct alc_spec *spec = codec->spec;
3307 unsigned int oldval = spec->gpio_led;
3310 spec->gpio_led &= ~0x08;
3312 spec->gpio_led |= 0x08;
3313 if (spec->gpio_led != oldval)
3314 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3318 /* turn on/off mic-mute LED per capture hook */
3319 static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec,
3320 struct snd_kcontrol *kcontrol,
3321 struct snd_ctl_elem_value *ucontrol)
3323 struct alc_spec *spec = codec->spec;
3324 unsigned int oldval = spec->gpio_led;
3329 if (ucontrol->value.integer.value[0] ||
3330 ucontrol->value.integer.value[1])
3331 spec->gpio_led &= ~0x10;
3333 spec->gpio_led |= 0x10;
3334 if (spec->gpio_led != oldval)
3335 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3339 static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
3340 const struct hda_fixup *fix, int action)
3342 struct alc_spec *spec = codec->spec;
3343 static const struct hda_verb gpio_init[] = {
3344 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3345 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3349 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3350 spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook;
3351 spec->gen.cap_sync_hook = alc269_fixup_hp_gpio_mic_mute_hook;
3353 snd_hda_add_verbs(codec, gpio_init);
3357 static void alc_headset_mode_unplugged(struct hda_codec *codec)
3361 switch (codec->vendor_id) {
3363 /* LDO and MISC control */
3364 alc_write_coef_idx(codec, 0x1b, 0x0c0b);
3365 /* UAJ function set to menual mode */
3366 alc_write_coef_idx(codec, 0x45, 0xd089);
3367 /* Direct Drive HP Amp control(Set to verb control)*/
3368 val = alc_read_coefex_idx(codec, 0x57, 0x05);
3369 alc_write_coefex_idx(codec, 0x57, 0x05, val & ~(1<<14));
3370 /* Set MIC2 Vref gate with HP */
3371 alc_write_coef_idx(codec, 0x06, 0x6104);
3372 /* Direct Drive HP Amp control */
3373 alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6);
3376 alc_write_coef_idx(codec, 0x1b, 0x0c0b);
3377 alc_write_coef_idx(codec, 0x45, 0xc429);
3378 val = alc_read_coef_idx(codec, 0x35);
3379 alc_write_coef_idx(codec, 0x35, val & 0xbfff);
3380 alc_write_coef_idx(codec, 0x06, 0x2104);
3381 alc_write_coef_idx(codec, 0x1a, 0x0001);
3382 alc_write_coef_idx(codec, 0x26, 0x0004);
3383 alc_write_coef_idx(codec, 0x32, 0x42a3);
3386 alc_write_coef_idx(codec, 0x76, 0x000e);
3387 alc_write_coef_idx(codec, 0x6c, 0x2400);
3388 alc_write_coef_idx(codec, 0x18, 0x7308);
3389 alc_write_coef_idx(codec, 0x6b, 0xc429);
3392 alc_write_coef_idx(codec, 0x15, 0x0d40);
3393 alc_write_coef_idx(codec, 0xb7, 0x802b);
3396 snd_printdd("Headset jack set to unplugged mode.\n");
3400 static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
3405 switch (codec->vendor_id) {
3407 alc_write_coef_idx(codec, 0x45, 0xc489);
3408 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3409 alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6);
3410 /* Set MIC2 Vref gate to normal */
3411 alc_write_coef_idx(codec, 0x06, 0x6100);
3412 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3415 alc_write_coef_idx(codec, 0x45, 0xc429);
3416 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3417 val = alc_read_coef_idx(codec, 0x35);
3418 alc_write_coef_idx(codec, 0x35, val | 1<<14);
3419 alc_write_coef_idx(codec, 0x06, 0x2100);
3420 alc_write_coef_idx(codec, 0x1a, 0x0021);
3421 alc_write_coef_idx(codec, 0x26, 0x008c);
3422 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3425 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3426 alc_write_coef_idx(codec, 0x19, 0xa208);
3427 alc_write_coef_idx(codec, 0x2e, 0xacf0);
3430 alc_write_coef_idx(codec, 0x11, 0x0001);
3431 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3432 alc_write_coef_idx(codec, 0xb7, 0x802b);
3433 alc_write_coef_idx(codec, 0xb5, 0x1040);
3434 val = alc_read_coef_idx(codec, 0xc3);
3435 alc_write_coef_idx(codec, 0xc3, val | 1<<12);
3436 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3439 snd_printdd("Headset jack set to mic-in mode.\n");
3442 static void alc_headset_mode_default(struct hda_codec *codec)
3444 switch (codec->vendor_id) {
3446 alc_write_coef_idx(codec, 0x45, 0xc089);
3447 alc_write_coef_idx(codec, 0x45, 0xc489);
3448 alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6);
3449 alc_write_coef_idx(codec, 0x49, 0x0049);
3452 alc_write_coef_idx(codec, 0x06, 0x2100);
3453 alc_write_coef_idx(codec, 0x32, 0x4ea3);
3456 alc_write_coef_idx(codec, 0x76, 0x000e);
3457 alc_write_coef_idx(codec, 0x6c, 0x2400);
3458 alc_write_coef_idx(codec, 0x6b, 0xc429);
3459 alc_write_coef_idx(codec, 0x18, 0x7308);
3462 alc_write_coef_idx(codec, 0x11, 0x0041);
3463 alc_write_coef_idx(codec, 0x15, 0x0d40);
3464 alc_write_coef_idx(codec, 0xb7, 0x802b);
3467 snd_printdd("Headset jack set to headphone (default) mode.\n");
3471 static void alc_headset_mode_ctia(struct hda_codec *codec)
3473 switch (codec->vendor_id) {
3475 /* Set to CTIA type */
3476 alc_write_coef_idx(codec, 0x45, 0xd489);
3477 alc_write_coef_idx(codec, 0x1b, 0x0c2b);
3478 alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6);
3481 alc_write_coef_idx(codec, 0x45, 0xd429);
3482 alc_write_coef_idx(codec, 0x1b, 0x0c2b);
3483 alc_write_coef_idx(codec, 0x32, 0x4ea3);
3486 alc_write_coef_idx(codec, 0x6b, 0xd429);
3487 alc_write_coef_idx(codec, 0x76, 0x0008);
3488 alc_write_coef_idx(codec, 0x18, 0x7388);
3491 alc_write_coef_idx(codec, 0x11, 0x0001);
3492 alc_write_coef_idx(codec, 0x15, 0x0d60);
3493 alc_write_coef_idx(codec, 0xc3, 0x0000);
3496 snd_printdd("Headset jack set to iPhone-style headset mode.\n");
3500 static void alc_headset_mode_omtp(struct hda_codec *codec)
3502 switch (codec->vendor_id) {
3504 /* Set to OMTP Type */
3505 alc_write_coef_idx(codec, 0x45, 0xe489);
3506 alc_write_coef_idx(codec, 0x1b, 0x0c2b);
3507 alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6);
3510 alc_write_coef_idx(codec, 0x45, 0xe429);
3511 alc_write_coef_idx(codec, 0x1b, 0x0c2b);
3512 alc_write_coef_idx(codec, 0x32, 0x4ea3);
3515 alc_write_coef_idx(codec, 0x6b, 0xe429);
3516 alc_write_coef_idx(codec, 0x76, 0x0008);
3517 alc_write_coef_idx(codec, 0x18, 0x7388);
3520 alc_write_coef_idx(codec, 0x11, 0x0001);
3521 alc_write_coef_idx(codec, 0x15, 0x0d50);
3522 alc_write_coef_idx(codec, 0xc3, 0x0000);
3525 snd_printdd("Headset jack set to Nokia-style headset mode.\n");
3528 static void alc_determine_headset_type(struct hda_codec *codec)
3531 bool is_ctia = false;
3532 struct alc_spec *spec = codec->spec;
3534 switch (codec->vendor_id) {
3536 /* combo jack auto switch control(Check type)*/
3537 alc_write_coef_idx(codec, 0x45, 0xd089);
3538 /* combo jack auto switch control(Vref conteol) */
3539 alc_write_coef_idx(codec, 0x49, 0x0149);
3541 val = alc_read_coef_idx(codec, 0x46);
3542 is_ctia = (val & 0x0070) == 0x0070;
3545 alc_write_coef_idx(codec, 0x45, 0xd029);
3547 val = alc_read_coef_idx(codec, 0x46);
3548 is_ctia = (val & 0x0070) == 0x0070;
3551 alc_write_coef_idx(codec, 0x6b, 0xd429);
3553 val = alc_read_coef_idx(codec, 0x6c);
3554 is_ctia = (val & 0x001c) == 0x001c;
3557 alc_write_coef_idx(codec, 0x11, 0x0001);
3558 alc_write_coef_idx(codec, 0xb7, 0x802b);
3559 alc_write_coef_idx(codec, 0x15, 0x0d60);
3560 alc_write_coef_idx(codec, 0xc3, 0x0c00);
3562 val = alc_read_coef_idx(codec, 0xbe);
3563 is_ctia = (val & 0x1c02) == 0x1c02;
3567 snd_printdd("Headset jack detected iPhone-style headset: %s\n",
3568 is_ctia ? "yes" : "no");
3569 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
3572 static void alc_update_headset_mode(struct hda_codec *codec)
3574 struct alc_spec *spec = codec->spec;
3576 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
3577 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3579 int new_headset_mode;
3581 if (!snd_hda_jack_detect(codec, hp_pin))
3582 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
3583 else if (mux_pin == spec->headset_mic_pin)
3584 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
3585 else if (mux_pin == spec->headphone_mic_pin)
3586 new_headset_mode = ALC_HEADSET_MODE_MIC;
3588 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
3590 if (new_headset_mode == spec->current_headset_mode) {
3591 snd_hda_gen_update_outputs(codec);
3595 switch (new_headset_mode) {
3596 case ALC_HEADSET_MODE_UNPLUGGED:
3597 alc_headset_mode_unplugged(codec);
3598 spec->gen.hp_jack_present = false;
3600 case ALC_HEADSET_MODE_HEADSET:
3601 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
3602 alc_determine_headset_type(codec);
3603 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
3604 alc_headset_mode_ctia(codec);
3605 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
3606 alc_headset_mode_omtp(codec);
3607 spec->gen.hp_jack_present = true;
3609 case ALC_HEADSET_MODE_MIC:
3610 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
3611 spec->gen.hp_jack_present = false;
3613 case ALC_HEADSET_MODE_HEADPHONE:
3614 alc_headset_mode_default(codec);
3615 spec->gen.hp_jack_present = true;
3618 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
3619 snd_hda_set_pin_ctl_cache(codec, hp_pin,
3620 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
3621 if (spec->headphone_mic_pin)
3622 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
3625 spec->current_headset_mode = new_headset_mode;
3627 snd_hda_gen_update_outputs(codec);
3630 static void alc_update_headset_mode_hook(struct hda_codec *codec,
3631 struct snd_kcontrol *kcontrol,
3632 struct snd_ctl_elem_value *ucontrol)
3634 alc_update_headset_mode(codec);
3637 static void alc_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_tbl *jack)
3639 struct alc_spec *spec = codec->spec;
3640 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
3641 snd_hda_gen_hp_automute(codec, jack);
3644 static void alc_probe_headset_mode(struct hda_codec *codec)
3647 struct alc_spec *spec = codec->spec;
3648 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
3651 for (i = 0; i < cfg->num_inputs; i++) {
3652 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
3653 spec->headset_mic_pin = cfg->inputs[i].pin;
3654 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
3655 spec->headphone_mic_pin = cfg->inputs[i].pin;
3658 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
3659 spec->gen.automute_hook = alc_update_headset_mode;
3660 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
3663 static void alc_fixup_headset_mode(struct hda_codec *codec,
3664 const struct hda_fixup *fix, int action)
3666 struct alc_spec *spec = codec->spec;
3669 case HDA_FIXUP_ACT_PRE_PROBE:
3670 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
3672 case HDA_FIXUP_ACT_PROBE:
3673 alc_probe_headset_mode(codec);
3675 case HDA_FIXUP_ACT_INIT:
3676 spec->current_headset_mode = 0;
3677 alc_update_headset_mode(codec);
3682 static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
3683 const struct hda_fixup *fix, int action)
3685 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3686 struct alc_spec *spec = codec->spec;
3687 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3690 alc_fixup_headset_mode(codec, fix, action);
3693 static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
3694 const struct hda_fixup *fix, int action)
3696 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3697 /* Set to iphone type */
3698 alc_write_coef_idx(codec, 0x1b, 0x880b);
3699 alc_write_coef_idx(codec, 0x45, 0xd089);
3700 alc_write_coef_idx(codec, 0x1b, 0x080b);
3701 alc_write_coef_idx(codec, 0x46, 0x0004);
3702 alc_write_coef_idx(codec, 0x1b, 0x0c0b);
3705 alc_fixup_headset_mode(codec, fix, action);
3708 static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
3709 const struct hda_fixup *fix, int action)
3711 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3712 struct alc_spec *spec = codec->spec;
3713 spec->gen.auto_mute_via_amp = 1;
3717 static void alc_no_shutup(struct hda_codec *codec)
3721 static void alc_fixup_no_shutup(struct hda_codec *codec,
3722 const struct hda_fixup *fix, int action)
3724 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3725 struct alc_spec *spec = codec->spec;
3726 spec->shutup = alc_no_shutup;
3730 static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
3731 const struct hda_fixup *fix, int action)
3733 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3735 alc_write_coef_idx(codec, 0xc4, 0x8000);
3736 val = alc_read_coef_idx(codec, 0xc2);
3737 alc_write_coef_idx(codec, 0xc2, val & 0xfe);
3738 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
3740 alc_fixup_headset_mode(codec, fix, action);
3743 /* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
3744 static int find_ext_mic_pin(struct hda_codec *codec)
3746 struct alc_spec *spec = codec->spec;
3747 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
3749 unsigned int defcfg;
3752 for (i = 0; i < cfg->num_inputs; i++) {
3753 if (cfg->inputs[i].type != AUTO_PIN_MIC)
3755 nid = cfg->inputs[i].pin;
3756 defcfg = snd_hda_codec_get_pincfg(codec, nid);
3757 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
3765 static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
3766 const struct hda_fixup *fix,
3769 struct alc_spec *spec = codec->spec;
3771 if (action == HDA_FIXUP_ACT_PROBE) {
3772 int mic_pin = find_ext_mic_pin(codec);
3773 int hp_pin = spec->gen.autocfg.hp_pins[0];
3775 if (snd_BUG_ON(!mic_pin || !hp_pin))
3777 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
3781 static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
3782 const struct hda_fixup *fix,
3785 struct alc_spec *spec = codec->spec;
3786 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
3789 /* The mic boosts on level 2 and 3 are too noisy
3790 on the internal mic input.
3791 Therefore limit the boost to 0 or 1. */
3793 if (action != HDA_FIXUP_ACT_PROBE)
3796 for (i = 0; i < cfg->num_inputs; i++) {
3797 hda_nid_t nid = cfg->inputs[i].pin;
3798 unsigned int defcfg;
3799 if (cfg->inputs[i].type != AUTO_PIN_MIC)
3801 defcfg = snd_hda_codec_get_pincfg(codec, nid);
3802 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
3805 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
3806 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
3807 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
3808 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
3809 (0 << AC_AMPCAP_MUTE_SHIFT));
3813 static void alc283_hp_automute_hook(struct hda_codec *codec,
3814 struct hda_jack_tbl *jack)
3816 struct alc_spec *spec = codec->spec;
3820 snd_hda_gen_hp_automute(codec, jack);
3822 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3825 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3829 static void alc283_fixup_chromebook(struct hda_codec *codec,
3830 const struct hda_fixup *fix, int action)
3832 struct alc_spec *spec = codec->spec;
3836 case HDA_FIXUP_ACT_PRE_PROBE:
3837 snd_hda_override_wcaps(codec, 0x03, 0);
3838 /* Disable AA-loopback as it causes white noise */
3839 spec->gen.mixer_nid = 0;
3841 case HDA_FIXUP_ACT_INIT:
3842 /* Enable Line1 input control by verb */
3843 val = alc_read_coef_idx(codec, 0x1a);
3844 alc_write_coef_idx(codec, 0x1a, val | (1 << 4));
3849 static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
3850 const struct hda_fixup *fix, int action)
3852 struct alc_spec *spec = codec->spec;
3856 case HDA_FIXUP_ACT_PRE_PROBE:
3857 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
3859 case HDA_FIXUP_ACT_INIT:
3860 /* MIC2-VREF control */
3861 /* Set to manual mode */
3862 val = alc_read_coef_idx(codec, 0x06);
3863 alc_write_coef_idx(codec, 0x06, val & ~0x000c);
3868 /* mute tablet speaker pin (0x14) via dock plugging in addition */
3869 static void asus_tx300_automute(struct hda_codec *codec)
3871 struct alc_spec *spec = codec->spec;
3872 snd_hda_gen_update_outputs(codec);
3873 if (snd_hda_jack_detect(codec, 0x1b))
3874 spec->gen.mute_bits |= (1ULL << 0x14);
3877 static void alc282_fixup_asus_tx300(struct hda_codec *codec,
3878 const struct hda_fixup *fix, int action)
3880 struct alc_spec *spec = codec->spec;
3881 /* TX300 needs to set up GPIO2 for the speaker amp */
3882 static const struct hda_verb gpio2_verbs[] = {
3883 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
3884 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
3885 { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 },
3888 static const struct hda_pintbl dock_pins[] = {
3889 { 0x1b, 0x21114000 }, /* dock speaker pin */
3892 struct snd_kcontrol *kctl;
3895 case HDA_FIXUP_ACT_PRE_PROBE:
3896 snd_hda_add_verbs(codec, gpio2_verbs);
3897 snd_hda_apply_pincfgs(codec, dock_pins);
3898 spec->gen.auto_mute_via_amp = 1;
3899 spec->gen.automute_hook = asus_tx300_automute;
3900 snd_hda_jack_detect_enable_callback(codec, 0x1b,
3902 snd_hda_gen_hp_automute);
3904 case HDA_FIXUP_ACT_BUILD:
3905 /* this is a bit tricky; give more sane names for the main
3906 * (tablet) speaker and the dock speaker, respectively
3908 kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch");
3910 strcpy(kctl->id.name, "Dock Speaker Playback Switch");
3911 kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch");
3913 strcpy(kctl->id.name, "Speaker Playback Switch");
3918 static void alc290_fixup_mono_speakers(struct hda_codec *codec,
3919 const struct hda_fixup *fix, int action)
3921 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3922 /* DAC node 0x03 is giving mono output. We therefore want to
3923 make sure 0x14 (front speaker) and 0x15 (headphones) use the
3924 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
3925 hda_nid_t conn1[2] = { 0x0c };
3926 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
3927 snd_hda_override_conn_list(codec, 0x15, 1, conn1);
3931 /* for hda_fixup_thinkpad_acpi() */
3932 #include "thinkpad_helper.c"
3935 ALC269_FIXUP_SONY_VAIO,
3936 ALC275_FIXUP_SONY_VAIO_GPIO2,
3937 ALC269_FIXUP_DELL_M101Z,
3938 ALC269_FIXUP_SKU_IGNORE,
3939 ALC269_FIXUP_ASUS_G73JW,
3940 ALC269_FIXUP_LENOVO_EAPD,
3941 ALC275_FIXUP_SONY_HWEQ,
3943 ALC269_FIXUP_PCM_44K,
3944 ALC269_FIXUP_STEREO_DMIC,
3945 ALC269_FIXUP_HEADSET_MIC,
3946 ALC269_FIXUP_QUANTA_MUTE,
3947 ALC269_FIXUP_LIFEBOOK,
3948 ALC269_FIXUP_LIFEBOOK_EXTMIC,
3951 ALC269VB_FIXUP_AMIC,
3952 ALC269VB_FIXUP_DMIC,
3953 ALC269_FIXUP_HP_MUTE_LED,
3954 ALC269_FIXUP_HP_MUTE_LED_MIC1,
3955 ALC269_FIXUP_HP_MUTE_LED_MIC2,
3956 ALC269_FIXUP_HP_GPIO_LED,
3957 ALC269_FIXUP_INV_DMIC,
3958 ALC269_FIXUP_LENOVO_DOCK,
3959 ALC269_FIXUP_NO_SHUTUP,
3960 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
3961 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
3962 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
3963 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
3964 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
3965 ALC269_FIXUP_HEADSET_MODE,
3966 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
3967 ALC269_FIXUP_ASUS_X101_FUNC,
3968 ALC269_FIXUP_ASUS_X101_VERB,
3969 ALC269_FIXUP_ASUS_X101,
3970 ALC271_FIXUP_AMIC_MIC2,
3971 ALC271_FIXUP_HP_GATE_MIC_JACK,
3972 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
3973 ALC269_FIXUP_ACER_AC700,
3974 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
3975 ALC269VB_FIXUP_ASUS_ZENBOOK,
3976 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
3977 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
3978 ALC269VB_FIXUP_ORDISSIMO_EVE2,
3979 ALC283_FIXUP_CHROME_BOOK,
3980 ALC283_FIXUP_SENSE_COMBO_JACK,
3981 ALC282_FIXUP_ASUS_TX300,
3982 ALC283_FIXUP_INT_MIC,
3983 ALC290_FIXUP_MONO_SPEAKERS,
3984 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
3985 ALC290_FIXUP_SUBWOOFER,
3986 ALC290_FIXUP_SUBWOOFER_HSJACK,
3987 ALC269_FIXUP_THINKPAD_ACPI,
3988 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
3989 ALC255_FIXUP_HEADSET_MODE,
3992 static const struct hda_fixup alc269_fixups[] = {
3993 [ALC269_FIXUP_SONY_VAIO] = {
3994 .type = HDA_FIXUP_PINCTLS,
3995 .v.pins = (const struct hda_pintbl[]) {
3996 {0x19, PIN_VREFGRD},
4000 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
4001 .type = HDA_FIXUP_VERBS,
4002 .v.verbs = (const struct hda_verb[]) {
4003 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
4004 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
4005 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4009 .chain_id = ALC269_FIXUP_SONY_VAIO
4011 [ALC269_FIXUP_DELL_M101Z] = {
4012 .type = HDA_FIXUP_VERBS,
4013 .v.verbs = (const struct hda_verb[]) {
4014 /* Enables internal speaker */
4015 {0x20, AC_VERB_SET_COEF_INDEX, 13},
4016 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
4020 [ALC269_FIXUP_SKU_IGNORE] = {
4021 .type = HDA_FIXUP_FUNC,
4022 .v.func = alc_fixup_sku_ignore,
4024 [ALC269_FIXUP_ASUS_G73JW] = {
4025 .type = HDA_FIXUP_PINS,
4026 .v.pins = (const struct hda_pintbl[]) {
4027 { 0x17, 0x99130111 }, /* subwoofer */
4031 [ALC269_FIXUP_LENOVO_EAPD] = {
4032 .type = HDA_FIXUP_VERBS,
4033 .v.verbs = (const struct hda_verb[]) {
4034 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
4038 [ALC275_FIXUP_SONY_HWEQ] = {
4039 .type = HDA_FIXUP_FUNC,
4040 .v.func = alc269_fixup_hweq,
4042 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
4044 [ALC271_FIXUP_DMIC] = {
4045 .type = HDA_FIXUP_FUNC,
4046 .v.func = alc271_fixup_dmic,
4048 [ALC269_FIXUP_PCM_44K] = {
4049 .type = HDA_FIXUP_FUNC,
4050 .v.func = alc269_fixup_pcm_44k,
4052 .chain_id = ALC269_FIXUP_QUANTA_MUTE
4054 [ALC269_FIXUP_STEREO_DMIC] = {
4055 .type = HDA_FIXUP_FUNC,
4056 .v.func = alc269_fixup_stereo_dmic,
4058 [ALC269_FIXUP_HEADSET_MIC] = {
4059 .type = HDA_FIXUP_FUNC,
4060 .v.func = alc269_fixup_headset_mic,
4062 [ALC269_FIXUP_QUANTA_MUTE] = {
4063 .type = HDA_FIXUP_FUNC,
4064 .v.func = alc269_fixup_quanta_mute,
4066 [ALC269_FIXUP_LIFEBOOK] = {
4067 .type = HDA_FIXUP_PINS,
4068 .v.pins = (const struct hda_pintbl[]) {
4069 { 0x1a, 0x2101103f }, /* dock line-out */
4070 { 0x1b, 0x23a11040 }, /* dock mic-in */
4074 .chain_id = ALC269_FIXUP_QUANTA_MUTE
4076 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
4077 .type = HDA_FIXUP_PINS,
4078 .v.pins = (const struct hda_pintbl[]) {
4079 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
4083 [ALC269_FIXUP_AMIC] = {
4084 .type = HDA_FIXUP_PINS,
4085 .v.pins = (const struct hda_pintbl[]) {
4086 { 0x14, 0x99130110 }, /* speaker */
4087 { 0x15, 0x0121401f }, /* HP out */
4088 { 0x18, 0x01a19c20 }, /* mic */
4089 { 0x19, 0x99a3092f }, /* int-mic */
4093 [ALC269_FIXUP_DMIC] = {
4094 .type = HDA_FIXUP_PINS,
4095 .v.pins = (const struct hda_pintbl[]) {
4096 { 0x12, 0x99a3092f }, /* int-mic */
4097 { 0x14, 0x99130110 }, /* speaker */
4098 { 0x15, 0x0121401f }, /* HP out */
4099 { 0x18, 0x01a19c20 }, /* mic */
4103 [ALC269VB_FIXUP_AMIC] = {
4104 .type = HDA_FIXUP_PINS,
4105 .v.pins = (const struct hda_pintbl[]) {
4106 { 0x14, 0x99130110 }, /* speaker */
4107 { 0x18, 0x01a19c20 }, /* mic */
4108 { 0x19, 0x99a3092f }, /* int-mic */
4109 { 0x21, 0x0121401f }, /* HP out */
4113 [ALC269VB_FIXUP_DMIC] = {
4114 .type = HDA_FIXUP_PINS,
4115 .v.pins = (const struct hda_pintbl[]) {
4116 { 0x12, 0x99a3092f }, /* int-mic */
4117 { 0x14, 0x99130110 }, /* speaker */
4118 { 0x18, 0x01a19c20 }, /* mic */
4119 { 0x21, 0x0121401f }, /* HP out */
4123 [ALC269_FIXUP_HP_MUTE_LED] = {
4124 .type = HDA_FIXUP_FUNC,
4125 .v.func = alc269_fixup_hp_mute_led,
4127 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
4128 .type = HDA_FIXUP_FUNC,
4129 .v.func = alc269_fixup_hp_mute_led_mic1,
4131 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
4132 .type = HDA_FIXUP_FUNC,
4133 .v.func = alc269_fixup_hp_mute_led_mic2,
4135 [ALC269_FIXUP_HP_GPIO_LED] = {
4136 .type = HDA_FIXUP_FUNC,
4137 .v.func = alc269_fixup_hp_gpio_led,
4139 [ALC269_FIXUP_INV_DMIC] = {
4140 .type = HDA_FIXUP_FUNC,
4141 .v.func = alc_fixup_inv_dmic_0x12,
4143 [ALC269_FIXUP_NO_SHUTUP] = {
4144 .type = HDA_FIXUP_FUNC,
4145 .v.func = alc_fixup_no_shutup,
4147 [ALC269_FIXUP_LENOVO_DOCK] = {
4148 .type = HDA_FIXUP_PINS,
4149 .v.pins = (const struct hda_pintbl[]) {
4150 { 0x19, 0x23a11040 }, /* dock mic */
4151 { 0x1b, 0x2121103f }, /* dock headphone */
4155 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
4157 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
4158 .type = HDA_FIXUP_FUNC,
4159 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
4161 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
4163 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
4164 .type = HDA_FIXUP_PINS,
4165 .v.pins = (const struct hda_pintbl[]) {
4166 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4167 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
4171 .chain_id = ALC269_FIXUP_HEADSET_MODE
4173 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
4174 .type = HDA_FIXUP_PINS,
4175 .v.pins = (const struct hda_pintbl[]) {
4176 { 0x16, 0x21014020 }, /* dock line out */
4177 { 0x19, 0x21a19030 }, /* dock mic */
4178 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4182 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
4184 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
4185 .type = HDA_FIXUP_PINS,
4186 .v.pins = (const struct hda_pintbl[]) {
4187 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4191 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
4193 [ALC269_FIXUP_HEADSET_MODE] = {
4194 .type = HDA_FIXUP_FUNC,
4195 .v.func = alc_fixup_headset_mode,
4197 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
4198 .type = HDA_FIXUP_FUNC,
4199 .v.func = alc_fixup_headset_mode_no_hp_mic,
4201 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
4202 .type = HDA_FIXUP_PINS,
4203 .v.pins = (const struct hda_pintbl[]) {
4204 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4208 .chain_id = ALC269_FIXUP_HEADSET_MIC
4210 [ALC269_FIXUP_ASUS_X101_FUNC] = {
4211 .type = HDA_FIXUP_FUNC,
4212 .v.func = alc269_fixup_x101_headset_mic,
4214 [ALC269_FIXUP_ASUS_X101_VERB] = {
4215 .type = HDA_FIXUP_VERBS,
4216 .v.verbs = (const struct hda_verb[]) {
4217 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4218 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
4219 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
4223 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
4225 [ALC269_FIXUP_ASUS_X101] = {
4226 .type = HDA_FIXUP_PINS,
4227 .v.pins = (const struct hda_pintbl[]) {
4228 { 0x18, 0x04a1182c }, /* Headset mic */
4232 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
4234 [ALC271_FIXUP_AMIC_MIC2] = {
4235 .type = HDA_FIXUP_PINS,
4236 .v.pins = (const struct hda_pintbl[]) {
4237 { 0x14, 0x99130110 }, /* speaker */
4238 { 0x19, 0x01a19c20 }, /* mic */
4239 { 0x1b, 0x99a7012f }, /* int-mic */
4240 { 0x21, 0x0121401f }, /* HP out */
4244 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
4245 .type = HDA_FIXUP_FUNC,
4246 .v.func = alc271_hp_gate_mic_jack,
4248 .chain_id = ALC271_FIXUP_AMIC_MIC2,
4250 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
4251 .type = HDA_FIXUP_FUNC,
4252 .v.func = alc269_fixup_limit_int_mic_boost,
4254 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
4256 [ALC269_FIXUP_ACER_AC700] = {
4257 .type = HDA_FIXUP_PINS,
4258 .v.pins = (const struct hda_pintbl[]) {
4259 { 0x12, 0x99a3092f }, /* int-mic */
4260 { 0x14, 0x99130110 }, /* speaker */
4261 { 0x18, 0x03a11c20 }, /* mic */
4262 { 0x1e, 0x0346101e }, /* SPDIF1 */
4263 { 0x21, 0x0321101f }, /* HP out */
4267 .chain_id = ALC271_FIXUP_DMIC,
4269 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
4270 .type = HDA_FIXUP_FUNC,
4271 .v.func = alc269_fixup_limit_int_mic_boost,
4273 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
4275 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
4276 .type = HDA_FIXUP_FUNC,
4277 .v.func = alc269_fixup_limit_int_mic_boost,
4279 .chain_id = ALC269VB_FIXUP_DMIC,
4281 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
4282 .type = HDA_FIXUP_VERBS,
4283 .v.verbs = (const struct hda_verb[]) {
4284 /* class-D output amp +5dB */
4285 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
4286 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
4290 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
4292 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
4293 .type = HDA_FIXUP_FUNC,
4294 .v.func = alc269_fixup_limit_int_mic_boost,
4296 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
4298 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
4299 .type = HDA_FIXUP_PINS,
4300 .v.pins = (const struct hda_pintbl[]) {
4301 { 0x12, 0x99a3092f }, /* int-mic */
4302 { 0x18, 0x03a11d20 }, /* mic */
4303 { 0x19, 0x411111f0 }, /* Unused bogus pin */
4307 [ALC283_FIXUP_CHROME_BOOK] = {
4308 .type = HDA_FIXUP_FUNC,
4309 .v.func = alc283_fixup_chromebook,
4311 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
4312 .type = HDA_FIXUP_FUNC,
4313 .v.func = alc283_fixup_sense_combo_jack,
4315 .chain_id = ALC283_FIXUP_CHROME_BOOK,
4317 [ALC282_FIXUP_ASUS_TX300] = {
4318 .type = HDA_FIXUP_FUNC,
4319 .v.func = alc282_fixup_asus_tx300,
4321 [ALC283_FIXUP_INT_MIC] = {
4322 .type = HDA_FIXUP_VERBS,
4323 .v.verbs = (const struct hda_verb[]) {
4324 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
4325 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
4329 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
4331 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
4332 .type = HDA_FIXUP_PINS,
4333 .v.pins = (const struct hda_pintbl[]) {
4334 { 0x17, 0x90170112 }, /* subwoofer */
4338 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
4340 [ALC290_FIXUP_SUBWOOFER] = {
4341 .type = HDA_FIXUP_PINS,
4342 .v.pins = (const struct hda_pintbl[]) {
4343 { 0x17, 0x90170112 }, /* subwoofer */
4347 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
4349 [ALC290_FIXUP_MONO_SPEAKERS] = {
4350 .type = HDA_FIXUP_FUNC,
4351 .v.func = alc290_fixup_mono_speakers,
4353 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
4354 .type = HDA_FIXUP_FUNC,
4355 .v.func = alc290_fixup_mono_speakers,
4357 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
4359 [ALC269_FIXUP_THINKPAD_ACPI] = {
4360 .type = HDA_FIXUP_FUNC,
4361 .v.func = hda_fixup_thinkpad_acpi,
4363 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
4364 .type = HDA_FIXUP_PINS,
4365 .v.pins = (const struct hda_pintbl[]) {
4366 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4367 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
4371 .chain_id = ALC255_FIXUP_HEADSET_MODE
4373 [ALC255_FIXUP_HEADSET_MODE] = {
4374 .type = HDA_FIXUP_FUNC,
4375 .v.func = alc_fixup_headset_mode_alc255,
4379 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
4380 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
4381 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
4382 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
4383 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
4384 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
4385 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
4386 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
4387 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
4388 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
4389 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4390 SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4391 SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4392 SND_PCI_QUIRK(0x1028, 0x05c5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4393 SND_PCI_QUIRK(0x1028, 0x05c6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4394 SND_PCI_QUIRK(0x1028, 0x05c7, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4395 SND_PCI_QUIRK(0x1028, 0x05c8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4396 SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4397 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4398 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4399 SND_PCI_QUIRK(0x1028, 0x05cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4400 SND_PCI_QUIRK(0x1028, 0x05cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4401 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
4402 SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4403 SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4404 SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4405 SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4406 SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4407 SND_PCI_QUIRK(0x1028, 0x05ec, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4408 SND_PCI_QUIRK(0x1028, 0x05ed, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4409 SND_PCI_QUIRK(0x1028, 0x05ee, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4410 SND_PCI_QUIRK(0x1028, 0x05f3, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4411 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4412 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4413 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4414 SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4415 SND_PCI_QUIRK(0x1028, 0x05f9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4416 SND_PCI_QUIRK(0x1028, 0x05fb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4417 SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4418 SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4419 SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4420 SND_PCI_QUIRK(0x1028, 0x060f, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE),
4421 SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE),
4422 SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4423 SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4424 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
4425 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
4426 SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4427 SND_PCI_QUIRK(0x1028, 0x0629, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4428 SND_PCI_QUIRK(0x1028, 0x062c, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4429 SND_PCI_QUIRK(0x1028, 0x062e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4430 SND_PCI_QUIRK(0x1028, 0x0632, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4431 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
4432 SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4433 SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4434 SND_PCI_QUIRK(0x1028, 0x0640, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4435 SND_PCI_QUIRK(0x1028, 0x064d, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4436 SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4437 SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4438 SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4439 SND_PCI_QUIRK(0x1028, 0x0657, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4440 SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4441 SND_PCI_QUIRK(0x1028, 0x065f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4442 SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4443 SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4444 SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4445 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
4446 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
4447 SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4448 SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4449 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
4451 SND_PCI_QUIRK(0x103c, 0x2191, "HP Touchsmart 14", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4452 SND_PCI_QUIRK(0x103c, 0x2192, "HP Touchsmart 15", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4453 SND_PCI_QUIRK(0x103c, 0x220d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4454 SND_PCI_QUIRK(0x103c, 0x220e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4455 SND_PCI_QUIRK(0x103c, 0x220f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4456 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4457 SND_PCI_QUIRK(0x103c, 0x2211, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4458 SND_PCI_QUIRK(0x103c, 0x2212, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4459 SND_PCI_QUIRK(0x103c, 0x2213, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4460 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4461 SND_PCI_QUIRK(0x103c, 0x2266, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4462 SND_PCI_QUIRK(0x103c, 0x2267, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4463 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4464 SND_PCI_QUIRK(0x103c, 0x2269, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4465 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4466 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4467 SND_PCI_QUIRK(0x103c, 0x226c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4468 SND_PCI_QUIRK(0x103c, 0x226d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4469 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4470 SND_PCI_QUIRK(0x103c, 0x226f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4471 SND_PCI_QUIRK(0x103c, 0x227a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4472 SND_PCI_QUIRK(0x103c, 0x227b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4473 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4474 SND_PCI_QUIRK(0x103c, 0x22a0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4475 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4476 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4477 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4478 SND_PCI_QUIRK(0x103c, 0x22c0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4479 SND_PCI_QUIRK(0x103c, 0x22c1, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4480 SND_PCI_QUIRK(0x103c, 0x22c2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4481 SND_PCI_QUIRK(0x103c, 0x22cd, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4482 SND_PCI_QUIRK(0x103c, 0x22ce, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4483 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4484 SND_PCI_QUIRK(0x103c, 0x22d0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4486 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4487 SND_PCI_QUIRK(0x103c, 0x2261, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4488 SND_PCI_QUIRK(0x103c, 0x2262, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4489 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4490 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4491 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4492 SND_PCI_QUIRK(0x103c, 0x227d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4493 SND_PCI_QUIRK(0x103c, 0x227e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4494 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4495 SND_PCI_QUIRK(0x103c, 0x2280, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4496 SND_PCI_QUIRK(0x103c, 0x2281, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4497 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4498 SND_PCI_QUIRK(0x103c, 0x2289, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4499 SND_PCI_QUIRK(0x103c, 0x228a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4500 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4501 SND_PCI_QUIRK(0x103c, 0x228c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4502 SND_PCI_QUIRK(0x103c, 0x228d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4503 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4504 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4505 SND_PCI_QUIRK(0x103c, 0x22c6, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4506 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4507 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4508 SND_PCI_QUIRK(0x103c, 0x22c3, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4509 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4510 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4511 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4512 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4513 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4514 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
4515 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
4516 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4517 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4518 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
4519 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
4520 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
4521 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
4522 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
4523 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4524 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
4525 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
4526 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
4527 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
4528 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
4529 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
4530 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
4531 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
4532 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
4533 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
4534 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
4535 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
4536 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
4537 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
4538 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
4539 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
4540 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
4541 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
4542 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
4543 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
4544 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
4545 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
4546 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
4547 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
4548 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4549 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4550 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4551 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4552 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
4553 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4554 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
4555 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4556 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4557 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
4558 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
4559 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
4560 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
4563 /* Below is a quirk table taken from the old code.
4564 * Basically the device should work as is without the fixup table.
4565 * If BIOS doesn't give a proper info, enable the corresponding
4568 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
4570 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
4571 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
4572 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
4573 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
4574 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
4575 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
4576 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
4577 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
4578 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
4579 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
4580 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
4581 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
4582 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
4583 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
4584 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
4585 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
4586 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
4587 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
4588 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
4589 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
4590 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
4591 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
4592 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
4593 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
4594 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
4595 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
4596 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
4597 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
4598 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
4599 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
4600 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
4601 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
4602 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
4603 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
4604 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
4605 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
4606 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
4607 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
4608 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
4613 static const struct hda_model_fixup alc269_fixup_models[] = {
4614 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
4615 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
4616 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
4617 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
4618 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
4619 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
4620 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
4621 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
4622 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
4623 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
4624 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-chrome"},
4625 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
4630 static void alc269_fill_coef(struct hda_codec *codec)
4632 struct alc_spec *spec = codec->spec;
4635 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
4638 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
4639 alc_write_coef_idx(codec, 0xf, 0x960b);
4640 alc_write_coef_idx(codec, 0xe, 0x8817);
4643 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
4644 alc_write_coef_idx(codec, 0xf, 0x960b);
4645 alc_write_coef_idx(codec, 0xe, 0x8814);
4648 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
4649 val = alc_read_coef_idx(codec, 0x04);
4650 /* Power up output pin */
4652 alc_write_coef_idx(codec, 0x04, val | (1<<11));
4655 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
4656 val = alc_read_coef_idx(codec, 0xd);
4657 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
4658 /* Capless ramp up clock control */
4659 alc_write_coef_idx(codec, 0xd, val | (1<<10));
4661 val = alc_read_coef_idx(codec, 0x17);
4662 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
4663 /* Class D power on reset */
4664 alc_write_coef_idx(codec, 0x17, val | (1<<7));
4668 val = alc_read_coef_idx(codec, 0xd); /* Class D */
4670 alc_write_coef_idx(codec, 0xd, val | (1<<14));
4672 val = alc_read_coef_idx(codec, 0x4); /* HP */
4674 alc_write_coef_idx(codec, 0x4, val | (1<<11));
4679 static int patch_alc269(struct hda_codec *codec)
4681 struct alc_spec *spec;
4684 err = alc_alloc_spec(codec, 0x0b);
4689 spec->gen.shared_mic_vref_pin = 0x18;
4691 snd_hda_pick_fixup(codec, alc269_fixup_models,
4692 alc269_fixup_tbl, alc269_fixups);
4693 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4695 alc_auto_parse_customize_define(codec);
4697 if (has_cdefine_beep(codec))
4698 spec->gen.beep_nid = 0x01;
4700 switch (codec->vendor_id) {
4702 spec->codec_variant = ALC269_TYPE_ALC269VA;
4703 switch (alc_get_coef0(codec) & 0x00f0) {
4705 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
4706 spec->cdefine.platform_type == 1)
4707 err = alc_codec_rename(codec, "ALC271X");
4708 spec->codec_variant = ALC269_TYPE_ALC269VB;
4711 if (codec->bus->pci->subsystem_vendor == 0x17aa &&
4712 codec->bus->pci->subsystem_device == 0x21f3)
4713 err = alc_codec_rename(codec, "ALC3202");
4714 spec->codec_variant = ALC269_TYPE_ALC269VC;
4717 spec->codec_variant = ALC269_TYPE_ALC269VD;
4720 alc_fix_pll_init(codec, 0x20, 0x04, 15);
4724 spec->init_hook = alc269_fill_coef;
4725 alc269_fill_coef(codec);
4730 spec->codec_variant = ALC269_TYPE_ALC280;
4733 spec->codec_variant = ALC269_TYPE_ALC282;
4737 spec->codec_variant = ALC269_TYPE_ALC283;
4738 spec->shutup = alc283_shutup;
4739 spec->init_hook = alc283_init;
4743 spec->codec_variant = ALC269_TYPE_ALC284;
4747 spec->codec_variant = ALC269_TYPE_ALC285;
4751 spec->codec_variant = ALC269_TYPE_ALC286;
4754 spec->codec_variant = ALC269_TYPE_ALC255;
4758 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
4759 spec->has_alc5505_dsp = 1;
4760 spec->init_hook = alc5505_dsp_init;
4763 /* automatic parse from the BIOS config */
4764 err = alc269_parse_auto_config(codec);
4768 if (!spec->gen.no_analog && spec->gen.beep_nid)
4769 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
4771 codec->patch_ops = alc_patch_ops;
4773 codec->patch_ops.suspend = alc269_suspend;
4774 codec->patch_ops.resume = alc269_resume;
4777 spec->shutup = alc269_shutup;
4779 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4792 static int alc861_parse_auto_config(struct hda_codec *codec)
4794 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
4795 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
4796 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
4799 /* Pin config fixes */
4801 ALC861_FIXUP_FSC_AMILO_PI1505,
4802 ALC861_FIXUP_AMP_VREF_0F,
4803 ALC861_FIXUP_NO_JACK_DETECT,
4804 ALC861_FIXUP_ASUS_A6RP,
4805 ALC660_FIXUP_ASUS_W7J,
4808 /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
4809 static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
4810 const struct hda_fixup *fix, int action)
4812 struct alc_spec *spec = codec->spec;
4815 if (action != HDA_FIXUP_ACT_INIT)
4817 val = snd_hda_codec_get_pin_target(codec, 0x0f);
4818 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
4819 val |= AC_PINCTL_IN_EN;
4820 val |= AC_PINCTL_VREF_50;
4821 snd_hda_set_pin_ctl(codec, 0x0f, val);
4822 spec->gen.keep_vref_in_automute = 1;
4825 /* suppress the jack-detection */
4826 static void alc_fixup_no_jack_detect(struct hda_codec *codec,
4827 const struct hda_fixup *fix, int action)
4829 if (action == HDA_FIXUP_ACT_PRE_PROBE)
4830 codec->no_jack_detect = 1;
4833 static const struct hda_fixup alc861_fixups[] = {
4834 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
4835 .type = HDA_FIXUP_PINS,
4836 .v.pins = (const struct hda_pintbl[]) {
4837 { 0x0b, 0x0221101f }, /* HP */
4838 { 0x0f, 0x90170310 }, /* speaker */
4842 [ALC861_FIXUP_AMP_VREF_0F] = {
4843 .type = HDA_FIXUP_FUNC,
4844 .v.func = alc861_fixup_asus_amp_vref_0f,
4846 [ALC861_FIXUP_NO_JACK_DETECT] = {
4847 .type = HDA_FIXUP_FUNC,
4848 .v.func = alc_fixup_no_jack_detect,
4850 [ALC861_FIXUP_ASUS_A6RP] = {
4851 .type = HDA_FIXUP_FUNC,
4852 .v.func = alc861_fixup_asus_amp_vref_0f,
4854 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
4856 [ALC660_FIXUP_ASUS_W7J] = {
4857 .type = HDA_FIXUP_VERBS,
4858 .v.verbs = (const struct hda_verb[]) {
4859 /* ASUS W7J needs a magic pin setup on unused NID 0x10
4860 * for enabling outputs
4862 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4868 static const struct snd_pci_quirk alc861_fixup_tbl[] = {
4869 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
4870 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
4871 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
4872 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
4873 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
4874 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
4875 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
4876 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
4882 static int patch_alc861(struct hda_codec *codec)
4884 struct alc_spec *spec;
4887 err = alc_alloc_spec(codec, 0x15);
4892 spec->gen.beep_nid = 0x23;
4894 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
4895 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4897 /* automatic parse from the BIOS config */
4898 err = alc861_parse_auto_config(codec);
4902 if (!spec->gen.no_analog)
4903 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
4905 codec->patch_ops = alc_patch_ops;
4907 spec->power_hook = alc_power_eapd;
4910 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4924 * In addition, an independent DAC
4926 static int alc861vd_parse_auto_config(struct hda_codec *codec)
4928 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
4929 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
4930 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
4934 ALC660VD_FIX_ASUS_GPIO1,
4935 ALC861VD_FIX_DALLAS,
4938 /* exclude VREF80 */
4939 static void alc861vd_fixup_dallas(struct hda_codec *codec,
4940 const struct hda_fixup *fix, int action)
4942 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4943 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
4944 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
4948 static const struct hda_fixup alc861vd_fixups[] = {
4949 [ALC660VD_FIX_ASUS_GPIO1] = {
4950 .type = HDA_FIXUP_VERBS,
4951 .v.verbs = (const struct hda_verb[]) {
4953 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
4954 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4955 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4959 [ALC861VD_FIX_DALLAS] = {
4960 .type = HDA_FIXUP_FUNC,
4961 .v.func = alc861vd_fixup_dallas,
4965 static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
4966 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
4967 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
4968 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
4974 static int patch_alc861vd(struct hda_codec *codec)
4976 struct alc_spec *spec;
4979 err = alc_alloc_spec(codec, 0x0b);
4984 spec->gen.beep_nid = 0x23;
4986 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
4987 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4989 /* automatic parse from the BIOS config */
4990 err = alc861vd_parse_auto_config(codec);
4994 if (!spec->gen.no_analog)
4995 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4997 codec->patch_ops = alc_patch_ops;
4999 spec->shutup = alc_eapd_shutup;
5001 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
5013 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
5014 * configuration. Each pin widget can choose any input DACs and a mixer.
5015 * Each ADC is connected from a mixer of all inputs. This makes possible
5016 * 6-channel independent captures.
5018 * In addition, an independent DAC for the multi-playback (not used in this
5023 * BIOS auto configuration
5026 static int alc662_parse_auto_config(struct hda_codec *codec)
5028 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
5029 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
5030 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
5031 const hda_nid_t *ssids;
5033 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
5034 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670 ||
5035 codec->vendor_id == 0x10ec0671)
5036 ssids = alc663_ssids;
5038 ssids = alc662_ssids;
5039 return alc_parse_auto_config(codec, alc662_ignore, ssids);
5042 static void alc272_fixup_mario(struct hda_codec *codec,
5043 const struct hda_fixup *fix, int action)
5045 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5047 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
5048 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
5049 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
5050 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
5051 (0 << AC_AMPCAP_MUTE_SHIFT)))
5053 "hda_codec: failed to override amp caps for NID 0x2\n");
5056 static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
5058 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
5060 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
5061 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
5065 /* override the 2.1 chmap */
5066 static void alc_fixup_bass_chmap(struct hda_codec *codec,
5067 const struct hda_fixup *fix, int action)
5069 if (action == HDA_FIXUP_ACT_BUILD) {
5070 struct alc_spec *spec = codec->spec;
5071 spec->gen.pcm_rec[0].stream[0].chmap = asus_pcm_2_1_chmaps;
5076 ALC662_FIXUP_ASPIRE,
5077 ALC662_FIXUP_IDEAPAD,
5079 ALC662_FIXUP_CZC_P10T,
5080 ALC662_FIXUP_SKU_IGNORE,
5081 ALC662_FIXUP_HP_RP5800,
5082 ALC662_FIXUP_ASUS_MODE1,
5083 ALC662_FIXUP_ASUS_MODE2,
5084 ALC662_FIXUP_ASUS_MODE3,
5085 ALC662_FIXUP_ASUS_MODE4,
5086 ALC662_FIXUP_ASUS_MODE5,
5087 ALC662_FIXUP_ASUS_MODE6,
5088 ALC662_FIXUP_ASUS_MODE7,
5089 ALC662_FIXUP_ASUS_MODE8,
5090 ALC662_FIXUP_NO_JACK_DETECT,
5091 ALC662_FIXUP_ZOTAC_Z68,
5092 ALC662_FIXUP_INV_DMIC,
5093 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
5094 ALC668_FIXUP_HEADSET_MODE,
5095 ALC662_FIXUP_BASS_CHMAP,
5096 ALC662_FIXUP_BASS_1A,
5097 ALC662_FIXUP_BASS_1A_CHMAP,
5098 ALC668_FIXUP_AUTO_MUTE,
5101 static const struct hda_fixup alc662_fixups[] = {
5102 [ALC662_FIXUP_ASPIRE] = {
5103 .type = HDA_FIXUP_PINS,
5104 .v.pins = (const struct hda_pintbl[]) {
5105 { 0x15, 0x99130112 }, /* subwoofer */
5109 [ALC662_FIXUP_IDEAPAD] = {
5110 .type = HDA_FIXUP_PINS,
5111 .v.pins = (const struct hda_pintbl[]) {
5112 { 0x17, 0x99130112 }, /* subwoofer */
5116 [ALC272_FIXUP_MARIO] = {
5117 .type = HDA_FIXUP_FUNC,
5118 .v.func = alc272_fixup_mario,
5120 [ALC662_FIXUP_CZC_P10T] = {
5121 .type = HDA_FIXUP_VERBS,
5122 .v.verbs = (const struct hda_verb[]) {
5123 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
5127 [ALC662_FIXUP_SKU_IGNORE] = {
5128 .type = HDA_FIXUP_FUNC,
5129 .v.func = alc_fixup_sku_ignore,
5131 [ALC662_FIXUP_HP_RP5800] = {
5132 .type = HDA_FIXUP_PINS,
5133 .v.pins = (const struct hda_pintbl[]) {
5134 { 0x14, 0x0221201f }, /* HP out */
5138 .chain_id = ALC662_FIXUP_SKU_IGNORE
5140 [ALC662_FIXUP_ASUS_MODE1] = {
5141 .type = HDA_FIXUP_PINS,
5142 .v.pins = (const struct hda_pintbl[]) {
5143 { 0x14, 0x99130110 }, /* speaker */
5144 { 0x18, 0x01a19c20 }, /* mic */
5145 { 0x19, 0x99a3092f }, /* int-mic */
5146 { 0x21, 0x0121401f }, /* HP out */
5150 .chain_id = ALC662_FIXUP_SKU_IGNORE
5152 [ALC662_FIXUP_ASUS_MODE2] = {
5153 .type = HDA_FIXUP_PINS,
5154 .v.pins = (const struct hda_pintbl[]) {
5155 { 0x14, 0x99130110 }, /* speaker */
5156 { 0x18, 0x01a19820 }, /* mic */
5157 { 0x19, 0x99a3092f }, /* int-mic */
5158 { 0x1b, 0x0121401f }, /* HP out */
5162 .chain_id = ALC662_FIXUP_SKU_IGNORE
5164 [ALC662_FIXUP_ASUS_MODE3] = {
5165 .type = HDA_FIXUP_PINS,
5166 .v.pins = (const struct hda_pintbl[]) {
5167 { 0x14, 0x99130110 }, /* speaker */
5168 { 0x15, 0x0121441f }, /* HP */
5169 { 0x18, 0x01a19840 }, /* mic */
5170 { 0x19, 0x99a3094f }, /* int-mic */
5171 { 0x21, 0x01211420 }, /* HP2 */
5175 .chain_id = ALC662_FIXUP_SKU_IGNORE
5177 [ALC662_FIXUP_ASUS_MODE4] = {
5178 .type = HDA_FIXUP_PINS,
5179 .v.pins = (const struct hda_pintbl[]) {
5180 { 0x14, 0x99130110 }, /* speaker */
5181 { 0x16, 0x99130111 }, /* speaker */
5182 { 0x18, 0x01a19840 }, /* mic */
5183 { 0x19, 0x99a3094f }, /* int-mic */
5184 { 0x21, 0x0121441f }, /* HP */
5188 .chain_id = ALC662_FIXUP_SKU_IGNORE
5190 [ALC662_FIXUP_ASUS_MODE5] = {
5191 .type = HDA_FIXUP_PINS,
5192 .v.pins = (const struct hda_pintbl[]) {
5193 { 0x14, 0x99130110 }, /* speaker */
5194 { 0x15, 0x0121441f }, /* HP */
5195 { 0x16, 0x99130111 }, /* speaker */
5196 { 0x18, 0x01a19840 }, /* mic */
5197 { 0x19, 0x99a3094f }, /* int-mic */
5201 .chain_id = ALC662_FIXUP_SKU_IGNORE
5203 [ALC662_FIXUP_ASUS_MODE6] = {
5204 .type = HDA_FIXUP_PINS,
5205 .v.pins = (const struct hda_pintbl[]) {
5206 { 0x14, 0x99130110 }, /* speaker */
5207 { 0x15, 0x01211420 }, /* HP2 */
5208 { 0x18, 0x01a19840 }, /* mic */
5209 { 0x19, 0x99a3094f }, /* int-mic */
5210 { 0x1b, 0x0121441f }, /* HP */
5214 .chain_id = ALC662_FIXUP_SKU_IGNORE
5216 [ALC662_FIXUP_ASUS_MODE7] = {
5217 .type = HDA_FIXUP_PINS,
5218 .v.pins = (const struct hda_pintbl[]) {
5219 { 0x14, 0x99130110 }, /* speaker */
5220 { 0x17, 0x99130111 }, /* speaker */
5221 { 0x18, 0x01a19840 }, /* mic */
5222 { 0x19, 0x99a3094f }, /* int-mic */
5223 { 0x1b, 0x01214020 }, /* HP */
5224 { 0x21, 0x0121401f }, /* HP */
5228 .chain_id = ALC662_FIXUP_SKU_IGNORE
5230 [ALC662_FIXUP_ASUS_MODE8] = {
5231 .type = HDA_FIXUP_PINS,
5232 .v.pins = (const struct hda_pintbl[]) {
5233 { 0x14, 0x99130110 }, /* speaker */
5234 { 0x12, 0x99a30970 }, /* int-mic */
5235 { 0x15, 0x01214020 }, /* HP */
5236 { 0x17, 0x99130111 }, /* speaker */
5237 { 0x18, 0x01a19840 }, /* mic */
5238 { 0x21, 0x0121401f }, /* HP */
5242 .chain_id = ALC662_FIXUP_SKU_IGNORE
5244 [ALC662_FIXUP_NO_JACK_DETECT] = {
5245 .type = HDA_FIXUP_FUNC,
5246 .v.func = alc_fixup_no_jack_detect,
5248 [ALC662_FIXUP_ZOTAC_Z68] = {
5249 .type = HDA_FIXUP_PINS,
5250 .v.pins = (const struct hda_pintbl[]) {
5251 { 0x1b, 0x02214020 }, /* Front HP */
5255 [ALC662_FIXUP_INV_DMIC] = {
5256 .type = HDA_FIXUP_FUNC,
5257 .v.func = alc_fixup_inv_dmic_0x12,
5259 [ALC668_FIXUP_AUTO_MUTE] = {
5260 .type = HDA_FIXUP_FUNC,
5261 .v.func = alc_fixup_auto_mute_via_amp,
5263 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
5265 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
5266 .type = HDA_FIXUP_PINS,
5267 .v.pins = (const struct hda_pintbl[]) {
5268 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
5269 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
5273 .chain_id = ALC668_FIXUP_HEADSET_MODE
5275 [ALC668_FIXUP_HEADSET_MODE] = {
5276 .type = HDA_FIXUP_FUNC,
5277 .v.func = alc_fixup_headset_mode_alc668,
5279 [ALC662_FIXUP_BASS_CHMAP] = {
5280 .type = HDA_FIXUP_FUNC,
5281 .v.func = alc_fixup_bass_chmap,
5283 .chain_id = ALC662_FIXUP_ASUS_MODE4
5285 [ALC662_FIXUP_BASS_1A] = {
5286 .type = HDA_FIXUP_PINS,
5287 .v.pins = (const struct hda_pintbl[]) {
5288 {0x1a, 0x80106111}, /* bass speaker */
5292 [ALC662_FIXUP_BASS_1A_CHMAP] = {
5293 .type = HDA_FIXUP_FUNC,
5294 .v.func = alc_fixup_bass_chmap,
5296 .chain_id = ALC662_FIXUP_BASS_1A,
5300 static const struct snd_pci_quirk alc662_fixup_tbl[] = {
5301 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
5302 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
5303 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
5304 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
5305 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
5306 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
5307 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
5308 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5309 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5310 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5311 SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE),
5312 SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE),
5313 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5314 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5315 SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE),
5316 SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE),
5317 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5318 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5319 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
5320 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A_CHMAP),
5321 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_CHMAP),
5322 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_CHMAP),
5323 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
5324 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
5325 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
5326 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
5327 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
5328 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
5329 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
5332 /* Below is a quirk table taken from the old code.
5333 * Basically the device should work as is without the fixup table.
5334 * If BIOS doesn't give a proper info, enable the corresponding
5337 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
5338 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
5339 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
5340 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
5341 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
5342 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5343 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
5344 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
5345 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
5346 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5347 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
5348 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
5349 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
5350 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
5351 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
5352 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5353 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
5354 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
5355 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5356 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
5357 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
5358 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5359 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
5360 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
5361 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
5362 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5363 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
5364 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
5365 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5366 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
5367 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5368 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5369 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
5370 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
5371 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
5372 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
5373 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
5374 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
5375 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
5376 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5377 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
5378 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
5379 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
5380 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
5381 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
5382 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
5383 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
5384 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
5385 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
5386 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
5391 static const struct hda_model_fixup alc662_fixup_models[] = {
5392 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
5393 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
5394 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
5395 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
5396 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
5397 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
5398 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
5399 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
5400 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
5401 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
5402 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
5406 static void alc662_fill_coef(struct hda_codec *codec)
5410 coef = alc_get_coef0(codec);
5412 switch (codec->vendor_id) {
5414 if ((coef & 0x00f0) == 0x0030) {
5415 val = alc_read_coef_idx(codec, 0x4); /* EAPD Ctrl */
5416 alc_write_coef_idx(codec, 0x4, val & ~(1<<10));
5426 val = alc_read_coef_idx(codec, 0xd); /* EAPD Ctrl */
5427 alc_write_coef_idx(codec, 0xd, val | (1<<14));
5434 static int patch_alc662(struct hda_codec *codec)
5436 struct alc_spec *spec;
5439 err = alc_alloc_spec(codec, 0x0b);
5445 /* handle multiple HPs as is */
5446 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5448 alc_fix_pll_init(codec, 0x20, 0x04, 15);
5450 spec->init_hook = alc662_fill_coef;
5451 alc662_fill_coef(codec);
5453 snd_hda_pick_fixup(codec, alc662_fixup_models,
5454 alc662_fixup_tbl, alc662_fixups);
5455 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
5457 alc_auto_parse_customize_define(codec);
5459 if (has_cdefine_beep(codec))
5460 spec->gen.beep_nid = 0x01;
5462 if ((alc_get_coef0(codec) & (1 << 14)) &&
5463 codec->bus->pci->subsystem_vendor == 0x1025 &&
5464 spec->cdefine.platform_type == 1) {
5465 err = alc_codec_rename(codec, "ALC272X");
5470 /* automatic parse from the BIOS config */
5471 err = alc662_parse_auto_config(codec);
5475 if (!spec->gen.no_analog && spec->gen.beep_nid) {
5476 switch (codec->vendor_id) {
5478 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5484 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
5487 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
5492 codec->patch_ops = alc_patch_ops;
5493 spec->shutup = alc_eapd_shutup;
5495 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
5508 static int alc680_parse_auto_config(struct hda_codec *codec)
5510 return alc_parse_auto_config(codec, NULL, NULL);
5515 static int patch_alc680(struct hda_codec *codec)
5519 /* ALC680 has no aa-loopback mixer */
5520 err = alc_alloc_spec(codec, 0);
5524 /* automatic parse from the BIOS config */
5525 err = alc680_parse_auto_config(codec);
5531 codec->patch_ops = alc_patch_ops;
5539 static const struct hda_codec_preset snd_hda_preset_realtek[] = {
5540 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
5541 { .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 },
5542 { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 },
5543 { .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 },
5544 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
5545 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
5546 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
5547 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
5548 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
5549 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
5550 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
5551 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
5552 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
5553 { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 },
5554 { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 },
5555 { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 },
5556 { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 },
5557 { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 },
5558 { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 },
5559 { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 },
5560 { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 },
5561 { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 },
5562 { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 },
5563 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
5564 .patch = patch_alc861 },
5565 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
5566 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
5567 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
5568 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
5569 .patch = patch_alc882 },
5570 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
5571 .patch = patch_alc662 },
5572 { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3",
5573 .patch = patch_alc662 },
5574 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
5575 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
5576 { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 },
5577 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
5578 { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 },
5579 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
5580 { .id = 0x10ec0867, .name = "ALC891", .patch = patch_alc882 },
5581 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
5582 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
5583 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
5584 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
5585 .patch = patch_alc882 },
5586 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
5587 .patch = patch_alc882 },
5588 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
5589 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
5590 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
5591 .patch = patch_alc882 },
5592 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
5593 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
5594 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
5595 { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 },
5596 { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 },
5600 MODULE_ALIAS("snd-hda-codec-id:10ec*");
5602 MODULE_LICENSE("GPL");
5603 MODULE_DESCRIPTION("Realtek HD-audio codec");
5605 static struct hda_codec_preset_list realtek_list = {
5606 .preset = snd_hda_preset_realtek,
5607 .owner = THIS_MODULE,
5610 static int __init patch_realtek_init(void)
5612 return snd_hda_add_codec_preset(&realtek_list);
5615 static void __exit patch_realtek_exit(void)
5617 snd_hda_delete_codec_preset(&realtek_list);
5620 module_init(patch_realtek_init)
5621 module_exit(patch_realtek_exit)