pvrusb2: reduce stack usage pvr2_eeprom_analyze()
[linux/fpc-iii.git] / sound / pci / hda / patch_sigmatel.c
blob0abab7926dca3fe835decb2d28030b214a2adee0
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_92HD89XX_HP_FRONT_JACK,
81 STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK,
82 STAC_92HD73XX_ASUS_MOBO,
83 STAC_92HD73XX_MODELS
86 enum {
87 STAC_92HD83XXX_REF,
88 STAC_92HD83XXX_PWR_REF,
89 STAC_DELL_S14,
90 STAC_DELL_VOSTRO_3500,
91 STAC_92HD83XXX_HP_cNB11_INTQUAD,
92 STAC_HP_DV7_4000,
93 STAC_HP_ZEPHYR,
94 STAC_92HD83XXX_HP_LED,
95 STAC_92HD83XXX_HP_INV_LED,
96 STAC_92HD83XXX_HP_MIC_LED,
97 STAC_HP_LED_GPIO10,
98 STAC_92HD83XXX_HEADSET_JACK,
99 STAC_92HD83XXX_HP,
100 STAC_HP_ENVY_BASS,
101 STAC_HP_BNB13_EQ,
102 STAC_HP_ENVY_TS_BASS,
103 STAC_HP_ENVY_TS_DAC_BIND,
104 STAC_92HD83XXX_GPIO10_EAPD,
105 STAC_92HD83XXX_MODELS
108 enum {
109 STAC_92HD71BXX_REF,
110 STAC_DELL_M4_1,
111 STAC_DELL_M4_2,
112 STAC_DELL_M4_3,
113 STAC_HP_M4,
114 STAC_HP_DV4,
115 STAC_HP_DV5,
116 STAC_HP_HDX,
117 STAC_92HD71BXX_HP,
118 STAC_92HD71BXX_NO_DMIC,
119 STAC_92HD71BXX_NO_SMUX,
120 STAC_92HD71BXX_MODELS
123 enum {
124 STAC_92HD95_HP_LED,
125 STAC_92HD95_HP_BASS,
126 STAC_92HD95_MODELS
129 enum {
130 STAC_925x_REF,
131 STAC_M1,
132 STAC_M1_2,
133 STAC_M2,
134 STAC_M2_2,
135 STAC_M3,
136 STAC_M5,
137 STAC_M6,
138 STAC_925x_MODELS
141 enum {
142 STAC_D945_REF,
143 STAC_D945GTP3,
144 STAC_D945GTP5,
145 STAC_INTEL_MAC_V1,
146 STAC_INTEL_MAC_V2,
147 STAC_INTEL_MAC_V3,
148 STAC_INTEL_MAC_V4,
149 STAC_INTEL_MAC_V5,
150 STAC_INTEL_MAC_AUTO,
151 STAC_ECS_202,
152 STAC_922X_DELL_D81,
153 STAC_922X_DELL_D82,
154 STAC_922X_DELL_M81,
155 STAC_922X_DELL_M82,
156 STAC_922X_INTEL_MAC_GPIO,
157 STAC_922X_MODELS
160 enum {
161 STAC_D965_REF_NO_JD, /* no jack-detection */
162 STAC_D965_REF,
163 STAC_D965_3ST,
164 STAC_D965_5ST,
165 STAC_D965_5ST_NO_FP,
166 STAC_D965_VERBS,
167 STAC_DELL_3ST,
168 STAC_DELL_BIOS,
169 STAC_DELL_BIOS_AMIC,
170 STAC_DELL_BIOS_SPDIF,
171 STAC_927X_DELL_DMIC,
172 STAC_927X_VOLKNOB,
173 STAC_927X_MODELS
176 enum {
177 STAC_9872_VAIO,
178 STAC_9872_MODELS
181 struct sigmatel_spec {
182 struct hda_gen_spec gen;
184 unsigned int eapd_switch: 1;
185 unsigned int linear_tone_beep:1;
186 unsigned int headset_jack:1; /* 4-pin headset jack (hp + mono mic) */
187 unsigned int volknob_init:1; /* special volume-knob initialization */
188 unsigned int powerdown_adcs:1;
189 unsigned int have_spdif_mux:1;
191 /* gpio lines */
192 unsigned int eapd_mask;
193 unsigned int gpio_mask;
194 unsigned int gpio_dir;
195 unsigned int gpio_data;
196 unsigned int gpio_mute;
197 unsigned int gpio_led;
198 unsigned int gpio_led_polarity;
199 unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */
200 unsigned int vref_led;
201 int default_polarity;
203 unsigned int mic_mute_led_gpio; /* capture mute LED GPIO */
204 unsigned int mic_enabled; /* current mic mute state (bitmask) */
206 /* stream */
207 unsigned int stream_delay;
209 /* analog loopback */
210 const struct snd_kcontrol_new *aloopback_ctl;
211 unsigned int aloopback;
212 unsigned char aloopback_mask;
213 unsigned char aloopback_shift;
215 /* power management */
216 unsigned int power_map_bits;
217 unsigned int num_pwrs;
218 const hda_nid_t *pwr_nids;
219 unsigned int active_adcs;
221 /* beep widgets */
222 hda_nid_t anabeep_nid;
224 /* SPDIF-out mux */
225 const char * const *spdif_labels;
226 struct hda_input_mux spdif_mux;
227 unsigned int cur_smux[2];
230 #define AC_VERB_IDT_SET_POWER_MAP 0x7ec
231 #define AC_VERB_IDT_GET_POWER_MAP 0xfec
233 static const hda_nid_t stac92hd73xx_pwr_nids[8] = {
234 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
235 0x0f, 0x10, 0x11
238 static const hda_nid_t stac92hd83xxx_pwr_nids[7] = {
239 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
240 0x0f, 0x10
243 static const hda_nid_t stac92hd71bxx_pwr_nids[3] = {
244 0x0a, 0x0d, 0x0f
249 * PCM hooks
251 static void stac_playback_pcm_hook(struct hda_pcm_stream *hinfo,
252 struct hda_codec *codec,
253 struct snd_pcm_substream *substream,
254 int action)
256 struct sigmatel_spec *spec = codec->spec;
257 if (action == HDA_GEN_PCM_ACT_OPEN && spec->stream_delay)
258 msleep(spec->stream_delay);
261 static void stac_capture_pcm_hook(struct hda_pcm_stream *hinfo,
262 struct hda_codec *codec,
263 struct snd_pcm_substream *substream,
264 int action)
266 struct sigmatel_spec *spec = codec->spec;
267 int i, idx = 0;
269 if (!spec->powerdown_adcs)
270 return;
272 for (i = 0; i < spec->gen.num_all_adcs; i++) {
273 if (spec->gen.all_adcs[i] == hinfo->nid) {
274 idx = i;
275 break;
279 switch (action) {
280 case HDA_GEN_PCM_ACT_OPEN:
281 msleep(40);
282 snd_hda_codec_write(codec, hinfo->nid, 0,
283 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
284 spec->active_adcs |= (1 << idx);
285 break;
286 case HDA_GEN_PCM_ACT_CLOSE:
287 snd_hda_codec_write(codec, hinfo->nid, 0,
288 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
289 spec->active_adcs &= ~(1 << idx);
290 break;
295 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
296 * funky external mute control using GPIO pins.
299 static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
300 unsigned int dir_mask, unsigned int data)
302 unsigned int gpiostate, gpiomask, gpiodir;
303 hda_nid_t fg = codec->core.afg;
305 codec_dbg(codec, "%s msk %x dir %x gpio %x\n", __func__, mask, dir_mask, data);
307 gpiostate = snd_hda_codec_read(codec, fg, 0,
308 AC_VERB_GET_GPIO_DATA, 0);
309 gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask);
311 gpiomask = snd_hda_codec_read(codec, fg, 0,
312 AC_VERB_GET_GPIO_MASK, 0);
313 gpiomask |= mask;
315 gpiodir = snd_hda_codec_read(codec, fg, 0,
316 AC_VERB_GET_GPIO_DIRECTION, 0);
317 gpiodir |= dir_mask;
319 /* Configure GPIOx as CMOS */
320 snd_hda_codec_write(codec, fg, 0, 0x7e7, 0);
322 snd_hda_codec_write(codec, fg, 0,
323 AC_VERB_SET_GPIO_MASK, gpiomask);
324 snd_hda_codec_read(codec, fg, 0,
325 AC_VERB_SET_GPIO_DIRECTION, gpiodir); /* sync */
327 msleep(1);
329 snd_hda_codec_read(codec, fg, 0,
330 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
333 /* hook for controlling mic-mute LED GPIO */
334 static void stac_capture_led_hook(struct hda_codec *codec,
335 struct snd_kcontrol *kcontrol,
336 struct snd_ctl_elem_value *ucontrol)
338 struct sigmatel_spec *spec = codec->spec;
339 unsigned int mask;
340 bool cur_mute, prev_mute;
342 if (!kcontrol || !ucontrol)
343 return;
345 mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
346 prev_mute = !spec->mic_enabled;
347 if (ucontrol->value.integer.value[0] ||
348 ucontrol->value.integer.value[1])
349 spec->mic_enabled |= mask;
350 else
351 spec->mic_enabled &= ~mask;
352 cur_mute = !spec->mic_enabled;
353 if (cur_mute != prev_mute) {
354 if (cur_mute)
355 spec->gpio_data |= spec->mic_mute_led_gpio;
356 else
357 spec->gpio_data &= ~spec->mic_mute_led_gpio;
358 stac_gpio_set(codec, spec->gpio_mask,
359 spec->gpio_dir, spec->gpio_data);
363 static int stac_vrefout_set(struct hda_codec *codec,
364 hda_nid_t nid, unsigned int new_vref)
366 int error, pinctl;
368 codec_dbg(codec, "%s, nid %x ctl %x\n", __func__, nid, new_vref);
369 pinctl = snd_hda_codec_read(codec, nid, 0,
370 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
372 if (pinctl < 0)
373 return pinctl;
375 pinctl &= 0xff;
376 pinctl &= ~AC_PINCTL_VREFEN;
377 pinctl |= (new_vref & AC_PINCTL_VREFEN);
379 error = snd_hda_set_pin_ctl_cache(codec, nid, pinctl);
380 if (error < 0)
381 return error;
383 return 1;
386 /* prevent codec AFG to D3 state when vref-out pin is used for mute LED */
387 /* this hook is set in stac_setup_gpio() */
388 static unsigned int stac_vref_led_power_filter(struct hda_codec *codec,
389 hda_nid_t nid,
390 unsigned int power_state)
392 if (nid == codec->core.afg && power_state == AC_PWRST_D3)
393 return AC_PWRST_D1;
394 return snd_hda_gen_path_power_filter(codec, nid, power_state);
397 /* update mute-LED accoring to the master switch */
398 static void stac_update_led_status(struct hda_codec *codec, int enabled)
400 struct sigmatel_spec *spec = codec->spec;
401 int muted = !enabled;
403 if (!spec->gpio_led)
404 return;
406 /* LED state is inverted on these systems */
407 if (spec->gpio_led_polarity)
408 muted = !muted;
410 if (!spec->vref_mute_led_nid) {
411 if (muted)
412 spec->gpio_data |= spec->gpio_led;
413 else
414 spec->gpio_data &= ~spec->gpio_led;
415 stac_gpio_set(codec, spec->gpio_mask,
416 spec->gpio_dir, spec->gpio_data);
417 } else {
418 spec->vref_led = muted ? AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
419 stac_vrefout_set(codec, spec->vref_mute_led_nid,
420 spec->vref_led);
424 /* vmaster hook to update mute LED */
425 static void stac_vmaster_hook(void *private_data, int val)
427 stac_update_led_status(private_data, val);
430 /* automute hook to handle GPIO mute and EAPD updates */
431 static void stac_update_outputs(struct hda_codec *codec)
433 struct sigmatel_spec *spec = codec->spec;
435 if (spec->gpio_mute)
436 spec->gen.master_mute =
437 !(snd_hda_codec_read(codec, codec->core.afg, 0,
438 AC_VERB_GET_GPIO_DATA, 0) & spec->gpio_mute);
440 snd_hda_gen_update_outputs(codec);
442 if (spec->eapd_mask && spec->eapd_switch) {
443 unsigned int val = spec->gpio_data;
444 if (spec->gen.speaker_muted)
445 val &= ~spec->eapd_mask;
446 else
447 val |= spec->eapd_mask;
448 if (spec->gpio_data != val) {
449 spec->gpio_data = val;
450 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir,
451 val);
456 static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
457 bool enable, bool do_write)
459 struct sigmatel_spec *spec = codec->spec;
460 unsigned int idx, val;
462 for (idx = 0; idx < spec->num_pwrs; idx++) {
463 if (spec->pwr_nids[idx] == nid)
464 break;
466 if (idx >= spec->num_pwrs)
467 return;
469 idx = 1 << idx;
471 val = spec->power_map_bits;
472 if (enable)
473 val &= ~idx;
474 else
475 val |= idx;
477 /* power down unused output ports */
478 if (val != spec->power_map_bits) {
479 spec->power_map_bits = val;
480 if (do_write)
481 snd_hda_codec_write(codec, codec->core.afg, 0,
482 AC_VERB_IDT_SET_POWER_MAP, val);
486 /* update power bit per jack plug/unplug */
487 static void jack_update_power(struct hda_codec *codec,
488 struct hda_jack_callback *jack)
490 struct sigmatel_spec *spec = codec->spec;
491 int i;
493 if (!spec->num_pwrs)
494 return;
496 if (jack && jack->nid) {
497 stac_toggle_power_map(codec, jack->nid,
498 snd_hda_jack_detect(codec, jack->nid),
499 true);
500 return;
503 /* update all jacks */
504 for (i = 0; i < spec->num_pwrs; i++) {
505 hda_nid_t nid = spec->pwr_nids[i];
506 if (!snd_hda_jack_tbl_get(codec, nid))
507 continue;
508 stac_toggle_power_map(codec, nid,
509 snd_hda_jack_detect(codec, nid),
510 false);
513 snd_hda_codec_write(codec, codec->core.afg, 0,
514 AC_VERB_IDT_SET_POWER_MAP,
515 spec->power_map_bits);
518 static void stac_vref_event(struct hda_codec *codec,
519 struct hda_jack_callback *event)
521 unsigned int data;
523 data = snd_hda_codec_read(codec, codec->core.afg, 0,
524 AC_VERB_GET_GPIO_DATA, 0);
525 /* toggle VREF state based on GPIOx status */
526 snd_hda_codec_write(codec, codec->core.afg, 0, 0x7e0,
527 !!(data & (1 << event->private_data)));
530 /* initialize the power map and enable the power event to jacks that
531 * haven't been assigned to automute
533 static void stac_init_power_map(struct hda_codec *codec)
535 struct sigmatel_spec *spec = codec->spec;
536 int i;
538 for (i = 0; i < spec->num_pwrs; i++) {
539 hda_nid_t nid = spec->pwr_nids[i];
540 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
541 def_conf = get_defcfg_connect(def_conf);
542 if (def_conf == AC_JACK_PORT_COMPLEX &&
543 spec->vref_mute_led_nid != nid &&
544 is_jack_detectable(codec, nid)) {
545 snd_hda_jack_detect_enable_callback(codec, nid,
546 jack_update_power);
547 } else {
548 if (def_conf == AC_JACK_PORT_NONE)
549 stac_toggle_power_map(codec, nid, false, false);
550 else
551 stac_toggle_power_map(codec, nid, true, false);
559 static inline bool get_int_hint(struct hda_codec *codec, const char *key,
560 int *valp)
562 return !snd_hda_get_int_hint(codec, key, valp);
565 /* override some hints from the hwdep entry */
566 static void stac_store_hints(struct hda_codec *codec)
568 struct sigmatel_spec *spec = codec->spec;
569 int val;
571 if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) {
572 spec->eapd_mask = spec->gpio_dir = spec->gpio_data =
573 spec->gpio_mask;
575 if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir))
576 spec->gpio_dir &= spec->gpio_mask;
577 if (get_int_hint(codec, "gpio_data", &spec->gpio_data))
578 spec->gpio_data &= spec->gpio_mask;
579 if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask))
580 spec->eapd_mask &= spec->gpio_mask;
581 if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute))
582 spec->gpio_mute &= spec->gpio_mask;
583 val = snd_hda_get_bool_hint(codec, "eapd_switch");
584 if (val >= 0)
585 spec->eapd_switch = val;
589 * loopback controls
592 #define stac_aloopback_info snd_ctl_boolean_mono_info
594 static int stac_aloopback_get(struct snd_kcontrol *kcontrol,
595 struct snd_ctl_elem_value *ucontrol)
597 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
598 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
599 struct sigmatel_spec *spec = codec->spec;
601 ucontrol->value.integer.value[0] = !!(spec->aloopback &
602 (spec->aloopback_mask << idx));
603 return 0;
606 static int stac_aloopback_put(struct snd_kcontrol *kcontrol,
607 struct snd_ctl_elem_value *ucontrol)
609 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
610 struct sigmatel_spec *spec = codec->spec;
611 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
612 unsigned int dac_mode;
613 unsigned int val, idx_val;
615 idx_val = spec->aloopback_mask << idx;
616 if (ucontrol->value.integer.value[0])
617 val = spec->aloopback | idx_val;
618 else
619 val = spec->aloopback & ~idx_val;
620 if (spec->aloopback == val)
621 return 0;
623 spec->aloopback = val;
625 /* Only return the bits defined by the shift value of the
626 * first two bytes of the mask
628 dac_mode = snd_hda_codec_read(codec, codec->core.afg, 0,
629 kcontrol->private_value & 0xFFFF, 0x0);
630 dac_mode >>= spec->aloopback_shift;
632 if (spec->aloopback & idx_val) {
633 snd_hda_power_up(codec);
634 dac_mode |= idx_val;
635 } else {
636 snd_hda_power_down(codec);
637 dac_mode &= ~idx_val;
640 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
641 kcontrol->private_value >> 16, dac_mode);
643 return 1;
646 #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \
648 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
649 .name = "Analog Loopback", \
650 .count = cnt, \
651 .info = stac_aloopback_info, \
652 .get = stac_aloopback_get, \
653 .put = stac_aloopback_put, \
654 .private_value = verb_read | (verb_write << 16), \
658 * Mute LED handling on HP laptops
661 /* check whether it's a HP laptop with a docking port */
662 static bool hp_bnb2011_with_dock(struct hda_codec *codec)
664 if (codec->core.vendor_id != 0x111d7605 &&
665 codec->core.vendor_id != 0x111d76d1)
666 return false;
668 switch (codec->core.subsystem_id) {
669 case 0x103c1618:
670 case 0x103c1619:
671 case 0x103c161a:
672 case 0x103c161b:
673 case 0x103c161c:
674 case 0x103c161d:
675 case 0x103c161e:
676 case 0x103c161f:
678 case 0x103c162a:
679 case 0x103c162b:
681 case 0x103c1630:
682 case 0x103c1631:
684 case 0x103c1633:
685 case 0x103c1634:
686 case 0x103c1635:
688 case 0x103c3587:
689 case 0x103c3588:
690 case 0x103c3589:
691 case 0x103c358a:
693 case 0x103c3667:
694 case 0x103c3668:
695 case 0x103c3669:
697 return true;
699 return false;
702 static bool hp_blike_system(u32 subsystem_id)
704 switch (subsystem_id) {
705 case 0x103c1473: /* HP ProBook 6550b */
706 case 0x103c1520:
707 case 0x103c1521:
708 case 0x103c1523:
709 case 0x103c1524:
710 case 0x103c1525:
711 case 0x103c1722:
712 case 0x103c1723:
713 case 0x103c1724:
714 case 0x103c1725:
715 case 0x103c1726:
716 case 0x103c1727:
717 case 0x103c1728:
718 case 0x103c1729:
719 case 0x103c172a:
720 case 0x103c172b:
721 case 0x103c307e:
722 case 0x103c307f:
723 case 0x103c3080:
724 case 0x103c3081:
725 case 0x103c7007:
726 case 0x103c7008:
727 return true;
729 return false;
732 static void set_hp_led_gpio(struct hda_codec *codec)
734 struct sigmatel_spec *spec = codec->spec;
735 unsigned int gpio;
737 if (spec->gpio_led)
738 return;
740 gpio = snd_hda_param_read(codec, codec->core.afg, AC_PAR_GPIO_CAP);
741 gpio &= AC_GPIO_IO_COUNT;
742 if (gpio > 3)
743 spec->gpio_led = 0x08; /* GPIO 3 */
744 else
745 spec->gpio_led = 0x01; /* GPIO 0 */
749 * This method searches for the mute LED GPIO configuration
750 * provided as OEM string in SMBIOS. The format of that string
751 * is HP_Mute_LED_P_G or HP_Mute_LED_P
752 * where P can be 0 or 1 and defines mute LED GPIO control state (low/high)
753 * that corresponds to the NOT muted state of the master volume
754 * and G is the index of the GPIO to use as the mute LED control (0..9)
755 * If _G portion is missing it is assigned based on the codec ID
757 * So, HP B-series like systems may have HP_Mute_LED_0 (current models)
758 * or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings
761 * The dv-series laptops don't seem to have the HP_Mute_LED* strings in
762 * SMBIOS - at least the ones I have seen do not have them - which include
763 * my own system (HP Pavilion dv6-1110ax) and my cousin's
764 * HP Pavilion dv9500t CTO.
765 * Need more information on whether it is true across the entire series.
766 * -- kunal
768 static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity)
770 struct sigmatel_spec *spec = codec->spec;
771 const struct dmi_device *dev = NULL;
773 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
774 get_int_hint(codec, "gpio_led_polarity",
775 &spec->gpio_led_polarity);
776 return 1;
779 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
780 if (sscanf(dev->name, "HP_Mute_LED_%u_%x",
781 &spec->gpio_led_polarity,
782 &spec->gpio_led) == 2) {
783 unsigned int max_gpio;
784 max_gpio = snd_hda_param_read(codec, codec->core.afg,
785 AC_PAR_GPIO_CAP);
786 max_gpio &= AC_GPIO_IO_COUNT;
787 if (spec->gpio_led < max_gpio)
788 spec->gpio_led = 1 << spec->gpio_led;
789 else
790 spec->vref_mute_led_nid = spec->gpio_led;
791 return 1;
793 if (sscanf(dev->name, "HP_Mute_LED_%u",
794 &spec->gpio_led_polarity) == 1) {
795 set_hp_led_gpio(codec);
796 return 1;
798 /* BIOS bug: unfilled OEM string */
799 if (strstr(dev->name, "HP_Mute_LED_P_G")) {
800 set_hp_led_gpio(codec);
801 if (default_polarity >= 0)
802 spec->gpio_led_polarity = default_polarity;
803 else
804 spec->gpio_led_polarity = 1;
805 return 1;
810 * Fallback case - if we don't find the DMI strings,
811 * we statically set the GPIO - if not a B-series system
812 * and default polarity is provided
814 if (!hp_blike_system(codec->core.subsystem_id) &&
815 (default_polarity == 0 || default_polarity == 1)) {
816 set_hp_led_gpio(codec);
817 spec->gpio_led_polarity = default_polarity;
818 return 1;
820 return 0;
823 /* check whether a built-in speaker is included in parsed pins */
824 static bool has_builtin_speaker(struct hda_codec *codec)
826 struct sigmatel_spec *spec = codec->spec;
827 hda_nid_t *nid_pin;
828 int nids, i;
830 if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) {
831 nid_pin = spec->gen.autocfg.line_out_pins;
832 nids = spec->gen.autocfg.line_outs;
833 } else {
834 nid_pin = spec->gen.autocfg.speaker_pins;
835 nids = spec->gen.autocfg.speaker_outs;
838 for (i = 0; i < nids; i++) {
839 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid_pin[i]);
840 if (snd_hda_get_input_pin_attr(def_conf) == INPUT_PIN_ATTR_INT)
841 return true;
843 return false;
847 * PC beep controls
850 /* create PC beep volume controls */
851 static int stac_auto_create_beep_ctls(struct hda_codec *codec,
852 hda_nid_t nid)
854 struct sigmatel_spec *spec = codec->spec;
855 u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
856 struct snd_kcontrol_new *knew;
857 static struct snd_kcontrol_new abeep_mute_ctl =
858 HDA_CODEC_MUTE(NULL, 0, 0, 0);
859 static struct snd_kcontrol_new dbeep_mute_ctl =
860 HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0);
861 static struct snd_kcontrol_new beep_vol_ctl =
862 HDA_CODEC_VOLUME(NULL, 0, 0, 0);
864 /* check for mute support for the the amp */
865 if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) {
866 const struct snd_kcontrol_new *temp;
867 if (spec->anabeep_nid == nid)
868 temp = &abeep_mute_ctl;
869 else
870 temp = &dbeep_mute_ctl;
871 knew = snd_hda_gen_add_kctl(&spec->gen,
872 "Beep Playback Switch", temp);
873 if (!knew)
874 return -ENOMEM;
875 knew->private_value =
876 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT);
879 /* check to see if there is volume support for the amp */
880 if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
881 knew = snd_hda_gen_add_kctl(&spec->gen,
882 "Beep Playback Volume",
883 &beep_vol_ctl);
884 if (!knew)
885 return -ENOMEM;
886 knew->private_value =
887 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT);
889 return 0;
892 #ifdef CONFIG_SND_HDA_INPUT_BEEP
893 #define stac_dig_beep_switch_info snd_ctl_boolean_mono_info
895 static int stac_dig_beep_switch_get(struct snd_kcontrol *kcontrol,
896 struct snd_ctl_elem_value *ucontrol)
898 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
899 ucontrol->value.integer.value[0] = codec->beep->enabled;
900 return 0;
903 static int stac_dig_beep_switch_put(struct snd_kcontrol *kcontrol,
904 struct snd_ctl_elem_value *ucontrol)
906 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
907 return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]);
910 static const struct snd_kcontrol_new stac_dig_beep_ctrl = {
911 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
912 .name = "Beep Playback Switch",
913 .info = stac_dig_beep_switch_info,
914 .get = stac_dig_beep_switch_get,
915 .put = stac_dig_beep_switch_put,
918 static int stac_beep_switch_ctl(struct hda_codec *codec)
920 struct sigmatel_spec *spec = codec->spec;
922 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &stac_dig_beep_ctrl))
923 return -ENOMEM;
924 return 0;
926 #endif
929 * SPDIF-out mux controls
932 static int stac_smux_enum_info(struct snd_kcontrol *kcontrol,
933 struct snd_ctl_elem_info *uinfo)
935 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
936 struct sigmatel_spec *spec = codec->spec;
937 return snd_hda_input_mux_info(&spec->spdif_mux, uinfo);
940 static int stac_smux_enum_get(struct snd_kcontrol *kcontrol,
941 struct snd_ctl_elem_value *ucontrol)
943 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
944 struct sigmatel_spec *spec = codec->spec;
945 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
947 ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx];
948 return 0;
951 static int stac_smux_enum_put(struct snd_kcontrol *kcontrol,
952 struct snd_ctl_elem_value *ucontrol)
954 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
955 struct sigmatel_spec *spec = codec->spec;
956 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
958 return snd_hda_input_mux_put(codec, &spec->spdif_mux, ucontrol,
959 spec->gen.autocfg.dig_out_pins[smux_idx],
960 &spec->cur_smux[smux_idx]);
963 static struct snd_kcontrol_new stac_smux_mixer = {
964 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
965 .name = "IEC958 Playback Source",
966 /* count set later */
967 .info = stac_smux_enum_info,
968 .get = stac_smux_enum_get,
969 .put = stac_smux_enum_put,
972 static const char * const stac_spdif_labels[] = {
973 "Digital Playback", "Analog Mux 1", "Analog Mux 2", NULL
976 static int stac_create_spdif_mux_ctls(struct hda_codec *codec)
978 struct sigmatel_spec *spec = codec->spec;
979 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
980 const char * const *labels = spec->spdif_labels;
981 struct snd_kcontrol_new *kctl;
982 int i, num_cons;
984 if (cfg->dig_outs < 1)
985 return 0;
987 num_cons = snd_hda_get_num_conns(codec, cfg->dig_out_pins[0]);
988 if (num_cons <= 1)
989 return 0;
991 if (!labels)
992 labels = stac_spdif_labels;
993 for (i = 0; i < num_cons; i++) {
994 if (snd_BUG_ON(!labels[i]))
995 return -EINVAL;
996 snd_hda_add_imux_item(codec, &spec->spdif_mux, labels[i], i, NULL);
999 kctl = snd_hda_gen_add_kctl(&spec->gen, NULL, &stac_smux_mixer);
1000 if (!kctl)
1001 return -ENOMEM;
1002 kctl->count = cfg->dig_outs;
1004 return 0;
1010 static const struct hda_verb stac9200_core_init[] = {
1011 /* set dac0mux for dac converter */
1012 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1016 static const struct hda_verb stac9200_eapd_init[] = {
1017 /* set dac0mux for dac converter */
1018 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1019 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1023 static const struct hda_verb dell_eq_core_init[] = {
1024 /* set master volume to max value without distortion
1025 * and direct control */
1026 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
1030 static const struct hda_verb stac92hd73xx_core_init[] = {
1031 /* set master volume and direct control */
1032 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1036 static const struct hda_verb stac92hd83xxx_core_init[] = {
1037 /* power state controls amps */
1038 { 0x01, AC_VERB_SET_EAPD, 1 << 2},
1042 static const struct hda_verb stac92hd83xxx_hp_zephyr_init[] = {
1043 { 0x22, 0x785, 0x43 },
1044 { 0x22, 0x782, 0xe0 },
1045 { 0x22, 0x795, 0x00 },
1049 static const struct hda_verb stac92hd71bxx_core_init[] = {
1050 /* set master volume and direct control */
1051 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1055 static const hda_nid_t stac92hd71bxx_unmute_nids[] = {
1056 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */
1057 0x0f, 0x0a, 0x0d, 0
1060 static const struct hda_verb stac925x_core_init[] = {
1061 /* set dac0mux for dac converter */
1062 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
1063 /* mute the master volume */
1064 { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1068 static const struct hda_verb stac922x_core_init[] = {
1069 /* set master volume and direct control */
1070 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1074 static const struct hda_verb d965_core_init[] = {
1075 /* unmute node 0x1b */
1076 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1077 /* select node 0x03 as DAC */
1078 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
1082 static const struct hda_verb dell_3st_core_init[] = {
1083 /* don't set delta bit */
1084 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
1085 /* unmute node 0x1b */
1086 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1087 /* select node 0x03 as DAC */
1088 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
1092 static const struct hda_verb stac927x_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 hda_verb stac927x_volknob_core_init[] = {
1101 /* don't set delta bit */
1102 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
1103 /* enable analog pc beep path */
1104 {0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
1108 static const struct hda_verb stac9205_core_init[] = {
1109 /* set master volume and direct control */
1110 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1111 /* enable analog pc beep path */
1112 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
1116 static const struct snd_kcontrol_new stac92hd73xx_6ch_loopback =
1117 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3);
1119 static const struct snd_kcontrol_new stac92hd73xx_8ch_loopback =
1120 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4);
1122 static const struct snd_kcontrol_new stac92hd73xx_10ch_loopback =
1123 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5);
1125 static const struct snd_kcontrol_new stac92hd71bxx_loopback =
1126 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2);
1128 static const struct snd_kcontrol_new stac9205_loopback =
1129 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1);
1131 static const struct snd_kcontrol_new stac927x_loopback =
1132 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1);
1134 static const struct hda_pintbl ref9200_pin_configs[] = {
1135 { 0x08, 0x01c47010 },
1136 { 0x09, 0x01447010 },
1137 { 0x0d, 0x0221401f },
1138 { 0x0e, 0x01114010 },
1139 { 0x0f, 0x02a19020 },
1140 { 0x10, 0x01a19021 },
1141 { 0x11, 0x90100140 },
1142 { 0x12, 0x01813122 },
1146 static const struct hda_pintbl gateway9200_m4_pin_configs[] = {
1147 { 0x08, 0x400000fe },
1148 { 0x09, 0x404500f4 },
1149 { 0x0d, 0x400100f0 },
1150 { 0x0e, 0x90110010 },
1151 { 0x0f, 0x400100f1 },
1152 { 0x10, 0x02a1902e },
1153 { 0x11, 0x500000f2 },
1154 { 0x12, 0x500000f3 },
1158 static const struct hda_pintbl gateway9200_m4_2_pin_configs[] = {
1159 { 0x08, 0x400000fe },
1160 { 0x09, 0x404500f4 },
1161 { 0x0d, 0x400100f0 },
1162 { 0x0e, 0x90110010 },
1163 { 0x0f, 0x400100f1 },
1164 { 0x10, 0x02a1902e },
1165 { 0x11, 0x500000f2 },
1166 { 0x12, 0x500000f3 },
1171 STAC 9200 pin configs for
1172 102801A8
1173 102801DE
1174 102801E8
1176 static const struct hda_pintbl dell9200_d21_pin_configs[] = {
1177 { 0x08, 0x400001f0 },
1178 { 0x09, 0x400001f1 },
1179 { 0x0d, 0x02214030 },
1180 { 0x0e, 0x01014010 },
1181 { 0x0f, 0x02a19020 },
1182 { 0x10, 0x01a19021 },
1183 { 0x11, 0x90100140 },
1184 { 0x12, 0x01813122 },
1189 STAC 9200 pin configs for
1190 102801C0
1191 102801C1
1193 static const struct hda_pintbl dell9200_d22_pin_configs[] = {
1194 { 0x08, 0x400001f0 },
1195 { 0x09, 0x400001f1 },
1196 { 0x0d, 0x0221401f },
1197 { 0x0e, 0x01014010 },
1198 { 0x0f, 0x01813020 },
1199 { 0x10, 0x02a19021 },
1200 { 0x11, 0x90100140 },
1201 { 0x12, 0x400001f2 },
1206 STAC 9200 pin configs for
1207 102801C4 (Dell Dimension E310)
1208 102801C5
1209 102801C7
1210 102801D9
1211 102801DA
1212 102801E3
1214 static const struct hda_pintbl dell9200_d23_pin_configs[] = {
1215 { 0x08, 0x400001f0 },
1216 { 0x09, 0x400001f1 },
1217 { 0x0d, 0x0221401f },
1218 { 0x0e, 0x01014010 },
1219 { 0x0f, 0x01813020 },
1220 { 0x10, 0x01a19021 },
1221 { 0x11, 0x90100140 },
1222 { 0x12, 0x400001f2 },
1228 STAC 9200-32 pin configs for
1229 102801B5 (Dell Inspiron 630m)
1230 102801D8 (Dell Inspiron 640m)
1232 static const struct hda_pintbl dell9200_m21_pin_configs[] = {
1233 { 0x08, 0x40c003fa },
1234 { 0x09, 0x03441340 },
1235 { 0x0d, 0x0321121f },
1236 { 0x0e, 0x90170310 },
1237 { 0x0f, 0x408003fb },
1238 { 0x10, 0x03a11020 },
1239 { 0x11, 0x401003fc },
1240 { 0x12, 0x403003fd },
1245 STAC 9200-32 pin configs for
1246 102801C2 (Dell Latitude D620)
1247 102801C8
1248 102801CC (Dell Latitude D820)
1249 102801D4
1250 102801D6
1252 static const struct hda_pintbl dell9200_m22_pin_configs[] = {
1253 { 0x08, 0x40c003fa },
1254 { 0x09, 0x0144131f },
1255 { 0x0d, 0x0321121f },
1256 { 0x0e, 0x90170310 },
1257 { 0x0f, 0x90a70321 },
1258 { 0x10, 0x03a11020 },
1259 { 0x11, 0x401003fb },
1260 { 0x12, 0x40f000fc },
1265 STAC 9200-32 pin configs for
1266 102801CE (Dell XPS M1710)
1267 102801CF (Dell Precision M90)
1269 static const struct hda_pintbl dell9200_m23_pin_configs[] = {
1270 { 0x08, 0x40c003fa },
1271 { 0x09, 0x01441340 },
1272 { 0x0d, 0x0421421f },
1273 { 0x0e, 0x90170310 },
1274 { 0x0f, 0x408003fb },
1275 { 0x10, 0x04a1102e },
1276 { 0x11, 0x90170311 },
1277 { 0x12, 0x403003fc },
1282 STAC 9200-32 pin configs for
1283 102801C9
1284 102801CA
1285 102801CB (Dell Latitude 120L)
1286 102801D3
1288 static const struct hda_pintbl dell9200_m24_pin_configs[] = {
1289 { 0x08, 0x40c003fa },
1290 { 0x09, 0x404003fb },
1291 { 0x0d, 0x0321121f },
1292 { 0x0e, 0x90170310 },
1293 { 0x0f, 0x408003fc },
1294 { 0x10, 0x03a11020 },
1295 { 0x11, 0x401003fd },
1296 { 0x12, 0x403003fe },
1301 STAC 9200-32 pin configs for
1302 102801BD (Dell Inspiron E1505n)
1303 102801EE
1304 102801EF
1306 static const struct hda_pintbl dell9200_m25_pin_configs[] = {
1307 { 0x08, 0x40c003fa },
1308 { 0x09, 0x01441340 },
1309 { 0x0d, 0x0421121f },
1310 { 0x0e, 0x90170310 },
1311 { 0x0f, 0x408003fb },
1312 { 0x10, 0x04a11020 },
1313 { 0x11, 0x401003fc },
1314 { 0x12, 0x403003fd },
1319 STAC 9200-32 pin configs for
1320 102801F5 (Dell Inspiron 1501)
1321 102801F6
1323 static const struct hda_pintbl dell9200_m26_pin_configs[] = {
1324 { 0x08, 0x40c003fa },
1325 { 0x09, 0x404003fb },
1326 { 0x0d, 0x0421121f },
1327 { 0x0e, 0x90170310 },
1328 { 0x0f, 0x408003fc },
1329 { 0x10, 0x04a11020 },
1330 { 0x11, 0x401003fd },
1331 { 0x12, 0x403003fe },
1336 STAC 9200-32
1337 102801CD (Dell Inspiron E1705/9400)
1339 static const struct hda_pintbl dell9200_m27_pin_configs[] = {
1340 { 0x08, 0x40c003fa },
1341 { 0x09, 0x01441340 },
1342 { 0x0d, 0x0421121f },
1343 { 0x0e, 0x90170310 },
1344 { 0x0f, 0x90170310 },
1345 { 0x10, 0x04a11020 },
1346 { 0x11, 0x90170310 },
1347 { 0x12, 0x40f003fc },
1351 static const struct hda_pintbl oqo9200_pin_configs[] = {
1352 { 0x08, 0x40c000f0 },
1353 { 0x09, 0x404000f1 },
1354 { 0x0d, 0x0221121f },
1355 { 0x0e, 0x02211210 },
1356 { 0x0f, 0x90170111 },
1357 { 0x10, 0x90a70120 },
1358 { 0x11, 0x400000f2 },
1359 { 0x12, 0x400000f3 },
1364 static void stac9200_fixup_panasonic(struct hda_codec *codec,
1365 const struct hda_fixup *fix, int action)
1367 struct sigmatel_spec *spec = codec->spec;
1369 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1370 spec->gpio_mask = spec->gpio_dir = 0x09;
1371 spec->gpio_data = 0x00;
1372 /* CF-74 has no headphone detection, and the driver should *NOT*
1373 * do detection and HP/speaker toggle because the hardware does it.
1375 spec->gen.suppress_auto_mute = 1;
1380 static const struct hda_fixup stac9200_fixups[] = {
1381 [STAC_REF] = {
1382 .type = HDA_FIXUP_PINS,
1383 .v.pins = ref9200_pin_configs,
1385 [STAC_9200_OQO] = {
1386 .type = HDA_FIXUP_PINS,
1387 .v.pins = oqo9200_pin_configs,
1388 .chained = true,
1389 .chain_id = STAC_9200_EAPD_INIT,
1391 [STAC_9200_DELL_D21] = {
1392 .type = HDA_FIXUP_PINS,
1393 .v.pins = dell9200_d21_pin_configs,
1395 [STAC_9200_DELL_D22] = {
1396 .type = HDA_FIXUP_PINS,
1397 .v.pins = dell9200_d22_pin_configs,
1399 [STAC_9200_DELL_D23] = {
1400 .type = HDA_FIXUP_PINS,
1401 .v.pins = dell9200_d23_pin_configs,
1403 [STAC_9200_DELL_M21] = {
1404 .type = HDA_FIXUP_PINS,
1405 .v.pins = dell9200_m21_pin_configs,
1407 [STAC_9200_DELL_M22] = {
1408 .type = HDA_FIXUP_PINS,
1409 .v.pins = dell9200_m22_pin_configs,
1411 [STAC_9200_DELL_M23] = {
1412 .type = HDA_FIXUP_PINS,
1413 .v.pins = dell9200_m23_pin_configs,
1415 [STAC_9200_DELL_M24] = {
1416 .type = HDA_FIXUP_PINS,
1417 .v.pins = dell9200_m24_pin_configs,
1419 [STAC_9200_DELL_M25] = {
1420 .type = HDA_FIXUP_PINS,
1421 .v.pins = dell9200_m25_pin_configs,
1423 [STAC_9200_DELL_M26] = {
1424 .type = HDA_FIXUP_PINS,
1425 .v.pins = dell9200_m26_pin_configs,
1427 [STAC_9200_DELL_M27] = {
1428 .type = HDA_FIXUP_PINS,
1429 .v.pins = dell9200_m27_pin_configs,
1431 [STAC_9200_M4] = {
1432 .type = HDA_FIXUP_PINS,
1433 .v.pins = gateway9200_m4_pin_configs,
1434 .chained = true,
1435 .chain_id = STAC_9200_EAPD_INIT,
1437 [STAC_9200_M4_2] = {
1438 .type = HDA_FIXUP_PINS,
1439 .v.pins = gateway9200_m4_2_pin_configs,
1440 .chained = true,
1441 .chain_id = STAC_9200_EAPD_INIT,
1443 [STAC_9200_PANASONIC] = {
1444 .type = HDA_FIXUP_FUNC,
1445 .v.func = stac9200_fixup_panasonic,
1447 [STAC_9200_EAPD_INIT] = {
1448 .type = HDA_FIXUP_VERBS,
1449 .v.verbs = (const struct hda_verb[]) {
1450 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1456 static const struct hda_model_fixup stac9200_models[] = {
1457 { .id = STAC_REF, .name = "ref" },
1458 { .id = STAC_9200_OQO, .name = "oqo" },
1459 { .id = STAC_9200_DELL_D21, .name = "dell-d21" },
1460 { .id = STAC_9200_DELL_D22, .name = "dell-d22" },
1461 { .id = STAC_9200_DELL_D23, .name = "dell-d23" },
1462 { .id = STAC_9200_DELL_M21, .name = "dell-m21" },
1463 { .id = STAC_9200_DELL_M22, .name = "dell-m22" },
1464 { .id = STAC_9200_DELL_M23, .name = "dell-m23" },
1465 { .id = STAC_9200_DELL_M24, .name = "dell-m24" },
1466 { .id = STAC_9200_DELL_M25, .name = "dell-m25" },
1467 { .id = STAC_9200_DELL_M26, .name = "dell-m26" },
1468 { .id = STAC_9200_DELL_M27, .name = "dell-m27" },
1469 { .id = STAC_9200_M4, .name = "gateway-m4" },
1470 { .id = STAC_9200_M4_2, .name = "gateway-m4-2" },
1471 { .id = STAC_9200_PANASONIC, .name = "panasonic" },
1475 static const struct snd_pci_quirk stac9200_fixup_tbl[] = {
1476 /* SigmaTel reference board */
1477 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1478 "DFI LanParty", STAC_REF),
1479 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
1480 "DFI LanParty", STAC_REF),
1481 /* Dell laptops have BIOS problem */
1482 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
1483 "unknown Dell", STAC_9200_DELL_D21),
1484 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
1485 "Dell Inspiron 630m", STAC_9200_DELL_M21),
1486 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
1487 "Dell Inspiron E1505n", STAC_9200_DELL_M25),
1488 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
1489 "unknown Dell", STAC_9200_DELL_D22),
1490 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
1491 "unknown Dell", STAC_9200_DELL_D22),
1492 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
1493 "Dell Latitude D620", STAC_9200_DELL_M22),
1494 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
1495 "unknown Dell", STAC_9200_DELL_D23),
1496 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
1497 "unknown Dell", STAC_9200_DELL_D23),
1498 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
1499 "unknown Dell", STAC_9200_DELL_M22),
1500 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
1501 "unknown Dell", STAC_9200_DELL_M24),
1502 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
1503 "unknown Dell", STAC_9200_DELL_M24),
1504 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
1505 "Dell Latitude 120L", STAC_9200_DELL_M24),
1506 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
1507 "Dell Latitude D820", STAC_9200_DELL_M22),
1508 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
1509 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
1510 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
1511 "Dell XPS M1710", STAC_9200_DELL_M23),
1512 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
1513 "Dell Precision M90", STAC_9200_DELL_M23),
1514 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
1515 "unknown Dell", STAC_9200_DELL_M22),
1516 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
1517 "unknown Dell", STAC_9200_DELL_M22),
1518 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
1519 "unknown Dell", STAC_9200_DELL_M22),
1520 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
1521 "Dell Inspiron 640m", STAC_9200_DELL_M21),
1522 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
1523 "unknown Dell", STAC_9200_DELL_D23),
1524 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
1525 "unknown Dell", STAC_9200_DELL_D23),
1526 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
1527 "unknown Dell", STAC_9200_DELL_D21),
1528 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
1529 "unknown Dell", STAC_9200_DELL_D23),
1530 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
1531 "unknown Dell", STAC_9200_DELL_D21),
1532 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
1533 "unknown Dell", STAC_9200_DELL_M25),
1534 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
1535 "unknown Dell", STAC_9200_DELL_M25),
1536 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
1537 "Dell Inspiron 1501", STAC_9200_DELL_M26),
1538 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
1539 "unknown Dell", STAC_9200_DELL_M26),
1540 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0201,
1541 "Dell Latitude D430", STAC_9200_DELL_M22),
1542 /* Panasonic */
1543 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC),
1544 /* Gateway machines needs EAPD to be set on resume */
1545 SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_M4),
1546 SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", STAC_9200_M4_2),
1547 SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", STAC_9200_M4_2),
1548 /* OQO Mobile */
1549 SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO),
1550 {} /* terminator */
1553 static const struct hda_pintbl ref925x_pin_configs[] = {
1554 { 0x07, 0x40c003f0 },
1555 { 0x08, 0x424503f2 },
1556 { 0x0a, 0x01813022 },
1557 { 0x0b, 0x02a19021 },
1558 { 0x0c, 0x90a70320 },
1559 { 0x0d, 0x02214210 },
1560 { 0x10, 0x01019020 },
1561 { 0x11, 0x9033032e },
1565 static const struct hda_pintbl stac925xM1_pin_configs[] = {
1566 { 0x07, 0x40c003f4 },
1567 { 0x08, 0x424503f2 },
1568 { 0x0a, 0x400000f3 },
1569 { 0x0b, 0x02a19020 },
1570 { 0x0c, 0x40a000f0 },
1571 { 0x0d, 0x90100210 },
1572 { 0x10, 0x400003f1 },
1573 { 0x11, 0x9033032e },
1577 static const struct hda_pintbl stac925xM1_2_pin_configs[] = {
1578 { 0x07, 0x40c003f4 },
1579 { 0x08, 0x424503f2 },
1580 { 0x0a, 0x400000f3 },
1581 { 0x0b, 0x02a19020 },
1582 { 0x0c, 0x40a000f0 },
1583 { 0x0d, 0x90100210 },
1584 { 0x10, 0x400003f1 },
1585 { 0x11, 0x9033032e },
1589 static const struct hda_pintbl stac925xM2_pin_configs[] = {
1590 { 0x07, 0x40c003f4 },
1591 { 0x08, 0x424503f2 },
1592 { 0x0a, 0x400000f3 },
1593 { 0x0b, 0x02a19020 },
1594 { 0x0c, 0x40a000f0 },
1595 { 0x0d, 0x90100210 },
1596 { 0x10, 0x400003f1 },
1597 { 0x11, 0x9033032e },
1601 static const struct hda_pintbl stac925xM2_2_pin_configs[] = {
1602 { 0x07, 0x40c003f4 },
1603 { 0x08, 0x424503f2 },
1604 { 0x0a, 0x400000f3 },
1605 { 0x0b, 0x02a19020 },
1606 { 0x0c, 0x40a000f0 },
1607 { 0x0d, 0x90100210 },
1608 { 0x10, 0x400003f1 },
1609 { 0x11, 0x9033032e },
1613 static const struct hda_pintbl stac925xM3_pin_configs[] = {
1614 { 0x07, 0x40c003f4 },
1615 { 0x08, 0x424503f2 },
1616 { 0x0a, 0x400000f3 },
1617 { 0x0b, 0x02a19020 },
1618 { 0x0c, 0x40a000f0 },
1619 { 0x0d, 0x90100210 },
1620 { 0x10, 0x400003f1 },
1621 { 0x11, 0x503303f3 },
1625 static const struct hda_pintbl stac925xM5_pin_configs[] = {
1626 { 0x07, 0x40c003f4 },
1627 { 0x08, 0x424503f2 },
1628 { 0x0a, 0x400000f3 },
1629 { 0x0b, 0x02a19020 },
1630 { 0x0c, 0x40a000f0 },
1631 { 0x0d, 0x90100210 },
1632 { 0x10, 0x400003f1 },
1633 { 0x11, 0x9033032e },
1637 static const struct hda_pintbl stac925xM6_pin_configs[] = {
1638 { 0x07, 0x40c003f4 },
1639 { 0x08, 0x424503f2 },
1640 { 0x0a, 0x400000f3 },
1641 { 0x0b, 0x02a19020 },
1642 { 0x0c, 0x40a000f0 },
1643 { 0x0d, 0x90100210 },
1644 { 0x10, 0x400003f1 },
1645 { 0x11, 0x90330320 },
1649 static const struct hda_fixup stac925x_fixups[] = {
1650 [STAC_REF] = {
1651 .type = HDA_FIXUP_PINS,
1652 .v.pins = ref925x_pin_configs,
1654 [STAC_M1] = {
1655 .type = HDA_FIXUP_PINS,
1656 .v.pins = stac925xM1_pin_configs,
1658 [STAC_M1_2] = {
1659 .type = HDA_FIXUP_PINS,
1660 .v.pins = stac925xM1_2_pin_configs,
1662 [STAC_M2] = {
1663 .type = HDA_FIXUP_PINS,
1664 .v.pins = stac925xM2_pin_configs,
1666 [STAC_M2_2] = {
1667 .type = HDA_FIXUP_PINS,
1668 .v.pins = stac925xM2_2_pin_configs,
1670 [STAC_M3] = {
1671 .type = HDA_FIXUP_PINS,
1672 .v.pins = stac925xM3_pin_configs,
1674 [STAC_M5] = {
1675 .type = HDA_FIXUP_PINS,
1676 .v.pins = stac925xM5_pin_configs,
1678 [STAC_M6] = {
1679 .type = HDA_FIXUP_PINS,
1680 .v.pins = stac925xM6_pin_configs,
1684 static const struct hda_model_fixup stac925x_models[] = {
1685 { .id = STAC_REF, .name = "ref" },
1686 { .id = STAC_M1, .name = "m1" },
1687 { .id = STAC_M1_2, .name = "m1-2" },
1688 { .id = STAC_M2, .name = "m2" },
1689 { .id = STAC_M2_2, .name = "m2-2" },
1690 { .id = STAC_M3, .name = "m3" },
1691 { .id = STAC_M5, .name = "m5" },
1692 { .id = STAC_M6, .name = "m6" },
1696 static const struct snd_pci_quirk stac925x_fixup_tbl[] = {
1697 /* SigmaTel reference board */
1698 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
1699 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF),
1700 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
1702 /* Default table for unknown ID */
1703 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2),
1705 /* gateway machines are checked via codec ssid */
1706 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2),
1707 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5),
1708 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1),
1709 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_M2),
1710 SND_PCI_QUIRK(0x107b, 0x0367, "Gateway MX6453", STAC_M1_2),
1711 /* Not sure about the brand name for those */
1712 SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M1),
1713 SND_PCI_QUIRK(0x107b, 0x0507, "Gateway mobile", STAC_M3),
1714 SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M6),
1715 SND_PCI_QUIRK(0x107b, 0x0685, "Gateway mobile", STAC_M2_2),
1716 {} /* terminator */
1719 static const struct hda_pintbl ref92hd73xx_pin_configs[] = {
1720 { 0x0a, 0x02214030 },
1721 { 0x0b, 0x02a19040 },
1722 { 0x0c, 0x01a19020 },
1723 { 0x0d, 0x02214030 },
1724 { 0x0e, 0x0181302e },
1725 { 0x0f, 0x01014010 },
1726 { 0x10, 0x01014020 },
1727 { 0x11, 0x01014030 },
1728 { 0x12, 0x02319040 },
1729 { 0x13, 0x90a000f0 },
1730 { 0x14, 0x90a000f0 },
1731 { 0x22, 0x01452050 },
1732 { 0x23, 0x01452050 },
1736 static const struct hda_pintbl dell_m6_pin_configs[] = {
1737 { 0x0a, 0x0321101f },
1738 { 0x0b, 0x4f00000f },
1739 { 0x0c, 0x4f0000f0 },
1740 { 0x0d, 0x90170110 },
1741 { 0x0e, 0x03a11020 },
1742 { 0x0f, 0x0321101f },
1743 { 0x10, 0x4f0000f0 },
1744 { 0x11, 0x4f0000f0 },
1745 { 0x12, 0x4f0000f0 },
1746 { 0x13, 0x90a60160 },
1747 { 0x14, 0x4f0000f0 },
1748 { 0x22, 0x4f0000f0 },
1749 { 0x23, 0x4f0000f0 },
1753 static const struct hda_pintbl alienware_m17x_pin_configs[] = {
1754 { 0x0a, 0x0321101f },
1755 { 0x0b, 0x0321101f },
1756 { 0x0c, 0x03a11020 },
1757 { 0x0d, 0x03014020 },
1758 { 0x0e, 0x90170110 },
1759 { 0x0f, 0x4f0000f0 },
1760 { 0x10, 0x4f0000f0 },
1761 { 0x11, 0x4f0000f0 },
1762 { 0x12, 0x4f0000f0 },
1763 { 0x13, 0x90a60160 },
1764 { 0x14, 0x4f0000f0 },
1765 { 0x22, 0x4f0000f0 },
1766 { 0x23, 0x904601b0 },
1770 static const struct hda_pintbl intel_dg45id_pin_configs[] = {
1771 { 0x0a, 0x02214230 },
1772 { 0x0b, 0x02A19240 },
1773 { 0x0c, 0x01013214 },
1774 { 0x0d, 0x01014210 },
1775 { 0x0e, 0x01A19250 },
1776 { 0x0f, 0x01011212 },
1777 { 0x10, 0x01016211 },
1781 static const struct hda_pintbl stac92hd89xx_hp_front_jack_pin_configs[] = {
1782 { 0x0a, 0x02214030 },
1783 { 0x0b, 0x02A19010 },
1787 static const struct hda_pintbl stac92hd89xx_hp_z1_g2_right_mic_jack_pin_configs[] = {
1788 { 0x0e, 0x400000f0 },
1792 static void stac92hd73xx_fixup_ref(struct hda_codec *codec,
1793 const struct hda_fixup *fix, int action)
1795 struct sigmatel_spec *spec = codec->spec;
1797 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1798 return;
1800 snd_hda_apply_pincfgs(codec, ref92hd73xx_pin_configs);
1801 spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0;
1804 static void stac92hd73xx_fixup_dell(struct hda_codec *codec)
1806 struct sigmatel_spec *spec = codec->spec;
1808 snd_hda_apply_pincfgs(codec, dell_m6_pin_configs);
1809 spec->eapd_switch = 0;
1812 static void stac92hd73xx_fixup_dell_eq(struct hda_codec *codec,
1813 const struct hda_fixup *fix, int action)
1815 struct sigmatel_spec *spec = codec->spec;
1817 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1818 return;
1820 stac92hd73xx_fixup_dell(codec);
1821 snd_hda_add_verbs(codec, dell_eq_core_init);
1822 spec->volknob_init = 1;
1825 /* Analog Mics */
1826 static void stac92hd73xx_fixup_dell_m6_amic(struct hda_codec *codec,
1827 const struct hda_fixup *fix, int action)
1829 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1830 return;
1832 stac92hd73xx_fixup_dell(codec);
1833 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
1836 /* Digital Mics */
1837 static void stac92hd73xx_fixup_dell_m6_dmic(struct hda_codec *codec,
1838 const struct hda_fixup *fix, int action)
1840 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1841 return;
1843 stac92hd73xx_fixup_dell(codec);
1844 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
1847 /* Both */
1848 static void stac92hd73xx_fixup_dell_m6_both(struct hda_codec *codec,
1849 const struct hda_fixup *fix, int action)
1851 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1852 return;
1854 stac92hd73xx_fixup_dell(codec);
1855 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
1856 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
1859 static void stac92hd73xx_fixup_alienware_m17x(struct hda_codec *codec,
1860 const struct hda_fixup *fix, int action)
1862 struct sigmatel_spec *spec = codec->spec;
1864 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1865 return;
1867 snd_hda_apply_pincfgs(codec, alienware_m17x_pin_configs);
1868 spec->eapd_switch = 0;
1871 static void stac92hd73xx_fixup_no_jd(struct hda_codec *codec,
1872 const struct hda_fixup *fix, int action)
1874 if (action == HDA_FIXUP_ACT_PRE_PROBE)
1875 codec->no_jack_detect = 1;
1878 static const struct hda_fixup stac92hd73xx_fixups[] = {
1879 [STAC_92HD73XX_REF] = {
1880 .type = HDA_FIXUP_FUNC,
1881 .v.func = stac92hd73xx_fixup_ref,
1883 [STAC_DELL_M6_AMIC] = {
1884 .type = HDA_FIXUP_FUNC,
1885 .v.func = stac92hd73xx_fixup_dell_m6_amic,
1887 [STAC_DELL_M6_DMIC] = {
1888 .type = HDA_FIXUP_FUNC,
1889 .v.func = stac92hd73xx_fixup_dell_m6_dmic,
1891 [STAC_DELL_M6_BOTH] = {
1892 .type = HDA_FIXUP_FUNC,
1893 .v.func = stac92hd73xx_fixup_dell_m6_both,
1895 [STAC_DELL_EQ] = {
1896 .type = HDA_FIXUP_FUNC,
1897 .v.func = stac92hd73xx_fixup_dell_eq,
1899 [STAC_ALIENWARE_M17X] = {
1900 .type = HDA_FIXUP_FUNC,
1901 .v.func = stac92hd73xx_fixup_alienware_m17x,
1903 [STAC_92HD73XX_INTEL] = {
1904 .type = HDA_FIXUP_PINS,
1905 .v.pins = intel_dg45id_pin_configs,
1907 [STAC_92HD73XX_NO_JD] = {
1908 .type = HDA_FIXUP_FUNC,
1909 .v.func = stac92hd73xx_fixup_no_jd,
1911 [STAC_92HD89XX_HP_FRONT_JACK] = {
1912 .type = HDA_FIXUP_PINS,
1913 .v.pins = stac92hd89xx_hp_front_jack_pin_configs,
1915 [STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK] = {
1916 .type = HDA_FIXUP_PINS,
1917 .v.pins = stac92hd89xx_hp_z1_g2_right_mic_jack_pin_configs,
1919 [STAC_92HD73XX_ASUS_MOBO] = {
1920 .type = HDA_FIXUP_PINS,
1921 .v.pins = (const struct hda_pintbl[]) {
1922 /* enable 5.1 and SPDIF out */
1923 { 0x0c, 0x01014411 },
1924 { 0x0d, 0x01014410 },
1925 { 0x0e, 0x01014412 },
1926 { 0x22, 0x014b1180 },
1932 static const struct hda_model_fixup stac92hd73xx_models[] = {
1933 { .id = STAC_92HD73XX_NO_JD, .name = "no-jd" },
1934 { .id = STAC_92HD73XX_REF, .name = "ref" },
1935 { .id = STAC_92HD73XX_INTEL, .name = "intel" },
1936 { .id = STAC_DELL_M6_AMIC, .name = "dell-m6-amic" },
1937 { .id = STAC_DELL_M6_DMIC, .name = "dell-m6-dmic" },
1938 { .id = STAC_DELL_M6_BOTH, .name = "dell-m6" },
1939 { .id = STAC_DELL_EQ, .name = "dell-eq" },
1940 { .id = STAC_ALIENWARE_M17X, .name = "alienware" },
1941 { .id = STAC_92HD73XX_ASUS_MOBO, .name = "asus-mobo" },
1945 static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = {
1946 /* SigmaTel reference board */
1947 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1948 "DFI LanParty", STAC_92HD73XX_REF),
1949 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
1950 "DFI LanParty", STAC_92HD73XX_REF),
1951 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5002,
1952 "Intel DG45ID", STAC_92HD73XX_INTEL),
1953 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5003,
1954 "Intel DG45FC", STAC_92HD73XX_INTEL),
1955 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254,
1956 "Dell Studio 1535", STAC_DELL_M6_DMIC),
1957 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255,
1958 "unknown Dell", STAC_DELL_M6_DMIC),
1959 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256,
1960 "unknown Dell", STAC_DELL_M6_BOTH),
1961 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257,
1962 "unknown Dell", STAC_DELL_M6_BOTH),
1963 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e,
1964 "unknown Dell", STAC_DELL_M6_AMIC),
1965 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f,
1966 "unknown Dell", STAC_DELL_M6_AMIC),
1967 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271,
1968 "unknown Dell", STAC_DELL_M6_DMIC),
1969 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0272,
1970 "unknown Dell", STAC_DELL_M6_DMIC),
1971 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f,
1972 "Dell Studio 1537", STAC_DELL_M6_DMIC),
1973 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a0,
1974 "Dell Studio 17", STAC_DELL_M6_DMIC),
1975 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02be,
1976 "Dell Studio 1555", STAC_DELL_M6_DMIC),
1977 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd,
1978 "Dell Studio 1557", STAC_DELL_M6_DMIC),
1979 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe,
1980 "Dell Studio XPS 1645", STAC_DELL_M6_DMIC),
1981 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413,
1982 "Dell Studio 1558", STAC_DELL_M6_DMIC),
1983 /* codec SSID matching */
1984 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1,
1985 "Alienware M17x", STAC_ALIENWARE_M17X),
1986 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
1987 "Alienware M17x", STAC_ALIENWARE_M17X),
1988 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490,
1989 "Alienware M17x R3", STAC_DELL_EQ),
1990 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1927,
1991 "HP Z1 G2", STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK),
1992 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2b17,
1993 "unknown HP", STAC_92HD89XX_HP_FRONT_JACK),
1994 SND_PCI_QUIRK(PCI_VENDOR_ID_ASUSTEK, 0x83f8, "ASUS AT4NM10",
1995 STAC_92HD73XX_ASUS_MOBO),
1996 {} /* terminator */
1999 static const struct hda_pintbl ref92hd83xxx_pin_configs[] = {
2000 { 0x0a, 0x02214030 },
2001 { 0x0b, 0x02211010 },
2002 { 0x0c, 0x02a19020 },
2003 { 0x0d, 0x02170130 },
2004 { 0x0e, 0x01014050 },
2005 { 0x0f, 0x01819040 },
2006 { 0x10, 0x01014020 },
2007 { 0x11, 0x90a3014e },
2008 { 0x1f, 0x01451160 },
2009 { 0x20, 0x98560170 },
2013 static const struct hda_pintbl dell_s14_pin_configs[] = {
2014 { 0x0a, 0x0221403f },
2015 { 0x0b, 0x0221101f },
2016 { 0x0c, 0x02a19020 },
2017 { 0x0d, 0x90170110 },
2018 { 0x0e, 0x40f000f0 },
2019 { 0x0f, 0x40f000f0 },
2020 { 0x10, 0x40f000f0 },
2021 { 0x11, 0x90a60160 },
2022 { 0x1f, 0x40f000f0 },
2023 { 0x20, 0x40f000f0 },
2027 static const struct hda_pintbl dell_vostro_3500_pin_configs[] = {
2028 { 0x0a, 0x02a11020 },
2029 { 0x0b, 0x0221101f },
2030 { 0x0c, 0x400000f0 },
2031 { 0x0d, 0x90170110 },
2032 { 0x0e, 0x400000f1 },
2033 { 0x0f, 0x400000f2 },
2034 { 0x10, 0x400000f3 },
2035 { 0x11, 0x90a60160 },
2036 { 0x1f, 0x400000f4 },
2037 { 0x20, 0x400000f5 },
2041 static const struct hda_pintbl hp_dv7_4000_pin_configs[] = {
2042 { 0x0a, 0x03a12050 },
2043 { 0x0b, 0x0321201f },
2044 { 0x0c, 0x40f000f0 },
2045 { 0x0d, 0x90170110 },
2046 { 0x0e, 0x40f000f0 },
2047 { 0x0f, 0x40f000f0 },
2048 { 0x10, 0x90170110 },
2049 { 0x11, 0xd5a30140 },
2050 { 0x1f, 0x40f000f0 },
2051 { 0x20, 0x40f000f0 },
2055 static const struct hda_pintbl hp_zephyr_pin_configs[] = {
2056 { 0x0a, 0x01813050 },
2057 { 0x0b, 0x0421201f },
2058 { 0x0c, 0x04a1205e },
2059 { 0x0d, 0x96130310 },
2060 { 0x0e, 0x96130310 },
2061 { 0x0f, 0x0101401f },
2062 { 0x10, 0x1111611f },
2063 { 0x11, 0xd5a30130 },
2067 static const struct hda_pintbl hp_cNB11_intquad_pin_configs[] = {
2068 { 0x0a, 0x40f000f0 },
2069 { 0x0b, 0x0221101f },
2070 { 0x0c, 0x02a11020 },
2071 { 0x0d, 0x92170110 },
2072 { 0x0e, 0x40f000f0 },
2073 { 0x0f, 0x92170110 },
2074 { 0x10, 0x40f000f0 },
2075 { 0x11, 0xd5a30130 },
2076 { 0x1f, 0x40f000f0 },
2077 { 0x20, 0x40f000f0 },
2081 static void stac92hd83xxx_fixup_hp(struct hda_codec *codec,
2082 const struct hda_fixup *fix, int action)
2084 struct sigmatel_spec *spec = codec->spec;
2086 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2087 return;
2089 if (hp_bnb2011_with_dock(codec)) {
2090 snd_hda_codec_set_pincfg(codec, 0xa, 0x2101201f);
2091 snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);
2094 if (find_mute_led_cfg(codec, spec->default_polarity))
2095 codec_dbg(codec, "mute LED gpio %d polarity %d\n",
2096 spec->gpio_led,
2097 spec->gpio_led_polarity);
2099 /* allow auto-switching of dock line-in */
2100 spec->gen.line_in_auto_switch = true;
2103 static void stac92hd83xxx_fixup_hp_zephyr(struct hda_codec *codec,
2104 const struct hda_fixup *fix, int action)
2106 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2107 return;
2109 snd_hda_apply_pincfgs(codec, hp_zephyr_pin_configs);
2110 snd_hda_add_verbs(codec, stac92hd83xxx_hp_zephyr_init);
2113 static void stac92hd83xxx_fixup_hp_led(struct hda_codec *codec,
2114 const struct hda_fixup *fix, int action)
2116 struct sigmatel_spec *spec = codec->spec;
2118 if (action == HDA_FIXUP_ACT_PRE_PROBE)
2119 spec->default_polarity = 0;
2122 static void stac92hd83xxx_fixup_hp_inv_led(struct hda_codec *codec,
2123 const struct hda_fixup *fix, int action)
2125 struct sigmatel_spec *spec = codec->spec;
2127 if (action == HDA_FIXUP_ACT_PRE_PROBE)
2128 spec->default_polarity = 1;
2131 static void stac92hd83xxx_fixup_hp_mic_led(struct hda_codec *codec,
2132 const struct hda_fixup *fix, int action)
2134 struct sigmatel_spec *spec = codec->spec;
2136 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2137 spec->mic_mute_led_gpio = 0x08; /* GPIO3 */
2138 #ifdef CONFIG_PM
2139 /* resetting controller clears GPIO, so we need to keep on */
2140 codec->core.power_caps &= ~AC_PWRST_CLKSTOP;
2141 #endif
2145 static void stac92hd83xxx_fixup_hp_led_gpio10(struct hda_codec *codec,
2146 const struct hda_fixup *fix, int action)
2148 struct sigmatel_spec *spec = codec->spec;
2150 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2151 spec->gpio_led = 0x10; /* GPIO4 */
2152 spec->default_polarity = 0;
2156 static void stac92hd83xxx_fixup_headset_jack(struct hda_codec *codec,
2157 const struct hda_fixup *fix, int action)
2159 struct sigmatel_spec *spec = codec->spec;
2161 if (action == HDA_FIXUP_ACT_PRE_PROBE)
2162 spec->headset_jack = 1;
2165 static void stac92hd83xxx_fixup_gpio10_eapd(struct hda_codec *codec,
2166 const struct hda_fixup *fix,
2167 int action)
2169 struct sigmatel_spec *spec = codec->spec;
2171 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2172 return;
2173 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir =
2174 spec->gpio_data = 0x10;
2175 spec->eapd_switch = 0;
2178 static void hp_envy_ts_fixup_dac_bind(struct hda_codec *codec,
2179 const struct hda_fixup *fix,
2180 int action)
2182 struct sigmatel_spec *spec = codec->spec;
2183 static hda_nid_t preferred_pairs[] = {
2184 0xd, 0x13,
2188 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2189 return;
2191 spec->gen.preferred_dacs = preferred_pairs;
2194 static const struct hda_verb hp_bnb13_eq_verbs[] = {
2195 /* 44.1KHz base */
2196 { 0x22, 0x7A6, 0x3E },
2197 { 0x22, 0x7A7, 0x68 },
2198 { 0x22, 0x7A8, 0x17 },
2199 { 0x22, 0x7A9, 0x3E },
2200 { 0x22, 0x7AA, 0x68 },
2201 { 0x22, 0x7AB, 0x17 },
2202 { 0x22, 0x7AC, 0x00 },
2203 { 0x22, 0x7AD, 0x80 },
2204 { 0x22, 0x7A6, 0x83 },
2205 { 0x22, 0x7A7, 0x2F },
2206 { 0x22, 0x7A8, 0xD1 },
2207 { 0x22, 0x7A9, 0x83 },
2208 { 0x22, 0x7AA, 0x2F },
2209 { 0x22, 0x7AB, 0xD1 },
2210 { 0x22, 0x7AC, 0x01 },
2211 { 0x22, 0x7AD, 0x80 },
2212 { 0x22, 0x7A6, 0x3E },
2213 { 0x22, 0x7A7, 0x68 },
2214 { 0x22, 0x7A8, 0x17 },
2215 { 0x22, 0x7A9, 0x3E },
2216 { 0x22, 0x7AA, 0x68 },
2217 { 0x22, 0x7AB, 0x17 },
2218 { 0x22, 0x7AC, 0x02 },
2219 { 0x22, 0x7AD, 0x80 },
2220 { 0x22, 0x7A6, 0x7C },
2221 { 0x22, 0x7A7, 0xC6 },
2222 { 0x22, 0x7A8, 0x0C },
2223 { 0x22, 0x7A9, 0x7C },
2224 { 0x22, 0x7AA, 0xC6 },
2225 { 0x22, 0x7AB, 0x0C },
2226 { 0x22, 0x7AC, 0x03 },
2227 { 0x22, 0x7AD, 0x80 },
2228 { 0x22, 0x7A6, 0xC3 },
2229 { 0x22, 0x7A7, 0x25 },
2230 { 0x22, 0x7A8, 0xAF },
2231 { 0x22, 0x7A9, 0xC3 },
2232 { 0x22, 0x7AA, 0x25 },
2233 { 0x22, 0x7AB, 0xAF },
2234 { 0x22, 0x7AC, 0x04 },
2235 { 0x22, 0x7AD, 0x80 },
2236 { 0x22, 0x7A6, 0x3E },
2237 { 0x22, 0x7A7, 0x85 },
2238 { 0x22, 0x7A8, 0x73 },
2239 { 0x22, 0x7A9, 0x3E },
2240 { 0x22, 0x7AA, 0x85 },
2241 { 0x22, 0x7AB, 0x73 },
2242 { 0x22, 0x7AC, 0x05 },
2243 { 0x22, 0x7AD, 0x80 },
2244 { 0x22, 0x7A6, 0x85 },
2245 { 0x22, 0x7A7, 0x39 },
2246 { 0x22, 0x7A8, 0xC7 },
2247 { 0x22, 0x7A9, 0x85 },
2248 { 0x22, 0x7AA, 0x39 },
2249 { 0x22, 0x7AB, 0xC7 },
2250 { 0x22, 0x7AC, 0x06 },
2251 { 0x22, 0x7AD, 0x80 },
2252 { 0x22, 0x7A6, 0x3C },
2253 { 0x22, 0x7A7, 0x90 },
2254 { 0x22, 0x7A8, 0xB0 },
2255 { 0x22, 0x7A9, 0x3C },
2256 { 0x22, 0x7AA, 0x90 },
2257 { 0x22, 0x7AB, 0xB0 },
2258 { 0x22, 0x7AC, 0x07 },
2259 { 0x22, 0x7AD, 0x80 },
2260 { 0x22, 0x7A6, 0x7A },
2261 { 0x22, 0x7A7, 0xC6 },
2262 { 0x22, 0x7A8, 0x39 },
2263 { 0x22, 0x7A9, 0x7A },
2264 { 0x22, 0x7AA, 0xC6 },
2265 { 0x22, 0x7AB, 0x39 },
2266 { 0x22, 0x7AC, 0x08 },
2267 { 0x22, 0x7AD, 0x80 },
2268 { 0x22, 0x7A6, 0xC4 },
2269 { 0x22, 0x7A7, 0xE9 },
2270 { 0x22, 0x7A8, 0xDC },
2271 { 0x22, 0x7A9, 0xC4 },
2272 { 0x22, 0x7AA, 0xE9 },
2273 { 0x22, 0x7AB, 0xDC },
2274 { 0x22, 0x7AC, 0x09 },
2275 { 0x22, 0x7AD, 0x80 },
2276 { 0x22, 0x7A6, 0x3D },
2277 { 0x22, 0x7A7, 0xE1 },
2278 { 0x22, 0x7A8, 0x0D },
2279 { 0x22, 0x7A9, 0x3D },
2280 { 0x22, 0x7AA, 0xE1 },
2281 { 0x22, 0x7AB, 0x0D },
2282 { 0x22, 0x7AC, 0x0A },
2283 { 0x22, 0x7AD, 0x80 },
2284 { 0x22, 0x7A6, 0x89 },
2285 { 0x22, 0x7A7, 0xB6 },
2286 { 0x22, 0x7A8, 0xEB },
2287 { 0x22, 0x7A9, 0x89 },
2288 { 0x22, 0x7AA, 0xB6 },
2289 { 0x22, 0x7AB, 0xEB },
2290 { 0x22, 0x7AC, 0x0B },
2291 { 0x22, 0x7AD, 0x80 },
2292 { 0x22, 0x7A6, 0x39 },
2293 { 0x22, 0x7A7, 0x9D },
2294 { 0x22, 0x7A8, 0xFE },
2295 { 0x22, 0x7A9, 0x39 },
2296 { 0x22, 0x7AA, 0x9D },
2297 { 0x22, 0x7AB, 0xFE },
2298 { 0x22, 0x7AC, 0x0C },
2299 { 0x22, 0x7AD, 0x80 },
2300 { 0x22, 0x7A6, 0x76 },
2301 { 0x22, 0x7A7, 0x49 },
2302 { 0x22, 0x7A8, 0x15 },
2303 { 0x22, 0x7A9, 0x76 },
2304 { 0x22, 0x7AA, 0x49 },
2305 { 0x22, 0x7AB, 0x15 },
2306 { 0x22, 0x7AC, 0x0D },
2307 { 0x22, 0x7AD, 0x80 },
2308 { 0x22, 0x7A6, 0xC8 },
2309 { 0x22, 0x7A7, 0x80 },
2310 { 0x22, 0x7A8, 0xF5 },
2311 { 0x22, 0x7A9, 0xC8 },
2312 { 0x22, 0x7AA, 0x80 },
2313 { 0x22, 0x7AB, 0xF5 },
2314 { 0x22, 0x7AC, 0x0E },
2315 { 0x22, 0x7AD, 0x80 },
2316 { 0x22, 0x7A6, 0x40 },
2317 { 0x22, 0x7A7, 0x00 },
2318 { 0x22, 0x7A8, 0x00 },
2319 { 0x22, 0x7A9, 0x40 },
2320 { 0x22, 0x7AA, 0x00 },
2321 { 0x22, 0x7AB, 0x00 },
2322 { 0x22, 0x7AC, 0x0F },
2323 { 0x22, 0x7AD, 0x80 },
2324 { 0x22, 0x7A6, 0x90 },
2325 { 0x22, 0x7A7, 0x68 },
2326 { 0x22, 0x7A8, 0xF1 },
2327 { 0x22, 0x7A9, 0x90 },
2328 { 0x22, 0x7AA, 0x68 },
2329 { 0x22, 0x7AB, 0xF1 },
2330 { 0x22, 0x7AC, 0x10 },
2331 { 0x22, 0x7AD, 0x80 },
2332 { 0x22, 0x7A6, 0x34 },
2333 { 0x22, 0x7A7, 0x47 },
2334 { 0x22, 0x7A8, 0x6C },
2335 { 0x22, 0x7A9, 0x34 },
2336 { 0x22, 0x7AA, 0x47 },
2337 { 0x22, 0x7AB, 0x6C },
2338 { 0x22, 0x7AC, 0x11 },
2339 { 0x22, 0x7AD, 0x80 },
2340 { 0x22, 0x7A6, 0x6F },
2341 { 0x22, 0x7A7, 0x97 },
2342 { 0x22, 0x7A8, 0x0F },
2343 { 0x22, 0x7A9, 0x6F },
2344 { 0x22, 0x7AA, 0x97 },
2345 { 0x22, 0x7AB, 0x0F },
2346 { 0x22, 0x7AC, 0x12 },
2347 { 0x22, 0x7AD, 0x80 },
2348 { 0x22, 0x7A6, 0xCB },
2349 { 0x22, 0x7A7, 0xB8 },
2350 { 0x22, 0x7A8, 0x94 },
2351 { 0x22, 0x7A9, 0xCB },
2352 { 0x22, 0x7AA, 0xB8 },
2353 { 0x22, 0x7AB, 0x94 },
2354 { 0x22, 0x7AC, 0x13 },
2355 { 0x22, 0x7AD, 0x80 },
2356 { 0x22, 0x7A6, 0x40 },
2357 { 0x22, 0x7A7, 0x00 },
2358 { 0x22, 0x7A8, 0x00 },
2359 { 0x22, 0x7A9, 0x40 },
2360 { 0x22, 0x7AA, 0x00 },
2361 { 0x22, 0x7AB, 0x00 },
2362 { 0x22, 0x7AC, 0x14 },
2363 { 0x22, 0x7AD, 0x80 },
2364 { 0x22, 0x7A6, 0x95 },
2365 { 0x22, 0x7A7, 0x76 },
2366 { 0x22, 0x7A8, 0x5B },
2367 { 0x22, 0x7A9, 0x95 },
2368 { 0x22, 0x7AA, 0x76 },
2369 { 0x22, 0x7AB, 0x5B },
2370 { 0x22, 0x7AC, 0x15 },
2371 { 0x22, 0x7AD, 0x80 },
2372 { 0x22, 0x7A6, 0x31 },
2373 { 0x22, 0x7A7, 0xAC },
2374 { 0x22, 0x7A8, 0x31 },
2375 { 0x22, 0x7A9, 0x31 },
2376 { 0x22, 0x7AA, 0xAC },
2377 { 0x22, 0x7AB, 0x31 },
2378 { 0x22, 0x7AC, 0x16 },
2379 { 0x22, 0x7AD, 0x80 },
2380 { 0x22, 0x7A6, 0x6A },
2381 { 0x22, 0x7A7, 0x89 },
2382 { 0x22, 0x7A8, 0xA5 },
2383 { 0x22, 0x7A9, 0x6A },
2384 { 0x22, 0x7AA, 0x89 },
2385 { 0x22, 0x7AB, 0xA5 },
2386 { 0x22, 0x7AC, 0x17 },
2387 { 0x22, 0x7AD, 0x80 },
2388 { 0x22, 0x7A6, 0xCE },
2389 { 0x22, 0x7A7, 0x53 },
2390 { 0x22, 0x7A8, 0xCF },
2391 { 0x22, 0x7A9, 0xCE },
2392 { 0x22, 0x7AA, 0x53 },
2393 { 0x22, 0x7AB, 0xCF },
2394 { 0x22, 0x7AC, 0x18 },
2395 { 0x22, 0x7AD, 0x80 },
2396 { 0x22, 0x7A6, 0x40 },
2397 { 0x22, 0x7A7, 0x00 },
2398 { 0x22, 0x7A8, 0x00 },
2399 { 0x22, 0x7A9, 0x40 },
2400 { 0x22, 0x7AA, 0x00 },
2401 { 0x22, 0x7AB, 0x00 },
2402 { 0x22, 0x7AC, 0x19 },
2403 { 0x22, 0x7AD, 0x80 },
2404 /* 48KHz base */
2405 { 0x22, 0x7A6, 0x3E },
2406 { 0x22, 0x7A7, 0x88 },
2407 { 0x22, 0x7A8, 0xDC },
2408 { 0x22, 0x7A9, 0x3E },
2409 { 0x22, 0x7AA, 0x88 },
2410 { 0x22, 0x7AB, 0xDC },
2411 { 0x22, 0x7AC, 0x1A },
2412 { 0x22, 0x7AD, 0x80 },
2413 { 0x22, 0x7A6, 0x82 },
2414 { 0x22, 0x7A7, 0xEE },
2415 { 0x22, 0x7A8, 0x46 },
2416 { 0x22, 0x7A9, 0x82 },
2417 { 0x22, 0x7AA, 0xEE },
2418 { 0x22, 0x7AB, 0x46 },
2419 { 0x22, 0x7AC, 0x1B },
2420 { 0x22, 0x7AD, 0x80 },
2421 { 0x22, 0x7A6, 0x3E },
2422 { 0x22, 0x7A7, 0x88 },
2423 { 0x22, 0x7A8, 0xDC },
2424 { 0x22, 0x7A9, 0x3E },
2425 { 0x22, 0x7AA, 0x88 },
2426 { 0x22, 0x7AB, 0xDC },
2427 { 0x22, 0x7AC, 0x1C },
2428 { 0x22, 0x7AD, 0x80 },
2429 { 0x22, 0x7A6, 0x7D },
2430 { 0x22, 0x7A7, 0x09 },
2431 { 0x22, 0x7A8, 0x28 },
2432 { 0x22, 0x7A9, 0x7D },
2433 { 0x22, 0x7AA, 0x09 },
2434 { 0x22, 0x7AB, 0x28 },
2435 { 0x22, 0x7AC, 0x1D },
2436 { 0x22, 0x7AD, 0x80 },
2437 { 0x22, 0x7A6, 0xC2 },
2438 { 0x22, 0x7A7, 0xE5 },
2439 { 0x22, 0x7A8, 0xB4 },
2440 { 0x22, 0x7A9, 0xC2 },
2441 { 0x22, 0x7AA, 0xE5 },
2442 { 0x22, 0x7AB, 0xB4 },
2443 { 0x22, 0x7AC, 0x1E },
2444 { 0x22, 0x7AD, 0x80 },
2445 { 0x22, 0x7A6, 0x3E },
2446 { 0x22, 0x7A7, 0xA3 },
2447 { 0x22, 0x7A8, 0x1F },
2448 { 0x22, 0x7A9, 0x3E },
2449 { 0x22, 0x7AA, 0xA3 },
2450 { 0x22, 0x7AB, 0x1F },
2451 { 0x22, 0x7AC, 0x1F },
2452 { 0x22, 0x7AD, 0x80 },
2453 { 0x22, 0x7A6, 0x84 },
2454 { 0x22, 0x7A7, 0xCA },
2455 { 0x22, 0x7A8, 0xF1 },
2456 { 0x22, 0x7A9, 0x84 },
2457 { 0x22, 0x7AA, 0xCA },
2458 { 0x22, 0x7AB, 0xF1 },
2459 { 0x22, 0x7AC, 0x20 },
2460 { 0x22, 0x7AD, 0x80 },
2461 { 0x22, 0x7A6, 0x3C },
2462 { 0x22, 0x7A7, 0xD5 },
2463 { 0x22, 0x7A8, 0x9C },
2464 { 0x22, 0x7A9, 0x3C },
2465 { 0x22, 0x7AA, 0xD5 },
2466 { 0x22, 0x7AB, 0x9C },
2467 { 0x22, 0x7AC, 0x21 },
2468 { 0x22, 0x7AD, 0x80 },
2469 { 0x22, 0x7A6, 0x7B },
2470 { 0x22, 0x7A7, 0x35 },
2471 { 0x22, 0x7A8, 0x0F },
2472 { 0x22, 0x7A9, 0x7B },
2473 { 0x22, 0x7AA, 0x35 },
2474 { 0x22, 0x7AB, 0x0F },
2475 { 0x22, 0x7AC, 0x22 },
2476 { 0x22, 0x7AD, 0x80 },
2477 { 0x22, 0x7A6, 0xC4 },
2478 { 0x22, 0x7A7, 0x87 },
2479 { 0x22, 0x7A8, 0x45 },
2480 { 0x22, 0x7A9, 0xC4 },
2481 { 0x22, 0x7AA, 0x87 },
2482 { 0x22, 0x7AB, 0x45 },
2483 { 0x22, 0x7AC, 0x23 },
2484 { 0x22, 0x7AD, 0x80 },
2485 { 0x22, 0x7A6, 0x3E },
2486 { 0x22, 0x7A7, 0x0A },
2487 { 0x22, 0x7A8, 0x78 },
2488 { 0x22, 0x7A9, 0x3E },
2489 { 0x22, 0x7AA, 0x0A },
2490 { 0x22, 0x7AB, 0x78 },
2491 { 0x22, 0x7AC, 0x24 },
2492 { 0x22, 0x7AD, 0x80 },
2493 { 0x22, 0x7A6, 0x88 },
2494 { 0x22, 0x7A7, 0xE2 },
2495 { 0x22, 0x7A8, 0x05 },
2496 { 0x22, 0x7A9, 0x88 },
2497 { 0x22, 0x7AA, 0xE2 },
2498 { 0x22, 0x7AB, 0x05 },
2499 { 0x22, 0x7AC, 0x25 },
2500 { 0x22, 0x7AD, 0x80 },
2501 { 0x22, 0x7A6, 0x3A },
2502 { 0x22, 0x7A7, 0x1A },
2503 { 0x22, 0x7A8, 0xA3 },
2504 { 0x22, 0x7A9, 0x3A },
2505 { 0x22, 0x7AA, 0x1A },
2506 { 0x22, 0x7AB, 0xA3 },
2507 { 0x22, 0x7AC, 0x26 },
2508 { 0x22, 0x7AD, 0x80 },
2509 { 0x22, 0x7A6, 0x77 },
2510 { 0x22, 0x7A7, 0x1D },
2511 { 0x22, 0x7A8, 0xFB },
2512 { 0x22, 0x7A9, 0x77 },
2513 { 0x22, 0x7AA, 0x1D },
2514 { 0x22, 0x7AB, 0xFB },
2515 { 0x22, 0x7AC, 0x27 },
2516 { 0x22, 0x7AD, 0x80 },
2517 { 0x22, 0x7A6, 0xC7 },
2518 { 0x22, 0x7A7, 0xDA },
2519 { 0x22, 0x7A8, 0xE5 },
2520 { 0x22, 0x7A9, 0xC7 },
2521 { 0x22, 0x7AA, 0xDA },
2522 { 0x22, 0x7AB, 0xE5 },
2523 { 0x22, 0x7AC, 0x28 },
2524 { 0x22, 0x7AD, 0x80 },
2525 { 0x22, 0x7A6, 0x40 },
2526 { 0x22, 0x7A7, 0x00 },
2527 { 0x22, 0x7A8, 0x00 },
2528 { 0x22, 0x7A9, 0x40 },
2529 { 0x22, 0x7AA, 0x00 },
2530 { 0x22, 0x7AB, 0x00 },
2531 { 0x22, 0x7AC, 0x29 },
2532 { 0x22, 0x7AD, 0x80 },
2533 { 0x22, 0x7A6, 0x8E },
2534 { 0x22, 0x7A7, 0xD7 },
2535 { 0x22, 0x7A8, 0x22 },
2536 { 0x22, 0x7A9, 0x8E },
2537 { 0x22, 0x7AA, 0xD7 },
2538 { 0x22, 0x7AB, 0x22 },
2539 { 0x22, 0x7AC, 0x2A },
2540 { 0x22, 0x7AD, 0x80 },
2541 { 0x22, 0x7A6, 0x35 },
2542 { 0x22, 0x7A7, 0x26 },
2543 { 0x22, 0x7A8, 0xC6 },
2544 { 0x22, 0x7A9, 0x35 },
2545 { 0x22, 0x7AA, 0x26 },
2546 { 0x22, 0x7AB, 0xC6 },
2547 { 0x22, 0x7AC, 0x2B },
2548 { 0x22, 0x7AD, 0x80 },
2549 { 0x22, 0x7A6, 0x71 },
2550 { 0x22, 0x7A7, 0x28 },
2551 { 0x22, 0x7A8, 0xDE },
2552 { 0x22, 0x7A9, 0x71 },
2553 { 0x22, 0x7AA, 0x28 },
2554 { 0x22, 0x7AB, 0xDE },
2555 { 0x22, 0x7AC, 0x2C },
2556 { 0x22, 0x7AD, 0x80 },
2557 { 0x22, 0x7A6, 0xCA },
2558 { 0x22, 0x7A7, 0xD9 },
2559 { 0x22, 0x7A8, 0x3A },
2560 { 0x22, 0x7A9, 0xCA },
2561 { 0x22, 0x7AA, 0xD9 },
2562 { 0x22, 0x7AB, 0x3A },
2563 { 0x22, 0x7AC, 0x2D },
2564 { 0x22, 0x7AD, 0x80 },
2565 { 0x22, 0x7A6, 0x40 },
2566 { 0x22, 0x7A7, 0x00 },
2567 { 0x22, 0x7A8, 0x00 },
2568 { 0x22, 0x7A9, 0x40 },
2569 { 0x22, 0x7AA, 0x00 },
2570 { 0x22, 0x7AB, 0x00 },
2571 { 0x22, 0x7AC, 0x2E },
2572 { 0x22, 0x7AD, 0x80 },
2573 { 0x22, 0x7A6, 0x93 },
2574 { 0x22, 0x7A7, 0x5E },
2575 { 0x22, 0x7A8, 0xD8 },
2576 { 0x22, 0x7A9, 0x93 },
2577 { 0x22, 0x7AA, 0x5E },
2578 { 0x22, 0x7AB, 0xD8 },
2579 { 0x22, 0x7AC, 0x2F },
2580 { 0x22, 0x7AD, 0x80 },
2581 { 0x22, 0x7A6, 0x32 },
2582 { 0x22, 0x7A7, 0xB7 },
2583 { 0x22, 0x7A8, 0xB1 },
2584 { 0x22, 0x7A9, 0x32 },
2585 { 0x22, 0x7AA, 0xB7 },
2586 { 0x22, 0x7AB, 0xB1 },
2587 { 0x22, 0x7AC, 0x30 },
2588 { 0x22, 0x7AD, 0x80 },
2589 { 0x22, 0x7A6, 0x6C },
2590 { 0x22, 0x7A7, 0xA1 },
2591 { 0x22, 0x7A8, 0x28 },
2592 { 0x22, 0x7A9, 0x6C },
2593 { 0x22, 0x7AA, 0xA1 },
2594 { 0x22, 0x7AB, 0x28 },
2595 { 0x22, 0x7AC, 0x31 },
2596 { 0x22, 0x7AD, 0x80 },
2597 { 0x22, 0x7A6, 0xCD },
2598 { 0x22, 0x7A7, 0x48 },
2599 { 0x22, 0x7A8, 0x4F },
2600 { 0x22, 0x7A9, 0xCD },
2601 { 0x22, 0x7AA, 0x48 },
2602 { 0x22, 0x7AB, 0x4F },
2603 { 0x22, 0x7AC, 0x32 },
2604 { 0x22, 0x7AD, 0x80 },
2605 { 0x22, 0x7A6, 0x40 },
2606 { 0x22, 0x7A7, 0x00 },
2607 { 0x22, 0x7A8, 0x00 },
2608 { 0x22, 0x7A9, 0x40 },
2609 { 0x22, 0x7AA, 0x00 },
2610 { 0x22, 0x7AB, 0x00 },
2611 { 0x22, 0x7AC, 0x33 },
2612 { 0x22, 0x7AD, 0x80 },
2613 /* common */
2614 { 0x22, 0x782, 0xC1 },
2615 { 0x22, 0x771, 0x2C },
2616 { 0x22, 0x772, 0x2C },
2617 { 0x22, 0x788, 0x04 },
2618 { 0x01, 0x7B0, 0x08 },
2622 static const struct hda_fixup stac92hd83xxx_fixups[] = {
2623 [STAC_92HD83XXX_REF] = {
2624 .type = HDA_FIXUP_PINS,
2625 .v.pins = ref92hd83xxx_pin_configs,
2627 [STAC_92HD83XXX_PWR_REF] = {
2628 .type = HDA_FIXUP_PINS,
2629 .v.pins = ref92hd83xxx_pin_configs,
2631 [STAC_DELL_S14] = {
2632 .type = HDA_FIXUP_PINS,
2633 .v.pins = dell_s14_pin_configs,
2635 [STAC_DELL_VOSTRO_3500] = {
2636 .type = HDA_FIXUP_PINS,
2637 .v.pins = dell_vostro_3500_pin_configs,
2639 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = {
2640 .type = HDA_FIXUP_PINS,
2641 .v.pins = hp_cNB11_intquad_pin_configs,
2642 .chained = true,
2643 .chain_id = STAC_92HD83XXX_HP,
2645 [STAC_92HD83XXX_HP] = {
2646 .type = HDA_FIXUP_FUNC,
2647 .v.func = stac92hd83xxx_fixup_hp,
2649 [STAC_HP_DV7_4000] = {
2650 .type = HDA_FIXUP_PINS,
2651 .v.pins = hp_dv7_4000_pin_configs,
2652 .chained = true,
2653 .chain_id = STAC_92HD83XXX_HP,
2655 [STAC_HP_ZEPHYR] = {
2656 .type = HDA_FIXUP_FUNC,
2657 .v.func = stac92hd83xxx_fixup_hp_zephyr,
2658 .chained = true,
2659 .chain_id = STAC_92HD83XXX_HP,
2661 [STAC_92HD83XXX_HP_LED] = {
2662 .type = HDA_FIXUP_FUNC,
2663 .v.func = stac92hd83xxx_fixup_hp_led,
2664 .chained = true,
2665 .chain_id = STAC_92HD83XXX_HP,
2667 [STAC_92HD83XXX_HP_INV_LED] = {
2668 .type = HDA_FIXUP_FUNC,
2669 .v.func = stac92hd83xxx_fixup_hp_inv_led,
2670 .chained = true,
2671 .chain_id = STAC_92HD83XXX_HP,
2673 [STAC_92HD83XXX_HP_MIC_LED] = {
2674 .type = HDA_FIXUP_FUNC,
2675 .v.func = stac92hd83xxx_fixup_hp_mic_led,
2676 .chained = true,
2677 .chain_id = STAC_92HD83XXX_HP,
2679 [STAC_HP_LED_GPIO10] = {
2680 .type = HDA_FIXUP_FUNC,
2681 .v.func = stac92hd83xxx_fixup_hp_led_gpio10,
2682 .chained = true,
2683 .chain_id = STAC_92HD83XXX_HP,
2685 [STAC_92HD83XXX_HEADSET_JACK] = {
2686 .type = HDA_FIXUP_FUNC,
2687 .v.func = stac92hd83xxx_fixup_headset_jack,
2689 [STAC_HP_ENVY_BASS] = {
2690 .type = HDA_FIXUP_PINS,
2691 .v.pins = (const struct hda_pintbl[]) {
2692 { 0x0f, 0x90170111 },
2696 [STAC_HP_BNB13_EQ] = {
2697 .type = HDA_FIXUP_VERBS,
2698 .v.verbs = hp_bnb13_eq_verbs,
2699 .chained = true,
2700 .chain_id = STAC_92HD83XXX_HP_MIC_LED,
2702 [STAC_HP_ENVY_TS_BASS] = {
2703 .type = HDA_FIXUP_PINS,
2704 .v.pins = (const struct hda_pintbl[]) {
2705 { 0x10, 0x92170111 },
2709 [STAC_HP_ENVY_TS_DAC_BIND] = {
2710 .type = HDA_FIXUP_FUNC,
2711 .v.func = hp_envy_ts_fixup_dac_bind,
2712 .chained = true,
2713 .chain_id = STAC_HP_ENVY_TS_BASS,
2715 [STAC_92HD83XXX_GPIO10_EAPD] = {
2716 .type = HDA_FIXUP_FUNC,
2717 .v.func = stac92hd83xxx_fixup_gpio10_eapd,
2721 static const struct hda_model_fixup stac92hd83xxx_models[] = {
2722 { .id = STAC_92HD83XXX_REF, .name = "ref" },
2723 { .id = STAC_92HD83XXX_PWR_REF, .name = "mic-ref" },
2724 { .id = STAC_DELL_S14, .name = "dell-s14" },
2725 { .id = STAC_DELL_VOSTRO_3500, .name = "dell-vostro-3500" },
2726 { .id = STAC_92HD83XXX_HP_cNB11_INTQUAD, .name = "hp_cNB11_intquad" },
2727 { .id = STAC_HP_DV7_4000, .name = "hp-dv7-4000" },
2728 { .id = STAC_HP_ZEPHYR, .name = "hp-zephyr" },
2729 { .id = STAC_92HD83XXX_HP_LED, .name = "hp-led" },
2730 { .id = STAC_92HD83XXX_HP_INV_LED, .name = "hp-inv-led" },
2731 { .id = STAC_92HD83XXX_HP_MIC_LED, .name = "hp-mic-led" },
2732 { .id = STAC_92HD83XXX_HEADSET_JACK, .name = "headset-jack" },
2733 { .id = STAC_HP_ENVY_BASS, .name = "hp-envy-bass" },
2734 { .id = STAC_HP_BNB13_EQ, .name = "hp-bnb13-eq" },
2735 { .id = STAC_HP_ENVY_TS_BASS, .name = "hp-envy-ts-bass" },
2739 static const struct snd_pci_quirk stac92hd83xxx_fixup_tbl[] = {
2740 /* SigmaTel reference board */
2741 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2742 "DFI LanParty", STAC_92HD83XXX_REF),
2743 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
2744 "DFI LanParty", STAC_92HD83XXX_REF),
2745 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
2746 "unknown Dell", STAC_DELL_S14),
2747 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0532,
2748 "Dell Latitude E6230", STAC_92HD83XXX_HEADSET_JACK),
2749 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0533,
2750 "Dell Latitude E6330", STAC_92HD83XXX_HEADSET_JACK),
2751 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0534,
2752 "Dell Latitude E6430", STAC_92HD83XXX_HEADSET_JACK),
2753 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0535,
2754 "Dell Latitude E6530", STAC_92HD83XXX_HEADSET_JACK),
2755 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053c,
2756 "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
2757 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053d,
2758 "Dell Latitude E5530", STAC_92HD83XXX_HEADSET_JACK),
2759 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0549,
2760 "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
2761 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x057d,
2762 "Dell Latitude E6430s", STAC_92HD83XXX_HEADSET_JACK),
2763 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0584,
2764 "Dell Latitude E6430U", STAC_92HD83XXX_HEADSET_JACK),
2765 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028,
2766 "Dell Vostro 3500", STAC_DELL_VOSTRO_3500),
2767 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
2768 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2769 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657,
2770 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2771 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658,
2772 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2773 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659,
2774 "HP Pavilion dv7", STAC_HP_DV7_4000),
2775 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A,
2776 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2777 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
2778 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2779 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1888,
2780 "HP Envy Spectre", STAC_HP_ENVY_BASS),
2781 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1899,
2782 "HP Folio 13", STAC_HP_LED_GPIO10),
2783 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df,
2784 "HP Folio", STAC_HP_BNB13_EQ),
2785 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18F8,
2786 "HP bNB13", STAC_HP_BNB13_EQ),
2787 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1909,
2788 "HP bNB13", STAC_HP_BNB13_EQ),
2789 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x190A,
2790 "HP bNB13", STAC_HP_BNB13_EQ),
2791 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x190e,
2792 "HP ENVY TS", STAC_HP_ENVY_TS_BASS),
2793 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1967,
2794 "HP ENVY TS", STAC_HP_ENVY_TS_DAC_BIND),
2795 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1940,
2796 "HP bNB13", STAC_HP_BNB13_EQ),
2797 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1941,
2798 "HP bNB13", STAC_HP_BNB13_EQ),
2799 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1942,
2800 "HP bNB13", STAC_HP_BNB13_EQ),
2801 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1943,
2802 "HP bNB13", STAC_HP_BNB13_EQ),
2803 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1944,
2804 "HP bNB13", STAC_HP_BNB13_EQ),
2805 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1945,
2806 "HP bNB13", STAC_HP_BNB13_EQ),
2807 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1946,
2808 "HP bNB13", STAC_HP_BNB13_EQ),
2809 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1948,
2810 "HP bNB13", STAC_HP_BNB13_EQ),
2811 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1949,
2812 "HP bNB13", STAC_HP_BNB13_EQ),
2813 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194A,
2814 "HP bNB13", STAC_HP_BNB13_EQ),
2815 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194B,
2816 "HP bNB13", STAC_HP_BNB13_EQ),
2817 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194C,
2818 "HP bNB13", STAC_HP_BNB13_EQ),
2819 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194E,
2820 "HP bNB13", STAC_HP_BNB13_EQ),
2821 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194F,
2822 "HP bNB13", STAC_HP_BNB13_EQ),
2823 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1950,
2824 "HP bNB13", STAC_HP_BNB13_EQ),
2825 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1951,
2826 "HP bNB13", STAC_HP_BNB13_EQ),
2827 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x195A,
2828 "HP bNB13", STAC_HP_BNB13_EQ),
2829 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x195B,
2830 "HP bNB13", STAC_HP_BNB13_EQ),
2831 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x195C,
2832 "HP bNB13", STAC_HP_BNB13_EQ),
2833 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1991,
2834 "HP bNB13", STAC_HP_BNB13_EQ),
2835 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2103,
2836 "HP bNB13", STAC_HP_BNB13_EQ),
2837 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2104,
2838 "HP bNB13", STAC_HP_BNB13_EQ),
2839 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2105,
2840 "HP bNB13", STAC_HP_BNB13_EQ),
2841 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2106,
2842 "HP bNB13", STAC_HP_BNB13_EQ),
2843 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2107,
2844 "HP bNB13", STAC_HP_BNB13_EQ),
2845 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2108,
2846 "HP bNB13", STAC_HP_BNB13_EQ),
2847 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2109,
2848 "HP bNB13", STAC_HP_BNB13_EQ),
2849 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x210A,
2850 "HP bNB13", STAC_HP_BNB13_EQ),
2851 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x210B,
2852 "HP bNB13", STAC_HP_BNB13_EQ),
2853 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211C,
2854 "HP bNB13", STAC_HP_BNB13_EQ),
2855 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211D,
2856 "HP bNB13", STAC_HP_BNB13_EQ),
2857 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211E,
2858 "HP bNB13", STAC_HP_BNB13_EQ),
2859 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211F,
2860 "HP bNB13", STAC_HP_BNB13_EQ),
2861 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2120,
2862 "HP bNB13", STAC_HP_BNB13_EQ),
2863 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2121,
2864 "HP bNB13", STAC_HP_BNB13_EQ),
2865 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2122,
2866 "HP bNB13", STAC_HP_BNB13_EQ),
2867 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2123,
2868 "HP bNB13", STAC_HP_BNB13_EQ),
2869 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x213E,
2870 "HP bNB13", STAC_HP_BNB13_EQ),
2871 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x213F,
2872 "HP bNB13", STAC_HP_BNB13_EQ),
2873 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2140,
2874 "HP bNB13", STAC_HP_BNB13_EQ),
2875 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B2,
2876 "HP bNB13", STAC_HP_BNB13_EQ),
2877 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B3,
2878 "HP bNB13", STAC_HP_BNB13_EQ),
2879 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B5,
2880 "HP bNB13", STAC_HP_BNB13_EQ),
2881 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B6,
2882 "HP bNB13", STAC_HP_BNB13_EQ),
2883 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x1900,
2884 "HP", STAC_92HD83XXX_HP_MIC_LED),
2885 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x2000,
2886 "HP", STAC_92HD83XXX_HP_MIC_LED),
2887 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x2100,
2888 "HP", STAC_92HD83XXX_HP_MIC_LED),
2889 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388,
2890 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2891 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389,
2892 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2893 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355B,
2894 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2895 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355C,
2896 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2897 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355D,
2898 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2899 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355E,
2900 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2901 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355F,
2902 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2903 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3560,
2904 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2905 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358B,
2906 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2907 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358C,
2908 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2909 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358D,
2910 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2911 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3591,
2912 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2913 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3592,
2914 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2915 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
2916 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2917 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
2918 "HP", STAC_HP_ZEPHYR),
2919 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3660,
2920 "HP Mini", STAC_92HD83XXX_HP_LED),
2921 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x144E,
2922 "HP Pavilion dv5", STAC_92HD83XXX_HP_INV_LED),
2923 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x148a,
2924 "HP Mini", STAC_92HD83XXX_HP_LED),
2925 SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_HP, "HP", STAC_92HD83XXX_HP),
2926 /* match both for 0xfa91 and 0xfa93 */
2927 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_TOSHIBA, 0xfffd, 0xfa91,
2928 "Toshiba Satellite S50D", STAC_92HD83XXX_GPIO10_EAPD),
2929 {} /* terminator */
2932 /* HP dv7 bass switch - GPIO5 */
2933 #define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info
2934 static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol,
2935 struct snd_ctl_elem_value *ucontrol)
2937 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2938 struct sigmatel_spec *spec = codec->spec;
2939 ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20);
2940 return 0;
2943 static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol,
2944 struct snd_ctl_elem_value *ucontrol)
2946 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2947 struct sigmatel_spec *spec = codec->spec;
2948 unsigned int gpio_data;
2950 gpio_data = (spec->gpio_data & ~0x20) |
2951 (ucontrol->value.integer.value[0] ? 0x20 : 0);
2952 if (gpio_data == spec->gpio_data)
2953 return 0;
2954 spec->gpio_data = gpio_data;
2955 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
2956 return 1;
2959 static const struct snd_kcontrol_new stac_hp_bass_sw_ctrl = {
2960 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2961 .info = stac_hp_bass_gpio_info,
2962 .get = stac_hp_bass_gpio_get,
2963 .put = stac_hp_bass_gpio_put,
2966 static int stac_add_hp_bass_switch(struct hda_codec *codec)
2968 struct sigmatel_spec *spec = codec->spec;
2970 if (!snd_hda_gen_add_kctl(&spec->gen, "Bass Speaker Playback Switch",
2971 &stac_hp_bass_sw_ctrl))
2972 return -ENOMEM;
2974 spec->gpio_mask |= 0x20;
2975 spec->gpio_dir |= 0x20;
2976 spec->gpio_data |= 0x20;
2977 return 0;
2980 static const struct hda_pintbl ref92hd71bxx_pin_configs[] = {
2981 { 0x0a, 0x02214030 },
2982 { 0x0b, 0x02a19040 },
2983 { 0x0c, 0x01a19020 },
2984 { 0x0d, 0x01014010 },
2985 { 0x0e, 0x0181302e },
2986 { 0x0f, 0x01014010 },
2987 { 0x14, 0x01019020 },
2988 { 0x18, 0x90a000f0 },
2989 { 0x19, 0x90a000f0 },
2990 { 0x1e, 0x01452050 },
2991 { 0x1f, 0x01452050 },
2995 static const struct hda_pintbl dell_m4_1_pin_configs[] = {
2996 { 0x0a, 0x0421101f },
2997 { 0x0b, 0x04a11221 },
2998 { 0x0c, 0x40f000f0 },
2999 { 0x0d, 0x90170110 },
3000 { 0x0e, 0x23a1902e },
3001 { 0x0f, 0x23014250 },
3002 { 0x14, 0x40f000f0 },
3003 { 0x18, 0x90a000f0 },
3004 { 0x19, 0x40f000f0 },
3005 { 0x1e, 0x4f0000f0 },
3006 { 0x1f, 0x4f0000f0 },
3010 static const struct hda_pintbl dell_m4_2_pin_configs[] = {
3011 { 0x0a, 0x0421101f },
3012 { 0x0b, 0x04a11221 },
3013 { 0x0c, 0x90a70330 },
3014 { 0x0d, 0x90170110 },
3015 { 0x0e, 0x23a1902e },
3016 { 0x0f, 0x23014250 },
3017 { 0x14, 0x40f000f0 },
3018 { 0x18, 0x40f000f0 },
3019 { 0x19, 0x40f000f0 },
3020 { 0x1e, 0x044413b0 },
3021 { 0x1f, 0x044413b0 },
3025 static const struct hda_pintbl dell_m4_3_pin_configs[] = {
3026 { 0x0a, 0x0421101f },
3027 { 0x0b, 0x04a11221 },
3028 { 0x0c, 0x90a70330 },
3029 { 0x0d, 0x90170110 },
3030 { 0x0e, 0x40f000f0 },
3031 { 0x0f, 0x40f000f0 },
3032 { 0x14, 0x40f000f0 },
3033 { 0x18, 0x90a000f0 },
3034 { 0x19, 0x40f000f0 },
3035 { 0x1e, 0x044413b0 },
3036 { 0x1f, 0x044413b0 },
3040 static void stac92hd71bxx_fixup_ref(struct hda_codec *codec,
3041 const struct hda_fixup *fix, int action)
3043 struct sigmatel_spec *spec = codec->spec;
3045 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3046 return;
3048 snd_hda_apply_pincfgs(codec, ref92hd71bxx_pin_configs);
3049 spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0;
3052 static void stac92hd71bxx_fixup_hp_m4(struct hda_codec *codec,
3053 const struct hda_fixup *fix, int action)
3055 struct sigmatel_spec *spec = codec->spec;
3056 struct hda_jack_callback *jack;
3058 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3059 return;
3061 /* Enable VREF power saving on GPIO1 detect */
3062 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
3063 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
3064 jack = snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
3065 stac_vref_event);
3066 if (!IS_ERR(jack))
3067 jack->private_data = 0x02;
3069 spec->gpio_mask |= 0x02;
3071 /* enable internal microphone */
3072 snd_hda_codec_set_pincfg(codec, 0x0e, 0x01813040);
3075 static void stac92hd71bxx_fixup_hp_dv4(struct hda_codec *codec,
3076 const struct hda_fixup *fix, int action)
3078 struct sigmatel_spec *spec = codec->spec;
3080 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3081 return;
3082 spec->gpio_led = 0x01;
3085 static void stac92hd71bxx_fixup_hp_dv5(struct hda_codec *codec,
3086 const struct hda_fixup *fix, int action)
3088 unsigned int cap;
3090 switch (action) {
3091 case HDA_FIXUP_ACT_PRE_PROBE:
3092 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
3093 break;
3095 case HDA_FIXUP_ACT_PROBE:
3096 /* enable bass on HP dv7 */
3097 cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
3098 cap &= AC_GPIO_IO_COUNT;
3099 if (cap >= 6)
3100 stac_add_hp_bass_switch(codec);
3101 break;
3105 static void stac92hd71bxx_fixup_hp_hdx(struct hda_codec *codec,
3106 const struct hda_fixup *fix, int action)
3108 struct sigmatel_spec *spec = codec->spec;
3110 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3111 return;
3112 spec->gpio_led = 0x08;
3115 static bool is_hp_output(struct hda_codec *codec, hda_nid_t pin)
3117 unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, pin);
3119 /* count line-out, too, as BIOS sets often so */
3120 return get_defcfg_connect(pin_cfg) != AC_JACK_PORT_NONE &&
3121 (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT ||
3122 get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT);
3125 static void fixup_hp_headphone(struct hda_codec *codec, hda_nid_t pin)
3127 unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, pin);
3129 /* It was changed in the BIOS to just satisfy MS DTM.
3130 * Lets turn it back into slaved HP
3132 pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE)) |
3133 (AC_JACK_HP_OUT << AC_DEFCFG_DEVICE_SHIFT);
3134 pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC | AC_DEFCFG_SEQUENCE))) |
3135 0x1f;
3136 snd_hda_codec_set_pincfg(codec, pin, pin_cfg);
3139 static void stac92hd71bxx_fixup_hp(struct hda_codec *codec,
3140 const struct hda_fixup *fix, int action)
3142 struct sigmatel_spec *spec = codec->spec;
3144 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3145 return;
3147 /* when both output A and F are assigned, these are supposedly
3148 * dock and built-in headphones; fix both pin configs
3150 if (is_hp_output(codec, 0x0a) && is_hp_output(codec, 0x0f)) {
3151 fixup_hp_headphone(codec, 0x0a);
3152 fixup_hp_headphone(codec, 0x0f);
3155 if (find_mute_led_cfg(codec, 1))
3156 codec_dbg(codec, "mute LED gpio %d polarity %d\n",
3157 spec->gpio_led,
3158 spec->gpio_led_polarity);
3162 static const struct hda_fixup stac92hd71bxx_fixups[] = {
3163 [STAC_92HD71BXX_REF] = {
3164 .type = HDA_FIXUP_FUNC,
3165 .v.func = stac92hd71bxx_fixup_ref,
3167 [STAC_DELL_M4_1] = {
3168 .type = HDA_FIXUP_PINS,
3169 .v.pins = dell_m4_1_pin_configs,
3171 [STAC_DELL_M4_2] = {
3172 .type = HDA_FIXUP_PINS,
3173 .v.pins = dell_m4_2_pin_configs,
3175 [STAC_DELL_M4_3] = {
3176 .type = HDA_FIXUP_PINS,
3177 .v.pins = dell_m4_3_pin_configs,
3179 [STAC_HP_M4] = {
3180 .type = HDA_FIXUP_FUNC,
3181 .v.func = stac92hd71bxx_fixup_hp_m4,
3182 .chained = true,
3183 .chain_id = STAC_92HD71BXX_HP,
3185 [STAC_HP_DV4] = {
3186 .type = HDA_FIXUP_FUNC,
3187 .v.func = stac92hd71bxx_fixup_hp_dv4,
3188 .chained = true,
3189 .chain_id = STAC_HP_DV5,
3191 [STAC_HP_DV5] = {
3192 .type = HDA_FIXUP_FUNC,
3193 .v.func = stac92hd71bxx_fixup_hp_dv5,
3194 .chained = true,
3195 .chain_id = STAC_92HD71BXX_HP,
3197 [STAC_HP_HDX] = {
3198 .type = HDA_FIXUP_FUNC,
3199 .v.func = stac92hd71bxx_fixup_hp_hdx,
3200 .chained = true,
3201 .chain_id = STAC_92HD71BXX_HP,
3203 [STAC_92HD71BXX_HP] = {
3204 .type = HDA_FIXUP_FUNC,
3205 .v.func = stac92hd71bxx_fixup_hp,
3209 static const struct hda_model_fixup stac92hd71bxx_models[] = {
3210 { .id = STAC_92HD71BXX_REF, .name = "ref" },
3211 { .id = STAC_DELL_M4_1, .name = "dell-m4-1" },
3212 { .id = STAC_DELL_M4_2, .name = "dell-m4-2" },
3213 { .id = STAC_DELL_M4_3, .name = "dell-m4-3" },
3214 { .id = STAC_HP_M4, .name = "hp-m4" },
3215 { .id = STAC_HP_DV4, .name = "hp-dv4" },
3216 { .id = STAC_HP_DV5, .name = "hp-dv5" },
3217 { .id = STAC_HP_HDX, .name = "hp-hdx" },
3218 { .id = STAC_HP_DV4, .name = "hp-dv4-1222nr" },
3222 static const struct snd_pci_quirk stac92hd71bxx_fixup_tbl[] = {
3223 /* SigmaTel reference board */
3224 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3225 "DFI LanParty", STAC_92HD71BXX_REF),
3226 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3227 "DFI LanParty", STAC_92HD71BXX_REF),
3228 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720,
3229 "HP", STAC_HP_DV5),
3230 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
3231 "HP", STAC_HP_DV5),
3232 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
3233 "HP dv4-7", STAC_HP_DV4),
3234 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600,
3235 "HP dv4-7", STAC_HP_DV5),
3236 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610,
3237 "HP HDX", STAC_HP_HDX), /* HDX18 */
3238 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
3239 "HP mini 1000", STAC_HP_M4),
3240 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b,
3241 "HP HDX", STAC_HP_HDX), /* HDX16 */
3242 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620,
3243 "HP dv6", STAC_HP_DV5),
3244 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061,
3245 "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */
3246 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x363e,
3247 "HP DV6", STAC_HP_DV5),
3248 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010,
3249 "HP", STAC_HP_DV5),
3250 SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_HP, "HP", STAC_92HD71BXX_HP),
3251 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
3252 "unknown Dell", STAC_DELL_M4_1),
3253 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234,
3254 "unknown Dell", STAC_DELL_M4_1),
3255 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0250,
3256 "unknown Dell", STAC_DELL_M4_1),
3257 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024f,
3258 "unknown Dell", STAC_DELL_M4_1),
3259 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024d,
3260 "unknown Dell", STAC_DELL_M4_1),
3261 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0251,
3262 "unknown Dell", STAC_DELL_M4_1),
3263 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0277,
3264 "unknown Dell", STAC_DELL_M4_1),
3265 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0263,
3266 "unknown Dell", STAC_DELL_M4_2),
3267 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0265,
3268 "unknown Dell", STAC_DELL_M4_2),
3269 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0262,
3270 "unknown Dell", STAC_DELL_M4_2),
3271 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264,
3272 "unknown Dell", STAC_DELL_M4_2),
3273 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02aa,
3274 "unknown Dell", STAC_DELL_M4_3),
3275 {} /* terminator */
3278 static const struct hda_pintbl ref922x_pin_configs[] = {
3279 { 0x0a, 0x01014010 },
3280 { 0x0b, 0x01016011 },
3281 { 0x0c, 0x01012012 },
3282 { 0x0d, 0x0221401f },
3283 { 0x0e, 0x01813122 },
3284 { 0x0f, 0x01011014 },
3285 { 0x10, 0x01441030 },
3286 { 0x11, 0x01c41030 },
3287 { 0x15, 0x40000100 },
3288 { 0x1b, 0x40000100 },
3293 STAC 922X pin configs for
3294 102801A7
3295 102801AB
3296 102801A9
3297 102801D1
3298 102801D2
3300 static const struct hda_pintbl dell_922x_d81_pin_configs[] = {
3301 { 0x0a, 0x02214030 },
3302 { 0x0b, 0x01a19021 },
3303 { 0x0c, 0x01111012 },
3304 { 0x0d, 0x01114010 },
3305 { 0x0e, 0x02a19020 },
3306 { 0x0f, 0x01117011 },
3307 { 0x10, 0x400001f0 },
3308 { 0x11, 0x400001f1 },
3309 { 0x15, 0x01813122 },
3310 { 0x1b, 0x400001f2 },
3315 STAC 922X pin configs for
3316 102801AC
3317 102801D0
3319 static const struct hda_pintbl dell_922x_d82_pin_configs[] = {
3320 { 0x0a, 0x02214030 },
3321 { 0x0b, 0x01a19021 },
3322 { 0x0c, 0x01111012 },
3323 { 0x0d, 0x01114010 },
3324 { 0x0e, 0x02a19020 },
3325 { 0x0f, 0x01117011 },
3326 { 0x10, 0x01451140 },
3327 { 0x11, 0x400001f0 },
3328 { 0x15, 0x01813122 },
3329 { 0x1b, 0x400001f1 },
3334 STAC 922X pin configs for
3335 102801BF
3337 static const struct hda_pintbl dell_922x_m81_pin_configs[] = {
3338 { 0x0a, 0x0321101f },
3339 { 0x0b, 0x01112024 },
3340 { 0x0c, 0x01111222 },
3341 { 0x0d, 0x91174220 },
3342 { 0x0e, 0x03a11050 },
3343 { 0x0f, 0x01116221 },
3344 { 0x10, 0x90a70330 },
3345 { 0x11, 0x01452340 },
3346 { 0x15, 0x40C003f1 },
3347 { 0x1b, 0x405003f0 },
3352 STAC 9221 A1 pin configs for
3353 102801D7 (Dell XPS M1210)
3355 static const struct hda_pintbl dell_922x_m82_pin_configs[] = {
3356 { 0x0a, 0x02211211 },
3357 { 0x0b, 0x408103ff },
3358 { 0x0c, 0x02a1123e },
3359 { 0x0d, 0x90100310 },
3360 { 0x0e, 0x408003f1 },
3361 { 0x0f, 0x0221121f },
3362 { 0x10, 0x03451340 },
3363 { 0x11, 0x40c003f2 },
3364 { 0x15, 0x508003f3 },
3365 { 0x1b, 0x405003f4 },
3369 static const struct hda_pintbl d945gtp3_pin_configs[] = {
3370 { 0x0a, 0x0221401f },
3371 { 0x0b, 0x01a19022 },
3372 { 0x0c, 0x01813021 },
3373 { 0x0d, 0x01014010 },
3374 { 0x0e, 0x40000100 },
3375 { 0x0f, 0x40000100 },
3376 { 0x10, 0x40000100 },
3377 { 0x11, 0x40000100 },
3378 { 0x15, 0x02a19120 },
3379 { 0x1b, 0x40000100 },
3383 static const struct hda_pintbl d945gtp5_pin_configs[] = {
3384 { 0x0a, 0x0221401f },
3385 { 0x0b, 0x01011012 },
3386 { 0x0c, 0x01813024 },
3387 { 0x0d, 0x01014010 },
3388 { 0x0e, 0x01a19021 },
3389 { 0x0f, 0x01016011 },
3390 { 0x10, 0x01452130 },
3391 { 0x11, 0x40000100 },
3392 { 0x15, 0x02a19320 },
3393 { 0x1b, 0x40000100 },
3397 static const struct hda_pintbl intel_mac_v1_pin_configs[] = {
3398 { 0x0a, 0x0121e21f },
3399 { 0x0b, 0x400000ff },
3400 { 0x0c, 0x9017e110 },
3401 { 0x0d, 0x400000fd },
3402 { 0x0e, 0x400000fe },
3403 { 0x0f, 0x0181e020 },
3404 { 0x10, 0x1145e030 },
3405 { 0x11, 0x11c5e240 },
3406 { 0x15, 0x400000fc },
3407 { 0x1b, 0x400000fb },
3411 static const struct hda_pintbl intel_mac_v2_pin_configs[] = {
3412 { 0x0a, 0x0121e21f },
3413 { 0x0b, 0x90a7012e },
3414 { 0x0c, 0x9017e110 },
3415 { 0x0d, 0x400000fd },
3416 { 0x0e, 0x400000fe },
3417 { 0x0f, 0x0181e020 },
3418 { 0x10, 0x1145e230 },
3419 { 0x11, 0x500000fa },
3420 { 0x15, 0x400000fc },
3421 { 0x1b, 0x400000fb },
3425 static const struct hda_pintbl intel_mac_v3_pin_configs[] = {
3426 { 0x0a, 0x0121e21f },
3427 { 0x0b, 0x90a7012e },
3428 { 0x0c, 0x9017e110 },
3429 { 0x0d, 0x400000fd },
3430 { 0x0e, 0x400000fe },
3431 { 0x0f, 0x0181e020 },
3432 { 0x10, 0x1145e230 },
3433 { 0x11, 0x11c5e240 },
3434 { 0x15, 0x400000fc },
3435 { 0x1b, 0x400000fb },
3439 static const struct hda_pintbl intel_mac_v4_pin_configs[] = {
3440 { 0x0a, 0x0321e21f },
3441 { 0x0b, 0x03a1e02e },
3442 { 0x0c, 0x9017e110 },
3443 { 0x0d, 0x9017e11f },
3444 { 0x0e, 0x400000fe },
3445 { 0x0f, 0x0381e020 },
3446 { 0x10, 0x1345e230 },
3447 { 0x11, 0x13c5e240 },
3448 { 0x15, 0x400000fc },
3449 { 0x1b, 0x400000fb },
3453 static const struct hda_pintbl intel_mac_v5_pin_configs[] = {
3454 { 0x0a, 0x0321e21f },
3455 { 0x0b, 0x03a1e02e },
3456 { 0x0c, 0x9017e110 },
3457 { 0x0d, 0x9017e11f },
3458 { 0x0e, 0x400000fe },
3459 { 0x0f, 0x0381e020 },
3460 { 0x10, 0x1345e230 },
3461 { 0x11, 0x13c5e240 },
3462 { 0x15, 0x400000fc },
3463 { 0x1b, 0x400000fb },
3467 static const struct hda_pintbl ecs202_pin_configs[] = {
3468 { 0x0a, 0x0221401f },
3469 { 0x0b, 0x02a19020 },
3470 { 0x0c, 0x01a19020 },
3471 { 0x0d, 0x01114010 },
3472 { 0x0e, 0x408000f0 },
3473 { 0x0f, 0x01813022 },
3474 { 0x10, 0x074510a0 },
3475 { 0x11, 0x40c400f1 },
3476 { 0x15, 0x9037012e },
3477 { 0x1b, 0x40e000f2 },
3481 /* codec SSIDs for Intel Mac sharing the same PCI SSID 8384:7680 */
3482 static const struct snd_pci_quirk stac922x_intel_mac_fixup_tbl[] = {
3483 SND_PCI_QUIRK(0x0000, 0x0100, "Mac Mini", STAC_INTEL_MAC_V3),
3484 SND_PCI_QUIRK(0x106b, 0x0800, "Mac", STAC_INTEL_MAC_V1),
3485 SND_PCI_QUIRK(0x106b, 0x0600, "Mac", STAC_INTEL_MAC_V2),
3486 SND_PCI_QUIRK(0x106b, 0x0700, "Mac", STAC_INTEL_MAC_V2),
3487 SND_PCI_QUIRK(0x106b, 0x0e00, "Mac", STAC_INTEL_MAC_V3),
3488 SND_PCI_QUIRK(0x106b, 0x0f00, "Mac", STAC_INTEL_MAC_V3),
3489 SND_PCI_QUIRK(0x106b, 0x1600, "Mac", STAC_INTEL_MAC_V3),
3490 SND_PCI_QUIRK(0x106b, 0x1700, "Mac", STAC_INTEL_MAC_V3),
3491 SND_PCI_QUIRK(0x106b, 0x0200, "Mac", STAC_INTEL_MAC_V3),
3492 SND_PCI_QUIRK(0x106b, 0x1e00, "Mac", STAC_INTEL_MAC_V3),
3493 SND_PCI_QUIRK(0x106b, 0x1a00, "Mac", STAC_INTEL_MAC_V4),
3494 SND_PCI_QUIRK(0x106b, 0x0a00, "Mac", STAC_INTEL_MAC_V5),
3495 SND_PCI_QUIRK(0x106b, 0x2200, "Mac", STAC_INTEL_MAC_V5),
3499 static const struct hda_fixup stac922x_fixups[];
3501 /* remap the fixup from codec SSID and apply it */
3502 static void stac922x_fixup_intel_mac_auto(struct hda_codec *codec,
3503 const struct hda_fixup *fix,
3504 int action)
3506 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3507 return;
3509 codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
3510 snd_hda_pick_fixup(codec, NULL, stac922x_intel_mac_fixup_tbl,
3511 stac922x_fixups);
3512 if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET)
3513 snd_hda_apply_fixup(codec, action);
3516 static void stac922x_fixup_intel_mac_gpio(struct hda_codec *codec,
3517 const struct hda_fixup *fix,
3518 int action)
3520 struct sigmatel_spec *spec = codec->spec;
3522 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3523 spec->gpio_mask = spec->gpio_dir = 0x03;
3524 spec->gpio_data = 0x03;
3528 static const struct hda_fixup stac922x_fixups[] = {
3529 [STAC_D945_REF] = {
3530 .type = HDA_FIXUP_PINS,
3531 .v.pins = ref922x_pin_configs,
3533 [STAC_D945GTP3] = {
3534 .type = HDA_FIXUP_PINS,
3535 .v.pins = d945gtp3_pin_configs,
3537 [STAC_D945GTP5] = {
3538 .type = HDA_FIXUP_PINS,
3539 .v.pins = d945gtp5_pin_configs,
3541 [STAC_INTEL_MAC_AUTO] = {
3542 .type = HDA_FIXUP_FUNC,
3543 .v.func = stac922x_fixup_intel_mac_auto,
3545 [STAC_INTEL_MAC_V1] = {
3546 .type = HDA_FIXUP_PINS,
3547 .v.pins = intel_mac_v1_pin_configs,
3548 .chained = true,
3549 .chain_id = STAC_922X_INTEL_MAC_GPIO,
3551 [STAC_INTEL_MAC_V2] = {
3552 .type = HDA_FIXUP_PINS,
3553 .v.pins = intel_mac_v2_pin_configs,
3554 .chained = true,
3555 .chain_id = STAC_922X_INTEL_MAC_GPIO,
3557 [STAC_INTEL_MAC_V3] = {
3558 .type = HDA_FIXUP_PINS,
3559 .v.pins = intel_mac_v3_pin_configs,
3560 .chained = true,
3561 .chain_id = STAC_922X_INTEL_MAC_GPIO,
3563 [STAC_INTEL_MAC_V4] = {
3564 .type = HDA_FIXUP_PINS,
3565 .v.pins = intel_mac_v4_pin_configs,
3566 .chained = true,
3567 .chain_id = STAC_922X_INTEL_MAC_GPIO,
3569 [STAC_INTEL_MAC_V5] = {
3570 .type = HDA_FIXUP_PINS,
3571 .v.pins = intel_mac_v5_pin_configs,
3572 .chained = true,
3573 .chain_id = STAC_922X_INTEL_MAC_GPIO,
3575 [STAC_922X_INTEL_MAC_GPIO] = {
3576 .type = HDA_FIXUP_FUNC,
3577 .v.func = stac922x_fixup_intel_mac_gpio,
3579 [STAC_ECS_202] = {
3580 .type = HDA_FIXUP_PINS,
3581 .v.pins = ecs202_pin_configs,
3583 [STAC_922X_DELL_D81] = {
3584 .type = HDA_FIXUP_PINS,
3585 .v.pins = dell_922x_d81_pin_configs,
3587 [STAC_922X_DELL_D82] = {
3588 .type = HDA_FIXUP_PINS,
3589 .v.pins = dell_922x_d82_pin_configs,
3591 [STAC_922X_DELL_M81] = {
3592 .type = HDA_FIXUP_PINS,
3593 .v.pins = dell_922x_m81_pin_configs,
3595 [STAC_922X_DELL_M82] = {
3596 .type = HDA_FIXUP_PINS,
3597 .v.pins = dell_922x_m82_pin_configs,
3601 static const struct hda_model_fixup stac922x_models[] = {
3602 { .id = STAC_D945_REF, .name = "ref" },
3603 { .id = STAC_D945GTP5, .name = "5stack" },
3604 { .id = STAC_D945GTP3, .name = "3stack" },
3605 { .id = STAC_INTEL_MAC_V1, .name = "intel-mac-v1" },
3606 { .id = STAC_INTEL_MAC_V2, .name = "intel-mac-v2" },
3607 { .id = STAC_INTEL_MAC_V3, .name = "intel-mac-v3" },
3608 { .id = STAC_INTEL_MAC_V4, .name = "intel-mac-v4" },
3609 { .id = STAC_INTEL_MAC_V5, .name = "intel-mac-v5" },
3610 { .id = STAC_INTEL_MAC_AUTO, .name = "intel-mac-auto" },
3611 { .id = STAC_ECS_202, .name = "ecs202" },
3612 { .id = STAC_922X_DELL_D81, .name = "dell-d81" },
3613 { .id = STAC_922X_DELL_D82, .name = "dell-d82" },
3614 { .id = STAC_922X_DELL_M81, .name = "dell-m81" },
3615 { .id = STAC_922X_DELL_M82, .name = "dell-m82" },
3616 /* for backward compatibility */
3617 { .id = STAC_INTEL_MAC_V3, .name = "macmini" },
3618 { .id = STAC_INTEL_MAC_V5, .name = "macbook" },
3619 { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro-v1" },
3620 { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro" },
3621 { .id = STAC_INTEL_MAC_V2, .name = "imac-intel" },
3622 { .id = STAC_INTEL_MAC_V3, .name = "imac-intel-20" },
3626 static const struct snd_pci_quirk stac922x_fixup_tbl[] = {
3627 /* SigmaTel reference board */
3628 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3629 "DFI LanParty", STAC_D945_REF),
3630 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3631 "DFI LanParty", STAC_D945_REF),
3632 /* Intel 945G based systems */
3633 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
3634 "Intel D945G", STAC_D945GTP3),
3635 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
3636 "Intel D945G", STAC_D945GTP3),
3637 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
3638 "Intel D945G", STAC_D945GTP3),
3639 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
3640 "Intel D945G", STAC_D945GTP3),
3641 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
3642 "Intel D945G", STAC_D945GTP3),
3643 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
3644 "Intel D945G", STAC_D945GTP3),
3645 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
3646 "Intel D945G", STAC_D945GTP3),
3647 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
3648 "Intel D945G", STAC_D945GTP3),
3649 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
3650 "Intel D945G", STAC_D945GTP3),
3651 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
3652 "Intel D945G", STAC_D945GTP3),
3653 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
3654 "Intel D945G", STAC_D945GTP3),
3655 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
3656 "Intel D945G", STAC_D945GTP3),
3657 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
3658 "Intel D945G", STAC_D945GTP3),
3659 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
3660 "Intel D945G", STAC_D945GTP3),
3661 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
3662 "Intel D945G", STAC_D945GTP3),
3663 /* Intel D945G 5-stack systems */
3664 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
3665 "Intel D945G", STAC_D945GTP5),
3666 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
3667 "Intel D945G", STAC_D945GTP5),
3668 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
3669 "Intel D945G", STAC_D945GTP5),
3670 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
3671 "Intel D945G", STAC_D945GTP5),
3672 /* Intel 945P based systems */
3673 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
3674 "Intel D945P", STAC_D945GTP3),
3675 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
3676 "Intel D945P", STAC_D945GTP3),
3677 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
3678 "Intel D945P", STAC_D945GTP3),
3679 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
3680 "Intel D945P", STAC_D945GTP3),
3681 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
3682 "Intel D945P", STAC_D945GTP3),
3683 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
3684 "Intel D945P", STAC_D945GTP5),
3685 /* other intel */
3686 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0204,
3687 "Intel D945", STAC_D945_REF),
3688 /* other systems */
3690 /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */
3691 SND_PCI_QUIRK(0x8384, 0x7680, "Mac", STAC_INTEL_MAC_AUTO),
3693 /* Dell systems */
3694 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
3695 "unknown Dell", STAC_922X_DELL_D81),
3696 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
3697 "unknown Dell", STAC_922X_DELL_D81),
3698 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
3699 "unknown Dell", STAC_922X_DELL_D81),
3700 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
3701 "unknown Dell", STAC_922X_DELL_D82),
3702 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
3703 "unknown Dell", STAC_922X_DELL_M81),
3704 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
3705 "unknown Dell", STAC_922X_DELL_D82),
3706 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
3707 "unknown Dell", STAC_922X_DELL_D81),
3708 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
3709 "unknown Dell", STAC_922X_DELL_D81),
3710 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
3711 "Dell XPS M1210", STAC_922X_DELL_M82),
3712 /* ECS/PC Chips boards */
3713 SND_PCI_QUIRK_MASK(0x1019, 0xf000, 0x2000,
3714 "ECS/PC chips", STAC_ECS_202),
3715 {} /* terminator */
3718 static const struct hda_pintbl ref927x_pin_configs[] = {
3719 { 0x0a, 0x02214020 },
3720 { 0x0b, 0x02a19080 },
3721 { 0x0c, 0x0181304e },
3722 { 0x0d, 0x01014010 },
3723 { 0x0e, 0x01a19040 },
3724 { 0x0f, 0x01011012 },
3725 { 0x10, 0x01016011 },
3726 { 0x11, 0x0101201f },
3727 { 0x12, 0x183301f0 },
3728 { 0x13, 0x18a001f0 },
3729 { 0x14, 0x18a001f0 },
3730 { 0x21, 0x01442070 },
3731 { 0x22, 0x01c42190 },
3732 { 0x23, 0x40000100 },
3736 static const struct hda_pintbl d965_3st_pin_configs[] = {
3737 { 0x0a, 0x0221401f },
3738 { 0x0b, 0x02a19120 },
3739 { 0x0c, 0x40000100 },
3740 { 0x0d, 0x01014011 },
3741 { 0x0e, 0x01a19021 },
3742 { 0x0f, 0x01813024 },
3743 { 0x10, 0x40000100 },
3744 { 0x11, 0x40000100 },
3745 { 0x12, 0x40000100 },
3746 { 0x13, 0x40000100 },
3747 { 0x14, 0x40000100 },
3748 { 0x21, 0x40000100 },
3749 { 0x22, 0x40000100 },
3750 { 0x23, 0x40000100 },
3754 static const struct hda_pintbl d965_5st_pin_configs[] = {
3755 { 0x0a, 0x02214020 },
3756 { 0x0b, 0x02a19080 },
3757 { 0x0c, 0x0181304e },
3758 { 0x0d, 0x01014010 },
3759 { 0x0e, 0x01a19040 },
3760 { 0x0f, 0x01011012 },
3761 { 0x10, 0x01016011 },
3762 { 0x11, 0x40000100 },
3763 { 0x12, 0x40000100 },
3764 { 0x13, 0x40000100 },
3765 { 0x14, 0x40000100 },
3766 { 0x21, 0x01442070 },
3767 { 0x22, 0x40000100 },
3768 { 0x23, 0x40000100 },
3772 static const struct hda_pintbl d965_5st_no_fp_pin_configs[] = {
3773 { 0x0a, 0x40000100 },
3774 { 0x0b, 0x40000100 },
3775 { 0x0c, 0x0181304e },
3776 { 0x0d, 0x01014010 },
3777 { 0x0e, 0x01a19040 },
3778 { 0x0f, 0x01011012 },
3779 { 0x10, 0x01016011 },
3780 { 0x11, 0x40000100 },
3781 { 0x12, 0x40000100 },
3782 { 0x13, 0x40000100 },
3783 { 0x14, 0x40000100 },
3784 { 0x21, 0x01442070 },
3785 { 0x22, 0x40000100 },
3786 { 0x23, 0x40000100 },
3790 static const struct hda_pintbl dell_3st_pin_configs[] = {
3791 { 0x0a, 0x02211230 },
3792 { 0x0b, 0x02a11220 },
3793 { 0x0c, 0x01a19040 },
3794 { 0x0d, 0x01114210 },
3795 { 0x0e, 0x01111212 },
3796 { 0x0f, 0x01116211 },
3797 { 0x10, 0x01813050 },
3798 { 0x11, 0x01112214 },
3799 { 0x12, 0x403003fa },
3800 { 0x13, 0x90a60040 },
3801 { 0x14, 0x90a60040 },
3802 { 0x21, 0x404003fb },
3803 { 0x22, 0x40c003fc },
3804 { 0x23, 0x40000100 },
3808 static void stac927x_fixup_ref_no_jd(struct hda_codec *codec,
3809 const struct hda_fixup *fix, int action)
3811 /* no jack detecion for ref-no-jd model */
3812 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3813 codec->no_jack_detect = 1;
3816 static void stac927x_fixup_ref(struct hda_codec *codec,
3817 const struct hda_fixup *fix, int action)
3819 struct sigmatel_spec *spec = codec->spec;
3821 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3822 snd_hda_apply_pincfgs(codec, ref927x_pin_configs);
3823 spec->eapd_mask = spec->gpio_mask = 0;
3824 spec->gpio_dir = spec->gpio_data = 0;
3828 static void stac927x_fixup_dell_dmic(struct hda_codec *codec,
3829 const struct hda_fixup *fix, int action)
3831 struct sigmatel_spec *spec = codec->spec;
3833 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3834 return;
3836 if (codec->core.subsystem_id != 0x1028022f) {
3837 /* GPIO2 High = Enable EAPD */
3838 spec->eapd_mask = spec->gpio_mask = 0x04;
3839 spec->gpio_dir = spec->gpio_data = 0x04;
3842 snd_hda_add_verbs(codec, dell_3st_core_init);
3843 spec->volknob_init = 1;
3846 static void stac927x_fixup_volknob(struct hda_codec *codec,
3847 const struct hda_fixup *fix, int action)
3849 struct sigmatel_spec *spec = codec->spec;
3851 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3852 snd_hda_add_verbs(codec, stac927x_volknob_core_init);
3853 spec->volknob_init = 1;
3857 static const struct hda_fixup stac927x_fixups[] = {
3858 [STAC_D965_REF_NO_JD] = {
3859 .type = HDA_FIXUP_FUNC,
3860 .v.func = stac927x_fixup_ref_no_jd,
3861 .chained = true,
3862 .chain_id = STAC_D965_REF,
3864 [STAC_D965_REF] = {
3865 .type = HDA_FIXUP_FUNC,
3866 .v.func = stac927x_fixup_ref,
3868 [STAC_D965_3ST] = {
3869 .type = HDA_FIXUP_PINS,
3870 .v.pins = d965_3st_pin_configs,
3871 .chained = true,
3872 .chain_id = STAC_D965_VERBS,
3874 [STAC_D965_5ST] = {
3875 .type = HDA_FIXUP_PINS,
3876 .v.pins = d965_5st_pin_configs,
3877 .chained = true,
3878 .chain_id = STAC_D965_VERBS,
3880 [STAC_D965_VERBS] = {
3881 .type = HDA_FIXUP_VERBS,
3882 .v.verbs = d965_core_init,
3884 [STAC_D965_5ST_NO_FP] = {
3885 .type = HDA_FIXUP_PINS,
3886 .v.pins = d965_5st_no_fp_pin_configs,
3888 [STAC_DELL_3ST] = {
3889 .type = HDA_FIXUP_PINS,
3890 .v.pins = dell_3st_pin_configs,
3891 .chained = true,
3892 .chain_id = STAC_927X_DELL_DMIC,
3894 [STAC_DELL_BIOS] = {
3895 .type = HDA_FIXUP_PINS,
3896 .v.pins = (const struct hda_pintbl[]) {
3897 /* correct the front output jack as a hp out */
3898 { 0x0f, 0x0221101f },
3899 /* correct the front input jack as a mic */
3900 { 0x0e, 0x02a79130 },
3903 .chained = true,
3904 .chain_id = STAC_927X_DELL_DMIC,
3906 [STAC_DELL_BIOS_AMIC] = {
3907 .type = HDA_FIXUP_PINS,
3908 .v.pins = (const struct hda_pintbl[]) {
3909 /* configure the analog microphone on some laptops */
3910 { 0x0c, 0x90a79130 },
3913 .chained = true,
3914 .chain_id = STAC_DELL_BIOS,
3916 [STAC_DELL_BIOS_SPDIF] = {
3917 .type = HDA_FIXUP_PINS,
3918 .v.pins = (const struct hda_pintbl[]) {
3919 /* correct the device field to SPDIF out */
3920 { 0x21, 0x01442070 },
3923 .chained = true,
3924 .chain_id = STAC_DELL_BIOS,
3926 [STAC_927X_DELL_DMIC] = {
3927 .type = HDA_FIXUP_FUNC,
3928 .v.func = stac927x_fixup_dell_dmic,
3930 [STAC_927X_VOLKNOB] = {
3931 .type = HDA_FIXUP_FUNC,
3932 .v.func = stac927x_fixup_volknob,
3936 static const struct hda_model_fixup stac927x_models[] = {
3937 { .id = STAC_D965_REF_NO_JD, .name = "ref-no-jd" },
3938 { .id = STAC_D965_REF, .name = "ref" },
3939 { .id = STAC_D965_3ST, .name = "3stack" },
3940 { .id = STAC_D965_5ST, .name = "5stack" },
3941 { .id = STAC_D965_5ST_NO_FP, .name = "5stack-no-fp" },
3942 { .id = STAC_DELL_3ST, .name = "dell-3stack" },
3943 { .id = STAC_DELL_BIOS, .name = "dell-bios" },
3944 { .id = STAC_DELL_BIOS_AMIC, .name = "dell-bios-amic" },
3945 { .id = STAC_927X_VOLKNOB, .name = "volknob" },
3949 static const struct snd_pci_quirk stac927x_fixup_tbl[] = {
3950 /* SigmaTel reference board */
3951 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3952 "DFI LanParty", STAC_D965_REF),
3953 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3954 "DFI LanParty", STAC_D965_REF),
3955 /* Intel 946 based systems */
3956 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
3957 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
3958 /* 965 based 3 stack systems */
3959 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2100,
3960 "Intel D965", STAC_D965_3ST),
3961 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000,
3962 "Intel D965", STAC_D965_3ST),
3963 /* Dell 3 stack systems */
3964 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
3965 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
3966 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
3967 /* Dell 3 stack systems with verb table in BIOS */
3968 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
3969 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_BIOS),
3970 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
3971 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS_SPDIF),
3972 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS),
3973 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
3974 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
3975 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
3976 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS_SPDIF),
3977 /* 965 based 5 stack systems */
3978 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2300,
3979 "Intel D965", STAC_D965_5ST),
3980 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500,
3981 "Intel D965", STAC_D965_5ST),
3982 /* volume-knob fixes */
3983 SND_PCI_QUIRK_VENDOR(0x10cf, "FSC", STAC_927X_VOLKNOB),
3984 {} /* terminator */
3987 static const struct hda_pintbl ref9205_pin_configs[] = {
3988 { 0x0a, 0x40000100 },
3989 { 0x0b, 0x40000100 },
3990 { 0x0c, 0x01016011 },
3991 { 0x0d, 0x01014010 },
3992 { 0x0e, 0x01813122 },
3993 { 0x0f, 0x01a19021 },
3994 { 0x14, 0x01019020 },
3995 { 0x16, 0x40000100 },
3996 { 0x17, 0x90a000f0 },
3997 { 0x18, 0x90a000f0 },
3998 { 0x21, 0x01441030 },
3999 { 0x22, 0x01c41030 },
4004 STAC 9205 pin configs for
4005 102801F1
4006 102801F2
4007 102801FC
4008 102801FD
4009 10280204
4010 1028021F
4011 10280228 (Dell Vostro 1500)
4012 10280229 (Dell Vostro 1700)
4014 static const struct hda_pintbl dell_9205_m42_pin_configs[] = {
4015 { 0x0a, 0x0321101F },
4016 { 0x0b, 0x03A11020 },
4017 { 0x0c, 0x400003FA },
4018 { 0x0d, 0x90170310 },
4019 { 0x0e, 0x400003FB },
4020 { 0x0f, 0x400003FC },
4021 { 0x14, 0x400003FD },
4022 { 0x16, 0x40F000F9 },
4023 { 0x17, 0x90A60330 },
4024 { 0x18, 0x400003FF },
4025 { 0x21, 0x0144131F },
4026 { 0x22, 0x40C003FE },
4031 STAC 9205 pin configs for
4032 102801F9
4033 102801FA
4034 102801FE
4035 102801FF (Dell Precision M4300)
4036 10280206
4037 10280200
4038 10280201
4040 static const struct hda_pintbl dell_9205_m43_pin_configs[] = {
4041 { 0x0a, 0x0321101f },
4042 { 0x0b, 0x03a11020 },
4043 { 0x0c, 0x90a70330 },
4044 { 0x0d, 0x90170310 },
4045 { 0x0e, 0x400000fe },
4046 { 0x0f, 0x400000ff },
4047 { 0x14, 0x400000fd },
4048 { 0x16, 0x40f000f9 },
4049 { 0x17, 0x400000fa },
4050 { 0x18, 0x400000fc },
4051 { 0x21, 0x0144131f },
4052 { 0x22, 0x40c003f8 },
4053 /* Enable SPDIF in/out */
4054 { 0x1f, 0x01441030 },
4055 { 0x20, 0x1c410030 },
4059 static const struct hda_pintbl dell_9205_m44_pin_configs[] = {
4060 { 0x0a, 0x0421101f },
4061 { 0x0b, 0x04a11020 },
4062 { 0x0c, 0x400003fa },
4063 { 0x0d, 0x90170310 },
4064 { 0x0e, 0x400003fb },
4065 { 0x0f, 0x400003fc },
4066 { 0x14, 0x400003fd },
4067 { 0x16, 0x400003f9 },
4068 { 0x17, 0x90a60330 },
4069 { 0x18, 0x400003ff },
4070 { 0x21, 0x01441340 },
4071 { 0x22, 0x40c003fe },
4075 static void stac9205_fixup_ref(struct hda_codec *codec,
4076 const struct hda_fixup *fix, int action)
4078 struct sigmatel_spec *spec = codec->spec;
4080 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4081 snd_hda_apply_pincfgs(codec, ref9205_pin_configs);
4082 /* SPDIF-In enabled */
4083 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0;
4087 static void stac9205_fixup_dell_m43(struct hda_codec *codec,
4088 const struct hda_fixup *fix, int action)
4090 struct sigmatel_spec *spec = codec->spec;
4091 struct hda_jack_callback *jack;
4093 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4094 snd_hda_apply_pincfgs(codec, dell_9205_m43_pin_configs);
4096 /* Enable unsol response for GPIO4/Dock HP connection */
4097 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
4098 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
4099 jack = snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
4100 stac_vref_event);
4101 if (!IS_ERR(jack))
4102 jack->private_data = 0x01;
4104 spec->gpio_dir = 0x0b;
4105 spec->eapd_mask = 0x01;
4106 spec->gpio_mask = 0x1b;
4107 spec->gpio_mute = 0x10;
4108 /* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute,
4109 * GPIO3 Low = DRM
4111 spec->gpio_data = 0x01;
4115 static void stac9205_fixup_eapd(struct hda_codec *codec,
4116 const struct hda_fixup *fix, int action)
4118 struct sigmatel_spec *spec = codec->spec;
4120 if (action == HDA_FIXUP_ACT_PRE_PROBE)
4121 spec->eapd_switch = 0;
4124 static const struct hda_fixup stac9205_fixups[] = {
4125 [STAC_9205_REF] = {
4126 .type = HDA_FIXUP_FUNC,
4127 .v.func = stac9205_fixup_ref,
4129 [STAC_9205_DELL_M42] = {
4130 .type = HDA_FIXUP_PINS,
4131 .v.pins = dell_9205_m42_pin_configs,
4133 [STAC_9205_DELL_M43] = {
4134 .type = HDA_FIXUP_FUNC,
4135 .v.func = stac9205_fixup_dell_m43,
4137 [STAC_9205_DELL_M44] = {
4138 .type = HDA_FIXUP_PINS,
4139 .v.pins = dell_9205_m44_pin_configs,
4141 [STAC_9205_EAPD] = {
4142 .type = HDA_FIXUP_FUNC,
4143 .v.func = stac9205_fixup_eapd,
4148 static const struct hda_model_fixup stac9205_models[] = {
4149 { .id = STAC_9205_REF, .name = "ref" },
4150 { .id = STAC_9205_DELL_M42, .name = "dell-m42" },
4151 { .id = STAC_9205_DELL_M43, .name = "dell-m43" },
4152 { .id = STAC_9205_DELL_M44, .name = "dell-m44" },
4153 { .id = STAC_9205_EAPD, .name = "eapd" },
4157 static const struct snd_pci_quirk stac9205_fixup_tbl[] = {
4158 /* SigmaTel reference board */
4159 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
4160 "DFI LanParty", STAC_9205_REF),
4161 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xfb30,
4162 "SigmaTel", STAC_9205_REF),
4163 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
4164 "DFI LanParty", STAC_9205_REF),
4165 /* Dell */
4166 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
4167 "unknown Dell", STAC_9205_DELL_M42),
4168 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
4169 "unknown Dell", STAC_9205_DELL_M42),
4170 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
4171 "Dell Precision", STAC_9205_DELL_M43),
4172 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
4173 "Dell Precision", STAC_9205_DELL_M43),
4174 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
4175 "Dell Precision", STAC_9205_DELL_M43),
4176 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
4177 "unknown Dell", STAC_9205_DELL_M42),
4178 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
4179 "unknown Dell", STAC_9205_DELL_M42),
4180 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
4181 "Dell Precision", STAC_9205_DELL_M43),
4182 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
4183 "Dell Precision M4300", STAC_9205_DELL_M43),
4184 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
4185 "unknown Dell", STAC_9205_DELL_M42),
4186 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
4187 "Dell Precision", STAC_9205_DELL_M43),
4188 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
4189 "Dell Precision", STAC_9205_DELL_M43),
4190 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
4191 "Dell Precision", STAC_9205_DELL_M43),
4192 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
4193 "Dell Inspiron", STAC_9205_DELL_M44),
4194 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228,
4195 "Dell Vostro 1500", STAC_9205_DELL_M42),
4196 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0229,
4197 "Dell Vostro 1700", STAC_9205_DELL_M42),
4198 /* Gateway */
4199 SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD),
4200 SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD),
4201 {} /* terminator */
4204 static void stac92hd95_fixup_hp_led(struct hda_codec *codec,
4205 const struct hda_fixup *fix, int action)
4207 struct sigmatel_spec *spec = codec->spec;
4209 if (action != HDA_FIXUP_ACT_PRE_PROBE)
4210 return;
4212 if (find_mute_led_cfg(codec, spec->default_polarity))
4213 codec_dbg(codec, "mute LED gpio %d polarity %d\n",
4214 spec->gpio_led,
4215 spec->gpio_led_polarity);
4218 static const struct hda_fixup stac92hd95_fixups[] = {
4219 [STAC_92HD95_HP_LED] = {
4220 .type = HDA_FIXUP_FUNC,
4221 .v.func = stac92hd95_fixup_hp_led,
4223 [STAC_92HD95_HP_BASS] = {
4224 .type = HDA_FIXUP_VERBS,
4225 .v.verbs = (const struct hda_verb[]) {
4226 {0x1a, 0x795, 0x00}, /* HPF to 100Hz */
4229 .chained = true,
4230 .chain_id = STAC_92HD95_HP_LED,
4234 static const struct snd_pci_quirk stac92hd95_fixup_tbl[] = {
4235 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1911, "HP Spectre 13", STAC_92HD95_HP_BASS),
4236 {} /* terminator */
4239 static const struct hda_model_fixup stac92hd95_models[] = {
4240 { .id = STAC_92HD95_HP_LED, .name = "hp-led" },
4241 { .id = STAC_92HD95_HP_BASS, .name = "hp-bass" },
4246 static int stac_parse_auto_config(struct hda_codec *codec)
4248 struct sigmatel_spec *spec = codec->spec;
4249 int err;
4250 int flags = 0;
4252 if (spec->headset_jack)
4253 flags |= HDA_PINCFG_HEADSET_MIC;
4255 err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, flags);
4256 if (err < 0)
4257 return err;
4259 /* add hooks */
4260 spec->gen.pcm_playback_hook = stac_playback_pcm_hook;
4261 spec->gen.pcm_capture_hook = stac_capture_pcm_hook;
4263 spec->gen.automute_hook = stac_update_outputs;
4265 err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg);
4266 if (err < 0)
4267 return err;
4269 if (spec->vref_mute_led_nid) {
4270 err = snd_hda_gen_fix_pin_power(codec, spec->vref_mute_led_nid);
4271 if (err < 0)
4272 return err;
4275 /* setup analog beep controls */
4276 if (spec->anabeep_nid > 0) {
4277 err = stac_auto_create_beep_ctls(codec,
4278 spec->anabeep_nid);
4279 if (err < 0)
4280 return err;
4283 /* setup digital beep controls and input device */
4284 #ifdef CONFIG_SND_HDA_INPUT_BEEP
4285 if (spec->gen.beep_nid) {
4286 hda_nid_t nid = spec->gen.beep_nid;
4287 unsigned int caps;
4289 err = stac_auto_create_beep_ctls(codec, nid);
4290 if (err < 0)
4291 return err;
4292 if (codec->beep) {
4293 /* IDT/STAC codecs have linear beep tone parameter */
4294 codec->beep->linear_tone = spec->linear_tone_beep;
4295 /* if no beep switch is available, make its own one */
4296 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
4297 if (!(caps & AC_AMPCAP_MUTE)) {
4298 err = stac_beep_switch_ctl(codec);
4299 if (err < 0)
4300 return err;
4304 #endif
4306 if (spec->gpio_led)
4307 spec->gen.vmaster_mute.hook = stac_vmaster_hook;
4309 if (spec->aloopback_ctl &&
4310 snd_hda_get_bool_hint(codec, "loopback") == 1) {
4311 unsigned int wr_verb =
4312 spec->aloopback_ctl->private_value >> 16;
4313 if (snd_hdac_regmap_add_vendor_verb(&codec->core, wr_verb))
4314 return -ENOMEM;
4315 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, spec->aloopback_ctl))
4316 return -ENOMEM;
4319 if (spec->have_spdif_mux) {
4320 err = stac_create_spdif_mux_ctls(codec);
4321 if (err < 0)
4322 return err;
4325 stac_init_power_map(codec);
4327 return 0;
4330 static int stac_init(struct hda_codec *codec)
4332 struct sigmatel_spec *spec = codec->spec;
4333 int i;
4335 /* override some hints */
4336 stac_store_hints(codec);
4338 /* set up GPIO */
4339 /* turn on EAPD statically when spec->eapd_switch isn't set.
4340 * otherwise, unsol event will turn it on/off dynamically
4342 if (!spec->eapd_switch)
4343 spec->gpio_data |= spec->eapd_mask;
4344 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
4346 snd_hda_gen_init(codec);
4348 /* sync the power-map */
4349 if (spec->num_pwrs)
4350 snd_hda_codec_write(codec, codec->core.afg, 0,
4351 AC_VERB_IDT_SET_POWER_MAP,
4352 spec->power_map_bits);
4354 /* power down inactive ADCs */
4355 if (spec->powerdown_adcs) {
4356 for (i = 0; i < spec->gen.num_all_adcs; i++) {
4357 if (spec->active_adcs & (1 << i))
4358 continue;
4359 snd_hda_codec_write(codec, spec->gen.all_adcs[i], 0,
4360 AC_VERB_SET_POWER_STATE,
4361 AC_PWRST_D3);
4365 return 0;
4368 static void stac_shutup(struct hda_codec *codec)
4370 struct sigmatel_spec *spec = codec->spec;
4372 snd_hda_shutup_pins(codec);
4374 if (spec->eapd_mask)
4375 stac_gpio_set(codec, spec->gpio_mask,
4376 spec->gpio_dir, spec->gpio_data &
4377 ~spec->eapd_mask);
4380 #define stac_free snd_hda_gen_free
4382 #ifdef CONFIG_SND_PROC_FS
4383 static void stac92hd_proc_hook(struct snd_info_buffer *buffer,
4384 struct hda_codec *codec, hda_nid_t nid)
4386 if (nid == codec->core.afg)
4387 snd_iprintf(buffer, "Power-Map: 0x%02x\n",
4388 snd_hda_codec_read(codec, nid, 0,
4389 AC_VERB_IDT_GET_POWER_MAP, 0));
4392 static void analog_loop_proc_hook(struct snd_info_buffer *buffer,
4393 struct hda_codec *codec,
4394 unsigned int verb)
4396 snd_iprintf(buffer, "Analog Loopback: 0x%02x\n",
4397 snd_hda_codec_read(codec, codec->core.afg, 0, verb, 0));
4400 /* stac92hd71bxx, stac92hd73xx */
4401 static void stac92hd7x_proc_hook(struct snd_info_buffer *buffer,
4402 struct hda_codec *codec, hda_nid_t nid)
4404 stac92hd_proc_hook(buffer, codec, nid);
4405 if (nid == codec->core.afg)
4406 analog_loop_proc_hook(buffer, codec, 0xfa0);
4409 static void stac9205_proc_hook(struct snd_info_buffer *buffer,
4410 struct hda_codec *codec, hda_nid_t nid)
4412 if (nid == codec->core.afg)
4413 analog_loop_proc_hook(buffer, codec, 0xfe0);
4416 static void stac927x_proc_hook(struct snd_info_buffer *buffer,
4417 struct hda_codec *codec, hda_nid_t nid)
4419 if (nid == codec->core.afg)
4420 analog_loop_proc_hook(buffer, codec, 0xfeb);
4422 #else
4423 #define stac92hd_proc_hook NULL
4424 #define stac92hd7x_proc_hook NULL
4425 #define stac9205_proc_hook NULL
4426 #define stac927x_proc_hook NULL
4427 #endif
4429 #ifdef CONFIG_PM
4430 static int stac_suspend(struct hda_codec *codec)
4432 stac_shutup(codec);
4433 return 0;
4435 #else
4436 #define stac_suspend NULL
4437 #endif /* CONFIG_PM */
4439 static const struct hda_codec_ops stac_patch_ops = {
4440 .build_controls = snd_hda_gen_build_controls,
4441 .build_pcms = snd_hda_gen_build_pcms,
4442 .init = stac_init,
4443 .free = stac_free,
4444 .unsol_event = snd_hda_jack_unsol_event,
4445 #ifdef CONFIG_PM
4446 .suspend = stac_suspend,
4447 #endif
4448 .reboot_notify = stac_shutup,
4451 static int alloc_stac_spec(struct hda_codec *codec)
4453 struct sigmatel_spec *spec;
4455 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4456 if (!spec)
4457 return -ENOMEM;
4458 snd_hda_gen_spec_init(&spec->gen);
4459 codec->spec = spec;
4460 codec->no_trigger_sense = 1; /* seems common with STAC/IDT codecs */
4461 spec->gen.dac_min_mute = true;
4462 codec->patch_ops = stac_patch_ops;
4463 return 0;
4466 static int patch_stac9200(struct hda_codec *codec)
4468 struct sigmatel_spec *spec;
4469 int err;
4471 err = alloc_stac_spec(codec);
4472 if (err < 0)
4473 return err;
4475 spec = codec->spec;
4476 spec->linear_tone_beep = 1;
4477 spec->gen.own_eapd_ctl = 1;
4479 codec->power_filter = snd_hda_codec_eapd_power_filter;
4481 snd_hda_add_verbs(codec, stac9200_eapd_init);
4483 snd_hda_pick_fixup(codec, stac9200_models, stac9200_fixup_tbl,
4484 stac9200_fixups);
4485 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4487 err = stac_parse_auto_config(codec);
4488 if (err < 0) {
4489 stac_free(codec);
4490 return err;
4493 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4495 return 0;
4498 static int patch_stac925x(struct hda_codec *codec)
4500 struct sigmatel_spec *spec;
4501 int err;
4503 err = alloc_stac_spec(codec);
4504 if (err < 0)
4505 return err;
4507 spec = codec->spec;
4508 spec->linear_tone_beep = 1;
4509 spec->gen.own_eapd_ctl = 1;
4511 snd_hda_add_verbs(codec, stac925x_core_init);
4513 snd_hda_pick_fixup(codec, stac925x_models, stac925x_fixup_tbl,
4514 stac925x_fixups);
4515 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4517 err = stac_parse_auto_config(codec);
4518 if (err < 0) {
4519 stac_free(codec);
4520 return err;
4523 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4525 return 0;
4528 static int patch_stac92hd73xx(struct hda_codec *codec)
4530 struct sigmatel_spec *spec;
4531 int err;
4532 int num_dacs;
4534 err = alloc_stac_spec(codec);
4535 if (err < 0)
4536 return err;
4538 spec = codec->spec;
4539 /* enable power_save_node only for new 92HD89xx chips, as it causes
4540 * click noises on old 92HD73xx chips.
4542 if ((codec->core.vendor_id & 0xfffffff0) != 0x111d7670)
4543 codec->power_save_node = 1;
4544 spec->linear_tone_beep = 0;
4545 spec->gen.mixer_nid = 0x1d;
4546 spec->have_spdif_mux = 1;
4548 num_dacs = snd_hda_get_num_conns(codec, 0x0a) - 1;
4549 if (num_dacs < 3 || num_dacs > 5) {
4550 codec_warn(codec,
4551 "Could not determine number of channels defaulting to DAC count\n");
4552 num_dacs = 5;
4555 switch (num_dacs) {
4556 case 0x3: /* 6 Channel */
4557 spec->aloopback_ctl = &stac92hd73xx_6ch_loopback;
4558 break;
4559 case 0x4: /* 8 Channel */
4560 spec->aloopback_ctl = &stac92hd73xx_8ch_loopback;
4561 break;
4562 case 0x5: /* 10 Channel */
4563 spec->aloopback_ctl = &stac92hd73xx_10ch_loopback;
4564 break;
4567 spec->aloopback_mask = 0x01;
4568 spec->aloopback_shift = 8;
4570 spec->gen.beep_nid = 0x1c; /* digital beep */
4572 /* GPIO0 High = Enable EAPD */
4573 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
4574 spec->gpio_data = 0x01;
4576 spec->eapd_switch = 1;
4578 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
4579 spec->pwr_nids = stac92hd73xx_pwr_nids;
4581 spec->gen.own_eapd_ctl = 1;
4582 spec->gen.power_down_unused = 1;
4584 snd_hda_pick_fixup(codec, stac92hd73xx_models, stac92hd73xx_fixup_tbl,
4585 stac92hd73xx_fixups);
4586 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4588 if (!spec->volknob_init)
4589 snd_hda_add_verbs(codec, stac92hd73xx_core_init);
4591 err = stac_parse_auto_config(codec);
4592 if (err < 0) {
4593 stac_free(codec);
4594 return err;
4597 /* Don't GPIO-mute speakers if there are no internal speakers, because
4598 * the GPIO might be necessary for Headphone
4600 if (spec->eapd_switch && !has_builtin_speaker(codec))
4601 spec->eapd_switch = 0;
4603 codec->proc_widget_hook = stac92hd7x_proc_hook;
4605 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4607 return 0;
4610 static void stac_setup_gpio(struct hda_codec *codec)
4612 struct sigmatel_spec *spec = codec->spec;
4614 spec->gpio_mask |= spec->eapd_mask;
4615 if (spec->gpio_led) {
4616 if (!spec->vref_mute_led_nid) {
4617 spec->gpio_mask |= spec->gpio_led;
4618 spec->gpio_dir |= spec->gpio_led;
4619 spec->gpio_data |= spec->gpio_led;
4620 } else {
4621 codec->power_filter = stac_vref_led_power_filter;
4625 if (spec->mic_mute_led_gpio) {
4626 spec->gpio_mask |= spec->mic_mute_led_gpio;
4627 spec->gpio_dir |= spec->mic_mute_led_gpio;
4628 spec->mic_enabled = 0;
4629 spec->gpio_data |= spec->mic_mute_led_gpio;
4631 spec->gen.cap_sync_hook = stac_capture_led_hook;
4635 static int patch_stac92hd83xxx(struct hda_codec *codec)
4637 struct sigmatel_spec *spec;
4638 int err;
4640 err = alloc_stac_spec(codec);
4641 if (err < 0)
4642 return err;
4644 /* longer delay needed for D3 */
4645 codec->core.power_caps &= ~AC_PWRST_EPSS;
4647 spec = codec->spec;
4648 codec->power_save_node = 1;
4649 spec->linear_tone_beep = 0;
4650 spec->gen.own_eapd_ctl = 1;
4651 spec->gen.power_down_unused = 1;
4652 spec->gen.mixer_nid = 0x1b;
4654 spec->gen.beep_nid = 0x21; /* digital beep */
4655 spec->pwr_nids = stac92hd83xxx_pwr_nids;
4656 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
4657 spec->default_polarity = -1; /* no default cfg */
4659 snd_hda_add_verbs(codec, stac92hd83xxx_core_init);
4661 snd_hda_pick_fixup(codec, stac92hd83xxx_models, stac92hd83xxx_fixup_tbl,
4662 stac92hd83xxx_fixups);
4663 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4665 stac_setup_gpio(codec);
4667 err = stac_parse_auto_config(codec);
4668 if (err < 0) {
4669 stac_free(codec);
4670 return err;
4673 codec->proc_widget_hook = stac92hd_proc_hook;
4675 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4677 return 0;
4680 static const hda_nid_t stac92hd95_pwr_nids[] = {
4681 0x0a, 0x0b, 0x0c, 0x0d
4684 static int patch_stac92hd95(struct hda_codec *codec)
4686 struct sigmatel_spec *spec;
4687 int err;
4689 err = alloc_stac_spec(codec);
4690 if (err < 0)
4691 return err;
4693 /* longer delay needed for D3 */
4694 codec->core.power_caps &= ~AC_PWRST_EPSS;
4696 spec = codec->spec;
4697 codec->power_save_node = 1;
4698 spec->linear_tone_beep = 0;
4699 spec->gen.own_eapd_ctl = 1;
4700 spec->gen.power_down_unused = 1;
4702 spec->gen.beep_nid = 0x19; /* digital beep */
4703 spec->pwr_nids = stac92hd95_pwr_nids;
4704 spec->num_pwrs = ARRAY_SIZE(stac92hd95_pwr_nids);
4705 spec->default_polarity = 0;
4707 snd_hda_pick_fixup(codec, stac92hd95_models, stac92hd95_fixup_tbl,
4708 stac92hd95_fixups);
4709 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4711 stac_setup_gpio(codec);
4713 err = stac_parse_auto_config(codec);
4714 if (err < 0) {
4715 stac_free(codec);
4716 return err;
4719 codec->proc_widget_hook = stac92hd_proc_hook;
4721 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4723 return 0;
4726 static int patch_stac92hd71bxx(struct hda_codec *codec)
4728 struct sigmatel_spec *spec;
4729 const hda_nid_t *unmute_nids = stac92hd71bxx_unmute_nids;
4730 int err;
4732 err = alloc_stac_spec(codec);
4733 if (err < 0)
4734 return err;
4736 spec = codec->spec;
4737 /* disabled power_save_node since it causes noises on a Dell machine */
4738 /* codec->power_save_node = 1; */
4739 spec->linear_tone_beep = 0;
4740 spec->gen.own_eapd_ctl = 1;
4741 spec->gen.power_down_unused = 1;
4742 spec->gen.mixer_nid = 0x17;
4743 spec->have_spdif_mux = 1;
4745 /* GPIO0 = EAPD */
4746 spec->gpio_mask = 0x01;
4747 spec->gpio_dir = 0x01;
4748 spec->gpio_data = 0x01;
4750 switch (codec->core.vendor_id) {
4751 case 0x111d76b6: /* 4 Port without Analog Mixer */
4752 case 0x111d76b7:
4753 unmute_nids++;
4754 break;
4755 case 0x111d7608: /* 5 Port with Analog Mixer */
4756 if ((codec->core.revision_id & 0xf) == 0 ||
4757 (codec->core.revision_id & 0xf) == 1)
4758 spec->stream_delay = 40; /* 40 milliseconds */
4760 /* disable VSW */
4761 unmute_nids++;
4762 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0);
4763 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3);
4764 break;
4765 case 0x111d7603: /* 6 Port with Analog Mixer */
4766 if ((codec->core.revision_id & 0xf) == 1)
4767 spec->stream_delay = 40; /* 40 milliseconds */
4769 break;
4772 if (get_wcaps_type(get_wcaps(codec, 0x28)) == AC_WID_VOL_KNB)
4773 snd_hda_add_verbs(codec, stac92hd71bxx_core_init);
4775 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) {
4776 const hda_nid_t *p;
4777 for (p = unmute_nids; *p; p++)
4778 snd_hda_codec_amp_init_stereo(codec, *p, HDA_INPUT, 0,
4779 0xff, 0x00);
4782 spec->aloopback_ctl = &stac92hd71bxx_loopback;
4783 spec->aloopback_mask = 0x50;
4784 spec->aloopback_shift = 0;
4786 spec->powerdown_adcs = 1;
4787 spec->gen.beep_nid = 0x26; /* digital beep */
4788 spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
4789 spec->pwr_nids = stac92hd71bxx_pwr_nids;
4791 snd_hda_pick_fixup(codec, stac92hd71bxx_models, stac92hd71bxx_fixup_tbl,
4792 stac92hd71bxx_fixups);
4793 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4795 stac_setup_gpio(codec);
4797 err = stac_parse_auto_config(codec);
4798 if (err < 0) {
4799 stac_free(codec);
4800 return err;
4803 codec->proc_widget_hook = stac92hd7x_proc_hook;
4805 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4807 return 0;
4810 static int patch_stac922x(struct hda_codec *codec)
4812 struct sigmatel_spec *spec;
4813 int err;
4815 err = alloc_stac_spec(codec);
4816 if (err < 0)
4817 return err;
4819 spec = codec->spec;
4820 spec->linear_tone_beep = 1;
4821 spec->gen.own_eapd_ctl = 1;
4823 snd_hda_add_verbs(codec, stac922x_core_init);
4825 /* Fix Mux capture level; max to 2 */
4826 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
4827 (0 << AC_AMPCAP_OFFSET_SHIFT) |
4828 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4829 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4830 (0 << AC_AMPCAP_MUTE_SHIFT));
4832 snd_hda_pick_fixup(codec, stac922x_models, stac922x_fixup_tbl,
4833 stac922x_fixups);
4834 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4836 err = stac_parse_auto_config(codec);
4837 if (err < 0) {
4838 stac_free(codec);
4839 return err;
4842 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4844 return 0;
4847 static const char * const stac927x_spdif_labels[] = {
4848 "Digital Playback", "ADAT", "Analog Mux 1",
4849 "Analog Mux 2", "Analog Mux 3", NULL
4852 static int patch_stac927x(struct hda_codec *codec)
4854 struct sigmatel_spec *spec;
4855 int err;
4857 err = alloc_stac_spec(codec);
4858 if (err < 0)
4859 return err;
4861 spec = codec->spec;
4862 spec->linear_tone_beep = 1;
4863 spec->gen.own_eapd_ctl = 1;
4864 spec->have_spdif_mux = 1;
4865 spec->spdif_labels = stac927x_spdif_labels;
4867 spec->gen.beep_nid = 0x23; /* digital beep */
4869 /* GPIO0 High = Enable EAPD */
4870 spec->eapd_mask = spec->gpio_mask = 0x01;
4871 spec->gpio_dir = spec->gpio_data = 0x01;
4873 spec->aloopback_ctl = &stac927x_loopback;
4874 spec->aloopback_mask = 0x40;
4875 spec->aloopback_shift = 0;
4876 spec->eapd_switch = 1;
4878 snd_hda_pick_fixup(codec, stac927x_models, stac927x_fixup_tbl,
4879 stac927x_fixups);
4880 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4882 if (!spec->volknob_init)
4883 snd_hda_add_verbs(codec, stac927x_core_init);
4885 err = stac_parse_auto_config(codec);
4886 if (err < 0) {
4887 stac_free(codec);
4888 return err;
4891 codec->proc_widget_hook = stac927x_proc_hook;
4894 * !!FIXME!!
4895 * The STAC927x seem to require fairly long delays for certain
4896 * command sequences. With too short delays (even if the answer
4897 * is set to RIRB properly), it results in the silence output
4898 * on some hardwares like Dell.
4900 * The below flag enables the longer delay (see get_response
4901 * in hda_intel.c).
4903 codec->bus->needs_damn_long_delay = 1;
4905 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4907 return 0;
4910 static int patch_stac9205(struct hda_codec *codec)
4912 struct sigmatel_spec *spec;
4913 int err;
4915 err = alloc_stac_spec(codec);
4916 if (err < 0)
4917 return err;
4919 spec = codec->spec;
4920 spec->linear_tone_beep = 1;
4921 spec->gen.own_eapd_ctl = 1;
4922 spec->have_spdif_mux = 1;
4924 spec->gen.beep_nid = 0x23; /* digital beep */
4926 snd_hda_add_verbs(codec, stac9205_core_init);
4927 spec->aloopback_ctl = &stac9205_loopback;
4929 spec->aloopback_mask = 0x40;
4930 spec->aloopback_shift = 0;
4932 /* GPIO0 High = EAPD */
4933 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
4934 spec->gpio_data = 0x01;
4936 /* Turn on/off EAPD per HP plugging */
4937 spec->eapd_switch = 1;
4939 snd_hda_pick_fixup(codec, stac9205_models, stac9205_fixup_tbl,
4940 stac9205_fixups);
4941 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4943 err = stac_parse_auto_config(codec);
4944 if (err < 0) {
4945 stac_free(codec);
4946 return err;
4949 codec->proc_widget_hook = stac9205_proc_hook;
4951 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4953 return 0;
4957 * STAC9872 hack
4960 static const struct hda_verb stac9872_core_init[] = {
4961 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
4962 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
4966 static const struct hda_pintbl stac9872_vaio_pin_configs[] = {
4967 { 0x0a, 0x03211020 },
4968 { 0x0b, 0x411111f0 },
4969 { 0x0c, 0x411111f0 },
4970 { 0x0d, 0x03a15030 },
4971 { 0x0e, 0x411111f0 },
4972 { 0x0f, 0x90170110 },
4973 { 0x11, 0x411111f0 },
4974 { 0x13, 0x411111f0 },
4975 { 0x14, 0x90a7013e },
4979 static const struct hda_model_fixup stac9872_models[] = {
4980 { .id = STAC_9872_VAIO, .name = "vaio" },
4984 static const struct hda_fixup stac9872_fixups[] = {
4985 [STAC_9872_VAIO] = {
4986 .type = HDA_FIXUP_PINS,
4987 .v.pins = stac9872_vaio_pin_configs,
4991 static const struct snd_pci_quirk stac9872_fixup_tbl[] = {
4992 SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0,
4993 "Sony VAIO F/S", STAC_9872_VAIO),
4994 {} /* terminator */
4997 static int patch_stac9872(struct hda_codec *codec)
4999 struct sigmatel_spec *spec;
5000 int err;
5002 err = alloc_stac_spec(codec);
5003 if (err < 0)
5004 return err;
5006 spec = codec->spec;
5007 spec->linear_tone_beep = 1;
5008 spec->gen.own_eapd_ctl = 1;
5010 snd_hda_add_verbs(codec, stac9872_core_init);
5012 snd_hda_pick_fixup(codec, stac9872_models, stac9872_fixup_tbl,
5013 stac9872_fixups);
5014 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
5016 err = stac_parse_auto_config(codec);
5017 if (err < 0) {
5018 stac_free(codec);
5019 return -EINVAL;
5022 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
5024 return 0;
5029 * patch entries
5031 static const struct hda_device_id snd_hda_id_sigmatel[] = {
5032 HDA_CODEC_ENTRY(0x83847690, "STAC9200", patch_stac9200),
5033 HDA_CODEC_ENTRY(0x83847882, "STAC9220 A1", patch_stac922x),
5034 HDA_CODEC_ENTRY(0x83847680, "STAC9221 A1", patch_stac922x),
5035 HDA_CODEC_ENTRY(0x83847880, "STAC9220 A2", patch_stac922x),
5036 HDA_CODEC_ENTRY(0x83847681, "STAC9220D/9223D A2", patch_stac922x),
5037 HDA_CODEC_ENTRY(0x83847682, "STAC9221 A2", patch_stac922x),
5038 HDA_CODEC_ENTRY(0x83847683, "STAC9221D A2", patch_stac922x),
5039 HDA_CODEC_ENTRY(0x83847618, "STAC9227", patch_stac927x),
5040 HDA_CODEC_ENTRY(0x83847619, "STAC9227", patch_stac927x),
5041 HDA_CODEC_ENTRY(0x83847616, "STAC9228", patch_stac927x),
5042 HDA_CODEC_ENTRY(0x83847617, "STAC9228", patch_stac927x),
5043 HDA_CODEC_ENTRY(0x83847614, "STAC9229", patch_stac927x),
5044 HDA_CODEC_ENTRY(0x83847615, "STAC9229", patch_stac927x),
5045 HDA_CODEC_ENTRY(0x83847620, "STAC9274", patch_stac927x),
5046 HDA_CODEC_ENTRY(0x83847621, "STAC9274D", patch_stac927x),
5047 HDA_CODEC_ENTRY(0x83847622, "STAC9273X", patch_stac927x),
5048 HDA_CODEC_ENTRY(0x83847623, "STAC9273D", patch_stac927x),
5049 HDA_CODEC_ENTRY(0x83847624, "STAC9272X", patch_stac927x),
5050 HDA_CODEC_ENTRY(0x83847625, "STAC9272D", patch_stac927x),
5051 HDA_CODEC_ENTRY(0x83847626, "STAC9271X", patch_stac927x),
5052 HDA_CODEC_ENTRY(0x83847627, "STAC9271D", patch_stac927x),
5053 HDA_CODEC_ENTRY(0x83847628, "STAC9274X5NH", patch_stac927x),
5054 HDA_CODEC_ENTRY(0x83847629, "STAC9274D5NH", patch_stac927x),
5055 HDA_CODEC_ENTRY(0x83847632, "STAC9202", patch_stac925x),
5056 HDA_CODEC_ENTRY(0x83847633, "STAC9202D", patch_stac925x),
5057 HDA_CODEC_ENTRY(0x83847634, "STAC9250", patch_stac925x),
5058 HDA_CODEC_ENTRY(0x83847635, "STAC9250D", patch_stac925x),
5059 HDA_CODEC_ENTRY(0x83847636, "STAC9251", patch_stac925x),
5060 HDA_CODEC_ENTRY(0x83847637, "STAC9250D", patch_stac925x),
5061 HDA_CODEC_ENTRY(0x83847645, "92HD206X", patch_stac927x),
5062 HDA_CODEC_ENTRY(0x83847646, "92HD206D", patch_stac927x),
5063 /* The following does not take into account .id=0x83847661 when subsys =
5064 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
5065 * currently not fully supported.
5067 HDA_CODEC_ENTRY(0x83847661, "CXD9872RD/K", patch_stac9872),
5068 HDA_CODEC_ENTRY(0x83847662, "STAC9872AK", patch_stac9872),
5069 HDA_CODEC_ENTRY(0x83847664, "CXD9872AKD", patch_stac9872),
5070 HDA_CODEC_ENTRY(0x83847698, "STAC9205", patch_stac9205),
5071 HDA_CODEC_ENTRY(0x838476a0, "STAC9205", patch_stac9205),
5072 HDA_CODEC_ENTRY(0x838476a1, "STAC9205D", patch_stac9205),
5073 HDA_CODEC_ENTRY(0x838476a2, "STAC9204", patch_stac9205),
5074 HDA_CODEC_ENTRY(0x838476a3, "STAC9204D", patch_stac9205),
5075 HDA_CODEC_ENTRY(0x838476a4, "STAC9255", patch_stac9205),
5076 HDA_CODEC_ENTRY(0x838476a5, "STAC9255D", patch_stac9205),
5077 HDA_CODEC_ENTRY(0x838476a6, "STAC9254", patch_stac9205),
5078 HDA_CODEC_ENTRY(0x838476a7, "STAC9254D", patch_stac9205),
5079 HDA_CODEC_ENTRY(0x111d7603, "92HD75B3X5", patch_stac92hd71bxx),
5080 HDA_CODEC_ENTRY(0x111d7604, "92HD83C1X5", patch_stac92hd83xxx),
5081 HDA_CODEC_ENTRY(0x111d76d4, "92HD83C1C5", patch_stac92hd83xxx),
5082 HDA_CODEC_ENTRY(0x111d7605, "92HD81B1X5", patch_stac92hd83xxx),
5083 HDA_CODEC_ENTRY(0x111d76d5, "92HD81B1C5", patch_stac92hd83xxx),
5084 HDA_CODEC_ENTRY(0x111d76d1, "92HD87B1/3", patch_stac92hd83xxx),
5085 HDA_CODEC_ENTRY(0x111d76d9, "92HD87B2/4", patch_stac92hd83xxx),
5086 HDA_CODEC_ENTRY(0x111d7666, "92HD88B3", patch_stac92hd83xxx),
5087 HDA_CODEC_ENTRY(0x111d7667, "92HD88B1", patch_stac92hd83xxx),
5088 HDA_CODEC_ENTRY(0x111d7668, "92HD88B2", patch_stac92hd83xxx),
5089 HDA_CODEC_ENTRY(0x111d7669, "92HD88B4", patch_stac92hd83xxx),
5090 HDA_CODEC_ENTRY(0x111d7608, "92HD75B2X5", patch_stac92hd71bxx),
5091 HDA_CODEC_ENTRY(0x111d7674, "92HD73D1X5", patch_stac92hd73xx),
5092 HDA_CODEC_ENTRY(0x111d7675, "92HD73C1X5", patch_stac92hd73xx),
5093 HDA_CODEC_ENTRY(0x111d7676, "92HD73E1X5", patch_stac92hd73xx),
5094 HDA_CODEC_ENTRY(0x111d7695, "92HD95", patch_stac92hd95),
5095 HDA_CODEC_ENTRY(0x111d76b0, "92HD71B8X", patch_stac92hd71bxx),
5096 HDA_CODEC_ENTRY(0x111d76b1, "92HD71B8X", patch_stac92hd71bxx),
5097 HDA_CODEC_ENTRY(0x111d76b2, "92HD71B7X", patch_stac92hd71bxx),
5098 HDA_CODEC_ENTRY(0x111d76b3, "92HD71B7X", patch_stac92hd71bxx),
5099 HDA_CODEC_ENTRY(0x111d76b4, "92HD71B6X", patch_stac92hd71bxx),
5100 HDA_CODEC_ENTRY(0x111d76b5, "92HD71B6X", patch_stac92hd71bxx),
5101 HDA_CODEC_ENTRY(0x111d76b6, "92HD71B5X", patch_stac92hd71bxx),
5102 HDA_CODEC_ENTRY(0x111d76b7, "92HD71B5X", patch_stac92hd71bxx),
5103 HDA_CODEC_ENTRY(0x111d76c0, "92HD89C3", patch_stac92hd73xx),
5104 HDA_CODEC_ENTRY(0x111d76c1, "92HD89C2", patch_stac92hd73xx),
5105 HDA_CODEC_ENTRY(0x111d76c2, "92HD89C1", patch_stac92hd73xx),
5106 HDA_CODEC_ENTRY(0x111d76c3, "92HD89B3", patch_stac92hd73xx),
5107 HDA_CODEC_ENTRY(0x111d76c4, "92HD89B2", patch_stac92hd73xx),
5108 HDA_CODEC_ENTRY(0x111d76c5, "92HD89B1", patch_stac92hd73xx),
5109 HDA_CODEC_ENTRY(0x111d76c6, "92HD89E3", patch_stac92hd73xx),
5110 HDA_CODEC_ENTRY(0x111d76c7, "92HD89E2", patch_stac92hd73xx),
5111 HDA_CODEC_ENTRY(0x111d76c8, "92HD89E1", patch_stac92hd73xx),
5112 HDA_CODEC_ENTRY(0x111d76c9, "92HD89D3", patch_stac92hd73xx),
5113 HDA_CODEC_ENTRY(0x111d76ca, "92HD89D2", patch_stac92hd73xx),
5114 HDA_CODEC_ENTRY(0x111d76cb, "92HD89D1", patch_stac92hd73xx),
5115 HDA_CODEC_ENTRY(0x111d76cc, "92HD89F3", patch_stac92hd73xx),
5116 HDA_CODEC_ENTRY(0x111d76cd, "92HD89F2", patch_stac92hd73xx),
5117 HDA_CODEC_ENTRY(0x111d76ce, "92HD89F1", patch_stac92hd73xx),
5118 HDA_CODEC_ENTRY(0x111d76df, "92HD93BXX", patch_stac92hd83xxx),
5119 HDA_CODEC_ENTRY(0x111d76e0, "92HD91BXX", patch_stac92hd83xxx),
5120 HDA_CODEC_ENTRY(0x111d76e3, "92HD98BXX", patch_stac92hd83xxx),
5121 HDA_CODEC_ENTRY(0x111d76e5, "92HD99BXX", patch_stac92hd83xxx),
5122 HDA_CODEC_ENTRY(0x111d76e7, "92HD90BXX", patch_stac92hd83xxx),
5123 HDA_CODEC_ENTRY(0x111d76e8, "92HD66B1X5", patch_stac92hd83xxx),
5124 HDA_CODEC_ENTRY(0x111d76e9, "92HD66B2X5", patch_stac92hd83xxx),
5125 HDA_CODEC_ENTRY(0x111d76ea, "92HD66B3X5", patch_stac92hd83xxx),
5126 HDA_CODEC_ENTRY(0x111d76eb, "92HD66C1X5", patch_stac92hd83xxx),
5127 HDA_CODEC_ENTRY(0x111d76ec, "92HD66C2X5", patch_stac92hd83xxx),
5128 HDA_CODEC_ENTRY(0x111d76ed, "92HD66C3X5", patch_stac92hd83xxx),
5129 HDA_CODEC_ENTRY(0x111d76ee, "92HD66B1X3", patch_stac92hd83xxx),
5130 HDA_CODEC_ENTRY(0x111d76ef, "92HD66B2X3", patch_stac92hd83xxx),
5131 HDA_CODEC_ENTRY(0x111d76f0, "92HD66B3X3", patch_stac92hd83xxx),
5132 HDA_CODEC_ENTRY(0x111d76f1, "92HD66C1X3", patch_stac92hd83xxx),
5133 HDA_CODEC_ENTRY(0x111d76f2, "92HD66C2X3", patch_stac92hd83xxx),
5134 HDA_CODEC_ENTRY(0x111d76f3, "92HD66C3/65", patch_stac92hd83xxx),
5135 {} /* terminator */
5137 MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_sigmatel);
5139 MODULE_LICENSE("GPL");
5140 MODULE_DESCRIPTION("IDT/Sigmatel HD-audio codec");
5142 static struct hda_codec_driver sigmatel_driver = {
5143 .id = snd_hda_id_sigmatel,
5146 module_hda_codec_driver(sigmatel_driver);