net: dsa: mt7530: set CPU port to fallback mode
[linux/fpc-iii.git] / sound / pci / hda / patch_sigmatel.c
blobd8168aa2cef381fc05199d1e4044b4ee8a3c4202
1 /*
2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for SigmaTel STAC92xx
6 * Copyright (c) 2005 Embedded Alley Solutions, Inc.
7 * Matt Porter <mporter@embeddedalley.com>
9 * Based on patch_cmedia.c and patch_realtek.c
10 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
12 * This driver is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This driver is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/slab.h>
30 #include <linux/pci.h>
31 #include <linux/dmi.h>
32 #include <linux/module.h>
33 #include <sound/core.h>
34 #include <sound/jack.h>
35 #include "hda_codec.h"
36 #include "hda_local.h"
37 #include "hda_auto_parser.h"
38 #include "hda_beep.h"
39 #include "hda_jack.h"
40 #include "hda_generic.h"
42 enum {
43 STAC_REF,
44 STAC_9200_OQO,
45 STAC_9200_DELL_D21,
46 STAC_9200_DELL_D22,
47 STAC_9200_DELL_D23,
48 STAC_9200_DELL_M21,
49 STAC_9200_DELL_M22,
50 STAC_9200_DELL_M23,
51 STAC_9200_DELL_M24,
52 STAC_9200_DELL_M25,
53 STAC_9200_DELL_M26,
54 STAC_9200_DELL_M27,
55 STAC_9200_M4,
56 STAC_9200_M4_2,
57 STAC_9200_PANASONIC,
58 STAC_9200_EAPD_INIT,
59 STAC_9200_MODELS
62 enum {
63 STAC_9205_REF,
64 STAC_9205_DELL_M42,
65 STAC_9205_DELL_M43,
66 STAC_9205_DELL_M44,
67 STAC_9205_EAPD,
68 STAC_9205_MODELS
71 enum {
72 STAC_92HD73XX_NO_JD, /* no jack-detection */
73 STAC_92HD73XX_REF,
74 STAC_92HD73XX_INTEL,
75 STAC_DELL_M6_AMIC,
76 STAC_DELL_M6_DMIC,
77 STAC_DELL_M6_BOTH,
78 STAC_DELL_EQ,
79 STAC_ALIENWARE_M17X,
80 STAC_ELO_VUPOINT_15MX,
81 STAC_92HD89XX_HP_FRONT_JACK,
82 STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK,
83 STAC_92HD73XX_ASUS_MOBO,
84 STAC_92HD73XX_MODELS
87 enum {
88 STAC_92HD83XXX_REF,
89 STAC_92HD83XXX_PWR_REF,
90 STAC_DELL_S14,
91 STAC_DELL_VOSTRO_3500,
92 STAC_92HD83XXX_HP_cNB11_INTQUAD,
93 STAC_HP_DV7_4000,
94 STAC_HP_ZEPHYR,
95 STAC_92HD83XXX_HP_LED,
96 STAC_92HD83XXX_HP_INV_LED,
97 STAC_92HD83XXX_HP_MIC_LED,
98 STAC_HP_LED_GPIO10,
99 STAC_92HD83XXX_HEADSET_JACK,
100 STAC_92HD83XXX_HP,
101 STAC_HP_ENVY_BASS,
102 STAC_HP_BNB13_EQ,
103 STAC_HP_ENVY_TS_BASS,
104 STAC_HP_ENVY_TS_DAC_BIND,
105 STAC_92HD83XXX_GPIO10_EAPD,
106 STAC_92HD83XXX_MODELS
109 enum {
110 STAC_92HD71BXX_REF,
111 STAC_DELL_M4_1,
112 STAC_DELL_M4_2,
113 STAC_DELL_M4_3,
114 STAC_HP_M4,
115 STAC_HP_DV4,
116 STAC_HP_DV5,
117 STAC_HP_HDX,
118 STAC_92HD71BXX_HP,
119 STAC_92HD71BXX_NO_DMIC,
120 STAC_92HD71BXX_NO_SMUX,
121 STAC_92HD71BXX_MODELS
124 enum {
125 STAC_92HD95_HP_LED,
126 STAC_92HD95_HP_BASS,
127 STAC_92HD95_MODELS
130 enum {
131 STAC_925x_REF,
132 STAC_M1,
133 STAC_M1_2,
134 STAC_M2,
135 STAC_M2_2,
136 STAC_M3,
137 STAC_M5,
138 STAC_M6,
139 STAC_925x_MODELS
142 enum {
143 STAC_D945_REF,
144 STAC_D945GTP3,
145 STAC_D945GTP5,
146 STAC_INTEL_MAC_V1,
147 STAC_INTEL_MAC_V2,
148 STAC_INTEL_MAC_V3,
149 STAC_INTEL_MAC_V4,
150 STAC_INTEL_MAC_V5,
151 STAC_INTEL_MAC_AUTO,
152 STAC_ECS_202,
153 STAC_922X_DELL_D81,
154 STAC_922X_DELL_D82,
155 STAC_922X_DELL_M81,
156 STAC_922X_DELL_M82,
157 STAC_922X_INTEL_MAC_GPIO,
158 STAC_922X_MODELS
161 enum {
162 STAC_D965_REF_NO_JD, /* no jack-detection */
163 STAC_D965_REF,
164 STAC_D965_3ST,
165 STAC_D965_5ST,
166 STAC_D965_5ST_NO_FP,
167 STAC_D965_VERBS,
168 STAC_DELL_3ST,
169 STAC_DELL_BIOS,
170 STAC_NEMO_DEFAULT,
171 STAC_DELL_BIOS_AMIC,
172 STAC_DELL_BIOS_SPDIF,
173 STAC_927X_DELL_DMIC,
174 STAC_927X_VOLKNOB,
175 STAC_927X_MODELS
178 enum {
179 STAC_9872_VAIO,
180 STAC_9872_MODELS
183 struct sigmatel_spec {
184 struct hda_gen_spec gen;
186 unsigned int eapd_switch: 1;
187 unsigned int linear_tone_beep:1;
188 unsigned int headset_jack:1; /* 4-pin headset jack (hp + mono mic) */
189 unsigned int volknob_init:1; /* special volume-knob initialization */
190 unsigned int powerdown_adcs:1;
191 unsigned int have_spdif_mux:1;
193 /* gpio lines */
194 unsigned int eapd_mask;
195 unsigned int gpio_mask;
196 unsigned int gpio_dir;
197 unsigned int gpio_data;
198 unsigned int gpio_mute;
199 unsigned int gpio_led;
200 unsigned int gpio_led_polarity;
201 unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */
202 unsigned int vref_led;
203 int default_polarity;
205 unsigned int mic_mute_led_gpio; /* capture mute LED GPIO */
206 unsigned int mic_enabled; /* current mic mute state (bitmask) */
208 /* stream */
209 unsigned int stream_delay;
211 /* analog loopback */
212 const struct snd_kcontrol_new *aloopback_ctl;
213 unsigned int aloopback;
214 unsigned char aloopback_mask;
215 unsigned char aloopback_shift;
217 /* power management */
218 unsigned int power_map_bits;
219 unsigned int num_pwrs;
220 const hda_nid_t *pwr_nids;
221 unsigned int active_adcs;
223 /* beep widgets */
224 hda_nid_t anabeep_nid;
226 /* SPDIF-out mux */
227 const char * const *spdif_labels;
228 struct hda_input_mux spdif_mux;
229 unsigned int cur_smux[2];
232 #define AC_VERB_IDT_SET_POWER_MAP 0x7ec
233 #define AC_VERB_IDT_GET_POWER_MAP 0xfec
235 static const hda_nid_t stac92hd73xx_pwr_nids[8] = {
236 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
237 0x0f, 0x10, 0x11
240 static const hda_nid_t stac92hd83xxx_pwr_nids[7] = {
241 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
242 0x0f, 0x10
245 static const hda_nid_t stac92hd71bxx_pwr_nids[3] = {
246 0x0a, 0x0d, 0x0f
251 * PCM hooks
253 static void stac_playback_pcm_hook(struct hda_pcm_stream *hinfo,
254 struct hda_codec *codec,
255 struct snd_pcm_substream *substream,
256 int action)
258 struct sigmatel_spec *spec = codec->spec;
259 if (action == HDA_GEN_PCM_ACT_OPEN && spec->stream_delay)
260 msleep(spec->stream_delay);
263 static void stac_capture_pcm_hook(struct hda_pcm_stream *hinfo,
264 struct hda_codec *codec,
265 struct snd_pcm_substream *substream,
266 int action)
268 struct sigmatel_spec *spec = codec->spec;
269 int i, idx = 0;
271 if (!spec->powerdown_adcs)
272 return;
274 for (i = 0; i < spec->gen.num_all_adcs; i++) {
275 if (spec->gen.all_adcs[i] == hinfo->nid) {
276 idx = i;
277 break;
281 switch (action) {
282 case HDA_GEN_PCM_ACT_OPEN:
283 msleep(40);
284 snd_hda_codec_write(codec, hinfo->nid, 0,
285 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
286 spec->active_adcs |= (1 << idx);
287 break;
288 case HDA_GEN_PCM_ACT_CLOSE:
289 snd_hda_codec_write(codec, hinfo->nid, 0,
290 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
291 spec->active_adcs &= ~(1 << idx);
292 break;
297 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
298 * funky external mute control using GPIO pins.
301 static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
302 unsigned int dir_mask, unsigned int data)
304 unsigned int gpiostate, gpiomask, gpiodir;
305 hda_nid_t fg = codec->core.afg;
307 codec_dbg(codec, "%s msk %x dir %x gpio %x\n", __func__, mask, dir_mask, data);
309 gpiostate = snd_hda_codec_read(codec, fg, 0,
310 AC_VERB_GET_GPIO_DATA, 0);
311 gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask);
313 gpiomask = snd_hda_codec_read(codec, fg, 0,
314 AC_VERB_GET_GPIO_MASK, 0);
315 gpiomask |= mask;
317 gpiodir = snd_hda_codec_read(codec, fg, 0,
318 AC_VERB_GET_GPIO_DIRECTION, 0);
319 gpiodir |= dir_mask;
321 /* Configure GPIOx as CMOS */
322 snd_hda_codec_write(codec, fg, 0, 0x7e7, 0);
324 snd_hda_codec_write(codec, fg, 0,
325 AC_VERB_SET_GPIO_MASK, gpiomask);
326 snd_hda_codec_read(codec, fg, 0,
327 AC_VERB_SET_GPIO_DIRECTION, gpiodir); /* sync */
329 msleep(1);
331 snd_hda_codec_read(codec, fg, 0,
332 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
335 /* hook for controlling mic-mute LED GPIO */
336 static void stac_capture_led_update(struct hda_codec *codec)
338 struct sigmatel_spec *spec = codec->spec;
340 if (spec->gen.micmute_led.led_value)
341 spec->gpio_data |= spec->mic_mute_led_gpio;
342 else
343 spec->gpio_data &= ~spec->mic_mute_led_gpio;
344 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
347 static int stac_vrefout_set(struct hda_codec *codec,
348 hda_nid_t nid, unsigned int new_vref)
350 int error, pinctl;
352 codec_dbg(codec, "%s, nid %x ctl %x\n", __func__, nid, new_vref);
353 pinctl = snd_hda_codec_read(codec, nid, 0,
354 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
356 if (pinctl < 0)
357 return pinctl;
359 pinctl &= 0xff;
360 pinctl &= ~AC_PINCTL_VREFEN;
361 pinctl |= (new_vref & AC_PINCTL_VREFEN);
363 error = snd_hda_set_pin_ctl_cache(codec, nid, pinctl);
364 if (error < 0)
365 return error;
367 return 1;
370 /* prevent codec AFG to D3 state when vref-out pin is used for mute LED */
371 /* this hook is set in stac_setup_gpio() */
372 static unsigned int stac_vref_led_power_filter(struct hda_codec *codec,
373 hda_nid_t nid,
374 unsigned int power_state)
376 if (nid == codec->core.afg && power_state == AC_PWRST_D3)
377 return AC_PWRST_D1;
378 return snd_hda_gen_path_power_filter(codec, nid, power_state);
381 /* update mute-LED accoring to the master switch */
382 static void stac_update_led_status(struct hda_codec *codec, int enabled)
384 struct sigmatel_spec *spec = codec->spec;
385 int muted = !enabled;
387 if (!spec->gpio_led)
388 return;
390 /* LED state is inverted on these systems */
391 if (spec->gpio_led_polarity)
392 muted = !muted;
394 if (!spec->vref_mute_led_nid) {
395 if (muted)
396 spec->gpio_data |= spec->gpio_led;
397 else
398 spec->gpio_data &= ~spec->gpio_led;
399 stac_gpio_set(codec, spec->gpio_mask,
400 spec->gpio_dir, spec->gpio_data);
401 } else {
402 spec->vref_led = muted ? AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
403 stac_vrefout_set(codec, spec->vref_mute_led_nid,
404 spec->vref_led);
408 /* vmaster hook to update mute LED */
409 static void stac_vmaster_hook(void *private_data, int val)
411 stac_update_led_status(private_data, val);
414 /* automute hook to handle GPIO mute and EAPD updates */
415 static void stac_update_outputs(struct hda_codec *codec)
417 struct sigmatel_spec *spec = codec->spec;
419 if (spec->gpio_mute)
420 spec->gen.master_mute =
421 !(snd_hda_codec_read(codec, codec->core.afg, 0,
422 AC_VERB_GET_GPIO_DATA, 0) & spec->gpio_mute);
424 snd_hda_gen_update_outputs(codec);
426 if (spec->eapd_mask && spec->eapd_switch) {
427 unsigned int val = spec->gpio_data;
428 if (spec->gen.speaker_muted)
429 val &= ~spec->eapd_mask;
430 else
431 val |= spec->eapd_mask;
432 if (spec->gpio_data != val) {
433 spec->gpio_data = val;
434 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir,
435 val);
440 static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
441 bool enable, bool do_write)
443 struct sigmatel_spec *spec = codec->spec;
444 unsigned int idx, val;
446 for (idx = 0; idx < spec->num_pwrs; idx++) {
447 if (spec->pwr_nids[idx] == nid)
448 break;
450 if (idx >= spec->num_pwrs)
451 return;
453 idx = 1 << idx;
455 val = spec->power_map_bits;
456 if (enable)
457 val &= ~idx;
458 else
459 val |= idx;
461 /* power down unused output ports */
462 if (val != spec->power_map_bits) {
463 spec->power_map_bits = val;
464 if (do_write)
465 snd_hda_codec_write(codec, codec->core.afg, 0,
466 AC_VERB_IDT_SET_POWER_MAP, val);
470 /* update power bit per jack plug/unplug */
471 static void jack_update_power(struct hda_codec *codec,
472 struct hda_jack_callback *jack)
474 struct sigmatel_spec *spec = codec->spec;
475 int i;
477 if (!spec->num_pwrs)
478 return;
480 if (jack && jack->nid) {
481 stac_toggle_power_map(codec, jack->nid,
482 snd_hda_jack_detect(codec, jack->nid),
483 true);
484 return;
487 /* update all jacks */
488 for (i = 0; i < spec->num_pwrs; i++) {
489 hda_nid_t nid = spec->pwr_nids[i];
490 if (!snd_hda_jack_tbl_get(codec, nid))
491 continue;
492 stac_toggle_power_map(codec, nid,
493 snd_hda_jack_detect(codec, nid),
494 false);
497 snd_hda_codec_write(codec, codec->core.afg, 0,
498 AC_VERB_IDT_SET_POWER_MAP,
499 spec->power_map_bits);
502 static void stac_vref_event(struct hda_codec *codec,
503 struct hda_jack_callback *event)
505 unsigned int data;
507 data = snd_hda_codec_read(codec, codec->core.afg, 0,
508 AC_VERB_GET_GPIO_DATA, 0);
509 /* toggle VREF state based on GPIOx status */
510 snd_hda_codec_write(codec, codec->core.afg, 0, 0x7e0,
511 !!(data & (1 << event->private_data)));
514 /* initialize the power map and enable the power event to jacks that
515 * haven't been assigned to automute
517 static void stac_init_power_map(struct hda_codec *codec)
519 struct sigmatel_spec *spec = codec->spec;
520 int i;
522 for (i = 0; i < spec->num_pwrs; i++) {
523 hda_nid_t nid = spec->pwr_nids[i];
524 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
525 def_conf = get_defcfg_connect(def_conf);
526 if (def_conf == AC_JACK_PORT_COMPLEX &&
527 spec->vref_mute_led_nid != nid &&
528 is_jack_detectable(codec, nid)) {
529 snd_hda_jack_detect_enable_callback(codec, nid,
530 jack_update_power);
531 } else {
532 if (def_conf == AC_JACK_PORT_NONE)
533 stac_toggle_power_map(codec, nid, false, false);
534 else
535 stac_toggle_power_map(codec, nid, true, false);
543 static inline bool get_int_hint(struct hda_codec *codec, const char *key,
544 int *valp)
546 return !snd_hda_get_int_hint(codec, key, valp);
549 /* override some hints from the hwdep entry */
550 static void stac_store_hints(struct hda_codec *codec)
552 struct sigmatel_spec *spec = codec->spec;
553 int val;
555 if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) {
556 spec->eapd_mask = spec->gpio_dir = spec->gpio_data =
557 spec->gpio_mask;
559 if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir))
560 spec->gpio_dir &= spec->gpio_mask;
561 if (get_int_hint(codec, "gpio_data", &spec->gpio_data))
562 spec->gpio_data &= spec->gpio_mask;
563 if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask))
564 spec->eapd_mask &= spec->gpio_mask;
565 if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute))
566 spec->gpio_mute &= spec->gpio_mask;
567 val = snd_hda_get_bool_hint(codec, "eapd_switch");
568 if (val >= 0)
569 spec->eapd_switch = val;
573 * loopback controls
576 #define stac_aloopback_info snd_ctl_boolean_mono_info
578 static int stac_aloopback_get(struct snd_kcontrol *kcontrol,
579 struct snd_ctl_elem_value *ucontrol)
581 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
582 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
583 struct sigmatel_spec *spec = codec->spec;
585 ucontrol->value.integer.value[0] = !!(spec->aloopback &
586 (spec->aloopback_mask << idx));
587 return 0;
590 static int stac_aloopback_put(struct snd_kcontrol *kcontrol,
591 struct snd_ctl_elem_value *ucontrol)
593 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
594 struct sigmatel_spec *spec = codec->spec;
595 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
596 unsigned int dac_mode;
597 unsigned int val, idx_val;
599 idx_val = spec->aloopback_mask << idx;
600 if (ucontrol->value.integer.value[0])
601 val = spec->aloopback | idx_val;
602 else
603 val = spec->aloopback & ~idx_val;
604 if (spec->aloopback == val)
605 return 0;
607 spec->aloopback = val;
609 /* Only return the bits defined by the shift value of the
610 * first two bytes of the mask
612 dac_mode = snd_hda_codec_read(codec, codec->core.afg, 0,
613 kcontrol->private_value & 0xFFFF, 0x0);
614 dac_mode >>= spec->aloopback_shift;
616 if (spec->aloopback & idx_val) {
617 snd_hda_power_up(codec);
618 dac_mode |= idx_val;
619 } else {
620 snd_hda_power_down(codec);
621 dac_mode &= ~idx_val;
624 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
625 kcontrol->private_value >> 16, dac_mode);
627 return 1;
630 #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \
632 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
633 .name = "Analog Loopback", \
634 .count = cnt, \
635 .info = stac_aloopback_info, \
636 .get = stac_aloopback_get, \
637 .put = stac_aloopback_put, \
638 .private_value = verb_read | (verb_write << 16), \
642 * Mute LED handling on HP laptops
645 /* check whether it's a HP laptop with a docking port */
646 static bool hp_bnb2011_with_dock(struct hda_codec *codec)
648 if (codec->core.vendor_id != 0x111d7605 &&
649 codec->core.vendor_id != 0x111d76d1)
650 return false;
652 switch (codec->core.subsystem_id) {
653 case 0x103c1618:
654 case 0x103c1619:
655 case 0x103c161a:
656 case 0x103c161b:
657 case 0x103c161c:
658 case 0x103c161d:
659 case 0x103c161e:
660 case 0x103c161f:
662 case 0x103c162a:
663 case 0x103c162b:
665 case 0x103c1630:
666 case 0x103c1631:
668 case 0x103c1633:
669 case 0x103c1634:
670 case 0x103c1635:
672 case 0x103c3587:
673 case 0x103c3588:
674 case 0x103c3589:
675 case 0x103c358a:
677 case 0x103c3667:
678 case 0x103c3668:
679 case 0x103c3669:
681 return true;
683 return false;
686 static bool hp_blike_system(u32 subsystem_id)
688 switch (subsystem_id) {
689 case 0x103c1473: /* HP ProBook 6550b */
690 case 0x103c1520:
691 case 0x103c1521:
692 case 0x103c1523:
693 case 0x103c1524:
694 case 0x103c1525:
695 case 0x103c1722:
696 case 0x103c1723:
697 case 0x103c1724:
698 case 0x103c1725:
699 case 0x103c1726:
700 case 0x103c1727:
701 case 0x103c1728:
702 case 0x103c1729:
703 case 0x103c172a:
704 case 0x103c172b:
705 case 0x103c307e:
706 case 0x103c307f:
707 case 0x103c3080:
708 case 0x103c3081:
709 case 0x103c7007:
710 case 0x103c7008:
711 return true;
713 return false;
716 static void set_hp_led_gpio(struct hda_codec *codec)
718 struct sigmatel_spec *spec = codec->spec;
719 unsigned int gpio;
721 if (spec->gpio_led)
722 return;
724 gpio = snd_hda_param_read(codec, codec->core.afg, AC_PAR_GPIO_CAP);
725 gpio &= AC_GPIO_IO_COUNT;
726 if (gpio > 3)
727 spec->gpio_led = 0x08; /* GPIO 3 */
728 else
729 spec->gpio_led = 0x01; /* GPIO 0 */
733 * This method searches for the mute LED GPIO configuration
734 * provided as OEM string in SMBIOS. The format of that string
735 * is HP_Mute_LED_P_G or HP_Mute_LED_P
736 * where P can be 0 or 1 and defines mute LED GPIO control state (low/high)
737 * that corresponds to the NOT muted state of the master volume
738 * and G is the index of the GPIO to use as the mute LED control (0..9)
739 * If _G portion is missing it is assigned based on the codec ID
741 * So, HP B-series like systems may have HP_Mute_LED_0 (current models)
742 * or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings
745 * The dv-series laptops don't seem to have the HP_Mute_LED* strings in
746 * SMBIOS - at least the ones I have seen do not have them - which include
747 * my own system (HP Pavilion dv6-1110ax) and my cousin's
748 * HP Pavilion dv9500t CTO.
749 * Need more information on whether it is true across the entire series.
750 * -- kunal
752 static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity)
754 struct sigmatel_spec *spec = codec->spec;
755 const struct dmi_device *dev = NULL;
757 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
758 get_int_hint(codec, "gpio_led_polarity",
759 &spec->gpio_led_polarity);
760 return 1;
763 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
764 if (sscanf(dev->name, "HP_Mute_LED_%u_%x",
765 &spec->gpio_led_polarity,
766 &spec->gpio_led) == 2) {
767 unsigned int max_gpio;
768 max_gpio = snd_hda_param_read(codec, codec->core.afg,
769 AC_PAR_GPIO_CAP);
770 max_gpio &= AC_GPIO_IO_COUNT;
771 if (spec->gpio_led < max_gpio)
772 spec->gpio_led = 1 << spec->gpio_led;
773 else
774 spec->vref_mute_led_nid = spec->gpio_led;
775 return 1;
777 if (sscanf(dev->name, "HP_Mute_LED_%u",
778 &spec->gpio_led_polarity) == 1) {
779 set_hp_led_gpio(codec);
780 return 1;
782 /* BIOS bug: unfilled OEM string */
783 if (strstr(dev->name, "HP_Mute_LED_P_G")) {
784 set_hp_led_gpio(codec);
785 if (default_polarity >= 0)
786 spec->gpio_led_polarity = default_polarity;
787 else
788 spec->gpio_led_polarity = 1;
789 return 1;
794 * Fallback case - if we don't find the DMI strings,
795 * we statically set the GPIO - if not a B-series system
796 * and default polarity is provided
798 if (!hp_blike_system(codec->core.subsystem_id) &&
799 (default_polarity == 0 || default_polarity == 1)) {
800 set_hp_led_gpio(codec);
801 spec->gpio_led_polarity = default_polarity;
802 return 1;
804 return 0;
807 /* check whether a built-in speaker is included in parsed pins */
808 static bool has_builtin_speaker(struct hda_codec *codec)
810 struct sigmatel_spec *spec = codec->spec;
811 hda_nid_t *nid_pin;
812 int nids, i;
814 if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) {
815 nid_pin = spec->gen.autocfg.line_out_pins;
816 nids = spec->gen.autocfg.line_outs;
817 } else {
818 nid_pin = spec->gen.autocfg.speaker_pins;
819 nids = spec->gen.autocfg.speaker_outs;
822 for (i = 0; i < nids; i++) {
823 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid_pin[i]);
824 if (snd_hda_get_input_pin_attr(def_conf) == INPUT_PIN_ATTR_INT)
825 return true;
827 return false;
831 * PC beep controls
834 /* create PC beep volume controls */
835 static int stac_auto_create_beep_ctls(struct hda_codec *codec,
836 hda_nid_t nid)
838 struct sigmatel_spec *spec = codec->spec;
839 u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
840 struct snd_kcontrol_new *knew;
841 static struct snd_kcontrol_new abeep_mute_ctl =
842 HDA_CODEC_MUTE(NULL, 0, 0, 0);
843 static struct snd_kcontrol_new dbeep_mute_ctl =
844 HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0);
845 static struct snd_kcontrol_new beep_vol_ctl =
846 HDA_CODEC_VOLUME(NULL, 0, 0, 0);
848 /* check for mute support for the the amp */
849 if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) {
850 const struct snd_kcontrol_new *temp;
851 if (spec->anabeep_nid == nid)
852 temp = &abeep_mute_ctl;
853 else
854 temp = &dbeep_mute_ctl;
855 knew = snd_hda_gen_add_kctl(&spec->gen,
856 "Beep Playback Switch", temp);
857 if (!knew)
858 return -ENOMEM;
859 knew->private_value =
860 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT);
863 /* check to see if there is volume support for the amp */
864 if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
865 knew = snd_hda_gen_add_kctl(&spec->gen,
866 "Beep Playback Volume",
867 &beep_vol_ctl);
868 if (!knew)
869 return -ENOMEM;
870 knew->private_value =
871 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT);
873 return 0;
876 #ifdef CONFIG_SND_HDA_INPUT_BEEP
877 #define stac_dig_beep_switch_info snd_ctl_boolean_mono_info
879 static int stac_dig_beep_switch_get(struct snd_kcontrol *kcontrol,
880 struct snd_ctl_elem_value *ucontrol)
882 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
883 ucontrol->value.integer.value[0] = codec->beep->enabled;
884 return 0;
887 static int stac_dig_beep_switch_put(struct snd_kcontrol *kcontrol,
888 struct snd_ctl_elem_value *ucontrol)
890 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
891 return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]);
894 static const struct snd_kcontrol_new stac_dig_beep_ctrl = {
895 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
896 .name = "Beep Playback Switch",
897 .info = stac_dig_beep_switch_info,
898 .get = stac_dig_beep_switch_get,
899 .put = stac_dig_beep_switch_put,
902 static int stac_beep_switch_ctl(struct hda_codec *codec)
904 struct sigmatel_spec *spec = codec->spec;
906 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &stac_dig_beep_ctrl))
907 return -ENOMEM;
908 return 0;
910 #endif
913 * SPDIF-out mux controls
916 static int stac_smux_enum_info(struct snd_kcontrol *kcontrol,
917 struct snd_ctl_elem_info *uinfo)
919 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
920 struct sigmatel_spec *spec = codec->spec;
921 return snd_hda_input_mux_info(&spec->spdif_mux, uinfo);
924 static int stac_smux_enum_get(struct snd_kcontrol *kcontrol,
925 struct snd_ctl_elem_value *ucontrol)
927 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
928 struct sigmatel_spec *spec = codec->spec;
929 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
931 ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx];
932 return 0;
935 static int stac_smux_enum_put(struct snd_kcontrol *kcontrol,
936 struct snd_ctl_elem_value *ucontrol)
938 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
939 struct sigmatel_spec *spec = codec->spec;
940 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
942 return snd_hda_input_mux_put(codec, &spec->spdif_mux, ucontrol,
943 spec->gen.autocfg.dig_out_pins[smux_idx],
944 &spec->cur_smux[smux_idx]);
947 static const struct snd_kcontrol_new stac_smux_mixer = {
948 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
949 .name = "IEC958 Playback Source",
950 /* count set later */
951 .info = stac_smux_enum_info,
952 .get = stac_smux_enum_get,
953 .put = stac_smux_enum_put,
956 static const char * const stac_spdif_labels[] = {
957 "Digital Playback", "Analog Mux 1", "Analog Mux 2", NULL
960 static int stac_create_spdif_mux_ctls(struct hda_codec *codec)
962 struct sigmatel_spec *spec = codec->spec;
963 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
964 const char * const *labels = spec->spdif_labels;
965 struct snd_kcontrol_new *kctl;
966 int i, num_cons;
968 if (cfg->dig_outs < 1)
969 return 0;
971 num_cons = snd_hda_get_num_conns(codec, cfg->dig_out_pins[0]);
972 if (num_cons <= 1)
973 return 0;
975 if (!labels)
976 labels = stac_spdif_labels;
977 for (i = 0; i < num_cons; i++) {
978 if (snd_BUG_ON(!labels[i]))
979 return -EINVAL;
980 snd_hda_add_imux_item(codec, &spec->spdif_mux, labels[i], i, NULL);
983 kctl = snd_hda_gen_add_kctl(&spec->gen, NULL, &stac_smux_mixer);
984 if (!kctl)
985 return -ENOMEM;
986 kctl->count = cfg->dig_outs;
988 return 0;
994 static const struct hda_verb stac9200_core_init[] = {
995 /* set dac0mux for dac converter */
996 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1000 static const struct hda_verb stac9200_eapd_init[] = {
1001 /* set dac0mux for dac converter */
1002 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1003 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1007 static const struct hda_verb dell_eq_core_init[] = {
1008 /* set master volume to max value without distortion
1009 * and direct control */
1010 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
1014 static const struct hda_verb stac92hd73xx_core_init[] = {
1015 /* set master volume and direct control */
1016 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1020 static const struct hda_verb stac92hd83xxx_core_init[] = {
1021 /* power state controls amps */
1022 { 0x01, AC_VERB_SET_EAPD, 1 << 2},
1026 static const struct hda_verb stac92hd83xxx_hp_zephyr_init[] = {
1027 { 0x22, 0x785, 0x43 },
1028 { 0x22, 0x782, 0xe0 },
1029 { 0x22, 0x795, 0x00 },
1033 static const struct hda_verb stac92hd71bxx_core_init[] = {
1034 /* set master volume and direct control */
1035 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1039 static const hda_nid_t stac92hd71bxx_unmute_nids[] = {
1040 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */
1041 0x0f, 0x0a, 0x0d, 0
1044 static const struct hda_verb stac925x_core_init[] = {
1045 /* set dac0mux for dac converter */
1046 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
1047 /* mute the master volume */
1048 { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1052 static const struct hda_verb stac922x_core_init[] = {
1053 /* set master volume and direct control */
1054 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1058 static const struct hda_verb d965_core_init[] = {
1059 /* unmute node 0x1b */
1060 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1061 /* select node 0x03 as DAC */
1062 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
1066 static const struct hda_verb dell_3st_core_init[] = {
1067 /* don't set delta bit */
1068 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
1069 /* unmute node 0x1b */
1070 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1071 /* select node 0x03 as DAC */
1072 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
1076 static const struct hda_verb stac927x_core_init[] = {
1077 /* set master volume and direct control */
1078 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1079 /* enable analog pc beep path */
1080 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
1084 static const struct hda_verb stac927x_volknob_core_init[] = {
1085 /* don't set delta bit */
1086 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
1087 /* enable analog pc beep path */
1088 {0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
1092 static const struct hda_verb stac9205_core_init[] = {
1093 /* set master volume and direct control */
1094 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1095 /* enable analog pc beep path */
1096 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
1100 static const struct snd_kcontrol_new stac92hd73xx_6ch_loopback =
1101 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3);
1103 static const struct snd_kcontrol_new stac92hd73xx_8ch_loopback =
1104 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4);
1106 static const struct snd_kcontrol_new stac92hd73xx_10ch_loopback =
1107 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5);
1109 static const struct snd_kcontrol_new stac92hd71bxx_loopback =
1110 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2);
1112 static const struct snd_kcontrol_new stac9205_loopback =
1113 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1);
1115 static const struct snd_kcontrol_new stac927x_loopback =
1116 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1);
1118 static const struct hda_pintbl ref9200_pin_configs[] = {
1119 { 0x08, 0x01c47010 },
1120 { 0x09, 0x01447010 },
1121 { 0x0d, 0x0221401f },
1122 { 0x0e, 0x01114010 },
1123 { 0x0f, 0x02a19020 },
1124 { 0x10, 0x01a19021 },
1125 { 0x11, 0x90100140 },
1126 { 0x12, 0x01813122 },
1130 static const struct hda_pintbl gateway9200_m4_pin_configs[] = {
1131 { 0x08, 0x400000fe },
1132 { 0x09, 0x404500f4 },
1133 { 0x0d, 0x400100f0 },
1134 { 0x0e, 0x90110010 },
1135 { 0x0f, 0x400100f1 },
1136 { 0x10, 0x02a1902e },
1137 { 0x11, 0x500000f2 },
1138 { 0x12, 0x500000f3 },
1142 static const struct hda_pintbl gateway9200_m4_2_pin_configs[] = {
1143 { 0x08, 0x400000fe },
1144 { 0x09, 0x404500f4 },
1145 { 0x0d, 0x400100f0 },
1146 { 0x0e, 0x90110010 },
1147 { 0x0f, 0x400100f1 },
1148 { 0x10, 0x02a1902e },
1149 { 0x11, 0x500000f2 },
1150 { 0x12, 0x500000f3 },
1155 STAC 9200 pin configs for
1156 102801A8
1157 102801DE
1158 102801E8
1160 static const struct hda_pintbl dell9200_d21_pin_configs[] = {
1161 { 0x08, 0x400001f0 },
1162 { 0x09, 0x400001f1 },
1163 { 0x0d, 0x02214030 },
1164 { 0x0e, 0x01014010 },
1165 { 0x0f, 0x02a19020 },
1166 { 0x10, 0x01a19021 },
1167 { 0x11, 0x90100140 },
1168 { 0x12, 0x01813122 },
1173 STAC 9200 pin configs for
1174 102801C0
1175 102801C1
1177 static const struct hda_pintbl dell9200_d22_pin_configs[] = {
1178 { 0x08, 0x400001f0 },
1179 { 0x09, 0x400001f1 },
1180 { 0x0d, 0x0221401f },
1181 { 0x0e, 0x01014010 },
1182 { 0x0f, 0x01813020 },
1183 { 0x10, 0x02a19021 },
1184 { 0x11, 0x90100140 },
1185 { 0x12, 0x400001f2 },
1190 STAC 9200 pin configs for
1191 102801C4 (Dell Dimension E310)
1192 102801C5
1193 102801C7
1194 102801D9
1195 102801DA
1196 102801E3
1198 static const struct hda_pintbl dell9200_d23_pin_configs[] = {
1199 { 0x08, 0x400001f0 },
1200 { 0x09, 0x400001f1 },
1201 { 0x0d, 0x0221401f },
1202 { 0x0e, 0x01014010 },
1203 { 0x0f, 0x01813020 },
1204 { 0x10, 0x01a19021 },
1205 { 0x11, 0x90100140 },
1206 { 0x12, 0x400001f2 },
1212 STAC 9200-32 pin configs for
1213 102801B5 (Dell Inspiron 630m)
1214 102801D8 (Dell Inspiron 640m)
1216 static const struct hda_pintbl dell9200_m21_pin_configs[] = {
1217 { 0x08, 0x40c003fa },
1218 { 0x09, 0x03441340 },
1219 { 0x0d, 0x0321121f },
1220 { 0x0e, 0x90170310 },
1221 { 0x0f, 0x408003fb },
1222 { 0x10, 0x03a11020 },
1223 { 0x11, 0x401003fc },
1224 { 0x12, 0x403003fd },
1229 STAC 9200-32 pin configs for
1230 102801C2 (Dell Latitude D620)
1231 102801C8
1232 102801CC (Dell Latitude D820)
1233 102801D4
1234 102801D6
1236 static const struct hda_pintbl dell9200_m22_pin_configs[] = {
1237 { 0x08, 0x40c003fa },
1238 { 0x09, 0x0144131f },
1239 { 0x0d, 0x0321121f },
1240 { 0x0e, 0x90170310 },
1241 { 0x0f, 0x90a70321 },
1242 { 0x10, 0x03a11020 },
1243 { 0x11, 0x401003fb },
1244 { 0x12, 0x40f000fc },
1249 STAC 9200-32 pin configs for
1250 102801CE (Dell XPS M1710)
1251 102801CF (Dell Precision M90)
1253 static const struct hda_pintbl dell9200_m23_pin_configs[] = {
1254 { 0x08, 0x40c003fa },
1255 { 0x09, 0x01441340 },
1256 { 0x0d, 0x0421421f },
1257 { 0x0e, 0x90170310 },
1258 { 0x0f, 0x408003fb },
1259 { 0x10, 0x04a1102e },
1260 { 0x11, 0x90170311 },
1261 { 0x12, 0x403003fc },
1266 STAC 9200-32 pin configs for
1267 102801C9
1268 102801CA
1269 102801CB (Dell Latitude 120L)
1270 102801D3
1272 static const struct hda_pintbl dell9200_m24_pin_configs[] = {
1273 { 0x08, 0x40c003fa },
1274 { 0x09, 0x404003fb },
1275 { 0x0d, 0x0321121f },
1276 { 0x0e, 0x90170310 },
1277 { 0x0f, 0x408003fc },
1278 { 0x10, 0x03a11020 },
1279 { 0x11, 0x401003fd },
1280 { 0x12, 0x403003fe },
1285 STAC 9200-32 pin configs for
1286 102801BD (Dell Inspiron E1505n)
1287 102801EE
1288 102801EF
1290 static const struct hda_pintbl dell9200_m25_pin_configs[] = {
1291 { 0x08, 0x40c003fa },
1292 { 0x09, 0x01441340 },
1293 { 0x0d, 0x0421121f },
1294 { 0x0e, 0x90170310 },
1295 { 0x0f, 0x408003fb },
1296 { 0x10, 0x04a11020 },
1297 { 0x11, 0x401003fc },
1298 { 0x12, 0x403003fd },
1303 STAC 9200-32 pin configs for
1304 102801F5 (Dell Inspiron 1501)
1305 102801F6
1307 static const struct hda_pintbl dell9200_m26_pin_configs[] = {
1308 { 0x08, 0x40c003fa },
1309 { 0x09, 0x404003fb },
1310 { 0x0d, 0x0421121f },
1311 { 0x0e, 0x90170310 },
1312 { 0x0f, 0x408003fc },
1313 { 0x10, 0x04a11020 },
1314 { 0x11, 0x401003fd },
1315 { 0x12, 0x403003fe },
1320 STAC 9200-32
1321 102801CD (Dell Inspiron E1705/9400)
1323 static const struct hda_pintbl dell9200_m27_pin_configs[] = {
1324 { 0x08, 0x40c003fa },
1325 { 0x09, 0x01441340 },
1326 { 0x0d, 0x0421121f },
1327 { 0x0e, 0x90170310 },
1328 { 0x0f, 0x90170310 },
1329 { 0x10, 0x04a11020 },
1330 { 0x11, 0x90170310 },
1331 { 0x12, 0x40f003fc },
1335 static const struct hda_pintbl oqo9200_pin_configs[] = {
1336 { 0x08, 0x40c000f0 },
1337 { 0x09, 0x404000f1 },
1338 { 0x0d, 0x0221121f },
1339 { 0x0e, 0x02211210 },
1340 { 0x0f, 0x90170111 },
1341 { 0x10, 0x90a70120 },
1342 { 0x11, 0x400000f2 },
1343 { 0x12, 0x400000f3 },
1348 * STAC 92HD700
1349 * 18881000 Amigaone X1000
1351 static const struct hda_pintbl nemo_pin_configs[] = {
1352 { 0x0a, 0x02214020 }, /* Front panel HP socket */
1353 { 0x0b, 0x02a19080 }, /* Front Mic */
1354 { 0x0c, 0x0181304e }, /* Line in */
1355 { 0x0d, 0x01014010 }, /* Line out */
1356 { 0x0e, 0x01a19040 }, /* Rear Mic */
1357 { 0x0f, 0x01011012 }, /* Rear speakers */
1358 { 0x10, 0x01016011 }, /* Center speaker */
1359 { 0x11, 0x01012014 }, /* Side speakers (7.1) */
1360 { 0x12, 0x103301f0 }, /* Motherboard CD line in connector */
1361 { 0x13, 0x411111f0 }, /* Unused */
1362 { 0x14, 0x411111f0 }, /* Unused */
1363 { 0x21, 0x01442170 }, /* S/PDIF line out */
1364 { 0x22, 0x411111f0 }, /* Unused */
1365 { 0x23, 0x411111f0 }, /* Unused */
1369 static void stac9200_fixup_panasonic(struct hda_codec *codec,
1370 const struct hda_fixup *fix, int action)
1372 struct sigmatel_spec *spec = codec->spec;
1374 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1375 spec->gpio_mask = spec->gpio_dir = 0x09;
1376 spec->gpio_data = 0x00;
1377 /* CF-74 has no headphone detection, and the driver should *NOT*
1378 * do detection and HP/speaker toggle because the hardware does it.
1380 spec->gen.suppress_auto_mute = 1;
1385 static const struct hda_fixup stac9200_fixups[] = {
1386 [STAC_REF] = {
1387 .type = HDA_FIXUP_PINS,
1388 .v.pins = ref9200_pin_configs,
1390 [STAC_9200_OQO] = {
1391 .type = HDA_FIXUP_PINS,
1392 .v.pins = oqo9200_pin_configs,
1393 .chained = true,
1394 .chain_id = STAC_9200_EAPD_INIT,
1396 [STAC_9200_DELL_D21] = {
1397 .type = HDA_FIXUP_PINS,
1398 .v.pins = dell9200_d21_pin_configs,
1400 [STAC_9200_DELL_D22] = {
1401 .type = HDA_FIXUP_PINS,
1402 .v.pins = dell9200_d22_pin_configs,
1404 [STAC_9200_DELL_D23] = {
1405 .type = HDA_FIXUP_PINS,
1406 .v.pins = dell9200_d23_pin_configs,
1408 [STAC_9200_DELL_M21] = {
1409 .type = HDA_FIXUP_PINS,
1410 .v.pins = dell9200_m21_pin_configs,
1412 [STAC_9200_DELL_M22] = {
1413 .type = HDA_FIXUP_PINS,
1414 .v.pins = dell9200_m22_pin_configs,
1416 [STAC_9200_DELL_M23] = {
1417 .type = HDA_FIXUP_PINS,
1418 .v.pins = dell9200_m23_pin_configs,
1420 [STAC_9200_DELL_M24] = {
1421 .type = HDA_FIXUP_PINS,
1422 .v.pins = dell9200_m24_pin_configs,
1424 [STAC_9200_DELL_M25] = {
1425 .type = HDA_FIXUP_PINS,
1426 .v.pins = dell9200_m25_pin_configs,
1428 [STAC_9200_DELL_M26] = {
1429 .type = HDA_FIXUP_PINS,
1430 .v.pins = dell9200_m26_pin_configs,
1432 [STAC_9200_DELL_M27] = {
1433 .type = HDA_FIXUP_PINS,
1434 .v.pins = dell9200_m27_pin_configs,
1436 [STAC_9200_M4] = {
1437 .type = HDA_FIXUP_PINS,
1438 .v.pins = gateway9200_m4_pin_configs,
1439 .chained = true,
1440 .chain_id = STAC_9200_EAPD_INIT,
1442 [STAC_9200_M4_2] = {
1443 .type = HDA_FIXUP_PINS,
1444 .v.pins = gateway9200_m4_2_pin_configs,
1445 .chained = true,
1446 .chain_id = STAC_9200_EAPD_INIT,
1448 [STAC_9200_PANASONIC] = {
1449 .type = HDA_FIXUP_FUNC,
1450 .v.func = stac9200_fixup_panasonic,
1452 [STAC_9200_EAPD_INIT] = {
1453 .type = HDA_FIXUP_VERBS,
1454 .v.verbs = (const struct hda_verb[]) {
1455 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1461 static const struct hda_model_fixup stac9200_models[] = {
1462 { .id = STAC_REF, .name = "ref" },
1463 { .id = STAC_9200_OQO, .name = "oqo" },
1464 { .id = STAC_9200_DELL_D21, .name = "dell-d21" },
1465 { .id = STAC_9200_DELL_D22, .name = "dell-d22" },
1466 { .id = STAC_9200_DELL_D23, .name = "dell-d23" },
1467 { .id = STAC_9200_DELL_M21, .name = "dell-m21" },
1468 { .id = STAC_9200_DELL_M22, .name = "dell-m22" },
1469 { .id = STAC_9200_DELL_M23, .name = "dell-m23" },
1470 { .id = STAC_9200_DELL_M24, .name = "dell-m24" },
1471 { .id = STAC_9200_DELL_M25, .name = "dell-m25" },
1472 { .id = STAC_9200_DELL_M26, .name = "dell-m26" },
1473 { .id = STAC_9200_DELL_M27, .name = "dell-m27" },
1474 { .id = STAC_9200_M4, .name = "gateway-m4" },
1475 { .id = STAC_9200_M4_2, .name = "gateway-m4-2" },
1476 { .id = STAC_9200_PANASONIC, .name = "panasonic" },
1480 static const struct snd_pci_quirk stac9200_fixup_tbl[] = {
1481 /* SigmaTel reference board */
1482 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1483 "DFI LanParty", STAC_REF),
1484 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
1485 "DFI LanParty", STAC_REF),
1486 /* Dell laptops have BIOS problem */
1487 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
1488 "unknown Dell", STAC_9200_DELL_D21),
1489 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
1490 "Dell Inspiron 630m", STAC_9200_DELL_M21),
1491 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
1492 "Dell Inspiron E1505n", STAC_9200_DELL_M25),
1493 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
1494 "unknown Dell", STAC_9200_DELL_D22),
1495 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
1496 "unknown Dell", STAC_9200_DELL_D22),
1497 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
1498 "Dell Latitude D620", STAC_9200_DELL_M22),
1499 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
1500 "unknown Dell", STAC_9200_DELL_D23),
1501 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
1502 "unknown Dell", STAC_9200_DELL_D23),
1503 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
1504 "unknown Dell", STAC_9200_DELL_M22),
1505 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
1506 "unknown Dell", STAC_9200_DELL_M24),
1507 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
1508 "unknown Dell", STAC_9200_DELL_M24),
1509 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
1510 "Dell Latitude 120L", STAC_9200_DELL_M24),
1511 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
1512 "Dell Latitude D820", STAC_9200_DELL_M22),
1513 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
1514 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
1515 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
1516 "Dell XPS M1710", STAC_9200_DELL_M23),
1517 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
1518 "Dell Precision M90", STAC_9200_DELL_M23),
1519 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
1520 "unknown Dell", STAC_9200_DELL_M22),
1521 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
1522 "unknown Dell", STAC_9200_DELL_M22),
1523 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
1524 "unknown Dell", STAC_9200_DELL_M22),
1525 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
1526 "Dell Inspiron 640m", STAC_9200_DELL_M21),
1527 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
1528 "unknown Dell", STAC_9200_DELL_D23),
1529 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
1530 "unknown Dell", STAC_9200_DELL_D23),
1531 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
1532 "unknown Dell", STAC_9200_DELL_D21),
1533 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
1534 "unknown Dell", STAC_9200_DELL_D23),
1535 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
1536 "unknown Dell", STAC_9200_DELL_D21),
1537 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
1538 "unknown Dell", STAC_9200_DELL_M25),
1539 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
1540 "unknown Dell", STAC_9200_DELL_M25),
1541 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
1542 "Dell Inspiron 1501", STAC_9200_DELL_M26),
1543 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
1544 "unknown Dell", STAC_9200_DELL_M26),
1545 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0201,
1546 "Dell Latitude D430", STAC_9200_DELL_M22),
1547 /* Panasonic */
1548 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC),
1549 /* Gateway machines needs EAPD to be set on resume */
1550 SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_M4),
1551 SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", STAC_9200_M4_2),
1552 SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", STAC_9200_M4_2),
1553 /* OQO Mobile */
1554 SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO),
1555 {} /* terminator */
1558 static const struct hda_pintbl ref925x_pin_configs[] = {
1559 { 0x07, 0x40c003f0 },
1560 { 0x08, 0x424503f2 },
1561 { 0x0a, 0x01813022 },
1562 { 0x0b, 0x02a19021 },
1563 { 0x0c, 0x90a70320 },
1564 { 0x0d, 0x02214210 },
1565 { 0x10, 0x01019020 },
1566 { 0x11, 0x9033032e },
1570 static const struct hda_pintbl stac925xM1_pin_configs[] = {
1571 { 0x07, 0x40c003f4 },
1572 { 0x08, 0x424503f2 },
1573 { 0x0a, 0x400000f3 },
1574 { 0x0b, 0x02a19020 },
1575 { 0x0c, 0x40a000f0 },
1576 { 0x0d, 0x90100210 },
1577 { 0x10, 0x400003f1 },
1578 { 0x11, 0x9033032e },
1582 static const struct hda_pintbl stac925xM1_2_pin_configs[] = {
1583 { 0x07, 0x40c003f4 },
1584 { 0x08, 0x424503f2 },
1585 { 0x0a, 0x400000f3 },
1586 { 0x0b, 0x02a19020 },
1587 { 0x0c, 0x40a000f0 },
1588 { 0x0d, 0x90100210 },
1589 { 0x10, 0x400003f1 },
1590 { 0x11, 0x9033032e },
1594 static const struct hda_pintbl stac925xM2_pin_configs[] = {
1595 { 0x07, 0x40c003f4 },
1596 { 0x08, 0x424503f2 },
1597 { 0x0a, 0x400000f3 },
1598 { 0x0b, 0x02a19020 },
1599 { 0x0c, 0x40a000f0 },
1600 { 0x0d, 0x90100210 },
1601 { 0x10, 0x400003f1 },
1602 { 0x11, 0x9033032e },
1606 static const struct hda_pintbl stac925xM2_2_pin_configs[] = {
1607 { 0x07, 0x40c003f4 },
1608 { 0x08, 0x424503f2 },
1609 { 0x0a, 0x400000f3 },
1610 { 0x0b, 0x02a19020 },
1611 { 0x0c, 0x40a000f0 },
1612 { 0x0d, 0x90100210 },
1613 { 0x10, 0x400003f1 },
1614 { 0x11, 0x9033032e },
1618 static const struct hda_pintbl stac925xM3_pin_configs[] = {
1619 { 0x07, 0x40c003f4 },
1620 { 0x08, 0x424503f2 },
1621 { 0x0a, 0x400000f3 },
1622 { 0x0b, 0x02a19020 },
1623 { 0x0c, 0x40a000f0 },
1624 { 0x0d, 0x90100210 },
1625 { 0x10, 0x400003f1 },
1626 { 0x11, 0x503303f3 },
1630 static const struct hda_pintbl stac925xM5_pin_configs[] = {
1631 { 0x07, 0x40c003f4 },
1632 { 0x08, 0x424503f2 },
1633 { 0x0a, 0x400000f3 },
1634 { 0x0b, 0x02a19020 },
1635 { 0x0c, 0x40a000f0 },
1636 { 0x0d, 0x90100210 },
1637 { 0x10, 0x400003f1 },
1638 { 0x11, 0x9033032e },
1642 static const struct hda_pintbl stac925xM6_pin_configs[] = {
1643 { 0x07, 0x40c003f4 },
1644 { 0x08, 0x424503f2 },
1645 { 0x0a, 0x400000f3 },
1646 { 0x0b, 0x02a19020 },
1647 { 0x0c, 0x40a000f0 },
1648 { 0x0d, 0x90100210 },
1649 { 0x10, 0x400003f1 },
1650 { 0x11, 0x90330320 },
1654 static const struct hda_fixup stac925x_fixups[] = {
1655 [STAC_REF] = {
1656 .type = HDA_FIXUP_PINS,
1657 .v.pins = ref925x_pin_configs,
1659 [STAC_M1] = {
1660 .type = HDA_FIXUP_PINS,
1661 .v.pins = stac925xM1_pin_configs,
1663 [STAC_M1_2] = {
1664 .type = HDA_FIXUP_PINS,
1665 .v.pins = stac925xM1_2_pin_configs,
1667 [STAC_M2] = {
1668 .type = HDA_FIXUP_PINS,
1669 .v.pins = stac925xM2_pin_configs,
1671 [STAC_M2_2] = {
1672 .type = HDA_FIXUP_PINS,
1673 .v.pins = stac925xM2_2_pin_configs,
1675 [STAC_M3] = {
1676 .type = HDA_FIXUP_PINS,
1677 .v.pins = stac925xM3_pin_configs,
1679 [STAC_M5] = {
1680 .type = HDA_FIXUP_PINS,
1681 .v.pins = stac925xM5_pin_configs,
1683 [STAC_M6] = {
1684 .type = HDA_FIXUP_PINS,
1685 .v.pins = stac925xM6_pin_configs,
1689 static const struct hda_model_fixup stac925x_models[] = {
1690 { .id = STAC_REF, .name = "ref" },
1691 { .id = STAC_M1, .name = "m1" },
1692 { .id = STAC_M1_2, .name = "m1-2" },
1693 { .id = STAC_M2, .name = "m2" },
1694 { .id = STAC_M2_2, .name = "m2-2" },
1695 { .id = STAC_M3, .name = "m3" },
1696 { .id = STAC_M5, .name = "m5" },
1697 { .id = STAC_M6, .name = "m6" },
1701 static const struct snd_pci_quirk stac925x_fixup_tbl[] = {
1702 /* SigmaTel reference board */
1703 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
1704 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF),
1705 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
1707 /* Default table for unknown ID */
1708 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2),
1710 /* gateway machines are checked via codec ssid */
1711 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2),
1712 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5),
1713 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1),
1714 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_M2),
1715 SND_PCI_QUIRK(0x107b, 0x0367, "Gateway MX6453", STAC_M1_2),
1716 /* Not sure about the brand name for those */
1717 SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M1),
1718 SND_PCI_QUIRK(0x107b, 0x0507, "Gateway mobile", STAC_M3),
1719 SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M6),
1720 SND_PCI_QUIRK(0x107b, 0x0685, "Gateway mobile", STAC_M2_2),
1721 {} /* terminator */
1724 static const struct hda_pintbl ref92hd73xx_pin_configs[] = {
1725 { 0x0a, 0x02214030 },
1726 { 0x0b, 0x02a19040 },
1727 { 0x0c, 0x01a19020 },
1728 { 0x0d, 0x02214030 },
1729 { 0x0e, 0x0181302e },
1730 { 0x0f, 0x01014010 },
1731 { 0x10, 0x01014020 },
1732 { 0x11, 0x01014030 },
1733 { 0x12, 0x02319040 },
1734 { 0x13, 0x90a000f0 },
1735 { 0x14, 0x90a000f0 },
1736 { 0x22, 0x01452050 },
1737 { 0x23, 0x01452050 },
1741 static const struct hda_pintbl dell_m6_pin_configs[] = {
1742 { 0x0a, 0x0321101f },
1743 { 0x0b, 0x4f00000f },
1744 { 0x0c, 0x4f0000f0 },
1745 { 0x0d, 0x90170110 },
1746 { 0x0e, 0x03a11020 },
1747 { 0x0f, 0x0321101f },
1748 { 0x10, 0x4f0000f0 },
1749 { 0x11, 0x4f0000f0 },
1750 { 0x12, 0x4f0000f0 },
1751 { 0x13, 0x90a60160 },
1752 { 0x14, 0x4f0000f0 },
1753 { 0x22, 0x4f0000f0 },
1754 { 0x23, 0x4f0000f0 },
1758 static const struct hda_pintbl alienware_m17x_pin_configs[] = {
1759 { 0x0a, 0x0321101f },
1760 { 0x0b, 0x0321101f },
1761 { 0x0c, 0x03a11020 },
1762 { 0x0d, 0x03014020 },
1763 { 0x0e, 0x90170110 },
1764 { 0x0f, 0x4f0000f0 },
1765 { 0x10, 0x4f0000f0 },
1766 { 0x11, 0x4f0000f0 },
1767 { 0x12, 0x4f0000f0 },
1768 { 0x13, 0x90a60160 },
1769 { 0x14, 0x4f0000f0 },
1770 { 0x22, 0x4f0000f0 },
1771 { 0x23, 0x904601b0 },
1775 static const struct hda_pintbl intel_dg45id_pin_configs[] = {
1776 { 0x0a, 0x02214230 },
1777 { 0x0b, 0x02A19240 },
1778 { 0x0c, 0x01013214 },
1779 { 0x0d, 0x01014210 },
1780 { 0x0e, 0x01A19250 },
1781 { 0x0f, 0x01011212 },
1782 { 0x10, 0x01016211 },
1786 static const struct hda_pintbl stac92hd89xx_hp_front_jack_pin_configs[] = {
1787 { 0x0a, 0x02214030 },
1788 { 0x0b, 0x02A19010 },
1792 static const struct hda_pintbl stac92hd89xx_hp_z1_g2_right_mic_jack_pin_configs[] = {
1793 { 0x0e, 0x400000f0 },
1797 static void stac92hd73xx_fixup_ref(struct hda_codec *codec,
1798 const struct hda_fixup *fix, int action)
1800 struct sigmatel_spec *spec = codec->spec;
1802 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1803 return;
1805 snd_hda_apply_pincfgs(codec, ref92hd73xx_pin_configs);
1806 spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0;
1809 static void stac92hd73xx_fixup_dell(struct hda_codec *codec)
1811 struct sigmatel_spec *spec = codec->spec;
1813 snd_hda_apply_pincfgs(codec, dell_m6_pin_configs);
1814 spec->eapd_switch = 0;
1817 static void stac92hd73xx_fixup_dell_eq(struct hda_codec *codec,
1818 const struct hda_fixup *fix, int action)
1820 struct sigmatel_spec *spec = codec->spec;
1822 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1823 return;
1825 stac92hd73xx_fixup_dell(codec);
1826 snd_hda_add_verbs(codec, dell_eq_core_init);
1827 spec->volknob_init = 1;
1830 /* Analog Mics */
1831 static void stac92hd73xx_fixup_dell_m6_amic(struct hda_codec *codec,
1832 const struct hda_fixup *fix, int action)
1834 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1835 return;
1837 stac92hd73xx_fixup_dell(codec);
1838 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
1841 /* Digital Mics */
1842 static void stac92hd73xx_fixup_dell_m6_dmic(struct hda_codec *codec,
1843 const struct hda_fixup *fix, int action)
1845 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1846 return;
1848 stac92hd73xx_fixup_dell(codec);
1849 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
1852 /* Both */
1853 static void stac92hd73xx_fixup_dell_m6_both(struct hda_codec *codec,
1854 const struct hda_fixup *fix, int action)
1856 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1857 return;
1859 stac92hd73xx_fixup_dell(codec);
1860 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
1861 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
1864 static void stac92hd73xx_fixup_alienware_m17x(struct hda_codec *codec,
1865 const struct hda_fixup *fix, int action)
1867 struct sigmatel_spec *spec = codec->spec;
1869 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1870 return;
1872 snd_hda_apply_pincfgs(codec, alienware_m17x_pin_configs);
1873 spec->eapd_switch = 0;
1876 static void stac92hd73xx_fixup_no_jd(struct hda_codec *codec,
1877 const struct hda_fixup *fix, int action)
1879 if (action == HDA_FIXUP_ACT_PRE_PROBE)
1880 codec->no_jack_detect = 1;
1884 static void stac92hd73xx_disable_automute(struct hda_codec *codec,
1885 const struct hda_fixup *fix, int action)
1887 struct sigmatel_spec *spec = codec->spec;
1889 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1890 return;
1892 spec->gen.suppress_auto_mute = 1;
1895 static const struct hda_fixup stac92hd73xx_fixups[] = {
1896 [STAC_92HD73XX_REF] = {
1897 .type = HDA_FIXUP_FUNC,
1898 .v.func = stac92hd73xx_fixup_ref,
1900 [STAC_DELL_M6_AMIC] = {
1901 .type = HDA_FIXUP_FUNC,
1902 .v.func = stac92hd73xx_fixup_dell_m6_amic,
1904 [STAC_DELL_M6_DMIC] = {
1905 .type = HDA_FIXUP_FUNC,
1906 .v.func = stac92hd73xx_fixup_dell_m6_dmic,
1908 [STAC_DELL_M6_BOTH] = {
1909 .type = HDA_FIXUP_FUNC,
1910 .v.func = stac92hd73xx_fixup_dell_m6_both,
1912 [STAC_DELL_EQ] = {
1913 .type = HDA_FIXUP_FUNC,
1914 .v.func = stac92hd73xx_fixup_dell_eq,
1916 [STAC_ALIENWARE_M17X] = {
1917 .type = HDA_FIXUP_FUNC,
1918 .v.func = stac92hd73xx_fixup_alienware_m17x,
1920 [STAC_ELO_VUPOINT_15MX] = {
1921 .type = HDA_FIXUP_FUNC,
1922 .v.func = stac92hd73xx_disable_automute,
1924 [STAC_92HD73XX_INTEL] = {
1925 .type = HDA_FIXUP_PINS,
1926 .v.pins = intel_dg45id_pin_configs,
1928 [STAC_92HD73XX_NO_JD] = {
1929 .type = HDA_FIXUP_FUNC,
1930 .v.func = stac92hd73xx_fixup_no_jd,
1932 [STAC_92HD89XX_HP_FRONT_JACK] = {
1933 .type = HDA_FIXUP_PINS,
1934 .v.pins = stac92hd89xx_hp_front_jack_pin_configs,
1936 [STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK] = {
1937 .type = HDA_FIXUP_PINS,
1938 .v.pins = stac92hd89xx_hp_z1_g2_right_mic_jack_pin_configs,
1940 [STAC_92HD73XX_ASUS_MOBO] = {
1941 .type = HDA_FIXUP_PINS,
1942 .v.pins = (const struct hda_pintbl[]) {
1943 /* enable 5.1 and SPDIF out */
1944 { 0x0c, 0x01014411 },
1945 { 0x0d, 0x01014410 },
1946 { 0x0e, 0x01014412 },
1947 { 0x22, 0x014b1180 },
1953 static const struct hda_model_fixup stac92hd73xx_models[] = {
1954 { .id = STAC_92HD73XX_NO_JD, .name = "no-jd" },
1955 { .id = STAC_92HD73XX_REF, .name = "ref" },
1956 { .id = STAC_92HD73XX_INTEL, .name = "intel" },
1957 { .id = STAC_DELL_M6_AMIC, .name = "dell-m6-amic" },
1958 { .id = STAC_DELL_M6_DMIC, .name = "dell-m6-dmic" },
1959 { .id = STAC_DELL_M6_BOTH, .name = "dell-m6" },
1960 { .id = STAC_DELL_EQ, .name = "dell-eq" },
1961 { .id = STAC_ALIENWARE_M17X, .name = "alienware" },
1962 { .id = STAC_ELO_VUPOINT_15MX, .name = "elo-vupoint-15mx" },
1963 { .id = STAC_92HD73XX_ASUS_MOBO, .name = "asus-mobo" },
1967 static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = {
1968 /* SigmaTel reference board */
1969 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1970 "DFI LanParty", STAC_92HD73XX_REF),
1971 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
1972 "DFI LanParty", STAC_92HD73XX_REF),
1973 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5002,
1974 "Intel DG45ID", STAC_92HD73XX_INTEL),
1975 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5003,
1976 "Intel DG45FC", STAC_92HD73XX_INTEL),
1977 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254,
1978 "Dell Studio 1535", STAC_DELL_M6_DMIC),
1979 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255,
1980 "unknown Dell", STAC_DELL_M6_DMIC),
1981 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256,
1982 "unknown Dell", STAC_DELL_M6_BOTH),
1983 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257,
1984 "unknown Dell", STAC_DELL_M6_BOTH),
1985 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e,
1986 "unknown Dell", STAC_DELL_M6_AMIC),
1987 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f,
1988 "unknown Dell", STAC_DELL_M6_AMIC),
1989 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271,
1990 "unknown Dell", STAC_DELL_M6_DMIC),
1991 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0272,
1992 "unknown Dell", STAC_DELL_M6_DMIC),
1993 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f,
1994 "Dell Studio 1537", STAC_DELL_M6_DMIC),
1995 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a0,
1996 "Dell Studio 17", STAC_DELL_M6_DMIC),
1997 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02be,
1998 "Dell Studio 1555", STAC_DELL_M6_DMIC),
1999 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd,
2000 "Dell Studio 1557", STAC_DELL_M6_DMIC),
2001 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe,
2002 "Dell Studio XPS 1645", STAC_DELL_M6_DMIC),
2003 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413,
2004 "Dell Studio 1558", STAC_DELL_M6_DMIC),
2005 /* codec SSID matching */
2006 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1,
2007 "Alienware M17x", STAC_ALIENWARE_M17X),
2008 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
2009 "Alienware M17x", STAC_ALIENWARE_M17X),
2010 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490,
2011 "Alienware M17x R3", STAC_DELL_EQ),
2012 SND_PCI_QUIRK(0x1059, 0x1011,
2013 "ELO VuPoint 15MX", STAC_ELO_VUPOINT_15MX),
2014 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1927,
2015 "HP Z1 G2", STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK),
2016 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2b17,
2017 "unknown HP", STAC_92HD89XX_HP_FRONT_JACK),
2018 SND_PCI_QUIRK(PCI_VENDOR_ID_ASUSTEK, 0x83f8, "ASUS AT4NM10",
2019 STAC_92HD73XX_ASUS_MOBO),
2020 {} /* terminator */
2023 static const struct hda_pintbl ref92hd83xxx_pin_configs[] = {
2024 { 0x0a, 0x02214030 },
2025 { 0x0b, 0x02211010 },
2026 { 0x0c, 0x02a19020 },
2027 { 0x0d, 0x02170130 },
2028 { 0x0e, 0x01014050 },
2029 { 0x0f, 0x01819040 },
2030 { 0x10, 0x01014020 },
2031 { 0x11, 0x90a3014e },
2032 { 0x1f, 0x01451160 },
2033 { 0x20, 0x98560170 },
2037 static const struct hda_pintbl dell_s14_pin_configs[] = {
2038 { 0x0a, 0x0221403f },
2039 { 0x0b, 0x0221101f },
2040 { 0x0c, 0x02a19020 },
2041 { 0x0d, 0x90170110 },
2042 { 0x0e, 0x40f000f0 },
2043 { 0x0f, 0x40f000f0 },
2044 { 0x10, 0x40f000f0 },
2045 { 0x11, 0x90a60160 },
2046 { 0x1f, 0x40f000f0 },
2047 { 0x20, 0x40f000f0 },
2051 static const struct hda_pintbl dell_vostro_3500_pin_configs[] = {
2052 { 0x0a, 0x02a11020 },
2053 { 0x0b, 0x0221101f },
2054 { 0x0c, 0x400000f0 },
2055 { 0x0d, 0x90170110 },
2056 { 0x0e, 0x400000f1 },
2057 { 0x0f, 0x400000f2 },
2058 { 0x10, 0x400000f3 },
2059 { 0x11, 0x90a60160 },
2060 { 0x1f, 0x400000f4 },
2061 { 0x20, 0x400000f5 },
2065 static const struct hda_pintbl hp_dv7_4000_pin_configs[] = {
2066 { 0x0a, 0x03a12050 },
2067 { 0x0b, 0x0321201f },
2068 { 0x0c, 0x40f000f0 },
2069 { 0x0d, 0x90170110 },
2070 { 0x0e, 0x40f000f0 },
2071 { 0x0f, 0x40f000f0 },
2072 { 0x10, 0x90170110 },
2073 { 0x11, 0xd5a30140 },
2074 { 0x1f, 0x40f000f0 },
2075 { 0x20, 0x40f000f0 },
2079 static const struct hda_pintbl hp_zephyr_pin_configs[] = {
2080 { 0x0a, 0x01813050 },
2081 { 0x0b, 0x0421201f },
2082 { 0x0c, 0x04a1205e },
2083 { 0x0d, 0x96130310 },
2084 { 0x0e, 0x96130310 },
2085 { 0x0f, 0x0101401f },
2086 { 0x10, 0x1111611f },
2087 { 0x11, 0xd5a30130 },
2091 static const struct hda_pintbl hp_cNB11_intquad_pin_configs[] = {
2092 { 0x0a, 0x40f000f0 },
2093 { 0x0b, 0x0221101f },
2094 { 0x0c, 0x02a11020 },
2095 { 0x0d, 0x92170110 },
2096 { 0x0e, 0x40f000f0 },
2097 { 0x0f, 0x92170110 },
2098 { 0x10, 0x40f000f0 },
2099 { 0x11, 0xd5a30130 },
2100 { 0x1f, 0x40f000f0 },
2101 { 0x20, 0x40f000f0 },
2105 static void stac92hd83xxx_fixup_hp(struct hda_codec *codec,
2106 const struct hda_fixup *fix, int action)
2108 struct sigmatel_spec *spec = codec->spec;
2110 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2111 return;
2113 if (hp_bnb2011_with_dock(codec)) {
2114 snd_hda_codec_set_pincfg(codec, 0xa, 0x2101201f);
2115 snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);
2118 if (find_mute_led_cfg(codec, spec->default_polarity))
2119 codec_dbg(codec, "mute LED gpio %d polarity %d\n",
2120 spec->gpio_led,
2121 spec->gpio_led_polarity);
2123 /* allow auto-switching of dock line-in */
2124 spec->gen.line_in_auto_switch = true;
2127 static void stac92hd83xxx_fixup_hp_zephyr(struct hda_codec *codec,
2128 const struct hda_fixup *fix, int action)
2130 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2131 return;
2133 snd_hda_apply_pincfgs(codec, hp_zephyr_pin_configs);
2134 snd_hda_add_verbs(codec, stac92hd83xxx_hp_zephyr_init);
2137 static void stac92hd83xxx_fixup_hp_led(struct hda_codec *codec,
2138 const struct hda_fixup *fix, int action)
2140 struct sigmatel_spec *spec = codec->spec;
2142 if (action == HDA_FIXUP_ACT_PRE_PROBE)
2143 spec->default_polarity = 0;
2146 static void stac92hd83xxx_fixup_hp_inv_led(struct hda_codec *codec,
2147 const struct hda_fixup *fix, int action)
2149 struct sigmatel_spec *spec = codec->spec;
2151 if (action == HDA_FIXUP_ACT_PRE_PROBE)
2152 spec->default_polarity = 1;
2155 static void stac92hd83xxx_fixup_hp_mic_led(struct hda_codec *codec,
2156 const struct hda_fixup *fix, int action)
2158 struct sigmatel_spec *spec = codec->spec;
2160 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2161 spec->mic_mute_led_gpio = 0x08; /* GPIO3 */
2162 #ifdef CONFIG_PM
2163 /* resetting controller clears GPIO, so we need to keep on */
2164 codec->core.power_caps &= ~AC_PWRST_CLKSTOP;
2165 #endif
2169 static void stac92hd83xxx_fixup_hp_led_gpio10(struct hda_codec *codec,
2170 const struct hda_fixup *fix, int action)
2172 struct sigmatel_spec *spec = codec->spec;
2174 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2175 spec->gpio_led = 0x10; /* GPIO4 */
2176 spec->default_polarity = 0;
2180 static void stac92hd83xxx_fixup_headset_jack(struct hda_codec *codec,
2181 const struct hda_fixup *fix, int action)
2183 struct sigmatel_spec *spec = codec->spec;
2185 if (action == HDA_FIXUP_ACT_PRE_PROBE)
2186 spec->headset_jack = 1;
2189 static void stac92hd83xxx_fixup_gpio10_eapd(struct hda_codec *codec,
2190 const struct hda_fixup *fix,
2191 int action)
2193 struct sigmatel_spec *spec = codec->spec;
2195 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2196 return;
2197 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir =
2198 spec->gpio_data = 0x10;
2199 spec->eapd_switch = 0;
2202 static void hp_envy_ts_fixup_dac_bind(struct hda_codec *codec,
2203 const struct hda_fixup *fix,
2204 int action)
2206 struct sigmatel_spec *spec = codec->spec;
2207 static hda_nid_t preferred_pairs[] = {
2208 0xd, 0x13,
2212 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2213 return;
2215 spec->gen.preferred_dacs = preferred_pairs;
2218 static const struct hda_verb hp_bnb13_eq_verbs[] = {
2219 /* 44.1KHz base */
2220 { 0x22, 0x7A6, 0x3E },
2221 { 0x22, 0x7A7, 0x68 },
2222 { 0x22, 0x7A8, 0x17 },
2223 { 0x22, 0x7A9, 0x3E },
2224 { 0x22, 0x7AA, 0x68 },
2225 { 0x22, 0x7AB, 0x17 },
2226 { 0x22, 0x7AC, 0x00 },
2227 { 0x22, 0x7AD, 0x80 },
2228 { 0x22, 0x7A6, 0x83 },
2229 { 0x22, 0x7A7, 0x2F },
2230 { 0x22, 0x7A8, 0xD1 },
2231 { 0x22, 0x7A9, 0x83 },
2232 { 0x22, 0x7AA, 0x2F },
2233 { 0x22, 0x7AB, 0xD1 },
2234 { 0x22, 0x7AC, 0x01 },
2235 { 0x22, 0x7AD, 0x80 },
2236 { 0x22, 0x7A6, 0x3E },
2237 { 0x22, 0x7A7, 0x68 },
2238 { 0x22, 0x7A8, 0x17 },
2239 { 0x22, 0x7A9, 0x3E },
2240 { 0x22, 0x7AA, 0x68 },
2241 { 0x22, 0x7AB, 0x17 },
2242 { 0x22, 0x7AC, 0x02 },
2243 { 0x22, 0x7AD, 0x80 },
2244 { 0x22, 0x7A6, 0x7C },
2245 { 0x22, 0x7A7, 0xC6 },
2246 { 0x22, 0x7A8, 0x0C },
2247 { 0x22, 0x7A9, 0x7C },
2248 { 0x22, 0x7AA, 0xC6 },
2249 { 0x22, 0x7AB, 0x0C },
2250 { 0x22, 0x7AC, 0x03 },
2251 { 0x22, 0x7AD, 0x80 },
2252 { 0x22, 0x7A6, 0xC3 },
2253 { 0x22, 0x7A7, 0x25 },
2254 { 0x22, 0x7A8, 0xAF },
2255 { 0x22, 0x7A9, 0xC3 },
2256 { 0x22, 0x7AA, 0x25 },
2257 { 0x22, 0x7AB, 0xAF },
2258 { 0x22, 0x7AC, 0x04 },
2259 { 0x22, 0x7AD, 0x80 },
2260 { 0x22, 0x7A6, 0x3E },
2261 { 0x22, 0x7A7, 0x85 },
2262 { 0x22, 0x7A8, 0x73 },
2263 { 0x22, 0x7A9, 0x3E },
2264 { 0x22, 0x7AA, 0x85 },
2265 { 0x22, 0x7AB, 0x73 },
2266 { 0x22, 0x7AC, 0x05 },
2267 { 0x22, 0x7AD, 0x80 },
2268 { 0x22, 0x7A6, 0x85 },
2269 { 0x22, 0x7A7, 0x39 },
2270 { 0x22, 0x7A8, 0xC7 },
2271 { 0x22, 0x7A9, 0x85 },
2272 { 0x22, 0x7AA, 0x39 },
2273 { 0x22, 0x7AB, 0xC7 },
2274 { 0x22, 0x7AC, 0x06 },
2275 { 0x22, 0x7AD, 0x80 },
2276 { 0x22, 0x7A6, 0x3C },
2277 { 0x22, 0x7A7, 0x90 },
2278 { 0x22, 0x7A8, 0xB0 },
2279 { 0x22, 0x7A9, 0x3C },
2280 { 0x22, 0x7AA, 0x90 },
2281 { 0x22, 0x7AB, 0xB0 },
2282 { 0x22, 0x7AC, 0x07 },
2283 { 0x22, 0x7AD, 0x80 },
2284 { 0x22, 0x7A6, 0x7A },
2285 { 0x22, 0x7A7, 0xC6 },
2286 { 0x22, 0x7A8, 0x39 },
2287 { 0x22, 0x7A9, 0x7A },
2288 { 0x22, 0x7AA, 0xC6 },
2289 { 0x22, 0x7AB, 0x39 },
2290 { 0x22, 0x7AC, 0x08 },
2291 { 0x22, 0x7AD, 0x80 },
2292 { 0x22, 0x7A6, 0xC4 },
2293 { 0x22, 0x7A7, 0xE9 },
2294 { 0x22, 0x7A8, 0xDC },
2295 { 0x22, 0x7A9, 0xC4 },
2296 { 0x22, 0x7AA, 0xE9 },
2297 { 0x22, 0x7AB, 0xDC },
2298 { 0x22, 0x7AC, 0x09 },
2299 { 0x22, 0x7AD, 0x80 },
2300 { 0x22, 0x7A6, 0x3D },
2301 { 0x22, 0x7A7, 0xE1 },
2302 { 0x22, 0x7A8, 0x0D },
2303 { 0x22, 0x7A9, 0x3D },
2304 { 0x22, 0x7AA, 0xE1 },
2305 { 0x22, 0x7AB, 0x0D },
2306 { 0x22, 0x7AC, 0x0A },
2307 { 0x22, 0x7AD, 0x80 },
2308 { 0x22, 0x7A6, 0x89 },
2309 { 0x22, 0x7A7, 0xB6 },
2310 { 0x22, 0x7A8, 0xEB },
2311 { 0x22, 0x7A9, 0x89 },
2312 { 0x22, 0x7AA, 0xB6 },
2313 { 0x22, 0x7AB, 0xEB },
2314 { 0x22, 0x7AC, 0x0B },
2315 { 0x22, 0x7AD, 0x80 },
2316 { 0x22, 0x7A6, 0x39 },
2317 { 0x22, 0x7A7, 0x9D },
2318 { 0x22, 0x7A8, 0xFE },
2319 { 0x22, 0x7A9, 0x39 },
2320 { 0x22, 0x7AA, 0x9D },
2321 { 0x22, 0x7AB, 0xFE },
2322 { 0x22, 0x7AC, 0x0C },
2323 { 0x22, 0x7AD, 0x80 },
2324 { 0x22, 0x7A6, 0x76 },
2325 { 0x22, 0x7A7, 0x49 },
2326 { 0x22, 0x7A8, 0x15 },
2327 { 0x22, 0x7A9, 0x76 },
2328 { 0x22, 0x7AA, 0x49 },
2329 { 0x22, 0x7AB, 0x15 },
2330 { 0x22, 0x7AC, 0x0D },
2331 { 0x22, 0x7AD, 0x80 },
2332 { 0x22, 0x7A6, 0xC8 },
2333 { 0x22, 0x7A7, 0x80 },
2334 { 0x22, 0x7A8, 0xF5 },
2335 { 0x22, 0x7A9, 0xC8 },
2336 { 0x22, 0x7AA, 0x80 },
2337 { 0x22, 0x7AB, 0xF5 },
2338 { 0x22, 0x7AC, 0x0E },
2339 { 0x22, 0x7AD, 0x80 },
2340 { 0x22, 0x7A6, 0x40 },
2341 { 0x22, 0x7A7, 0x00 },
2342 { 0x22, 0x7A8, 0x00 },
2343 { 0x22, 0x7A9, 0x40 },
2344 { 0x22, 0x7AA, 0x00 },
2345 { 0x22, 0x7AB, 0x00 },
2346 { 0x22, 0x7AC, 0x0F },
2347 { 0x22, 0x7AD, 0x80 },
2348 { 0x22, 0x7A6, 0x90 },
2349 { 0x22, 0x7A7, 0x68 },
2350 { 0x22, 0x7A8, 0xF1 },
2351 { 0x22, 0x7A9, 0x90 },
2352 { 0x22, 0x7AA, 0x68 },
2353 { 0x22, 0x7AB, 0xF1 },
2354 { 0x22, 0x7AC, 0x10 },
2355 { 0x22, 0x7AD, 0x80 },
2356 { 0x22, 0x7A6, 0x34 },
2357 { 0x22, 0x7A7, 0x47 },
2358 { 0x22, 0x7A8, 0x6C },
2359 { 0x22, 0x7A9, 0x34 },
2360 { 0x22, 0x7AA, 0x47 },
2361 { 0x22, 0x7AB, 0x6C },
2362 { 0x22, 0x7AC, 0x11 },
2363 { 0x22, 0x7AD, 0x80 },
2364 { 0x22, 0x7A6, 0x6F },
2365 { 0x22, 0x7A7, 0x97 },
2366 { 0x22, 0x7A8, 0x0F },
2367 { 0x22, 0x7A9, 0x6F },
2368 { 0x22, 0x7AA, 0x97 },
2369 { 0x22, 0x7AB, 0x0F },
2370 { 0x22, 0x7AC, 0x12 },
2371 { 0x22, 0x7AD, 0x80 },
2372 { 0x22, 0x7A6, 0xCB },
2373 { 0x22, 0x7A7, 0xB8 },
2374 { 0x22, 0x7A8, 0x94 },
2375 { 0x22, 0x7A9, 0xCB },
2376 { 0x22, 0x7AA, 0xB8 },
2377 { 0x22, 0x7AB, 0x94 },
2378 { 0x22, 0x7AC, 0x13 },
2379 { 0x22, 0x7AD, 0x80 },
2380 { 0x22, 0x7A6, 0x40 },
2381 { 0x22, 0x7A7, 0x00 },
2382 { 0x22, 0x7A8, 0x00 },
2383 { 0x22, 0x7A9, 0x40 },
2384 { 0x22, 0x7AA, 0x00 },
2385 { 0x22, 0x7AB, 0x00 },
2386 { 0x22, 0x7AC, 0x14 },
2387 { 0x22, 0x7AD, 0x80 },
2388 { 0x22, 0x7A6, 0x95 },
2389 { 0x22, 0x7A7, 0x76 },
2390 { 0x22, 0x7A8, 0x5B },
2391 { 0x22, 0x7A9, 0x95 },
2392 { 0x22, 0x7AA, 0x76 },
2393 { 0x22, 0x7AB, 0x5B },
2394 { 0x22, 0x7AC, 0x15 },
2395 { 0x22, 0x7AD, 0x80 },
2396 { 0x22, 0x7A6, 0x31 },
2397 { 0x22, 0x7A7, 0xAC },
2398 { 0x22, 0x7A8, 0x31 },
2399 { 0x22, 0x7A9, 0x31 },
2400 { 0x22, 0x7AA, 0xAC },
2401 { 0x22, 0x7AB, 0x31 },
2402 { 0x22, 0x7AC, 0x16 },
2403 { 0x22, 0x7AD, 0x80 },
2404 { 0x22, 0x7A6, 0x6A },
2405 { 0x22, 0x7A7, 0x89 },
2406 { 0x22, 0x7A8, 0xA5 },
2407 { 0x22, 0x7A9, 0x6A },
2408 { 0x22, 0x7AA, 0x89 },
2409 { 0x22, 0x7AB, 0xA5 },
2410 { 0x22, 0x7AC, 0x17 },
2411 { 0x22, 0x7AD, 0x80 },
2412 { 0x22, 0x7A6, 0xCE },
2413 { 0x22, 0x7A7, 0x53 },
2414 { 0x22, 0x7A8, 0xCF },
2415 { 0x22, 0x7A9, 0xCE },
2416 { 0x22, 0x7AA, 0x53 },
2417 { 0x22, 0x7AB, 0xCF },
2418 { 0x22, 0x7AC, 0x18 },
2419 { 0x22, 0x7AD, 0x80 },
2420 { 0x22, 0x7A6, 0x40 },
2421 { 0x22, 0x7A7, 0x00 },
2422 { 0x22, 0x7A8, 0x00 },
2423 { 0x22, 0x7A9, 0x40 },
2424 { 0x22, 0x7AA, 0x00 },
2425 { 0x22, 0x7AB, 0x00 },
2426 { 0x22, 0x7AC, 0x19 },
2427 { 0x22, 0x7AD, 0x80 },
2428 /* 48KHz base */
2429 { 0x22, 0x7A6, 0x3E },
2430 { 0x22, 0x7A7, 0x88 },
2431 { 0x22, 0x7A8, 0xDC },
2432 { 0x22, 0x7A9, 0x3E },
2433 { 0x22, 0x7AA, 0x88 },
2434 { 0x22, 0x7AB, 0xDC },
2435 { 0x22, 0x7AC, 0x1A },
2436 { 0x22, 0x7AD, 0x80 },
2437 { 0x22, 0x7A6, 0x82 },
2438 { 0x22, 0x7A7, 0xEE },
2439 { 0x22, 0x7A8, 0x46 },
2440 { 0x22, 0x7A9, 0x82 },
2441 { 0x22, 0x7AA, 0xEE },
2442 { 0x22, 0x7AB, 0x46 },
2443 { 0x22, 0x7AC, 0x1B },
2444 { 0x22, 0x7AD, 0x80 },
2445 { 0x22, 0x7A6, 0x3E },
2446 { 0x22, 0x7A7, 0x88 },
2447 { 0x22, 0x7A8, 0xDC },
2448 { 0x22, 0x7A9, 0x3E },
2449 { 0x22, 0x7AA, 0x88 },
2450 { 0x22, 0x7AB, 0xDC },
2451 { 0x22, 0x7AC, 0x1C },
2452 { 0x22, 0x7AD, 0x80 },
2453 { 0x22, 0x7A6, 0x7D },
2454 { 0x22, 0x7A7, 0x09 },
2455 { 0x22, 0x7A8, 0x28 },
2456 { 0x22, 0x7A9, 0x7D },
2457 { 0x22, 0x7AA, 0x09 },
2458 { 0x22, 0x7AB, 0x28 },
2459 { 0x22, 0x7AC, 0x1D },
2460 { 0x22, 0x7AD, 0x80 },
2461 { 0x22, 0x7A6, 0xC2 },
2462 { 0x22, 0x7A7, 0xE5 },
2463 { 0x22, 0x7A8, 0xB4 },
2464 { 0x22, 0x7A9, 0xC2 },
2465 { 0x22, 0x7AA, 0xE5 },
2466 { 0x22, 0x7AB, 0xB4 },
2467 { 0x22, 0x7AC, 0x1E },
2468 { 0x22, 0x7AD, 0x80 },
2469 { 0x22, 0x7A6, 0x3E },
2470 { 0x22, 0x7A7, 0xA3 },
2471 { 0x22, 0x7A8, 0x1F },
2472 { 0x22, 0x7A9, 0x3E },
2473 { 0x22, 0x7AA, 0xA3 },
2474 { 0x22, 0x7AB, 0x1F },
2475 { 0x22, 0x7AC, 0x1F },
2476 { 0x22, 0x7AD, 0x80 },
2477 { 0x22, 0x7A6, 0x84 },
2478 { 0x22, 0x7A7, 0xCA },
2479 { 0x22, 0x7A8, 0xF1 },
2480 { 0x22, 0x7A9, 0x84 },
2481 { 0x22, 0x7AA, 0xCA },
2482 { 0x22, 0x7AB, 0xF1 },
2483 { 0x22, 0x7AC, 0x20 },
2484 { 0x22, 0x7AD, 0x80 },
2485 { 0x22, 0x7A6, 0x3C },
2486 { 0x22, 0x7A7, 0xD5 },
2487 { 0x22, 0x7A8, 0x9C },
2488 { 0x22, 0x7A9, 0x3C },
2489 { 0x22, 0x7AA, 0xD5 },
2490 { 0x22, 0x7AB, 0x9C },
2491 { 0x22, 0x7AC, 0x21 },
2492 { 0x22, 0x7AD, 0x80 },
2493 { 0x22, 0x7A6, 0x7B },
2494 { 0x22, 0x7A7, 0x35 },
2495 { 0x22, 0x7A8, 0x0F },
2496 { 0x22, 0x7A9, 0x7B },
2497 { 0x22, 0x7AA, 0x35 },
2498 { 0x22, 0x7AB, 0x0F },
2499 { 0x22, 0x7AC, 0x22 },
2500 { 0x22, 0x7AD, 0x80 },
2501 { 0x22, 0x7A6, 0xC4 },
2502 { 0x22, 0x7A7, 0x87 },
2503 { 0x22, 0x7A8, 0x45 },
2504 { 0x22, 0x7A9, 0xC4 },
2505 { 0x22, 0x7AA, 0x87 },
2506 { 0x22, 0x7AB, 0x45 },
2507 { 0x22, 0x7AC, 0x23 },
2508 { 0x22, 0x7AD, 0x80 },
2509 { 0x22, 0x7A6, 0x3E },
2510 { 0x22, 0x7A7, 0x0A },
2511 { 0x22, 0x7A8, 0x78 },
2512 { 0x22, 0x7A9, 0x3E },
2513 { 0x22, 0x7AA, 0x0A },
2514 { 0x22, 0x7AB, 0x78 },
2515 { 0x22, 0x7AC, 0x24 },
2516 { 0x22, 0x7AD, 0x80 },
2517 { 0x22, 0x7A6, 0x88 },
2518 { 0x22, 0x7A7, 0xE2 },
2519 { 0x22, 0x7A8, 0x05 },
2520 { 0x22, 0x7A9, 0x88 },
2521 { 0x22, 0x7AA, 0xE2 },
2522 { 0x22, 0x7AB, 0x05 },
2523 { 0x22, 0x7AC, 0x25 },
2524 { 0x22, 0x7AD, 0x80 },
2525 { 0x22, 0x7A6, 0x3A },
2526 { 0x22, 0x7A7, 0x1A },
2527 { 0x22, 0x7A8, 0xA3 },
2528 { 0x22, 0x7A9, 0x3A },
2529 { 0x22, 0x7AA, 0x1A },
2530 { 0x22, 0x7AB, 0xA3 },
2531 { 0x22, 0x7AC, 0x26 },
2532 { 0x22, 0x7AD, 0x80 },
2533 { 0x22, 0x7A6, 0x77 },
2534 { 0x22, 0x7A7, 0x1D },
2535 { 0x22, 0x7A8, 0xFB },
2536 { 0x22, 0x7A9, 0x77 },
2537 { 0x22, 0x7AA, 0x1D },
2538 { 0x22, 0x7AB, 0xFB },
2539 { 0x22, 0x7AC, 0x27 },
2540 { 0x22, 0x7AD, 0x80 },
2541 { 0x22, 0x7A6, 0xC7 },
2542 { 0x22, 0x7A7, 0xDA },
2543 { 0x22, 0x7A8, 0xE5 },
2544 { 0x22, 0x7A9, 0xC7 },
2545 { 0x22, 0x7AA, 0xDA },
2546 { 0x22, 0x7AB, 0xE5 },
2547 { 0x22, 0x7AC, 0x28 },
2548 { 0x22, 0x7AD, 0x80 },
2549 { 0x22, 0x7A6, 0x40 },
2550 { 0x22, 0x7A7, 0x00 },
2551 { 0x22, 0x7A8, 0x00 },
2552 { 0x22, 0x7A9, 0x40 },
2553 { 0x22, 0x7AA, 0x00 },
2554 { 0x22, 0x7AB, 0x00 },
2555 { 0x22, 0x7AC, 0x29 },
2556 { 0x22, 0x7AD, 0x80 },
2557 { 0x22, 0x7A6, 0x8E },
2558 { 0x22, 0x7A7, 0xD7 },
2559 { 0x22, 0x7A8, 0x22 },
2560 { 0x22, 0x7A9, 0x8E },
2561 { 0x22, 0x7AA, 0xD7 },
2562 { 0x22, 0x7AB, 0x22 },
2563 { 0x22, 0x7AC, 0x2A },
2564 { 0x22, 0x7AD, 0x80 },
2565 { 0x22, 0x7A6, 0x35 },
2566 { 0x22, 0x7A7, 0x26 },
2567 { 0x22, 0x7A8, 0xC6 },
2568 { 0x22, 0x7A9, 0x35 },
2569 { 0x22, 0x7AA, 0x26 },
2570 { 0x22, 0x7AB, 0xC6 },
2571 { 0x22, 0x7AC, 0x2B },
2572 { 0x22, 0x7AD, 0x80 },
2573 { 0x22, 0x7A6, 0x71 },
2574 { 0x22, 0x7A7, 0x28 },
2575 { 0x22, 0x7A8, 0xDE },
2576 { 0x22, 0x7A9, 0x71 },
2577 { 0x22, 0x7AA, 0x28 },
2578 { 0x22, 0x7AB, 0xDE },
2579 { 0x22, 0x7AC, 0x2C },
2580 { 0x22, 0x7AD, 0x80 },
2581 { 0x22, 0x7A6, 0xCA },
2582 { 0x22, 0x7A7, 0xD9 },
2583 { 0x22, 0x7A8, 0x3A },
2584 { 0x22, 0x7A9, 0xCA },
2585 { 0x22, 0x7AA, 0xD9 },
2586 { 0x22, 0x7AB, 0x3A },
2587 { 0x22, 0x7AC, 0x2D },
2588 { 0x22, 0x7AD, 0x80 },
2589 { 0x22, 0x7A6, 0x40 },
2590 { 0x22, 0x7A7, 0x00 },
2591 { 0x22, 0x7A8, 0x00 },
2592 { 0x22, 0x7A9, 0x40 },
2593 { 0x22, 0x7AA, 0x00 },
2594 { 0x22, 0x7AB, 0x00 },
2595 { 0x22, 0x7AC, 0x2E },
2596 { 0x22, 0x7AD, 0x80 },
2597 { 0x22, 0x7A6, 0x93 },
2598 { 0x22, 0x7A7, 0x5E },
2599 { 0x22, 0x7A8, 0xD8 },
2600 { 0x22, 0x7A9, 0x93 },
2601 { 0x22, 0x7AA, 0x5E },
2602 { 0x22, 0x7AB, 0xD8 },
2603 { 0x22, 0x7AC, 0x2F },
2604 { 0x22, 0x7AD, 0x80 },
2605 { 0x22, 0x7A6, 0x32 },
2606 { 0x22, 0x7A7, 0xB7 },
2607 { 0x22, 0x7A8, 0xB1 },
2608 { 0x22, 0x7A9, 0x32 },
2609 { 0x22, 0x7AA, 0xB7 },
2610 { 0x22, 0x7AB, 0xB1 },
2611 { 0x22, 0x7AC, 0x30 },
2612 { 0x22, 0x7AD, 0x80 },
2613 { 0x22, 0x7A6, 0x6C },
2614 { 0x22, 0x7A7, 0xA1 },
2615 { 0x22, 0x7A8, 0x28 },
2616 { 0x22, 0x7A9, 0x6C },
2617 { 0x22, 0x7AA, 0xA1 },
2618 { 0x22, 0x7AB, 0x28 },
2619 { 0x22, 0x7AC, 0x31 },
2620 { 0x22, 0x7AD, 0x80 },
2621 { 0x22, 0x7A6, 0xCD },
2622 { 0x22, 0x7A7, 0x48 },
2623 { 0x22, 0x7A8, 0x4F },
2624 { 0x22, 0x7A9, 0xCD },
2625 { 0x22, 0x7AA, 0x48 },
2626 { 0x22, 0x7AB, 0x4F },
2627 { 0x22, 0x7AC, 0x32 },
2628 { 0x22, 0x7AD, 0x80 },
2629 { 0x22, 0x7A6, 0x40 },
2630 { 0x22, 0x7A7, 0x00 },
2631 { 0x22, 0x7A8, 0x00 },
2632 { 0x22, 0x7A9, 0x40 },
2633 { 0x22, 0x7AA, 0x00 },
2634 { 0x22, 0x7AB, 0x00 },
2635 { 0x22, 0x7AC, 0x33 },
2636 { 0x22, 0x7AD, 0x80 },
2637 /* common */
2638 { 0x22, 0x782, 0xC1 },
2639 { 0x22, 0x771, 0x2C },
2640 { 0x22, 0x772, 0x2C },
2641 { 0x22, 0x788, 0x04 },
2642 { 0x01, 0x7B0, 0x08 },
2646 static const struct hda_fixup stac92hd83xxx_fixups[] = {
2647 [STAC_92HD83XXX_REF] = {
2648 .type = HDA_FIXUP_PINS,
2649 .v.pins = ref92hd83xxx_pin_configs,
2651 [STAC_92HD83XXX_PWR_REF] = {
2652 .type = HDA_FIXUP_PINS,
2653 .v.pins = ref92hd83xxx_pin_configs,
2655 [STAC_DELL_S14] = {
2656 .type = HDA_FIXUP_PINS,
2657 .v.pins = dell_s14_pin_configs,
2659 [STAC_DELL_VOSTRO_3500] = {
2660 .type = HDA_FIXUP_PINS,
2661 .v.pins = dell_vostro_3500_pin_configs,
2663 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = {
2664 .type = HDA_FIXUP_PINS,
2665 .v.pins = hp_cNB11_intquad_pin_configs,
2666 .chained = true,
2667 .chain_id = STAC_92HD83XXX_HP,
2669 [STAC_92HD83XXX_HP] = {
2670 .type = HDA_FIXUP_FUNC,
2671 .v.func = stac92hd83xxx_fixup_hp,
2673 [STAC_HP_DV7_4000] = {
2674 .type = HDA_FIXUP_PINS,
2675 .v.pins = hp_dv7_4000_pin_configs,
2676 .chained = true,
2677 .chain_id = STAC_92HD83XXX_HP,
2679 [STAC_HP_ZEPHYR] = {
2680 .type = HDA_FIXUP_FUNC,
2681 .v.func = stac92hd83xxx_fixup_hp_zephyr,
2682 .chained = true,
2683 .chain_id = STAC_92HD83XXX_HP,
2685 [STAC_92HD83XXX_HP_LED] = {
2686 .type = HDA_FIXUP_FUNC,
2687 .v.func = stac92hd83xxx_fixup_hp_led,
2688 .chained = true,
2689 .chain_id = STAC_92HD83XXX_HP,
2691 [STAC_92HD83XXX_HP_INV_LED] = {
2692 .type = HDA_FIXUP_FUNC,
2693 .v.func = stac92hd83xxx_fixup_hp_inv_led,
2694 .chained = true,
2695 .chain_id = STAC_92HD83XXX_HP,
2697 [STAC_92HD83XXX_HP_MIC_LED] = {
2698 .type = HDA_FIXUP_FUNC,
2699 .v.func = stac92hd83xxx_fixup_hp_mic_led,
2700 .chained = true,
2701 .chain_id = STAC_92HD83XXX_HP,
2703 [STAC_HP_LED_GPIO10] = {
2704 .type = HDA_FIXUP_FUNC,
2705 .v.func = stac92hd83xxx_fixup_hp_led_gpio10,
2706 .chained = true,
2707 .chain_id = STAC_92HD83XXX_HP,
2709 [STAC_92HD83XXX_HEADSET_JACK] = {
2710 .type = HDA_FIXUP_FUNC,
2711 .v.func = stac92hd83xxx_fixup_headset_jack,
2713 [STAC_HP_ENVY_BASS] = {
2714 .type = HDA_FIXUP_PINS,
2715 .v.pins = (const struct hda_pintbl[]) {
2716 { 0x0f, 0x90170111 },
2720 [STAC_HP_BNB13_EQ] = {
2721 .type = HDA_FIXUP_VERBS,
2722 .v.verbs = hp_bnb13_eq_verbs,
2723 .chained = true,
2724 .chain_id = STAC_92HD83XXX_HP_MIC_LED,
2726 [STAC_HP_ENVY_TS_BASS] = {
2727 .type = HDA_FIXUP_PINS,
2728 .v.pins = (const struct hda_pintbl[]) {
2729 { 0x10, 0x92170111 },
2733 [STAC_HP_ENVY_TS_DAC_BIND] = {
2734 .type = HDA_FIXUP_FUNC,
2735 .v.func = hp_envy_ts_fixup_dac_bind,
2736 .chained = true,
2737 .chain_id = STAC_HP_ENVY_TS_BASS,
2739 [STAC_92HD83XXX_GPIO10_EAPD] = {
2740 .type = HDA_FIXUP_FUNC,
2741 .v.func = stac92hd83xxx_fixup_gpio10_eapd,
2745 static const struct hda_model_fixup stac92hd83xxx_models[] = {
2746 { .id = STAC_92HD83XXX_REF, .name = "ref" },
2747 { .id = STAC_92HD83XXX_PWR_REF, .name = "mic-ref" },
2748 { .id = STAC_DELL_S14, .name = "dell-s14" },
2749 { .id = STAC_DELL_VOSTRO_3500, .name = "dell-vostro-3500" },
2750 { .id = STAC_92HD83XXX_HP_cNB11_INTQUAD, .name = "hp_cNB11_intquad" },
2751 { .id = STAC_HP_DV7_4000, .name = "hp-dv7-4000" },
2752 { .id = STAC_HP_ZEPHYR, .name = "hp-zephyr" },
2753 { .id = STAC_92HD83XXX_HP_LED, .name = "hp-led" },
2754 { .id = STAC_92HD83XXX_HP_INV_LED, .name = "hp-inv-led" },
2755 { .id = STAC_92HD83XXX_HP_MIC_LED, .name = "hp-mic-led" },
2756 { .id = STAC_92HD83XXX_HEADSET_JACK, .name = "headset-jack" },
2757 { .id = STAC_HP_ENVY_BASS, .name = "hp-envy-bass" },
2758 { .id = STAC_HP_BNB13_EQ, .name = "hp-bnb13-eq" },
2759 { .id = STAC_HP_ENVY_TS_BASS, .name = "hp-envy-ts-bass" },
2763 static const struct snd_pci_quirk stac92hd83xxx_fixup_tbl[] = {
2764 /* SigmaTel reference board */
2765 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2766 "DFI LanParty", STAC_92HD83XXX_REF),
2767 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
2768 "DFI LanParty", STAC_92HD83XXX_REF),
2769 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
2770 "unknown Dell", STAC_DELL_S14),
2771 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0532,
2772 "Dell Latitude E6230", STAC_92HD83XXX_HEADSET_JACK),
2773 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0533,
2774 "Dell Latitude E6330", STAC_92HD83XXX_HEADSET_JACK),
2775 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0534,
2776 "Dell Latitude E6430", STAC_92HD83XXX_HEADSET_JACK),
2777 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0535,
2778 "Dell Latitude E6530", STAC_92HD83XXX_HEADSET_JACK),
2779 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053c,
2780 "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
2781 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053d,
2782 "Dell Latitude E5530", STAC_92HD83XXX_HEADSET_JACK),
2783 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0549,
2784 "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
2785 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x057d,
2786 "Dell Latitude E6430s", STAC_92HD83XXX_HEADSET_JACK),
2787 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0584,
2788 "Dell Latitude E6430U", STAC_92HD83XXX_HEADSET_JACK),
2789 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028,
2790 "Dell Vostro 3500", STAC_DELL_VOSTRO_3500),
2791 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
2792 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2793 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657,
2794 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2795 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658,
2796 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2797 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659,
2798 "HP Pavilion dv7", STAC_HP_DV7_4000),
2799 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A,
2800 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2801 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
2802 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2803 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1888,
2804 "HP Envy Spectre", STAC_HP_ENVY_BASS),
2805 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1899,
2806 "HP Folio 13", STAC_HP_LED_GPIO10),
2807 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df,
2808 "HP Folio", STAC_HP_BNB13_EQ),
2809 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18F8,
2810 "HP bNB13", STAC_HP_BNB13_EQ),
2811 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1909,
2812 "HP bNB13", STAC_HP_BNB13_EQ),
2813 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x190A,
2814 "HP bNB13", STAC_HP_BNB13_EQ),
2815 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x190e,
2816 "HP ENVY TS", STAC_HP_ENVY_TS_BASS),
2817 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1967,
2818 "HP ENVY TS", STAC_HP_ENVY_TS_DAC_BIND),
2819 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1940,
2820 "HP bNB13", STAC_HP_BNB13_EQ),
2821 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1941,
2822 "HP bNB13", STAC_HP_BNB13_EQ),
2823 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1942,
2824 "HP bNB13", STAC_HP_BNB13_EQ),
2825 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1943,
2826 "HP bNB13", STAC_HP_BNB13_EQ),
2827 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1944,
2828 "HP bNB13", STAC_HP_BNB13_EQ),
2829 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1945,
2830 "HP bNB13", STAC_HP_BNB13_EQ),
2831 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1946,
2832 "HP bNB13", STAC_HP_BNB13_EQ),
2833 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1948,
2834 "HP bNB13", STAC_HP_BNB13_EQ),
2835 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1949,
2836 "HP bNB13", STAC_HP_BNB13_EQ),
2837 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194A,
2838 "HP bNB13", STAC_HP_BNB13_EQ),
2839 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194B,
2840 "HP bNB13", STAC_HP_BNB13_EQ),
2841 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194C,
2842 "HP bNB13", STAC_HP_BNB13_EQ),
2843 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194E,
2844 "HP bNB13", STAC_HP_BNB13_EQ),
2845 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194F,
2846 "HP bNB13", STAC_HP_BNB13_EQ),
2847 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1950,
2848 "HP bNB13", STAC_HP_BNB13_EQ),
2849 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1951,
2850 "HP bNB13", STAC_HP_BNB13_EQ),
2851 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x195A,
2852 "HP bNB13", STAC_HP_BNB13_EQ),
2853 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x195B,
2854 "HP bNB13", STAC_HP_BNB13_EQ),
2855 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x195C,
2856 "HP bNB13", STAC_HP_BNB13_EQ),
2857 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1991,
2858 "HP bNB13", STAC_HP_BNB13_EQ),
2859 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2103,
2860 "HP bNB13", STAC_HP_BNB13_EQ),
2861 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2104,
2862 "HP bNB13", STAC_HP_BNB13_EQ),
2863 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2105,
2864 "HP bNB13", STAC_HP_BNB13_EQ),
2865 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2106,
2866 "HP bNB13", STAC_HP_BNB13_EQ),
2867 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2107,
2868 "HP bNB13", STAC_HP_BNB13_EQ),
2869 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2108,
2870 "HP bNB13", STAC_HP_BNB13_EQ),
2871 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2109,
2872 "HP bNB13", STAC_HP_BNB13_EQ),
2873 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x210A,
2874 "HP bNB13", STAC_HP_BNB13_EQ),
2875 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x210B,
2876 "HP bNB13", STAC_HP_BNB13_EQ),
2877 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211C,
2878 "HP bNB13", STAC_HP_BNB13_EQ),
2879 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211D,
2880 "HP bNB13", STAC_HP_BNB13_EQ),
2881 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211E,
2882 "HP bNB13", STAC_HP_BNB13_EQ),
2883 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211F,
2884 "HP bNB13", STAC_HP_BNB13_EQ),
2885 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2120,
2886 "HP bNB13", STAC_HP_BNB13_EQ),
2887 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2121,
2888 "HP bNB13", STAC_HP_BNB13_EQ),
2889 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2122,
2890 "HP bNB13", STAC_HP_BNB13_EQ),
2891 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2123,
2892 "HP bNB13", STAC_HP_BNB13_EQ),
2893 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x213E,
2894 "HP bNB13", STAC_HP_BNB13_EQ),
2895 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x213F,
2896 "HP bNB13", STAC_HP_BNB13_EQ),
2897 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2140,
2898 "HP bNB13", STAC_HP_BNB13_EQ),
2899 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B2,
2900 "HP bNB13", STAC_HP_BNB13_EQ),
2901 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B3,
2902 "HP bNB13", STAC_HP_BNB13_EQ),
2903 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B5,
2904 "HP bNB13", STAC_HP_BNB13_EQ),
2905 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B6,
2906 "HP bNB13", STAC_HP_BNB13_EQ),
2907 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x1900,
2908 "HP", STAC_92HD83XXX_HP_MIC_LED),
2909 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x2000,
2910 "HP", STAC_92HD83XXX_HP_MIC_LED),
2911 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x2100,
2912 "HP", STAC_92HD83XXX_HP_MIC_LED),
2913 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388,
2914 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2915 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389,
2916 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2917 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355B,
2918 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2919 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355C,
2920 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2921 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355D,
2922 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2923 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355E,
2924 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2925 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355F,
2926 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2927 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3560,
2928 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2929 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358B,
2930 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2931 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358C,
2932 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2933 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358D,
2934 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2935 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3591,
2936 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2937 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3592,
2938 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2939 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
2940 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2941 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
2942 "HP", STAC_HP_ZEPHYR),
2943 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3660,
2944 "HP Mini", STAC_92HD83XXX_HP_LED),
2945 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x144E,
2946 "HP Pavilion dv5", STAC_92HD83XXX_HP_INV_LED),
2947 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x148a,
2948 "HP Mini", STAC_92HD83XXX_HP_LED),
2949 SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_HP, "HP", STAC_92HD83XXX_HP),
2950 /* match both for 0xfa91 and 0xfa93 */
2951 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_TOSHIBA, 0xfffd, 0xfa91,
2952 "Toshiba Satellite S50D", STAC_92HD83XXX_GPIO10_EAPD),
2953 {} /* terminator */
2956 /* HP dv7 bass switch - GPIO5 */
2957 #define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info
2958 static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol,
2959 struct snd_ctl_elem_value *ucontrol)
2961 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2962 struct sigmatel_spec *spec = codec->spec;
2963 ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20);
2964 return 0;
2967 static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol,
2968 struct snd_ctl_elem_value *ucontrol)
2970 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2971 struct sigmatel_spec *spec = codec->spec;
2972 unsigned int gpio_data;
2974 gpio_data = (spec->gpio_data & ~0x20) |
2975 (ucontrol->value.integer.value[0] ? 0x20 : 0);
2976 if (gpio_data == spec->gpio_data)
2977 return 0;
2978 spec->gpio_data = gpio_data;
2979 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
2980 return 1;
2983 static const struct snd_kcontrol_new stac_hp_bass_sw_ctrl = {
2984 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2985 .info = stac_hp_bass_gpio_info,
2986 .get = stac_hp_bass_gpio_get,
2987 .put = stac_hp_bass_gpio_put,
2990 static int stac_add_hp_bass_switch(struct hda_codec *codec)
2992 struct sigmatel_spec *spec = codec->spec;
2994 if (!snd_hda_gen_add_kctl(&spec->gen, "Bass Speaker Playback Switch",
2995 &stac_hp_bass_sw_ctrl))
2996 return -ENOMEM;
2998 spec->gpio_mask |= 0x20;
2999 spec->gpio_dir |= 0x20;
3000 spec->gpio_data |= 0x20;
3001 return 0;
3004 static const struct hda_pintbl ref92hd71bxx_pin_configs[] = {
3005 { 0x0a, 0x02214030 },
3006 { 0x0b, 0x02a19040 },
3007 { 0x0c, 0x01a19020 },
3008 { 0x0d, 0x01014010 },
3009 { 0x0e, 0x0181302e },
3010 { 0x0f, 0x01014010 },
3011 { 0x14, 0x01019020 },
3012 { 0x18, 0x90a000f0 },
3013 { 0x19, 0x90a000f0 },
3014 { 0x1e, 0x01452050 },
3015 { 0x1f, 0x01452050 },
3019 static const struct hda_pintbl dell_m4_1_pin_configs[] = {
3020 { 0x0a, 0x0421101f },
3021 { 0x0b, 0x04a11221 },
3022 { 0x0c, 0x40f000f0 },
3023 { 0x0d, 0x90170110 },
3024 { 0x0e, 0x23a1902e },
3025 { 0x0f, 0x23014250 },
3026 { 0x14, 0x40f000f0 },
3027 { 0x18, 0x90a000f0 },
3028 { 0x19, 0x40f000f0 },
3029 { 0x1e, 0x4f0000f0 },
3030 { 0x1f, 0x4f0000f0 },
3034 static const struct hda_pintbl dell_m4_2_pin_configs[] = {
3035 { 0x0a, 0x0421101f },
3036 { 0x0b, 0x04a11221 },
3037 { 0x0c, 0x90a70330 },
3038 { 0x0d, 0x90170110 },
3039 { 0x0e, 0x23a1902e },
3040 { 0x0f, 0x23014250 },
3041 { 0x14, 0x40f000f0 },
3042 { 0x18, 0x40f000f0 },
3043 { 0x19, 0x40f000f0 },
3044 { 0x1e, 0x044413b0 },
3045 { 0x1f, 0x044413b0 },
3049 static const struct hda_pintbl dell_m4_3_pin_configs[] = {
3050 { 0x0a, 0x0421101f },
3051 { 0x0b, 0x04a11221 },
3052 { 0x0c, 0x90a70330 },
3053 { 0x0d, 0x90170110 },
3054 { 0x0e, 0x40f000f0 },
3055 { 0x0f, 0x40f000f0 },
3056 { 0x14, 0x40f000f0 },
3057 { 0x18, 0x90a000f0 },
3058 { 0x19, 0x40f000f0 },
3059 { 0x1e, 0x044413b0 },
3060 { 0x1f, 0x044413b0 },
3064 static void stac92hd71bxx_fixup_ref(struct hda_codec *codec,
3065 const struct hda_fixup *fix, int action)
3067 struct sigmatel_spec *spec = codec->spec;
3069 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3070 return;
3072 snd_hda_apply_pincfgs(codec, ref92hd71bxx_pin_configs);
3073 spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0;
3076 static void stac92hd71bxx_fixup_hp_m4(struct hda_codec *codec,
3077 const struct hda_fixup *fix, int action)
3079 struct sigmatel_spec *spec = codec->spec;
3080 struct hda_jack_callback *jack;
3082 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3083 return;
3085 /* Enable VREF power saving on GPIO1 detect */
3086 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
3087 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
3088 jack = snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
3089 stac_vref_event);
3090 if (!IS_ERR(jack))
3091 jack->private_data = 0x02;
3093 spec->gpio_mask |= 0x02;
3095 /* enable internal microphone */
3096 snd_hda_codec_set_pincfg(codec, 0x0e, 0x01813040);
3099 static void stac92hd71bxx_fixup_hp_dv4(struct hda_codec *codec,
3100 const struct hda_fixup *fix, int action)
3102 struct sigmatel_spec *spec = codec->spec;
3104 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3105 return;
3106 spec->gpio_led = 0x01;
3109 static void stac92hd71bxx_fixup_hp_dv5(struct hda_codec *codec,
3110 const struct hda_fixup *fix, int action)
3112 unsigned int cap;
3114 switch (action) {
3115 case HDA_FIXUP_ACT_PRE_PROBE:
3116 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
3117 break;
3119 case HDA_FIXUP_ACT_PROBE:
3120 /* enable bass on HP dv7 */
3121 cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
3122 cap &= AC_GPIO_IO_COUNT;
3123 if (cap >= 6)
3124 stac_add_hp_bass_switch(codec);
3125 break;
3129 static void stac92hd71bxx_fixup_hp_hdx(struct hda_codec *codec,
3130 const struct hda_fixup *fix, int action)
3132 struct sigmatel_spec *spec = codec->spec;
3134 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3135 return;
3136 spec->gpio_led = 0x08;
3139 static bool is_hp_output(struct hda_codec *codec, hda_nid_t pin)
3141 unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, pin);
3143 /* count line-out, too, as BIOS sets often so */
3144 return get_defcfg_connect(pin_cfg) != AC_JACK_PORT_NONE &&
3145 (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT ||
3146 get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT);
3149 static void fixup_hp_headphone(struct hda_codec *codec, hda_nid_t pin)
3151 unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, pin);
3153 /* It was changed in the BIOS to just satisfy MS DTM.
3154 * Lets turn it back into slaved HP
3156 pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE)) |
3157 (AC_JACK_HP_OUT << AC_DEFCFG_DEVICE_SHIFT);
3158 pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC | AC_DEFCFG_SEQUENCE))) |
3159 0x1f;
3160 snd_hda_codec_set_pincfg(codec, pin, pin_cfg);
3163 static void stac92hd71bxx_fixup_hp(struct hda_codec *codec,
3164 const struct hda_fixup *fix, int action)
3166 struct sigmatel_spec *spec = codec->spec;
3168 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3169 return;
3171 /* when both output A and F are assigned, these are supposedly
3172 * dock and built-in headphones; fix both pin configs
3174 if (is_hp_output(codec, 0x0a) && is_hp_output(codec, 0x0f)) {
3175 fixup_hp_headphone(codec, 0x0a);
3176 fixup_hp_headphone(codec, 0x0f);
3179 if (find_mute_led_cfg(codec, 1))
3180 codec_dbg(codec, "mute LED gpio %d polarity %d\n",
3181 spec->gpio_led,
3182 spec->gpio_led_polarity);
3186 static const struct hda_fixup stac92hd71bxx_fixups[] = {
3187 [STAC_92HD71BXX_REF] = {
3188 .type = HDA_FIXUP_FUNC,
3189 .v.func = stac92hd71bxx_fixup_ref,
3191 [STAC_DELL_M4_1] = {
3192 .type = HDA_FIXUP_PINS,
3193 .v.pins = dell_m4_1_pin_configs,
3195 [STAC_DELL_M4_2] = {
3196 .type = HDA_FIXUP_PINS,
3197 .v.pins = dell_m4_2_pin_configs,
3199 [STAC_DELL_M4_3] = {
3200 .type = HDA_FIXUP_PINS,
3201 .v.pins = dell_m4_3_pin_configs,
3203 [STAC_HP_M4] = {
3204 .type = HDA_FIXUP_FUNC,
3205 .v.func = stac92hd71bxx_fixup_hp_m4,
3206 .chained = true,
3207 .chain_id = STAC_92HD71BXX_HP,
3209 [STAC_HP_DV4] = {
3210 .type = HDA_FIXUP_FUNC,
3211 .v.func = stac92hd71bxx_fixup_hp_dv4,
3212 .chained = true,
3213 .chain_id = STAC_HP_DV5,
3215 [STAC_HP_DV5] = {
3216 .type = HDA_FIXUP_FUNC,
3217 .v.func = stac92hd71bxx_fixup_hp_dv5,
3218 .chained = true,
3219 .chain_id = STAC_92HD71BXX_HP,
3221 [STAC_HP_HDX] = {
3222 .type = HDA_FIXUP_FUNC,
3223 .v.func = stac92hd71bxx_fixup_hp_hdx,
3224 .chained = true,
3225 .chain_id = STAC_92HD71BXX_HP,
3227 [STAC_92HD71BXX_HP] = {
3228 .type = HDA_FIXUP_FUNC,
3229 .v.func = stac92hd71bxx_fixup_hp,
3233 static const struct hda_model_fixup stac92hd71bxx_models[] = {
3234 { .id = STAC_92HD71BXX_REF, .name = "ref" },
3235 { .id = STAC_DELL_M4_1, .name = "dell-m4-1" },
3236 { .id = STAC_DELL_M4_2, .name = "dell-m4-2" },
3237 { .id = STAC_DELL_M4_3, .name = "dell-m4-3" },
3238 { .id = STAC_HP_M4, .name = "hp-m4" },
3239 { .id = STAC_HP_DV4, .name = "hp-dv4" },
3240 { .id = STAC_HP_DV5, .name = "hp-dv5" },
3241 { .id = STAC_HP_HDX, .name = "hp-hdx" },
3242 { .id = STAC_HP_DV4, .name = "hp-dv4-1222nr" },
3246 static const struct snd_pci_quirk stac92hd71bxx_fixup_tbl[] = {
3247 /* SigmaTel reference board */
3248 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3249 "DFI LanParty", STAC_92HD71BXX_REF),
3250 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3251 "DFI LanParty", STAC_92HD71BXX_REF),
3252 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720,
3253 "HP", STAC_HP_DV5),
3254 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
3255 "HP", STAC_HP_DV5),
3256 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
3257 "HP dv4-7", STAC_HP_DV4),
3258 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600,
3259 "HP dv4-7", STAC_HP_DV5),
3260 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610,
3261 "HP HDX", STAC_HP_HDX), /* HDX18 */
3262 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
3263 "HP mini 1000", STAC_HP_M4),
3264 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b,
3265 "HP HDX", STAC_HP_HDX), /* HDX16 */
3266 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620,
3267 "HP dv6", STAC_HP_DV5),
3268 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061,
3269 "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */
3270 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x363e,
3271 "HP DV6", STAC_HP_DV5),
3272 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010,
3273 "HP", STAC_HP_DV5),
3274 SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_HP, "HP", STAC_92HD71BXX_HP),
3275 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
3276 "unknown Dell", STAC_DELL_M4_1),
3277 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234,
3278 "unknown Dell", STAC_DELL_M4_1),
3279 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0250,
3280 "unknown Dell", STAC_DELL_M4_1),
3281 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024f,
3282 "unknown Dell", STAC_DELL_M4_1),
3283 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024d,
3284 "unknown Dell", STAC_DELL_M4_1),
3285 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0251,
3286 "unknown Dell", STAC_DELL_M4_1),
3287 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0277,
3288 "unknown Dell", STAC_DELL_M4_1),
3289 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0263,
3290 "unknown Dell", STAC_DELL_M4_2),
3291 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0265,
3292 "unknown Dell", STAC_DELL_M4_2),
3293 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0262,
3294 "unknown Dell", STAC_DELL_M4_2),
3295 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264,
3296 "unknown Dell", STAC_DELL_M4_2),
3297 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02aa,
3298 "unknown Dell", STAC_DELL_M4_3),
3299 {} /* terminator */
3302 static const struct hda_pintbl ref922x_pin_configs[] = {
3303 { 0x0a, 0x01014010 },
3304 { 0x0b, 0x01016011 },
3305 { 0x0c, 0x01012012 },
3306 { 0x0d, 0x0221401f },
3307 { 0x0e, 0x01813122 },
3308 { 0x0f, 0x01011014 },
3309 { 0x10, 0x01441030 },
3310 { 0x11, 0x01c41030 },
3311 { 0x15, 0x40000100 },
3312 { 0x1b, 0x40000100 },
3317 STAC 922X pin configs for
3318 102801A7
3319 102801AB
3320 102801A9
3321 102801D1
3322 102801D2
3324 static const struct hda_pintbl dell_922x_d81_pin_configs[] = {
3325 { 0x0a, 0x02214030 },
3326 { 0x0b, 0x01a19021 },
3327 { 0x0c, 0x01111012 },
3328 { 0x0d, 0x01114010 },
3329 { 0x0e, 0x02a19020 },
3330 { 0x0f, 0x01117011 },
3331 { 0x10, 0x400001f0 },
3332 { 0x11, 0x400001f1 },
3333 { 0x15, 0x01813122 },
3334 { 0x1b, 0x400001f2 },
3339 STAC 922X pin configs for
3340 102801AC
3341 102801D0
3343 static const struct hda_pintbl dell_922x_d82_pin_configs[] = {
3344 { 0x0a, 0x02214030 },
3345 { 0x0b, 0x01a19021 },
3346 { 0x0c, 0x01111012 },
3347 { 0x0d, 0x01114010 },
3348 { 0x0e, 0x02a19020 },
3349 { 0x0f, 0x01117011 },
3350 { 0x10, 0x01451140 },
3351 { 0x11, 0x400001f0 },
3352 { 0x15, 0x01813122 },
3353 { 0x1b, 0x400001f1 },
3358 STAC 922X pin configs for
3359 102801BF
3361 static const struct hda_pintbl dell_922x_m81_pin_configs[] = {
3362 { 0x0a, 0x0321101f },
3363 { 0x0b, 0x01112024 },
3364 { 0x0c, 0x01111222 },
3365 { 0x0d, 0x91174220 },
3366 { 0x0e, 0x03a11050 },
3367 { 0x0f, 0x01116221 },
3368 { 0x10, 0x90a70330 },
3369 { 0x11, 0x01452340 },
3370 { 0x15, 0x40C003f1 },
3371 { 0x1b, 0x405003f0 },
3376 STAC 9221 A1 pin configs for
3377 102801D7 (Dell XPS M1210)
3379 static const struct hda_pintbl dell_922x_m82_pin_configs[] = {
3380 { 0x0a, 0x02211211 },
3381 { 0x0b, 0x408103ff },
3382 { 0x0c, 0x02a1123e },
3383 { 0x0d, 0x90100310 },
3384 { 0x0e, 0x408003f1 },
3385 { 0x0f, 0x0221121f },
3386 { 0x10, 0x03451340 },
3387 { 0x11, 0x40c003f2 },
3388 { 0x15, 0x508003f3 },
3389 { 0x1b, 0x405003f4 },
3393 static const struct hda_pintbl d945gtp3_pin_configs[] = {
3394 { 0x0a, 0x0221401f },
3395 { 0x0b, 0x01a19022 },
3396 { 0x0c, 0x01813021 },
3397 { 0x0d, 0x01014010 },
3398 { 0x0e, 0x40000100 },
3399 { 0x0f, 0x40000100 },
3400 { 0x10, 0x40000100 },
3401 { 0x11, 0x40000100 },
3402 { 0x15, 0x02a19120 },
3403 { 0x1b, 0x40000100 },
3407 static const struct hda_pintbl d945gtp5_pin_configs[] = {
3408 { 0x0a, 0x0221401f },
3409 { 0x0b, 0x01011012 },
3410 { 0x0c, 0x01813024 },
3411 { 0x0d, 0x01014010 },
3412 { 0x0e, 0x01a19021 },
3413 { 0x0f, 0x01016011 },
3414 { 0x10, 0x01452130 },
3415 { 0x11, 0x40000100 },
3416 { 0x15, 0x02a19320 },
3417 { 0x1b, 0x40000100 },
3421 static const struct hda_pintbl intel_mac_v1_pin_configs[] = {
3422 { 0x0a, 0x0121e21f },
3423 { 0x0b, 0x400000ff },
3424 { 0x0c, 0x9017e110 },
3425 { 0x0d, 0x400000fd },
3426 { 0x0e, 0x400000fe },
3427 { 0x0f, 0x0181e020 },
3428 { 0x10, 0x1145e030 },
3429 { 0x11, 0x11c5e240 },
3430 { 0x15, 0x400000fc },
3431 { 0x1b, 0x400000fb },
3435 static const struct hda_pintbl intel_mac_v2_pin_configs[] = {
3436 { 0x0a, 0x0121e21f },
3437 { 0x0b, 0x90a7012e },
3438 { 0x0c, 0x9017e110 },
3439 { 0x0d, 0x400000fd },
3440 { 0x0e, 0x400000fe },
3441 { 0x0f, 0x0181e020 },
3442 { 0x10, 0x1145e230 },
3443 { 0x11, 0x500000fa },
3444 { 0x15, 0x400000fc },
3445 { 0x1b, 0x400000fb },
3449 static const struct hda_pintbl intel_mac_v3_pin_configs[] = {
3450 { 0x0a, 0x0121e21f },
3451 { 0x0b, 0x90a7012e },
3452 { 0x0c, 0x9017e110 },
3453 { 0x0d, 0x400000fd },
3454 { 0x0e, 0x400000fe },
3455 { 0x0f, 0x0181e020 },
3456 { 0x10, 0x1145e230 },
3457 { 0x11, 0x11c5e240 },
3458 { 0x15, 0x400000fc },
3459 { 0x1b, 0x400000fb },
3463 static const struct hda_pintbl intel_mac_v4_pin_configs[] = {
3464 { 0x0a, 0x0321e21f },
3465 { 0x0b, 0x03a1e02e },
3466 { 0x0c, 0x9017e110 },
3467 { 0x0d, 0x9017e11f },
3468 { 0x0e, 0x400000fe },
3469 { 0x0f, 0x0381e020 },
3470 { 0x10, 0x1345e230 },
3471 { 0x11, 0x13c5e240 },
3472 { 0x15, 0x400000fc },
3473 { 0x1b, 0x400000fb },
3477 static const struct hda_pintbl intel_mac_v5_pin_configs[] = {
3478 { 0x0a, 0x0321e21f },
3479 { 0x0b, 0x03a1e02e },
3480 { 0x0c, 0x9017e110 },
3481 { 0x0d, 0x9017e11f },
3482 { 0x0e, 0x400000fe },
3483 { 0x0f, 0x0381e020 },
3484 { 0x10, 0x1345e230 },
3485 { 0x11, 0x13c5e240 },
3486 { 0x15, 0x400000fc },
3487 { 0x1b, 0x400000fb },
3491 static const struct hda_pintbl ecs202_pin_configs[] = {
3492 { 0x0a, 0x0221401f },
3493 { 0x0b, 0x02a19020 },
3494 { 0x0c, 0x01a19020 },
3495 { 0x0d, 0x01114010 },
3496 { 0x0e, 0x408000f0 },
3497 { 0x0f, 0x01813022 },
3498 { 0x10, 0x074510a0 },
3499 { 0x11, 0x40c400f1 },
3500 { 0x15, 0x9037012e },
3501 { 0x1b, 0x40e000f2 },
3505 /* codec SSIDs for Intel Mac sharing the same PCI SSID 8384:7680 */
3506 static const struct snd_pci_quirk stac922x_intel_mac_fixup_tbl[] = {
3507 SND_PCI_QUIRK(0x0000, 0x0100, "Mac Mini", STAC_INTEL_MAC_V3),
3508 SND_PCI_QUIRK(0x106b, 0x0800, "Mac", STAC_INTEL_MAC_V1),
3509 SND_PCI_QUIRK(0x106b, 0x0600, "Mac", STAC_INTEL_MAC_V2),
3510 SND_PCI_QUIRK(0x106b, 0x0700, "Mac", STAC_INTEL_MAC_V2),
3511 SND_PCI_QUIRK(0x106b, 0x0e00, "Mac", STAC_INTEL_MAC_V3),
3512 SND_PCI_QUIRK(0x106b, 0x0f00, "Mac", STAC_INTEL_MAC_V3),
3513 SND_PCI_QUIRK(0x106b, 0x1600, "Mac", STAC_INTEL_MAC_V3),
3514 SND_PCI_QUIRK(0x106b, 0x1700, "Mac", STAC_INTEL_MAC_V3),
3515 SND_PCI_QUIRK(0x106b, 0x0200, "Mac", STAC_INTEL_MAC_V3),
3516 SND_PCI_QUIRK(0x106b, 0x1e00, "Mac", STAC_INTEL_MAC_V3),
3517 SND_PCI_QUIRK(0x106b, 0x1a00, "Mac", STAC_INTEL_MAC_V4),
3518 SND_PCI_QUIRK(0x106b, 0x0a00, "Mac", STAC_INTEL_MAC_V5),
3519 SND_PCI_QUIRK(0x106b, 0x2200, "Mac", STAC_INTEL_MAC_V5),
3523 static const struct hda_fixup stac922x_fixups[];
3525 /* remap the fixup from codec SSID and apply it */
3526 static void stac922x_fixup_intel_mac_auto(struct hda_codec *codec,
3527 const struct hda_fixup *fix,
3528 int action)
3530 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3531 return;
3533 codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
3534 snd_hda_pick_fixup(codec, NULL, stac922x_intel_mac_fixup_tbl,
3535 stac922x_fixups);
3536 if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET)
3537 snd_hda_apply_fixup(codec, action);
3540 static void stac922x_fixup_intel_mac_gpio(struct hda_codec *codec,
3541 const struct hda_fixup *fix,
3542 int action)
3544 struct sigmatel_spec *spec = codec->spec;
3546 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3547 spec->gpio_mask = spec->gpio_dir = 0x03;
3548 spec->gpio_data = 0x03;
3552 static const struct hda_fixup stac922x_fixups[] = {
3553 [STAC_D945_REF] = {
3554 .type = HDA_FIXUP_PINS,
3555 .v.pins = ref922x_pin_configs,
3557 [STAC_D945GTP3] = {
3558 .type = HDA_FIXUP_PINS,
3559 .v.pins = d945gtp3_pin_configs,
3561 [STAC_D945GTP5] = {
3562 .type = HDA_FIXUP_PINS,
3563 .v.pins = d945gtp5_pin_configs,
3565 [STAC_INTEL_MAC_AUTO] = {
3566 .type = HDA_FIXUP_FUNC,
3567 .v.func = stac922x_fixup_intel_mac_auto,
3569 [STAC_INTEL_MAC_V1] = {
3570 .type = HDA_FIXUP_PINS,
3571 .v.pins = intel_mac_v1_pin_configs,
3572 .chained = true,
3573 .chain_id = STAC_922X_INTEL_MAC_GPIO,
3575 [STAC_INTEL_MAC_V2] = {
3576 .type = HDA_FIXUP_PINS,
3577 .v.pins = intel_mac_v2_pin_configs,
3578 .chained = true,
3579 .chain_id = STAC_922X_INTEL_MAC_GPIO,
3581 [STAC_INTEL_MAC_V3] = {
3582 .type = HDA_FIXUP_PINS,
3583 .v.pins = intel_mac_v3_pin_configs,
3584 .chained = true,
3585 .chain_id = STAC_922X_INTEL_MAC_GPIO,
3587 [STAC_INTEL_MAC_V4] = {
3588 .type = HDA_FIXUP_PINS,
3589 .v.pins = intel_mac_v4_pin_configs,
3590 .chained = true,
3591 .chain_id = STAC_922X_INTEL_MAC_GPIO,
3593 [STAC_INTEL_MAC_V5] = {
3594 .type = HDA_FIXUP_PINS,
3595 .v.pins = intel_mac_v5_pin_configs,
3596 .chained = true,
3597 .chain_id = STAC_922X_INTEL_MAC_GPIO,
3599 [STAC_922X_INTEL_MAC_GPIO] = {
3600 .type = HDA_FIXUP_FUNC,
3601 .v.func = stac922x_fixup_intel_mac_gpio,
3603 [STAC_ECS_202] = {
3604 .type = HDA_FIXUP_PINS,
3605 .v.pins = ecs202_pin_configs,
3607 [STAC_922X_DELL_D81] = {
3608 .type = HDA_FIXUP_PINS,
3609 .v.pins = dell_922x_d81_pin_configs,
3611 [STAC_922X_DELL_D82] = {
3612 .type = HDA_FIXUP_PINS,
3613 .v.pins = dell_922x_d82_pin_configs,
3615 [STAC_922X_DELL_M81] = {
3616 .type = HDA_FIXUP_PINS,
3617 .v.pins = dell_922x_m81_pin_configs,
3619 [STAC_922X_DELL_M82] = {
3620 .type = HDA_FIXUP_PINS,
3621 .v.pins = dell_922x_m82_pin_configs,
3625 static const struct hda_model_fixup stac922x_models[] = {
3626 { .id = STAC_D945_REF, .name = "ref" },
3627 { .id = STAC_D945GTP5, .name = "5stack" },
3628 { .id = STAC_D945GTP3, .name = "3stack" },
3629 { .id = STAC_INTEL_MAC_V1, .name = "intel-mac-v1" },
3630 { .id = STAC_INTEL_MAC_V2, .name = "intel-mac-v2" },
3631 { .id = STAC_INTEL_MAC_V3, .name = "intel-mac-v3" },
3632 { .id = STAC_INTEL_MAC_V4, .name = "intel-mac-v4" },
3633 { .id = STAC_INTEL_MAC_V5, .name = "intel-mac-v5" },
3634 { .id = STAC_INTEL_MAC_AUTO, .name = "intel-mac-auto" },
3635 { .id = STAC_ECS_202, .name = "ecs202" },
3636 { .id = STAC_922X_DELL_D81, .name = "dell-d81" },
3637 { .id = STAC_922X_DELL_D82, .name = "dell-d82" },
3638 { .id = STAC_922X_DELL_M81, .name = "dell-m81" },
3639 { .id = STAC_922X_DELL_M82, .name = "dell-m82" },
3640 /* for backward compatibility */
3641 { .id = STAC_INTEL_MAC_V3, .name = "macmini" },
3642 { .id = STAC_INTEL_MAC_V5, .name = "macbook" },
3643 { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro-v1" },
3644 { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro" },
3645 { .id = STAC_INTEL_MAC_V2, .name = "imac-intel" },
3646 { .id = STAC_INTEL_MAC_V3, .name = "imac-intel-20" },
3650 static const struct snd_pci_quirk stac922x_fixup_tbl[] = {
3651 /* SigmaTel reference board */
3652 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3653 "DFI LanParty", STAC_D945_REF),
3654 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3655 "DFI LanParty", STAC_D945_REF),
3656 /* Intel 945G based systems */
3657 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
3658 "Intel D945G", STAC_D945GTP3),
3659 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
3660 "Intel D945G", STAC_D945GTP3),
3661 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
3662 "Intel D945G", STAC_D945GTP3),
3663 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
3664 "Intel D945G", STAC_D945GTP3),
3665 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
3666 "Intel D945G", STAC_D945GTP3),
3667 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
3668 "Intel D945G", STAC_D945GTP3),
3669 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
3670 "Intel D945G", STAC_D945GTP3),
3671 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
3672 "Intel D945G", STAC_D945GTP3),
3673 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
3674 "Intel D945G", STAC_D945GTP3),
3675 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
3676 "Intel D945G", STAC_D945GTP3),
3677 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
3678 "Intel D945G", STAC_D945GTP3),
3679 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
3680 "Intel D945G", STAC_D945GTP3),
3681 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
3682 "Intel D945G", STAC_D945GTP3),
3683 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
3684 "Intel D945G", STAC_D945GTP3),
3685 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
3686 "Intel D945G", STAC_D945GTP3),
3687 /* Intel D945G 5-stack systems */
3688 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
3689 "Intel D945G", STAC_D945GTP5),
3690 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
3691 "Intel D945G", STAC_D945GTP5),
3692 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
3693 "Intel D945G", STAC_D945GTP5),
3694 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
3695 "Intel D945G", STAC_D945GTP5),
3696 /* Intel 945P based systems */
3697 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
3698 "Intel D945P", STAC_D945GTP3),
3699 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
3700 "Intel D945P", STAC_D945GTP3),
3701 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
3702 "Intel D945P", STAC_D945GTP3),
3703 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
3704 "Intel D945P", STAC_D945GTP3),
3705 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
3706 "Intel D945P", STAC_D945GTP3),
3707 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
3708 "Intel D945P", STAC_D945GTP5),
3709 /* other intel */
3710 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0204,
3711 "Intel D945", STAC_D945_REF),
3712 /* other systems */
3714 /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */
3715 SND_PCI_QUIRK(0x8384, 0x7680, "Mac", STAC_INTEL_MAC_AUTO),
3717 /* Dell systems */
3718 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
3719 "unknown Dell", STAC_922X_DELL_D81),
3720 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
3721 "unknown Dell", STAC_922X_DELL_D81),
3722 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
3723 "unknown Dell", STAC_922X_DELL_D81),
3724 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
3725 "unknown Dell", STAC_922X_DELL_D82),
3726 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
3727 "unknown Dell", STAC_922X_DELL_M81),
3728 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
3729 "unknown Dell", STAC_922X_DELL_D82),
3730 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
3731 "unknown Dell", STAC_922X_DELL_D81),
3732 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
3733 "unknown Dell", STAC_922X_DELL_D81),
3734 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
3735 "Dell XPS M1210", STAC_922X_DELL_M82),
3736 /* ECS/PC Chips boards */
3737 SND_PCI_QUIRK_MASK(0x1019, 0xf000, 0x2000,
3738 "ECS/PC chips", STAC_ECS_202),
3739 {} /* terminator */
3742 static const struct hda_pintbl ref927x_pin_configs[] = {
3743 { 0x0a, 0x02214020 },
3744 { 0x0b, 0x02a19080 },
3745 { 0x0c, 0x0181304e },
3746 { 0x0d, 0x01014010 },
3747 { 0x0e, 0x01a19040 },
3748 { 0x0f, 0x01011012 },
3749 { 0x10, 0x01016011 },
3750 { 0x11, 0x0101201f },
3751 { 0x12, 0x183301f0 },
3752 { 0x13, 0x18a001f0 },
3753 { 0x14, 0x18a001f0 },
3754 { 0x21, 0x01442070 },
3755 { 0x22, 0x01c42190 },
3756 { 0x23, 0x40000100 },
3760 static const struct hda_pintbl d965_3st_pin_configs[] = {
3761 { 0x0a, 0x0221401f },
3762 { 0x0b, 0x02a19120 },
3763 { 0x0c, 0x40000100 },
3764 { 0x0d, 0x01014011 },
3765 { 0x0e, 0x01a19021 },
3766 { 0x0f, 0x01813024 },
3767 { 0x10, 0x40000100 },
3768 { 0x11, 0x40000100 },
3769 { 0x12, 0x40000100 },
3770 { 0x13, 0x40000100 },
3771 { 0x14, 0x40000100 },
3772 { 0x21, 0x40000100 },
3773 { 0x22, 0x40000100 },
3774 { 0x23, 0x40000100 },
3778 static const struct hda_pintbl d965_5st_pin_configs[] = {
3779 { 0x0a, 0x02214020 },
3780 { 0x0b, 0x02a19080 },
3781 { 0x0c, 0x0181304e },
3782 { 0x0d, 0x01014010 },
3783 { 0x0e, 0x01a19040 },
3784 { 0x0f, 0x01011012 },
3785 { 0x10, 0x01016011 },
3786 { 0x11, 0x40000100 },
3787 { 0x12, 0x40000100 },
3788 { 0x13, 0x40000100 },
3789 { 0x14, 0x40000100 },
3790 { 0x21, 0x01442070 },
3791 { 0x22, 0x40000100 },
3792 { 0x23, 0x40000100 },
3796 static const struct hda_pintbl d965_5st_no_fp_pin_configs[] = {
3797 { 0x0a, 0x40000100 },
3798 { 0x0b, 0x40000100 },
3799 { 0x0c, 0x0181304e },
3800 { 0x0d, 0x01014010 },
3801 { 0x0e, 0x01a19040 },
3802 { 0x0f, 0x01011012 },
3803 { 0x10, 0x01016011 },
3804 { 0x11, 0x40000100 },
3805 { 0x12, 0x40000100 },
3806 { 0x13, 0x40000100 },
3807 { 0x14, 0x40000100 },
3808 { 0x21, 0x01442070 },
3809 { 0x22, 0x40000100 },
3810 { 0x23, 0x40000100 },
3814 static const struct hda_pintbl dell_3st_pin_configs[] = {
3815 { 0x0a, 0x02211230 },
3816 { 0x0b, 0x02a11220 },
3817 { 0x0c, 0x01a19040 },
3818 { 0x0d, 0x01114210 },
3819 { 0x0e, 0x01111212 },
3820 { 0x0f, 0x01116211 },
3821 { 0x10, 0x01813050 },
3822 { 0x11, 0x01112214 },
3823 { 0x12, 0x403003fa },
3824 { 0x13, 0x90a60040 },
3825 { 0x14, 0x90a60040 },
3826 { 0x21, 0x404003fb },
3827 { 0x22, 0x40c003fc },
3828 { 0x23, 0x40000100 },
3832 static void stac927x_fixup_ref_no_jd(struct hda_codec *codec,
3833 const struct hda_fixup *fix, int action)
3835 /* no jack detecion for ref-no-jd model */
3836 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3837 codec->no_jack_detect = 1;
3840 static void stac927x_fixup_ref(struct hda_codec *codec,
3841 const struct hda_fixup *fix, int action)
3843 struct sigmatel_spec *spec = codec->spec;
3845 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3846 snd_hda_apply_pincfgs(codec, ref927x_pin_configs);
3847 spec->eapd_mask = spec->gpio_mask = 0;
3848 spec->gpio_dir = spec->gpio_data = 0;
3852 static void stac927x_fixup_dell_dmic(struct hda_codec *codec,
3853 const struct hda_fixup *fix, int action)
3855 struct sigmatel_spec *spec = codec->spec;
3857 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3858 return;
3860 if (codec->core.subsystem_id != 0x1028022f) {
3861 /* GPIO2 High = Enable EAPD */
3862 spec->eapd_mask = spec->gpio_mask = 0x04;
3863 spec->gpio_dir = spec->gpio_data = 0x04;
3866 snd_hda_add_verbs(codec, dell_3st_core_init);
3867 spec->volknob_init = 1;
3870 static void stac927x_fixup_volknob(struct hda_codec *codec,
3871 const struct hda_fixup *fix, int action)
3873 struct sigmatel_spec *spec = codec->spec;
3875 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3876 snd_hda_add_verbs(codec, stac927x_volknob_core_init);
3877 spec->volknob_init = 1;
3881 static const struct hda_fixup stac927x_fixups[] = {
3882 [STAC_D965_REF_NO_JD] = {
3883 .type = HDA_FIXUP_FUNC,
3884 .v.func = stac927x_fixup_ref_no_jd,
3885 .chained = true,
3886 .chain_id = STAC_D965_REF,
3888 [STAC_D965_REF] = {
3889 .type = HDA_FIXUP_FUNC,
3890 .v.func = stac927x_fixup_ref,
3892 [STAC_D965_3ST] = {
3893 .type = HDA_FIXUP_PINS,
3894 .v.pins = d965_3st_pin_configs,
3895 .chained = true,
3896 .chain_id = STAC_D965_VERBS,
3898 [STAC_D965_5ST] = {
3899 .type = HDA_FIXUP_PINS,
3900 .v.pins = d965_5st_pin_configs,
3901 .chained = true,
3902 .chain_id = STAC_D965_VERBS,
3904 [STAC_D965_VERBS] = {
3905 .type = HDA_FIXUP_VERBS,
3906 .v.verbs = d965_core_init,
3908 [STAC_D965_5ST_NO_FP] = {
3909 .type = HDA_FIXUP_PINS,
3910 .v.pins = d965_5st_no_fp_pin_configs,
3912 [STAC_NEMO_DEFAULT] = {
3913 .type = HDA_FIXUP_PINS,
3914 .v.pins = nemo_pin_configs,
3916 [STAC_DELL_3ST] = {
3917 .type = HDA_FIXUP_PINS,
3918 .v.pins = dell_3st_pin_configs,
3919 .chained = true,
3920 .chain_id = STAC_927X_DELL_DMIC,
3922 [STAC_DELL_BIOS] = {
3923 .type = HDA_FIXUP_PINS,
3924 .v.pins = (const struct hda_pintbl[]) {
3925 /* correct the front output jack as a hp out */
3926 { 0x0f, 0x0221101f },
3927 /* correct the front input jack as a mic */
3928 { 0x0e, 0x02a79130 },
3931 .chained = true,
3932 .chain_id = STAC_927X_DELL_DMIC,
3934 [STAC_DELL_BIOS_AMIC] = {
3935 .type = HDA_FIXUP_PINS,
3936 .v.pins = (const struct hda_pintbl[]) {
3937 /* configure the analog microphone on some laptops */
3938 { 0x0c, 0x90a79130 },
3941 .chained = true,
3942 .chain_id = STAC_DELL_BIOS,
3944 [STAC_DELL_BIOS_SPDIF] = {
3945 .type = HDA_FIXUP_PINS,
3946 .v.pins = (const struct hda_pintbl[]) {
3947 /* correct the device field to SPDIF out */
3948 { 0x21, 0x01442070 },
3951 .chained = true,
3952 .chain_id = STAC_DELL_BIOS,
3954 [STAC_927X_DELL_DMIC] = {
3955 .type = HDA_FIXUP_FUNC,
3956 .v.func = stac927x_fixup_dell_dmic,
3958 [STAC_927X_VOLKNOB] = {
3959 .type = HDA_FIXUP_FUNC,
3960 .v.func = stac927x_fixup_volknob,
3964 static const struct hda_model_fixup stac927x_models[] = {
3965 { .id = STAC_D965_REF_NO_JD, .name = "ref-no-jd" },
3966 { .id = STAC_D965_REF, .name = "ref" },
3967 { .id = STAC_D965_3ST, .name = "3stack" },
3968 { .id = STAC_D965_5ST, .name = "5stack" },
3969 { .id = STAC_D965_5ST_NO_FP, .name = "5stack-no-fp" },
3970 { .id = STAC_DELL_3ST, .name = "dell-3stack" },
3971 { .id = STAC_DELL_BIOS, .name = "dell-bios" },
3972 { .id = STAC_NEMO_DEFAULT, .name = "nemo-default" },
3973 { .id = STAC_DELL_BIOS_AMIC, .name = "dell-bios-amic" },
3974 { .id = STAC_927X_VOLKNOB, .name = "volknob" },
3978 static const struct snd_pci_quirk stac927x_fixup_tbl[] = {
3979 /* SigmaTel reference board */
3980 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3981 "DFI LanParty", STAC_D965_REF),
3982 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3983 "DFI LanParty", STAC_D965_REF),
3984 /* Intel 946 based systems */
3985 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
3986 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
3987 /* 965 based 3 stack systems */
3988 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2100,
3989 "Intel D965", STAC_D965_3ST),
3990 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000,
3991 "Intel D965", STAC_D965_3ST),
3992 /* Dell 3 stack systems */
3993 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
3994 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
3995 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
3996 /* Dell 3 stack systems with verb table in BIOS */
3997 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
3998 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_BIOS),
3999 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
4000 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS_SPDIF),
4001 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS),
4002 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
4003 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
4004 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
4005 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS_SPDIF),
4006 /* 965 based 5 stack systems */
4007 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2300,
4008 "Intel D965", STAC_D965_5ST),
4009 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500,
4010 "Intel D965", STAC_D965_5ST),
4011 /* Nemo */
4012 SND_PCI_QUIRK(0x1888, 0x1000, "AmigaOne X1000", STAC_NEMO_DEFAULT),
4013 /* volume-knob fixes */
4014 SND_PCI_QUIRK_VENDOR(0x10cf, "FSC", STAC_927X_VOLKNOB),
4015 {} /* terminator */
4018 static const struct hda_pintbl ref9205_pin_configs[] = {
4019 { 0x0a, 0x40000100 },
4020 { 0x0b, 0x40000100 },
4021 { 0x0c, 0x01016011 },
4022 { 0x0d, 0x01014010 },
4023 { 0x0e, 0x01813122 },
4024 { 0x0f, 0x01a19021 },
4025 { 0x14, 0x01019020 },
4026 { 0x16, 0x40000100 },
4027 { 0x17, 0x90a000f0 },
4028 { 0x18, 0x90a000f0 },
4029 { 0x21, 0x01441030 },
4030 { 0x22, 0x01c41030 },
4035 STAC 9205 pin configs for
4036 102801F1
4037 102801F2
4038 102801FC
4039 102801FD
4040 10280204
4041 1028021F
4042 10280228 (Dell Vostro 1500)
4043 10280229 (Dell Vostro 1700)
4045 static const struct hda_pintbl dell_9205_m42_pin_configs[] = {
4046 { 0x0a, 0x0321101F },
4047 { 0x0b, 0x03A11020 },
4048 { 0x0c, 0x400003FA },
4049 { 0x0d, 0x90170310 },
4050 { 0x0e, 0x400003FB },
4051 { 0x0f, 0x400003FC },
4052 { 0x14, 0x400003FD },
4053 { 0x16, 0x40F000F9 },
4054 { 0x17, 0x90A60330 },
4055 { 0x18, 0x400003FF },
4056 { 0x21, 0x0144131F },
4057 { 0x22, 0x40C003FE },
4062 STAC 9205 pin configs for
4063 102801F9
4064 102801FA
4065 102801FE
4066 102801FF (Dell Precision M4300)
4067 10280206
4068 10280200
4069 10280201
4071 static const struct hda_pintbl dell_9205_m43_pin_configs[] = {
4072 { 0x0a, 0x0321101f },
4073 { 0x0b, 0x03a11020 },
4074 { 0x0c, 0x90a70330 },
4075 { 0x0d, 0x90170310 },
4076 { 0x0e, 0x400000fe },
4077 { 0x0f, 0x400000ff },
4078 { 0x14, 0x400000fd },
4079 { 0x16, 0x40f000f9 },
4080 { 0x17, 0x400000fa },
4081 { 0x18, 0x400000fc },
4082 { 0x21, 0x0144131f },
4083 { 0x22, 0x40c003f8 },
4084 /* Enable SPDIF in/out */
4085 { 0x1f, 0x01441030 },
4086 { 0x20, 0x1c410030 },
4090 static const struct hda_pintbl dell_9205_m44_pin_configs[] = {
4091 { 0x0a, 0x0421101f },
4092 { 0x0b, 0x04a11020 },
4093 { 0x0c, 0x400003fa },
4094 { 0x0d, 0x90170310 },
4095 { 0x0e, 0x400003fb },
4096 { 0x0f, 0x400003fc },
4097 { 0x14, 0x400003fd },
4098 { 0x16, 0x400003f9 },
4099 { 0x17, 0x90a60330 },
4100 { 0x18, 0x400003ff },
4101 { 0x21, 0x01441340 },
4102 { 0x22, 0x40c003fe },
4106 static void stac9205_fixup_ref(struct hda_codec *codec,
4107 const struct hda_fixup *fix, int action)
4109 struct sigmatel_spec *spec = codec->spec;
4111 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4112 snd_hda_apply_pincfgs(codec, ref9205_pin_configs);
4113 /* SPDIF-In enabled */
4114 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0;
4118 static void stac9205_fixup_dell_m43(struct hda_codec *codec,
4119 const struct hda_fixup *fix, int action)
4121 struct sigmatel_spec *spec = codec->spec;
4122 struct hda_jack_callback *jack;
4124 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4125 snd_hda_apply_pincfgs(codec, dell_9205_m43_pin_configs);
4127 /* Enable unsol response for GPIO4/Dock HP connection */
4128 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
4129 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
4130 jack = snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
4131 stac_vref_event);
4132 if (!IS_ERR(jack))
4133 jack->private_data = 0x01;
4135 spec->gpio_dir = 0x0b;
4136 spec->eapd_mask = 0x01;
4137 spec->gpio_mask = 0x1b;
4138 spec->gpio_mute = 0x10;
4139 /* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute,
4140 * GPIO3 Low = DRM
4142 spec->gpio_data = 0x01;
4146 static void stac9205_fixup_eapd(struct hda_codec *codec,
4147 const struct hda_fixup *fix, int action)
4149 struct sigmatel_spec *spec = codec->spec;
4151 if (action == HDA_FIXUP_ACT_PRE_PROBE)
4152 spec->eapd_switch = 0;
4155 static const struct hda_fixup stac9205_fixups[] = {
4156 [STAC_9205_REF] = {
4157 .type = HDA_FIXUP_FUNC,
4158 .v.func = stac9205_fixup_ref,
4160 [STAC_9205_DELL_M42] = {
4161 .type = HDA_FIXUP_PINS,
4162 .v.pins = dell_9205_m42_pin_configs,
4164 [STAC_9205_DELL_M43] = {
4165 .type = HDA_FIXUP_FUNC,
4166 .v.func = stac9205_fixup_dell_m43,
4168 [STAC_9205_DELL_M44] = {
4169 .type = HDA_FIXUP_PINS,
4170 .v.pins = dell_9205_m44_pin_configs,
4172 [STAC_9205_EAPD] = {
4173 .type = HDA_FIXUP_FUNC,
4174 .v.func = stac9205_fixup_eapd,
4179 static const struct hda_model_fixup stac9205_models[] = {
4180 { .id = STAC_9205_REF, .name = "ref" },
4181 { .id = STAC_9205_DELL_M42, .name = "dell-m42" },
4182 { .id = STAC_9205_DELL_M43, .name = "dell-m43" },
4183 { .id = STAC_9205_DELL_M44, .name = "dell-m44" },
4184 { .id = STAC_9205_EAPD, .name = "eapd" },
4188 static const struct snd_pci_quirk stac9205_fixup_tbl[] = {
4189 /* SigmaTel reference board */
4190 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
4191 "DFI LanParty", STAC_9205_REF),
4192 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xfb30,
4193 "SigmaTel", STAC_9205_REF),
4194 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
4195 "DFI LanParty", STAC_9205_REF),
4196 /* Dell */
4197 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
4198 "unknown Dell", STAC_9205_DELL_M42),
4199 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
4200 "unknown Dell", STAC_9205_DELL_M42),
4201 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
4202 "Dell Precision", STAC_9205_DELL_M43),
4203 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
4204 "Dell Precision", STAC_9205_DELL_M43),
4205 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
4206 "Dell Precision", STAC_9205_DELL_M43),
4207 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
4208 "unknown Dell", STAC_9205_DELL_M42),
4209 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
4210 "unknown Dell", STAC_9205_DELL_M42),
4211 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
4212 "Dell Precision", STAC_9205_DELL_M43),
4213 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
4214 "Dell Precision M4300", STAC_9205_DELL_M43),
4215 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
4216 "unknown Dell", STAC_9205_DELL_M42),
4217 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
4218 "Dell Precision", STAC_9205_DELL_M43),
4219 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
4220 "Dell Precision", STAC_9205_DELL_M43),
4221 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
4222 "Dell Precision", STAC_9205_DELL_M43),
4223 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
4224 "Dell Inspiron", STAC_9205_DELL_M44),
4225 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228,
4226 "Dell Vostro 1500", STAC_9205_DELL_M42),
4227 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0229,
4228 "Dell Vostro 1700", STAC_9205_DELL_M42),
4229 /* Gateway */
4230 SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD),
4231 SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD),
4232 {} /* terminator */
4235 static void stac92hd95_fixup_hp_led(struct hda_codec *codec,
4236 const struct hda_fixup *fix, int action)
4238 struct sigmatel_spec *spec = codec->spec;
4240 if (action != HDA_FIXUP_ACT_PRE_PROBE)
4241 return;
4243 if (find_mute_led_cfg(codec, spec->default_polarity))
4244 codec_dbg(codec, "mute LED gpio %d polarity %d\n",
4245 spec->gpio_led,
4246 spec->gpio_led_polarity);
4249 static const struct hda_fixup stac92hd95_fixups[] = {
4250 [STAC_92HD95_HP_LED] = {
4251 .type = HDA_FIXUP_FUNC,
4252 .v.func = stac92hd95_fixup_hp_led,
4254 [STAC_92HD95_HP_BASS] = {
4255 .type = HDA_FIXUP_VERBS,
4256 .v.verbs = (const struct hda_verb[]) {
4257 {0x1a, 0x795, 0x00}, /* HPF to 100Hz */
4260 .chained = true,
4261 .chain_id = STAC_92HD95_HP_LED,
4265 static const struct snd_pci_quirk stac92hd95_fixup_tbl[] = {
4266 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1911, "HP Spectre 13", STAC_92HD95_HP_BASS),
4267 {} /* terminator */
4270 static const struct hda_model_fixup stac92hd95_models[] = {
4271 { .id = STAC_92HD95_HP_LED, .name = "hp-led" },
4272 { .id = STAC_92HD95_HP_BASS, .name = "hp-bass" },
4277 static int stac_parse_auto_config(struct hda_codec *codec)
4279 struct sigmatel_spec *spec = codec->spec;
4280 int err;
4281 int flags = 0;
4283 if (spec->headset_jack)
4284 flags |= HDA_PINCFG_HEADSET_MIC;
4286 err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, flags);
4287 if (err < 0)
4288 return err;
4290 /* add hooks */
4291 spec->gen.pcm_playback_hook = stac_playback_pcm_hook;
4292 spec->gen.pcm_capture_hook = stac_capture_pcm_hook;
4294 spec->gen.automute_hook = stac_update_outputs;
4296 err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg);
4297 if (err < 0)
4298 return err;
4300 if (spec->vref_mute_led_nid) {
4301 err = snd_hda_gen_fix_pin_power(codec, spec->vref_mute_led_nid);
4302 if (err < 0)
4303 return err;
4306 /* setup analog beep controls */
4307 if (spec->anabeep_nid > 0) {
4308 err = stac_auto_create_beep_ctls(codec,
4309 spec->anabeep_nid);
4310 if (err < 0)
4311 return err;
4314 /* setup digital beep controls and input device */
4315 #ifdef CONFIG_SND_HDA_INPUT_BEEP
4316 if (spec->gen.beep_nid) {
4317 hda_nid_t nid = spec->gen.beep_nid;
4318 unsigned int caps;
4320 err = stac_auto_create_beep_ctls(codec, nid);
4321 if (err < 0)
4322 return err;
4323 if (codec->beep) {
4324 /* IDT/STAC codecs have linear beep tone parameter */
4325 codec->beep->linear_tone = spec->linear_tone_beep;
4326 /* if no beep switch is available, make its own one */
4327 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
4328 if (!(caps & AC_AMPCAP_MUTE)) {
4329 err = stac_beep_switch_ctl(codec);
4330 if (err < 0)
4331 return err;
4335 #endif
4337 if (spec->gpio_led)
4338 spec->gen.vmaster_mute.hook = stac_vmaster_hook;
4340 if (spec->aloopback_ctl &&
4341 snd_hda_get_bool_hint(codec, "loopback") == 1) {
4342 unsigned int wr_verb =
4343 spec->aloopback_ctl->private_value >> 16;
4344 if (snd_hdac_regmap_add_vendor_verb(&codec->core, wr_verb))
4345 return -ENOMEM;
4346 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, spec->aloopback_ctl))
4347 return -ENOMEM;
4350 if (spec->have_spdif_mux) {
4351 err = stac_create_spdif_mux_ctls(codec);
4352 if (err < 0)
4353 return err;
4356 stac_init_power_map(codec);
4358 return 0;
4361 static int stac_init(struct hda_codec *codec)
4363 struct sigmatel_spec *spec = codec->spec;
4364 int i;
4366 /* override some hints */
4367 stac_store_hints(codec);
4369 /* set up GPIO */
4370 /* turn on EAPD statically when spec->eapd_switch isn't set.
4371 * otherwise, unsol event will turn it on/off dynamically
4373 if (!spec->eapd_switch)
4374 spec->gpio_data |= spec->eapd_mask;
4375 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
4377 snd_hda_gen_init(codec);
4379 /* sync the power-map */
4380 if (spec->num_pwrs)
4381 snd_hda_codec_write(codec, codec->core.afg, 0,
4382 AC_VERB_IDT_SET_POWER_MAP,
4383 spec->power_map_bits);
4385 /* power down inactive ADCs */
4386 if (spec->powerdown_adcs) {
4387 for (i = 0; i < spec->gen.num_all_adcs; i++) {
4388 if (spec->active_adcs & (1 << i))
4389 continue;
4390 snd_hda_codec_write(codec, spec->gen.all_adcs[i], 0,
4391 AC_VERB_SET_POWER_STATE,
4392 AC_PWRST_D3);
4396 return 0;
4399 static void stac_shutup(struct hda_codec *codec)
4401 struct sigmatel_spec *spec = codec->spec;
4403 snd_hda_shutup_pins(codec);
4405 if (spec->eapd_mask)
4406 stac_gpio_set(codec, spec->gpio_mask,
4407 spec->gpio_dir, spec->gpio_data &
4408 ~spec->eapd_mask);
4411 #define stac_free snd_hda_gen_free
4413 #ifdef CONFIG_SND_PROC_FS
4414 static void stac92hd_proc_hook(struct snd_info_buffer *buffer,
4415 struct hda_codec *codec, hda_nid_t nid)
4417 if (nid == codec->core.afg)
4418 snd_iprintf(buffer, "Power-Map: 0x%02x\n",
4419 snd_hda_codec_read(codec, nid, 0,
4420 AC_VERB_IDT_GET_POWER_MAP, 0));
4423 static void analog_loop_proc_hook(struct snd_info_buffer *buffer,
4424 struct hda_codec *codec,
4425 unsigned int verb)
4427 snd_iprintf(buffer, "Analog Loopback: 0x%02x\n",
4428 snd_hda_codec_read(codec, codec->core.afg, 0, verb, 0));
4431 /* stac92hd71bxx, stac92hd73xx */
4432 static void stac92hd7x_proc_hook(struct snd_info_buffer *buffer,
4433 struct hda_codec *codec, hda_nid_t nid)
4435 stac92hd_proc_hook(buffer, codec, nid);
4436 if (nid == codec->core.afg)
4437 analog_loop_proc_hook(buffer, codec, 0xfa0);
4440 static void stac9205_proc_hook(struct snd_info_buffer *buffer,
4441 struct hda_codec *codec, hda_nid_t nid)
4443 if (nid == codec->core.afg)
4444 analog_loop_proc_hook(buffer, codec, 0xfe0);
4447 static void stac927x_proc_hook(struct snd_info_buffer *buffer,
4448 struct hda_codec *codec, hda_nid_t nid)
4450 if (nid == codec->core.afg)
4451 analog_loop_proc_hook(buffer, codec, 0xfeb);
4453 #else
4454 #define stac92hd_proc_hook NULL
4455 #define stac92hd7x_proc_hook NULL
4456 #define stac9205_proc_hook NULL
4457 #define stac927x_proc_hook NULL
4458 #endif
4460 #ifdef CONFIG_PM
4461 static int stac_suspend(struct hda_codec *codec)
4463 stac_shutup(codec);
4464 return 0;
4466 #else
4467 #define stac_suspend NULL
4468 #endif /* CONFIG_PM */
4470 static const struct hda_codec_ops stac_patch_ops = {
4471 .build_controls = snd_hda_gen_build_controls,
4472 .build_pcms = snd_hda_gen_build_pcms,
4473 .init = stac_init,
4474 .free = stac_free,
4475 .unsol_event = snd_hda_jack_unsol_event,
4476 #ifdef CONFIG_PM
4477 .suspend = stac_suspend,
4478 #endif
4479 .reboot_notify = stac_shutup,
4482 static int alloc_stac_spec(struct hda_codec *codec)
4484 struct sigmatel_spec *spec;
4486 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4487 if (!spec)
4488 return -ENOMEM;
4489 snd_hda_gen_spec_init(&spec->gen);
4490 codec->spec = spec;
4491 codec->no_trigger_sense = 1; /* seems common with STAC/IDT codecs */
4492 spec->gen.dac_min_mute = true;
4493 codec->patch_ops = stac_patch_ops;
4494 return 0;
4497 static int patch_stac9200(struct hda_codec *codec)
4499 struct sigmatel_spec *spec;
4500 int err;
4502 err = alloc_stac_spec(codec);
4503 if (err < 0)
4504 return err;
4506 spec = codec->spec;
4507 spec->linear_tone_beep = 1;
4508 spec->gen.own_eapd_ctl = 1;
4510 codec->power_filter = snd_hda_codec_eapd_power_filter;
4512 snd_hda_add_verbs(codec, stac9200_eapd_init);
4514 snd_hda_pick_fixup(codec, stac9200_models, stac9200_fixup_tbl,
4515 stac9200_fixups);
4516 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4518 err = stac_parse_auto_config(codec);
4519 if (err < 0) {
4520 stac_free(codec);
4521 return err;
4524 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4526 return 0;
4529 static int patch_stac925x(struct hda_codec *codec)
4531 struct sigmatel_spec *spec;
4532 int err;
4534 err = alloc_stac_spec(codec);
4535 if (err < 0)
4536 return err;
4538 spec = codec->spec;
4539 spec->linear_tone_beep = 1;
4540 spec->gen.own_eapd_ctl = 1;
4542 snd_hda_add_verbs(codec, stac925x_core_init);
4544 snd_hda_pick_fixup(codec, stac925x_models, stac925x_fixup_tbl,
4545 stac925x_fixups);
4546 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4548 err = stac_parse_auto_config(codec);
4549 if (err < 0) {
4550 stac_free(codec);
4551 return err;
4554 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4556 return 0;
4559 static int patch_stac92hd73xx(struct hda_codec *codec)
4561 struct sigmatel_spec *spec;
4562 int err;
4563 int num_dacs;
4565 err = alloc_stac_spec(codec);
4566 if (err < 0)
4567 return err;
4569 spec = codec->spec;
4570 /* enable power_save_node only for new 92HD89xx chips, as it causes
4571 * click noises on old 92HD73xx chips.
4573 if ((codec->core.vendor_id & 0xfffffff0) != 0x111d7670)
4574 codec->power_save_node = 1;
4575 spec->linear_tone_beep = 0;
4576 spec->gen.mixer_nid = 0x1d;
4577 spec->have_spdif_mux = 1;
4579 num_dacs = snd_hda_get_num_conns(codec, 0x0a) - 1;
4580 if (num_dacs < 3 || num_dacs > 5) {
4581 codec_warn(codec,
4582 "Could not determine number of channels defaulting to DAC count\n");
4583 num_dacs = 5;
4586 switch (num_dacs) {
4587 case 0x3: /* 6 Channel */
4588 spec->aloopback_ctl = &stac92hd73xx_6ch_loopback;
4589 break;
4590 case 0x4: /* 8 Channel */
4591 spec->aloopback_ctl = &stac92hd73xx_8ch_loopback;
4592 break;
4593 case 0x5: /* 10 Channel */
4594 spec->aloopback_ctl = &stac92hd73xx_10ch_loopback;
4595 break;
4598 spec->aloopback_mask = 0x01;
4599 spec->aloopback_shift = 8;
4601 spec->gen.beep_nid = 0x1c; /* digital beep */
4603 /* GPIO0 High = Enable EAPD */
4604 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
4605 spec->gpio_data = 0x01;
4607 spec->eapd_switch = 1;
4609 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
4610 spec->pwr_nids = stac92hd73xx_pwr_nids;
4612 spec->gen.own_eapd_ctl = 1;
4613 spec->gen.power_down_unused = 1;
4615 snd_hda_pick_fixup(codec, stac92hd73xx_models, stac92hd73xx_fixup_tbl,
4616 stac92hd73xx_fixups);
4617 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4619 if (!spec->volknob_init)
4620 snd_hda_add_verbs(codec, stac92hd73xx_core_init);
4622 err = stac_parse_auto_config(codec);
4623 if (err < 0) {
4624 stac_free(codec);
4625 return err;
4628 /* Don't GPIO-mute speakers if there are no internal speakers, because
4629 * the GPIO might be necessary for Headphone
4631 if (spec->eapd_switch && !has_builtin_speaker(codec))
4632 spec->eapd_switch = 0;
4634 codec->proc_widget_hook = stac92hd7x_proc_hook;
4636 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4638 return 0;
4641 static void stac_setup_gpio(struct hda_codec *codec)
4643 struct sigmatel_spec *spec = codec->spec;
4645 spec->gpio_mask |= spec->eapd_mask;
4646 if (spec->gpio_led) {
4647 if (!spec->vref_mute_led_nid) {
4648 spec->gpio_mask |= spec->gpio_led;
4649 spec->gpio_dir |= spec->gpio_led;
4650 spec->gpio_data |= spec->gpio_led;
4651 } else {
4652 codec->power_filter = stac_vref_led_power_filter;
4656 if (spec->mic_mute_led_gpio) {
4657 spec->gpio_mask |= spec->mic_mute_led_gpio;
4658 spec->gpio_dir |= spec->mic_mute_led_gpio;
4659 spec->mic_enabled = 0;
4660 spec->gpio_data |= spec->mic_mute_led_gpio;
4661 snd_hda_gen_add_micmute_led(codec, stac_capture_led_update);
4665 static int patch_stac92hd83xxx(struct hda_codec *codec)
4667 struct sigmatel_spec *spec;
4668 int err;
4670 err = alloc_stac_spec(codec);
4671 if (err < 0)
4672 return err;
4674 /* longer delay needed for D3 */
4675 codec->core.power_caps &= ~AC_PWRST_EPSS;
4677 spec = codec->spec;
4678 codec->power_save_node = 1;
4679 spec->linear_tone_beep = 0;
4680 spec->gen.own_eapd_ctl = 1;
4681 spec->gen.power_down_unused = 1;
4682 spec->gen.mixer_nid = 0x1b;
4684 spec->gen.beep_nid = 0x21; /* digital beep */
4685 spec->pwr_nids = stac92hd83xxx_pwr_nids;
4686 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
4687 spec->default_polarity = -1; /* no default cfg */
4689 snd_hda_add_verbs(codec, stac92hd83xxx_core_init);
4691 snd_hda_pick_fixup(codec, stac92hd83xxx_models, stac92hd83xxx_fixup_tbl,
4692 stac92hd83xxx_fixups);
4693 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4695 stac_setup_gpio(codec);
4697 err = stac_parse_auto_config(codec);
4698 if (err < 0) {
4699 stac_free(codec);
4700 return err;
4703 codec->proc_widget_hook = stac92hd_proc_hook;
4705 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4707 return 0;
4710 static const hda_nid_t stac92hd95_pwr_nids[] = {
4711 0x0a, 0x0b, 0x0c, 0x0d
4714 static int patch_stac92hd95(struct hda_codec *codec)
4716 struct sigmatel_spec *spec;
4717 int err;
4719 err = alloc_stac_spec(codec);
4720 if (err < 0)
4721 return err;
4723 /* longer delay needed for D3 */
4724 codec->core.power_caps &= ~AC_PWRST_EPSS;
4726 spec = codec->spec;
4727 codec->power_save_node = 1;
4728 spec->linear_tone_beep = 0;
4729 spec->gen.own_eapd_ctl = 1;
4730 spec->gen.power_down_unused = 1;
4732 spec->gen.beep_nid = 0x19; /* digital beep */
4733 spec->pwr_nids = stac92hd95_pwr_nids;
4734 spec->num_pwrs = ARRAY_SIZE(stac92hd95_pwr_nids);
4735 spec->default_polarity = 0;
4737 snd_hda_pick_fixup(codec, stac92hd95_models, stac92hd95_fixup_tbl,
4738 stac92hd95_fixups);
4739 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4741 stac_setup_gpio(codec);
4743 err = stac_parse_auto_config(codec);
4744 if (err < 0) {
4745 stac_free(codec);
4746 return err;
4749 codec->proc_widget_hook = stac92hd_proc_hook;
4751 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4753 return 0;
4756 static int patch_stac92hd71bxx(struct hda_codec *codec)
4758 struct sigmatel_spec *spec;
4759 const hda_nid_t *unmute_nids = stac92hd71bxx_unmute_nids;
4760 int err;
4762 err = alloc_stac_spec(codec);
4763 if (err < 0)
4764 return err;
4766 spec = codec->spec;
4767 /* disabled power_save_node since it causes noises on a Dell machine */
4768 /* codec->power_save_node = 1; */
4769 spec->linear_tone_beep = 0;
4770 spec->gen.own_eapd_ctl = 1;
4771 spec->gen.power_down_unused = 1;
4772 spec->gen.mixer_nid = 0x17;
4773 spec->have_spdif_mux = 1;
4775 /* GPIO0 = EAPD */
4776 spec->gpio_mask = 0x01;
4777 spec->gpio_dir = 0x01;
4778 spec->gpio_data = 0x01;
4780 switch (codec->core.vendor_id) {
4781 case 0x111d76b6: /* 4 Port without Analog Mixer */
4782 case 0x111d76b7:
4783 unmute_nids++;
4784 break;
4785 case 0x111d7608: /* 5 Port with Analog Mixer */
4786 if ((codec->core.revision_id & 0xf) == 0 ||
4787 (codec->core.revision_id & 0xf) == 1)
4788 spec->stream_delay = 40; /* 40 milliseconds */
4790 /* disable VSW */
4791 unmute_nids++;
4792 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0);
4793 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3);
4794 break;
4795 case 0x111d7603: /* 6 Port with Analog Mixer */
4796 if ((codec->core.revision_id & 0xf) == 1)
4797 spec->stream_delay = 40; /* 40 milliseconds */
4799 break;
4802 if (get_wcaps_type(get_wcaps(codec, 0x28)) == AC_WID_VOL_KNB)
4803 snd_hda_add_verbs(codec, stac92hd71bxx_core_init);
4805 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) {
4806 const hda_nid_t *p;
4807 for (p = unmute_nids; *p; p++)
4808 snd_hda_codec_amp_init_stereo(codec, *p, HDA_INPUT, 0,
4809 0xff, 0x00);
4812 spec->aloopback_ctl = &stac92hd71bxx_loopback;
4813 spec->aloopback_mask = 0x50;
4814 spec->aloopback_shift = 0;
4816 spec->powerdown_adcs = 1;
4817 spec->gen.beep_nid = 0x26; /* digital beep */
4818 spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
4819 spec->pwr_nids = stac92hd71bxx_pwr_nids;
4821 snd_hda_pick_fixup(codec, stac92hd71bxx_models, stac92hd71bxx_fixup_tbl,
4822 stac92hd71bxx_fixups);
4823 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4825 stac_setup_gpio(codec);
4827 err = stac_parse_auto_config(codec);
4828 if (err < 0) {
4829 stac_free(codec);
4830 return err;
4833 codec->proc_widget_hook = stac92hd7x_proc_hook;
4835 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4837 return 0;
4840 static int patch_stac922x(struct hda_codec *codec)
4842 struct sigmatel_spec *spec;
4843 int err;
4845 err = alloc_stac_spec(codec);
4846 if (err < 0)
4847 return err;
4849 spec = codec->spec;
4850 spec->linear_tone_beep = 1;
4851 spec->gen.own_eapd_ctl = 1;
4853 snd_hda_add_verbs(codec, stac922x_core_init);
4855 /* Fix Mux capture level; max to 2 */
4856 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
4857 (0 << AC_AMPCAP_OFFSET_SHIFT) |
4858 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4859 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4860 (0 << AC_AMPCAP_MUTE_SHIFT));
4862 snd_hda_pick_fixup(codec, stac922x_models, stac922x_fixup_tbl,
4863 stac922x_fixups);
4864 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4866 err = stac_parse_auto_config(codec);
4867 if (err < 0) {
4868 stac_free(codec);
4869 return err;
4872 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4874 return 0;
4877 static const char * const stac927x_spdif_labels[] = {
4878 "Digital Playback", "ADAT", "Analog Mux 1",
4879 "Analog Mux 2", "Analog Mux 3", NULL
4882 static int patch_stac927x(struct hda_codec *codec)
4884 struct sigmatel_spec *spec;
4885 int err;
4887 err = alloc_stac_spec(codec);
4888 if (err < 0)
4889 return err;
4891 spec = codec->spec;
4892 spec->linear_tone_beep = 1;
4893 spec->gen.own_eapd_ctl = 1;
4894 spec->have_spdif_mux = 1;
4895 spec->spdif_labels = stac927x_spdif_labels;
4897 spec->gen.beep_nid = 0x23; /* digital beep */
4899 /* GPIO0 High = Enable EAPD */
4900 spec->eapd_mask = spec->gpio_mask = 0x01;
4901 spec->gpio_dir = spec->gpio_data = 0x01;
4903 spec->aloopback_ctl = &stac927x_loopback;
4904 spec->aloopback_mask = 0x40;
4905 spec->aloopback_shift = 0;
4906 spec->eapd_switch = 1;
4908 snd_hda_pick_fixup(codec, stac927x_models, stac927x_fixup_tbl,
4909 stac927x_fixups);
4910 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4912 if (!spec->volknob_init)
4913 snd_hda_add_verbs(codec, stac927x_core_init);
4915 err = stac_parse_auto_config(codec);
4916 if (err < 0) {
4917 stac_free(codec);
4918 return err;
4921 codec->proc_widget_hook = stac927x_proc_hook;
4924 * !!FIXME!!
4925 * The STAC927x seem to require fairly long delays for certain
4926 * command sequences. With too short delays (even if the answer
4927 * is set to RIRB properly), it results in the silence output
4928 * on some hardwares like Dell.
4930 * The below flag enables the longer delay (see get_response
4931 * in hda_intel.c).
4933 codec->bus->needs_damn_long_delay = 1;
4935 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4937 return 0;
4940 static int patch_stac9205(struct hda_codec *codec)
4942 struct sigmatel_spec *spec;
4943 int err;
4945 err = alloc_stac_spec(codec);
4946 if (err < 0)
4947 return err;
4949 spec = codec->spec;
4950 spec->linear_tone_beep = 1;
4951 spec->gen.own_eapd_ctl = 1;
4952 spec->have_spdif_mux = 1;
4954 spec->gen.beep_nid = 0x23; /* digital beep */
4956 snd_hda_add_verbs(codec, stac9205_core_init);
4957 spec->aloopback_ctl = &stac9205_loopback;
4959 spec->aloopback_mask = 0x40;
4960 spec->aloopback_shift = 0;
4962 /* GPIO0 High = EAPD */
4963 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
4964 spec->gpio_data = 0x01;
4966 /* Turn on/off EAPD per HP plugging */
4967 spec->eapd_switch = 1;
4969 snd_hda_pick_fixup(codec, stac9205_models, stac9205_fixup_tbl,
4970 stac9205_fixups);
4971 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4973 err = stac_parse_auto_config(codec);
4974 if (err < 0) {
4975 stac_free(codec);
4976 return err;
4979 codec->proc_widget_hook = stac9205_proc_hook;
4981 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4983 return 0;
4987 * STAC9872 hack
4990 static const struct hda_verb stac9872_core_init[] = {
4991 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
4992 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
4996 static const struct hda_pintbl stac9872_vaio_pin_configs[] = {
4997 { 0x0a, 0x03211020 },
4998 { 0x0b, 0x411111f0 },
4999 { 0x0c, 0x411111f0 },
5000 { 0x0d, 0x03a15030 },
5001 { 0x0e, 0x411111f0 },
5002 { 0x0f, 0x90170110 },
5003 { 0x11, 0x411111f0 },
5004 { 0x13, 0x411111f0 },
5005 { 0x14, 0x90a7013e },
5009 static const struct hda_model_fixup stac9872_models[] = {
5010 { .id = STAC_9872_VAIO, .name = "vaio" },
5014 static const struct hda_fixup stac9872_fixups[] = {
5015 [STAC_9872_VAIO] = {
5016 .type = HDA_FIXUP_PINS,
5017 .v.pins = stac9872_vaio_pin_configs,
5021 static const struct snd_pci_quirk stac9872_fixup_tbl[] = {
5022 SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0,
5023 "Sony VAIO F/S", STAC_9872_VAIO),
5024 {} /* terminator */
5027 static int patch_stac9872(struct hda_codec *codec)
5029 struct sigmatel_spec *spec;
5030 int err;
5032 err = alloc_stac_spec(codec);
5033 if (err < 0)
5034 return err;
5036 spec = codec->spec;
5037 spec->linear_tone_beep = 1;
5038 spec->gen.own_eapd_ctl = 1;
5040 snd_hda_add_verbs(codec, stac9872_core_init);
5042 snd_hda_pick_fixup(codec, stac9872_models, stac9872_fixup_tbl,
5043 stac9872_fixups);
5044 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
5046 err = stac_parse_auto_config(codec);
5047 if (err < 0) {
5048 stac_free(codec);
5049 return -EINVAL;
5052 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
5054 return 0;
5059 * patch entries
5061 static const struct hda_device_id snd_hda_id_sigmatel[] = {
5062 HDA_CODEC_ENTRY(0x83847690, "STAC9200", patch_stac9200),
5063 HDA_CODEC_ENTRY(0x83847882, "STAC9220 A1", patch_stac922x),
5064 HDA_CODEC_ENTRY(0x83847680, "STAC9221 A1", patch_stac922x),
5065 HDA_CODEC_ENTRY(0x83847880, "STAC9220 A2", patch_stac922x),
5066 HDA_CODEC_ENTRY(0x83847681, "STAC9220D/9223D A2", patch_stac922x),
5067 HDA_CODEC_ENTRY(0x83847682, "STAC9221 A2", patch_stac922x),
5068 HDA_CODEC_ENTRY(0x83847683, "STAC9221D A2", patch_stac922x),
5069 HDA_CODEC_ENTRY(0x83847618, "STAC9227", patch_stac927x),
5070 HDA_CODEC_ENTRY(0x83847619, "STAC9227", patch_stac927x),
5071 HDA_CODEC_ENTRY(0x83847638, "STAC92HD700", patch_stac927x),
5072 HDA_CODEC_ENTRY(0x83847616, "STAC9228", patch_stac927x),
5073 HDA_CODEC_ENTRY(0x83847617, "STAC9228", patch_stac927x),
5074 HDA_CODEC_ENTRY(0x83847614, "STAC9229", patch_stac927x),
5075 HDA_CODEC_ENTRY(0x83847615, "STAC9229", patch_stac927x),
5076 HDA_CODEC_ENTRY(0x83847620, "STAC9274", patch_stac927x),
5077 HDA_CODEC_ENTRY(0x83847621, "STAC9274D", patch_stac927x),
5078 HDA_CODEC_ENTRY(0x83847622, "STAC9273X", patch_stac927x),
5079 HDA_CODEC_ENTRY(0x83847623, "STAC9273D", patch_stac927x),
5080 HDA_CODEC_ENTRY(0x83847624, "STAC9272X", patch_stac927x),
5081 HDA_CODEC_ENTRY(0x83847625, "STAC9272D", patch_stac927x),
5082 HDA_CODEC_ENTRY(0x83847626, "STAC9271X", patch_stac927x),
5083 HDA_CODEC_ENTRY(0x83847627, "STAC9271D", patch_stac927x),
5084 HDA_CODEC_ENTRY(0x83847628, "STAC9274X5NH", patch_stac927x),
5085 HDA_CODEC_ENTRY(0x83847629, "STAC9274D5NH", patch_stac927x),
5086 HDA_CODEC_ENTRY(0x83847632, "STAC9202", patch_stac925x),
5087 HDA_CODEC_ENTRY(0x83847633, "STAC9202D", patch_stac925x),
5088 HDA_CODEC_ENTRY(0x83847634, "STAC9250", patch_stac925x),
5089 HDA_CODEC_ENTRY(0x83847635, "STAC9250D", patch_stac925x),
5090 HDA_CODEC_ENTRY(0x83847636, "STAC9251", patch_stac925x),
5091 HDA_CODEC_ENTRY(0x83847637, "STAC9250D", patch_stac925x),
5092 HDA_CODEC_ENTRY(0x83847645, "92HD206X", patch_stac927x),
5093 HDA_CODEC_ENTRY(0x83847646, "92HD206D", patch_stac927x),
5094 /* The following does not take into account .id=0x83847661 when subsys =
5095 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
5096 * currently not fully supported.
5098 HDA_CODEC_ENTRY(0x83847661, "CXD9872RD/K", patch_stac9872),
5099 HDA_CODEC_ENTRY(0x83847662, "STAC9872AK", patch_stac9872),
5100 HDA_CODEC_ENTRY(0x83847664, "CXD9872AKD", patch_stac9872),
5101 HDA_CODEC_ENTRY(0x83847698, "STAC9205", patch_stac9205),
5102 HDA_CODEC_ENTRY(0x838476a0, "STAC9205", patch_stac9205),
5103 HDA_CODEC_ENTRY(0x838476a1, "STAC9205D", patch_stac9205),
5104 HDA_CODEC_ENTRY(0x838476a2, "STAC9204", patch_stac9205),
5105 HDA_CODEC_ENTRY(0x838476a3, "STAC9204D", patch_stac9205),
5106 HDA_CODEC_ENTRY(0x838476a4, "STAC9255", patch_stac9205),
5107 HDA_CODEC_ENTRY(0x838476a5, "STAC9255D", patch_stac9205),
5108 HDA_CODEC_ENTRY(0x838476a6, "STAC9254", patch_stac9205),
5109 HDA_CODEC_ENTRY(0x838476a7, "STAC9254D", patch_stac9205),
5110 HDA_CODEC_ENTRY(0x111d7603, "92HD75B3X5", patch_stac92hd71bxx),
5111 HDA_CODEC_ENTRY(0x111d7604, "92HD83C1X5", patch_stac92hd83xxx),
5112 HDA_CODEC_ENTRY(0x111d76d4, "92HD83C1C5", patch_stac92hd83xxx),
5113 HDA_CODEC_ENTRY(0x111d7605, "92HD81B1X5", patch_stac92hd83xxx),
5114 HDA_CODEC_ENTRY(0x111d76d5, "92HD81B1C5", patch_stac92hd83xxx),
5115 HDA_CODEC_ENTRY(0x111d76d1, "92HD87B1/3", patch_stac92hd83xxx),
5116 HDA_CODEC_ENTRY(0x111d76d9, "92HD87B2/4", patch_stac92hd83xxx),
5117 HDA_CODEC_ENTRY(0x111d7666, "92HD88B3", patch_stac92hd83xxx),
5118 HDA_CODEC_ENTRY(0x111d7667, "92HD88B1", patch_stac92hd83xxx),
5119 HDA_CODEC_ENTRY(0x111d7668, "92HD88B2", patch_stac92hd83xxx),
5120 HDA_CODEC_ENTRY(0x111d7669, "92HD88B4", patch_stac92hd83xxx),
5121 HDA_CODEC_ENTRY(0x111d7608, "92HD75B2X5", patch_stac92hd71bxx),
5122 HDA_CODEC_ENTRY(0x111d7674, "92HD73D1X5", patch_stac92hd73xx),
5123 HDA_CODEC_ENTRY(0x111d7675, "92HD73C1X5", patch_stac92hd73xx),
5124 HDA_CODEC_ENTRY(0x111d7676, "92HD73E1X5", patch_stac92hd73xx),
5125 HDA_CODEC_ENTRY(0x111d7695, "92HD95", patch_stac92hd95),
5126 HDA_CODEC_ENTRY(0x111d76b0, "92HD71B8X", patch_stac92hd71bxx),
5127 HDA_CODEC_ENTRY(0x111d76b1, "92HD71B8X", patch_stac92hd71bxx),
5128 HDA_CODEC_ENTRY(0x111d76b2, "92HD71B7X", patch_stac92hd71bxx),
5129 HDA_CODEC_ENTRY(0x111d76b3, "92HD71B7X", patch_stac92hd71bxx),
5130 HDA_CODEC_ENTRY(0x111d76b4, "92HD71B6X", patch_stac92hd71bxx),
5131 HDA_CODEC_ENTRY(0x111d76b5, "92HD71B6X", patch_stac92hd71bxx),
5132 HDA_CODEC_ENTRY(0x111d76b6, "92HD71B5X", patch_stac92hd71bxx),
5133 HDA_CODEC_ENTRY(0x111d76b7, "92HD71B5X", patch_stac92hd71bxx),
5134 HDA_CODEC_ENTRY(0x111d76c0, "92HD89C3", patch_stac92hd73xx),
5135 HDA_CODEC_ENTRY(0x111d76c1, "92HD89C2", patch_stac92hd73xx),
5136 HDA_CODEC_ENTRY(0x111d76c2, "92HD89C1", patch_stac92hd73xx),
5137 HDA_CODEC_ENTRY(0x111d76c3, "92HD89B3", patch_stac92hd73xx),
5138 HDA_CODEC_ENTRY(0x111d76c4, "92HD89B2", patch_stac92hd73xx),
5139 HDA_CODEC_ENTRY(0x111d76c5, "92HD89B1", patch_stac92hd73xx),
5140 HDA_CODEC_ENTRY(0x111d76c6, "92HD89E3", patch_stac92hd73xx),
5141 HDA_CODEC_ENTRY(0x111d76c7, "92HD89E2", patch_stac92hd73xx),
5142 HDA_CODEC_ENTRY(0x111d76c8, "92HD89E1", patch_stac92hd73xx),
5143 HDA_CODEC_ENTRY(0x111d76c9, "92HD89D3", patch_stac92hd73xx),
5144 HDA_CODEC_ENTRY(0x111d76ca, "92HD89D2", patch_stac92hd73xx),
5145 HDA_CODEC_ENTRY(0x111d76cb, "92HD89D1", patch_stac92hd73xx),
5146 HDA_CODEC_ENTRY(0x111d76cc, "92HD89F3", patch_stac92hd73xx),
5147 HDA_CODEC_ENTRY(0x111d76cd, "92HD89F2", patch_stac92hd73xx),
5148 HDA_CODEC_ENTRY(0x111d76ce, "92HD89F1", patch_stac92hd73xx),
5149 HDA_CODEC_ENTRY(0x111d76df, "92HD93BXX", patch_stac92hd83xxx),
5150 HDA_CODEC_ENTRY(0x111d76e0, "92HD91BXX", patch_stac92hd83xxx),
5151 HDA_CODEC_ENTRY(0x111d76e3, "92HD98BXX", patch_stac92hd83xxx),
5152 HDA_CODEC_ENTRY(0x111d76e5, "92HD99BXX", patch_stac92hd83xxx),
5153 HDA_CODEC_ENTRY(0x111d76e7, "92HD90BXX", patch_stac92hd83xxx),
5154 HDA_CODEC_ENTRY(0x111d76e8, "92HD66B1X5", patch_stac92hd83xxx),
5155 HDA_CODEC_ENTRY(0x111d76e9, "92HD66B2X5", patch_stac92hd83xxx),
5156 HDA_CODEC_ENTRY(0x111d76ea, "92HD66B3X5", patch_stac92hd83xxx),
5157 HDA_CODEC_ENTRY(0x111d76eb, "92HD66C1X5", patch_stac92hd83xxx),
5158 HDA_CODEC_ENTRY(0x111d76ec, "92HD66C2X5", patch_stac92hd83xxx),
5159 HDA_CODEC_ENTRY(0x111d76ed, "92HD66C3X5", patch_stac92hd83xxx),
5160 HDA_CODEC_ENTRY(0x111d76ee, "92HD66B1X3", patch_stac92hd83xxx),
5161 HDA_CODEC_ENTRY(0x111d76ef, "92HD66B2X3", patch_stac92hd83xxx),
5162 HDA_CODEC_ENTRY(0x111d76f0, "92HD66B3X3", patch_stac92hd83xxx),
5163 HDA_CODEC_ENTRY(0x111d76f1, "92HD66C1X3", patch_stac92hd83xxx),
5164 HDA_CODEC_ENTRY(0x111d76f2, "92HD66C2X3", patch_stac92hd83xxx),
5165 HDA_CODEC_ENTRY(0x111d76f3, "92HD66C3/65", patch_stac92hd83xxx),
5166 {} /* terminator */
5168 MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_sigmatel);
5170 MODULE_LICENSE("GPL");
5171 MODULE_DESCRIPTION("IDT/Sigmatel HD-audio codec");
5173 static struct hda_codec_driver sigmatel_driver = {
5174 .id = snd_hda_id_sigmatel,
5177 module_hda_codec_driver(sigmatel_driver);