HID: hiddev: Fix slab-out-of-bounds write in hiddev_ioctl_usage()
[linux/fpc-iii.git] / sound / pci / hda / patch_sigmatel.c
blob80b72d0702c5e0e7067db02bb0bf005550043def
1 /*
2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for SigmaTel STAC92xx
6 * Copyright (c) 2005 Embedded Alley Solutions, Inc.
7 * Matt Porter <mporter@embeddedalley.com>
9 * Based on patch_cmedia.c and patch_realtek.c
10 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
12 * This driver is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This driver is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/slab.h>
30 #include <linux/pci.h>
31 #include <linux/dmi.h>
32 #include <linux/module.h>
33 #include <sound/core.h>
34 #include <sound/jack.h>
35 #include "hda_codec.h"
36 #include "hda_local.h"
37 #include "hda_auto_parser.h"
38 #include "hda_beep.h"
39 #include "hda_jack.h"
40 #include "hda_generic.h"
42 enum {
43 STAC_REF,
44 STAC_9200_OQO,
45 STAC_9200_DELL_D21,
46 STAC_9200_DELL_D22,
47 STAC_9200_DELL_D23,
48 STAC_9200_DELL_M21,
49 STAC_9200_DELL_M22,
50 STAC_9200_DELL_M23,
51 STAC_9200_DELL_M24,
52 STAC_9200_DELL_M25,
53 STAC_9200_DELL_M26,
54 STAC_9200_DELL_M27,
55 STAC_9200_M4,
56 STAC_9200_M4_2,
57 STAC_9200_PANASONIC,
58 STAC_9200_EAPD_INIT,
59 STAC_9200_MODELS
62 enum {
63 STAC_9205_REF,
64 STAC_9205_DELL_M42,
65 STAC_9205_DELL_M43,
66 STAC_9205_DELL_M44,
67 STAC_9205_EAPD,
68 STAC_9205_MODELS
71 enum {
72 STAC_92HD73XX_NO_JD, /* no jack-detection */
73 STAC_92HD73XX_REF,
74 STAC_92HD73XX_INTEL,
75 STAC_DELL_M6_AMIC,
76 STAC_DELL_M6_DMIC,
77 STAC_DELL_M6_BOTH,
78 STAC_DELL_EQ,
79 STAC_ALIENWARE_M17X,
80 STAC_ELO_VUPOINT_15MX,
81 STAC_92HD89XX_HP_FRONT_JACK,
82 STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK,
83 STAC_92HD73XX_ASUS_MOBO,
84 STAC_92HD73XX_MODELS
87 enum {
88 STAC_92HD83XXX_REF,
89 STAC_92HD83XXX_PWR_REF,
90 STAC_DELL_S14,
91 STAC_DELL_VOSTRO_3500,
92 STAC_92HD83XXX_HP_cNB11_INTQUAD,
93 STAC_HP_DV7_4000,
94 STAC_HP_ZEPHYR,
95 STAC_92HD83XXX_HP_LED,
96 STAC_92HD83XXX_HP_INV_LED,
97 STAC_92HD83XXX_HP_MIC_LED,
98 STAC_HP_LED_GPIO10,
99 STAC_92HD83XXX_HEADSET_JACK,
100 STAC_92HD83XXX_HP,
101 STAC_HP_ENVY_BASS,
102 STAC_HP_BNB13_EQ,
103 STAC_HP_ENVY_TS_BASS,
104 STAC_HP_ENVY_TS_DAC_BIND,
105 STAC_92HD83XXX_GPIO10_EAPD,
106 STAC_92HD83XXX_MODELS
109 enum {
110 STAC_92HD71BXX_REF,
111 STAC_DELL_M4_1,
112 STAC_DELL_M4_2,
113 STAC_DELL_M4_3,
114 STAC_HP_M4,
115 STAC_HP_DV4,
116 STAC_HP_DV5,
117 STAC_HP_HDX,
118 STAC_92HD71BXX_HP,
119 STAC_92HD71BXX_NO_DMIC,
120 STAC_92HD71BXX_NO_SMUX,
121 STAC_92HD71BXX_MODELS
124 enum {
125 STAC_92HD95_HP_LED,
126 STAC_92HD95_HP_BASS,
127 STAC_92HD95_MODELS
130 enum {
131 STAC_925x_REF,
132 STAC_M1,
133 STAC_M1_2,
134 STAC_M2,
135 STAC_M2_2,
136 STAC_M3,
137 STAC_M5,
138 STAC_M6,
139 STAC_925x_MODELS
142 enum {
143 STAC_D945_REF,
144 STAC_D945GTP3,
145 STAC_D945GTP5,
146 STAC_INTEL_MAC_V1,
147 STAC_INTEL_MAC_V2,
148 STAC_INTEL_MAC_V3,
149 STAC_INTEL_MAC_V4,
150 STAC_INTEL_MAC_V5,
151 STAC_INTEL_MAC_AUTO,
152 STAC_ECS_202,
153 STAC_922X_DELL_D81,
154 STAC_922X_DELL_D82,
155 STAC_922X_DELL_M81,
156 STAC_922X_DELL_M82,
157 STAC_922X_INTEL_MAC_GPIO,
158 STAC_922X_MODELS
161 enum {
162 STAC_D965_REF_NO_JD, /* no jack-detection */
163 STAC_D965_REF,
164 STAC_D965_3ST,
165 STAC_D965_5ST,
166 STAC_D965_5ST_NO_FP,
167 STAC_D965_VERBS,
168 STAC_DELL_3ST,
169 STAC_DELL_BIOS,
170 STAC_DELL_BIOS_AMIC,
171 STAC_DELL_BIOS_SPDIF,
172 STAC_927X_DELL_DMIC,
173 STAC_927X_VOLKNOB,
174 STAC_927X_MODELS
177 enum {
178 STAC_9872_VAIO,
179 STAC_9872_MODELS
182 struct sigmatel_spec {
183 struct hda_gen_spec gen;
185 unsigned int eapd_switch: 1;
186 unsigned int linear_tone_beep:1;
187 unsigned int headset_jack:1; /* 4-pin headset jack (hp + mono mic) */
188 unsigned int volknob_init:1; /* special volume-knob initialization */
189 unsigned int powerdown_adcs:1;
190 unsigned int have_spdif_mux:1;
192 /* gpio lines */
193 unsigned int eapd_mask;
194 unsigned int gpio_mask;
195 unsigned int gpio_dir;
196 unsigned int gpio_data;
197 unsigned int gpio_mute;
198 unsigned int gpio_led;
199 unsigned int gpio_led_polarity;
200 unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */
201 unsigned int vref_led;
202 int default_polarity;
204 unsigned int mic_mute_led_gpio; /* capture mute LED GPIO */
205 unsigned int mic_enabled; /* current mic mute state (bitmask) */
207 /* stream */
208 unsigned int stream_delay;
210 /* analog loopback */
211 const struct snd_kcontrol_new *aloopback_ctl;
212 unsigned int aloopback;
213 unsigned char aloopback_mask;
214 unsigned char aloopback_shift;
216 /* power management */
217 unsigned int power_map_bits;
218 unsigned int num_pwrs;
219 const hda_nid_t *pwr_nids;
220 unsigned int active_adcs;
222 /* beep widgets */
223 hda_nid_t anabeep_nid;
225 /* SPDIF-out mux */
226 const char * const *spdif_labels;
227 struct hda_input_mux spdif_mux;
228 unsigned int cur_smux[2];
231 #define AC_VERB_IDT_SET_POWER_MAP 0x7ec
232 #define AC_VERB_IDT_GET_POWER_MAP 0xfec
234 static const hda_nid_t stac92hd73xx_pwr_nids[8] = {
235 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
236 0x0f, 0x10, 0x11
239 static const hda_nid_t stac92hd83xxx_pwr_nids[7] = {
240 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
241 0x0f, 0x10
244 static const hda_nid_t stac92hd71bxx_pwr_nids[3] = {
245 0x0a, 0x0d, 0x0f
250 * PCM hooks
252 static void stac_playback_pcm_hook(struct hda_pcm_stream *hinfo,
253 struct hda_codec *codec,
254 struct snd_pcm_substream *substream,
255 int action)
257 struct sigmatel_spec *spec = codec->spec;
258 if (action == HDA_GEN_PCM_ACT_OPEN && spec->stream_delay)
259 msleep(spec->stream_delay);
262 static void stac_capture_pcm_hook(struct hda_pcm_stream *hinfo,
263 struct hda_codec *codec,
264 struct snd_pcm_substream *substream,
265 int action)
267 struct sigmatel_spec *spec = codec->spec;
268 int i, idx = 0;
270 if (!spec->powerdown_adcs)
271 return;
273 for (i = 0; i < spec->gen.num_all_adcs; i++) {
274 if (spec->gen.all_adcs[i] == hinfo->nid) {
275 idx = i;
276 break;
280 switch (action) {
281 case HDA_GEN_PCM_ACT_OPEN:
282 msleep(40);
283 snd_hda_codec_write(codec, hinfo->nid, 0,
284 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
285 spec->active_adcs |= (1 << idx);
286 break;
287 case HDA_GEN_PCM_ACT_CLOSE:
288 snd_hda_codec_write(codec, hinfo->nid, 0,
289 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
290 spec->active_adcs &= ~(1 << idx);
291 break;
296 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
297 * funky external mute control using GPIO pins.
300 static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
301 unsigned int dir_mask, unsigned int data)
303 unsigned int gpiostate, gpiomask, gpiodir;
304 hda_nid_t fg = codec->core.afg;
306 codec_dbg(codec, "%s msk %x dir %x gpio %x\n", __func__, mask, dir_mask, data);
308 gpiostate = snd_hda_codec_read(codec, fg, 0,
309 AC_VERB_GET_GPIO_DATA, 0);
310 gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask);
312 gpiomask = snd_hda_codec_read(codec, fg, 0,
313 AC_VERB_GET_GPIO_MASK, 0);
314 gpiomask |= mask;
316 gpiodir = snd_hda_codec_read(codec, fg, 0,
317 AC_VERB_GET_GPIO_DIRECTION, 0);
318 gpiodir |= dir_mask;
320 /* Configure GPIOx as CMOS */
321 snd_hda_codec_write(codec, fg, 0, 0x7e7, 0);
323 snd_hda_codec_write(codec, fg, 0,
324 AC_VERB_SET_GPIO_MASK, gpiomask);
325 snd_hda_codec_read(codec, fg, 0,
326 AC_VERB_SET_GPIO_DIRECTION, gpiodir); /* sync */
328 msleep(1);
330 snd_hda_codec_read(codec, fg, 0,
331 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
334 /* hook for controlling mic-mute LED GPIO */
335 static void stac_capture_led_hook(struct hda_codec *codec,
336 struct snd_kcontrol *kcontrol,
337 struct snd_ctl_elem_value *ucontrol)
339 struct sigmatel_spec *spec = codec->spec;
340 unsigned int mask;
341 bool cur_mute, prev_mute;
343 if (!kcontrol || !ucontrol)
344 return;
346 mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
347 prev_mute = !spec->mic_enabled;
348 if (ucontrol->value.integer.value[0] ||
349 ucontrol->value.integer.value[1])
350 spec->mic_enabled |= mask;
351 else
352 spec->mic_enabled &= ~mask;
353 cur_mute = !spec->mic_enabled;
354 if (cur_mute != prev_mute) {
355 if (cur_mute)
356 spec->gpio_data |= spec->mic_mute_led_gpio;
357 else
358 spec->gpio_data &= ~spec->mic_mute_led_gpio;
359 stac_gpio_set(codec, spec->gpio_mask,
360 spec->gpio_dir, spec->gpio_data);
364 static int stac_vrefout_set(struct hda_codec *codec,
365 hda_nid_t nid, unsigned int new_vref)
367 int error, pinctl;
369 codec_dbg(codec, "%s, nid %x ctl %x\n", __func__, nid, new_vref);
370 pinctl = snd_hda_codec_read(codec, nid, 0,
371 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
373 if (pinctl < 0)
374 return pinctl;
376 pinctl &= 0xff;
377 pinctl &= ~AC_PINCTL_VREFEN;
378 pinctl |= (new_vref & AC_PINCTL_VREFEN);
380 error = snd_hda_set_pin_ctl_cache(codec, nid, pinctl);
381 if (error < 0)
382 return error;
384 return 1;
387 /* prevent codec AFG to D3 state when vref-out pin is used for mute LED */
388 /* this hook is set in stac_setup_gpio() */
389 static unsigned int stac_vref_led_power_filter(struct hda_codec *codec,
390 hda_nid_t nid,
391 unsigned int power_state)
393 if (nid == codec->core.afg && power_state == AC_PWRST_D3)
394 return AC_PWRST_D1;
395 return snd_hda_gen_path_power_filter(codec, nid, power_state);
398 /* update mute-LED accoring to the master switch */
399 static void stac_update_led_status(struct hda_codec *codec, int enabled)
401 struct sigmatel_spec *spec = codec->spec;
402 int muted = !enabled;
404 if (!spec->gpio_led)
405 return;
407 /* LED state is inverted on these systems */
408 if (spec->gpio_led_polarity)
409 muted = !muted;
411 if (!spec->vref_mute_led_nid) {
412 if (muted)
413 spec->gpio_data |= spec->gpio_led;
414 else
415 spec->gpio_data &= ~spec->gpio_led;
416 stac_gpio_set(codec, spec->gpio_mask,
417 spec->gpio_dir, spec->gpio_data);
418 } else {
419 spec->vref_led = muted ? AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
420 stac_vrefout_set(codec, spec->vref_mute_led_nid,
421 spec->vref_led);
425 /* vmaster hook to update mute LED */
426 static void stac_vmaster_hook(void *private_data, int val)
428 stac_update_led_status(private_data, val);
431 /* automute hook to handle GPIO mute and EAPD updates */
432 static void stac_update_outputs(struct hda_codec *codec)
434 struct sigmatel_spec *spec = codec->spec;
436 if (spec->gpio_mute)
437 spec->gen.master_mute =
438 !(snd_hda_codec_read(codec, codec->core.afg, 0,
439 AC_VERB_GET_GPIO_DATA, 0) & spec->gpio_mute);
441 snd_hda_gen_update_outputs(codec);
443 if (spec->eapd_mask && spec->eapd_switch) {
444 unsigned int val = spec->gpio_data;
445 if (spec->gen.speaker_muted)
446 val &= ~spec->eapd_mask;
447 else
448 val |= spec->eapd_mask;
449 if (spec->gpio_data != val) {
450 spec->gpio_data = val;
451 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir,
452 val);
457 static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
458 bool enable, bool do_write)
460 struct sigmatel_spec *spec = codec->spec;
461 unsigned int idx, val;
463 for (idx = 0; idx < spec->num_pwrs; idx++) {
464 if (spec->pwr_nids[idx] == nid)
465 break;
467 if (idx >= spec->num_pwrs)
468 return;
470 idx = 1 << idx;
472 val = spec->power_map_bits;
473 if (enable)
474 val &= ~idx;
475 else
476 val |= idx;
478 /* power down unused output ports */
479 if (val != spec->power_map_bits) {
480 spec->power_map_bits = val;
481 if (do_write)
482 snd_hda_codec_write(codec, codec->core.afg, 0,
483 AC_VERB_IDT_SET_POWER_MAP, val);
487 /* update power bit per jack plug/unplug */
488 static void jack_update_power(struct hda_codec *codec,
489 struct hda_jack_callback *jack)
491 struct sigmatel_spec *spec = codec->spec;
492 int i;
494 if (!spec->num_pwrs)
495 return;
497 if (jack && jack->nid) {
498 stac_toggle_power_map(codec, jack->nid,
499 snd_hda_jack_detect(codec, jack->nid),
500 true);
501 return;
504 /* update all jacks */
505 for (i = 0; i < spec->num_pwrs; i++) {
506 hda_nid_t nid = spec->pwr_nids[i];
507 if (!snd_hda_jack_tbl_get(codec, nid))
508 continue;
509 stac_toggle_power_map(codec, nid,
510 snd_hda_jack_detect(codec, nid),
511 false);
514 snd_hda_codec_write(codec, codec->core.afg, 0,
515 AC_VERB_IDT_SET_POWER_MAP,
516 spec->power_map_bits);
519 static void stac_vref_event(struct hda_codec *codec,
520 struct hda_jack_callback *event)
522 unsigned int data;
524 data = snd_hda_codec_read(codec, codec->core.afg, 0,
525 AC_VERB_GET_GPIO_DATA, 0);
526 /* toggle VREF state based on GPIOx status */
527 snd_hda_codec_write(codec, codec->core.afg, 0, 0x7e0,
528 !!(data & (1 << event->private_data)));
531 /* initialize the power map and enable the power event to jacks that
532 * haven't been assigned to automute
534 static void stac_init_power_map(struct hda_codec *codec)
536 struct sigmatel_spec *spec = codec->spec;
537 int i;
539 for (i = 0; i < spec->num_pwrs; i++) {
540 hda_nid_t nid = spec->pwr_nids[i];
541 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
542 def_conf = get_defcfg_connect(def_conf);
543 if (def_conf == AC_JACK_PORT_COMPLEX &&
544 spec->vref_mute_led_nid != nid &&
545 is_jack_detectable(codec, nid)) {
546 snd_hda_jack_detect_enable_callback(codec, nid,
547 jack_update_power);
548 } else {
549 if (def_conf == AC_JACK_PORT_NONE)
550 stac_toggle_power_map(codec, nid, false, false);
551 else
552 stac_toggle_power_map(codec, nid, true, false);
560 static inline bool get_int_hint(struct hda_codec *codec, const char *key,
561 int *valp)
563 return !snd_hda_get_int_hint(codec, key, valp);
566 /* override some hints from the hwdep entry */
567 static void stac_store_hints(struct hda_codec *codec)
569 struct sigmatel_spec *spec = codec->spec;
570 int val;
572 if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) {
573 spec->eapd_mask = spec->gpio_dir = spec->gpio_data =
574 spec->gpio_mask;
576 if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir))
577 spec->gpio_dir &= spec->gpio_mask;
578 if (get_int_hint(codec, "gpio_data", &spec->gpio_data))
579 spec->gpio_data &= spec->gpio_mask;
580 if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask))
581 spec->eapd_mask &= spec->gpio_mask;
582 if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute))
583 spec->gpio_mute &= spec->gpio_mask;
584 val = snd_hda_get_bool_hint(codec, "eapd_switch");
585 if (val >= 0)
586 spec->eapd_switch = val;
590 * loopback controls
593 #define stac_aloopback_info snd_ctl_boolean_mono_info
595 static int stac_aloopback_get(struct snd_kcontrol *kcontrol,
596 struct snd_ctl_elem_value *ucontrol)
598 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
599 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
600 struct sigmatel_spec *spec = codec->spec;
602 ucontrol->value.integer.value[0] = !!(spec->aloopback &
603 (spec->aloopback_mask << idx));
604 return 0;
607 static int stac_aloopback_put(struct snd_kcontrol *kcontrol,
608 struct snd_ctl_elem_value *ucontrol)
610 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
611 struct sigmatel_spec *spec = codec->spec;
612 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
613 unsigned int dac_mode;
614 unsigned int val, idx_val;
616 idx_val = spec->aloopback_mask << idx;
617 if (ucontrol->value.integer.value[0])
618 val = spec->aloopback | idx_val;
619 else
620 val = spec->aloopback & ~idx_val;
621 if (spec->aloopback == val)
622 return 0;
624 spec->aloopback = val;
626 /* Only return the bits defined by the shift value of the
627 * first two bytes of the mask
629 dac_mode = snd_hda_codec_read(codec, codec->core.afg, 0,
630 kcontrol->private_value & 0xFFFF, 0x0);
631 dac_mode >>= spec->aloopback_shift;
633 if (spec->aloopback & idx_val) {
634 snd_hda_power_up(codec);
635 dac_mode |= idx_val;
636 } else {
637 snd_hda_power_down(codec);
638 dac_mode &= ~idx_val;
641 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
642 kcontrol->private_value >> 16, dac_mode);
644 return 1;
647 #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \
649 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
650 .name = "Analog Loopback", \
651 .count = cnt, \
652 .info = stac_aloopback_info, \
653 .get = stac_aloopback_get, \
654 .put = stac_aloopback_put, \
655 .private_value = verb_read | (verb_write << 16), \
659 * Mute LED handling on HP laptops
662 /* check whether it's a HP laptop with a docking port */
663 static bool hp_bnb2011_with_dock(struct hda_codec *codec)
665 if (codec->core.vendor_id != 0x111d7605 &&
666 codec->core.vendor_id != 0x111d76d1)
667 return false;
669 switch (codec->core.subsystem_id) {
670 case 0x103c1618:
671 case 0x103c1619:
672 case 0x103c161a:
673 case 0x103c161b:
674 case 0x103c161c:
675 case 0x103c161d:
676 case 0x103c161e:
677 case 0x103c161f:
679 case 0x103c162a:
680 case 0x103c162b:
682 case 0x103c1630:
683 case 0x103c1631:
685 case 0x103c1633:
686 case 0x103c1634:
687 case 0x103c1635:
689 case 0x103c3587:
690 case 0x103c3588:
691 case 0x103c3589:
692 case 0x103c358a:
694 case 0x103c3667:
695 case 0x103c3668:
696 case 0x103c3669:
698 return true;
700 return false;
703 static bool hp_blike_system(u32 subsystem_id)
705 switch (subsystem_id) {
706 case 0x103c1473: /* HP ProBook 6550b */
707 case 0x103c1520:
708 case 0x103c1521:
709 case 0x103c1523:
710 case 0x103c1524:
711 case 0x103c1525:
712 case 0x103c1722:
713 case 0x103c1723:
714 case 0x103c1724:
715 case 0x103c1725:
716 case 0x103c1726:
717 case 0x103c1727:
718 case 0x103c1728:
719 case 0x103c1729:
720 case 0x103c172a:
721 case 0x103c172b:
722 case 0x103c307e:
723 case 0x103c307f:
724 case 0x103c3080:
725 case 0x103c3081:
726 case 0x103c7007:
727 case 0x103c7008:
728 return true;
730 return false;
733 static void set_hp_led_gpio(struct hda_codec *codec)
735 struct sigmatel_spec *spec = codec->spec;
736 unsigned int gpio;
738 if (spec->gpio_led)
739 return;
741 gpio = snd_hda_param_read(codec, codec->core.afg, AC_PAR_GPIO_CAP);
742 gpio &= AC_GPIO_IO_COUNT;
743 if (gpio > 3)
744 spec->gpio_led = 0x08; /* GPIO 3 */
745 else
746 spec->gpio_led = 0x01; /* GPIO 0 */
750 * This method searches for the mute LED GPIO configuration
751 * provided as OEM string in SMBIOS. The format of that string
752 * is HP_Mute_LED_P_G or HP_Mute_LED_P
753 * where P can be 0 or 1 and defines mute LED GPIO control state (low/high)
754 * that corresponds to the NOT muted state of the master volume
755 * and G is the index of the GPIO to use as the mute LED control (0..9)
756 * If _G portion is missing it is assigned based on the codec ID
758 * So, HP B-series like systems may have HP_Mute_LED_0 (current models)
759 * or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings
762 * The dv-series laptops don't seem to have the HP_Mute_LED* strings in
763 * SMBIOS - at least the ones I have seen do not have them - which include
764 * my own system (HP Pavilion dv6-1110ax) and my cousin's
765 * HP Pavilion dv9500t CTO.
766 * Need more information on whether it is true across the entire series.
767 * -- kunal
769 static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity)
771 struct sigmatel_spec *spec = codec->spec;
772 const struct dmi_device *dev = NULL;
774 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
775 get_int_hint(codec, "gpio_led_polarity",
776 &spec->gpio_led_polarity);
777 return 1;
780 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
781 if (sscanf(dev->name, "HP_Mute_LED_%u_%x",
782 &spec->gpio_led_polarity,
783 &spec->gpio_led) == 2) {
784 unsigned int max_gpio;
785 max_gpio = snd_hda_param_read(codec, codec->core.afg,
786 AC_PAR_GPIO_CAP);
787 max_gpio &= AC_GPIO_IO_COUNT;
788 if (spec->gpio_led < max_gpio)
789 spec->gpio_led = 1 << spec->gpio_led;
790 else
791 spec->vref_mute_led_nid = spec->gpio_led;
792 return 1;
794 if (sscanf(dev->name, "HP_Mute_LED_%u",
795 &spec->gpio_led_polarity) == 1) {
796 set_hp_led_gpio(codec);
797 return 1;
799 /* BIOS bug: unfilled OEM string */
800 if (strstr(dev->name, "HP_Mute_LED_P_G")) {
801 set_hp_led_gpio(codec);
802 if (default_polarity >= 0)
803 spec->gpio_led_polarity = default_polarity;
804 else
805 spec->gpio_led_polarity = 1;
806 return 1;
811 * Fallback case - if we don't find the DMI strings,
812 * we statically set the GPIO - if not a B-series system
813 * and default polarity is provided
815 if (!hp_blike_system(codec->core.subsystem_id) &&
816 (default_polarity == 0 || default_polarity == 1)) {
817 set_hp_led_gpio(codec);
818 spec->gpio_led_polarity = default_polarity;
819 return 1;
821 return 0;
824 /* check whether a built-in speaker is included in parsed pins */
825 static bool has_builtin_speaker(struct hda_codec *codec)
827 struct sigmatel_spec *spec = codec->spec;
828 hda_nid_t *nid_pin;
829 int nids, i;
831 if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) {
832 nid_pin = spec->gen.autocfg.line_out_pins;
833 nids = spec->gen.autocfg.line_outs;
834 } else {
835 nid_pin = spec->gen.autocfg.speaker_pins;
836 nids = spec->gen.autocfg.speaker_outs;
839 for (i = 0; i < nids; i++) {
840 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid_pin[i]);
841 if (snd_hda_get_input_pin_attr(def_conf) == INPUT_PIN_ATTR_INT)
842 return true;
844 return false;
848 * PC beep controls
851 /* create PC beep volume controls */
852 static int stac_auto_create_beep_ctls(struct hda_codec *codec,
853 hda_nid_t nid)
855 struct sigmatel_spec *spec = codec->spec;
856 u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
857 struct snd_kcontrol_new *knew;
858 static struct snd_kcontrol_new abeep_mute_ctl =
859 HDA_CODEC_MUTE(NULL, 0, 0, 0);
860 static struct snd_kcontrol_new dbeep_mute_ctl =
861 HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0);
862 static struct snd_kcontrol_new beep_vol_ctl =
863 HDA_CODEC_VOLUME(NULL, 0, 0, 0);
865 /* check for mute support for the amp */
866 if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) {
867 const struct snd_kcontrol_new *temp;
868 if (spec->anabeep_nid == nid)
869 temp = &abeep_mute_ctl;
870 else
871 temp = &dbeep_mute_ctl;
872 knew = snd_hda_gen_add_kctl(&spec->gen,
873 "Beep Playback Switch", temp);
874 if (!knew)
875 return -ENOMEM;
876 knew->private_value =
877 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT);
880 /* check to see if there is volume support for the amp */
881 if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
882 knew = snd_hda_gen_add_kctl(&spec->gen,
883 "Beep Playback Volume",
884 &beep_vol_ctl);
885 if (!knew)
886 return -ENOMEM;
887 knew->private_value =
888 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT);
890 return 0;
893 #ifdef CONFIG_SND_HDA_INPUT_BEEP
894 #define stac_dig_beep_switch_info snd_ctl_boolean_mono_info
896 static int stac_dig_beep_switch_get(struct snd_kcontrol *kcontrol,
897 struct snd_ctl_elem_value *ucontrol)
899 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
900 ucontrol->value.integer.value[0] = codec->beep->enabled;
901 return 0;
904 static int stac_dig_beep_switch_put(struct snd_kcontrol *kcontrol,
905 struct snd_ctl_elem_value *ucontrol)
907 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
908 return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]);
911 static const struct snd_kcontrol_new stac_dig_beep_ctrl = {
912 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
913 .name = "Beep Playback Switch",
914 .info = stac_dig_beep_switch_info,
915 .get = stac_dig_beep_switch_get,
916 .put = stac_dig_beep_switch_put,
919 static int stac_beep_switch_ctl(struct hda_codec *codec)
921 struct sigmatel_spec *spec = codec->spec;
923 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &stac_dig_beep_ctrl))
924 return -ENOMEM;
925 return 0;
927 #endif
930 * SPDIF-out mux controls
933 static int stac_smux_enum_info(struct snd_kcontrol *kcontrol,
934 struct snd_ctl_elem_info *uinfo)
936 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
937 struct sigmatel_spec *spec = codec->spec;
938 return snd_hda_input_mux_info(&spec->spdif_mux, uinfo);
941 static int stac_smux_enum_get(struct snd_kcontrol *kcontrol,
942 struct snd_ctl_elem_value *ucontrol)
944 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
945 struct sigmatel_spec *spec = codec->spec;
946 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
948 ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx];
949 return 0;
952 static int stac_smux_enum_put(struct snd_kcontrol *kcontrol,
953 struct snd_ctl_elem_value *ucontrol)
955 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
956 struct sigmatel_spec *spec = codec->spec;
957 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
959 return snd_hda_input_mux_put(codec, &spec->spdif_mux, ucontrol,
960 spec->gen.autocfg.dig_out_pins[smux_idx],
961 &spec->cur_smux[smux_idx]);
964 static struct snd_kcontrol_new stac_smux_mixer = {
965 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
966 .name = "IEC958 Playback Source",
967 /* count set later */
968 .info = stac_smux_enum_info,
969 .get = stac_smux_enum_get,
970 .put = stac_smux_enum_put,
973 static const char * const stac_spdif_labels[] = {
974 "Digital Playback", "Analog Mux 1", "Analog Mux 2", NULL
977 static int stac_create_spdif_mux_ctls(struct hda_codec *codec)
979 struct sigmatel_spec *spec = codec->spec;
980 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
981 const char * const *labels = spec->spdif_labels;
982 struct snd_kcontrol_new *kctl;
983 int i, num_cons;
985 if (cfg->dig_outs < 1)
986 return 0;
988 num_cons = snd_hda_get_num_conns(codec, cfg->dig_out_pins[0]);
989 if (num_cons <= 1)
990 return 0;
992 if (!labels)
993 labels = stac_spdif_labels;
994 for (i = 0; i < num_cons; i++) {
995 if (snd_BUG_ON(!labels[i]))
996 return -EINVAL;
997 snd_hda_add_imux_item(codec, &spec->spdif_mux, labels[i], i, NULL);
1000 kctl = snd_hda_gen_add_kctl(&spec->gen, NULL, &stac_smux_mixer);
1001 if (!kctl)
1002 return -ENOMEM;
1003 kctl->count = cfg->dig_outs;
1005 return 0;
1011 static const struct hda_verb stac9200_core_init[] = {
1012 /* set dac0mux for dac converter */
1013 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1017 static const struct hda_verb stac9200_eapd_init[] = {
1018 /* set dac0mux for dac converter */
1019 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1020 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1024 static const struct hda_verb dell_eq_core_init[] = {
1025 /* set master volume to max value without distortion
1026 * and direct control */
1027 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
1031 static const struct hda_verb stac92hd73xx_core_init[] = {
1032 /* set master volume and direct control */
1033 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1037 static const struct hda_verb stac92hd83xxx_core_init[] = {
1038 /* power state controls amps */
1039 { 0x01, AC_VERB_SET_EAPD, 1 << 2},
1043 static const struct hda_verb stac92hd83xxx_hp_zephyr_init[] = {
1044 { 0x22, 0x785, 0x43 },
1045 { 0x22, 0x782, 0xe0 },
1046 { 0x22, 0x795, 0x00 },
1050 static const struct hda_verb stac92hd71bxx_core_init[] = {
1051 /* set master volume and direct control */
1052 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1056 static const hda_nid_t stac92hd71bxx_unmute_nids[] = {
1057 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */
1058 0x0f, 0x0a, 0x0d, 0
1061 static const struct hda_verb stac925x_core_init[] = {
1062 /* set dac0mux for dac converter */
1063 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
1064 /* mute the master volume */
1065 { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1069 static const struct hda_verb stac922x_core_init[] = {
1070 /* set master volume and direct control */
1071 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1075 static const struct hda_verb d965_core_init[] = {
1076 /* unmute node 0x1b */
1077 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1078 /* select node 0x03 as DAC */
1079 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
1083 static const struct hda_verb dell_3st_core_init[] = {
1084 /* don't set delta bit */
1085 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
1086 /* unmute node 0x1b */
1087 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1088 /* select node 0x03 as DAC */
1089 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
1093 static const struct hda_verb stac927x_core_init[] = {
1094 /* set master volume and direct control */
1095 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1096 /* enable analog pc beep path */
1097 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
1101 static const struct hda_verb stac927x_volknob_core_init[] = {
1102 /* don't set delta bit */
1103 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
1104 /* enable analog pc beep path */
1105 {0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
1109 static const struct hda_verb stac9205_core_init[] = {
1110 /* set master volume and direct control */
1111 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1112 /* enable analog pc beep path */
1113 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
1117 static const struct snd_kcontrol_new stac92hd73xx_6ch_loopback =
1118 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3);
1120 static const struct snd_kcontrol_new stac92hd73xx_8ch_loopback =
1121 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4);
1123 static const struct snd_kcontrol_new stac92hd73xx_10ch_loopback =
1124 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5);
1126 static const struct snd_kcontrol_new stac92hd71bxx_loopback =
1127 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2);
1129 static const struct snd_kcontrol_new stac9205_loopback =
1130 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1);
1132 static const struct snd_kcontrol_new stac927x_loopback =
1133 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1);
1135 static const struct hda_pintbl ref9200_pin_configs[] = {
1136 { 0x08, 0x01c47010 },
1137 { 0x09, 0x01447010 },
1138 { 0x0d, 0x0221401f },
1139 { 0x0e, 0x01114010 },
1140 { 0x0f, 0x02a19020 },
1141 { 0x10, 0x01a19021 },
1142 { 0x11, 0x90100140 },
1143 { 0x12, 0x01813122 },
1147 static const struct hda_pintbl gateway9200_m4_pin_configs[] = {
1148 { 0x08, 0x400000fe },
1149 { 0x09, 0x404500f4 },
1150 { 0x0d, 0x400100f0 },
1151 { 0x0e, 0x90110010 },
1152 { 0x0f, 0x400100f1 },
1153 { 0x10, 0x02a1902e },
1154 { 0x11, 0x500000f2 },
1155 { 0x12, 0x500000f3 },
1159 static const struct hda_pintbl gateway9200_m4_2_pin_configs[] = {
1160 { 0x08, 0x400000fe },
1161 { 0x09, 0x404500f4 },
1162 { 0x0d, 0x400100f0 },
1163 { 0x0e, 0x90110010 },
1164 { 0x0f, 0x400100f1 },
1165 { 0x10, 0x02a1902e },
1166 { 0x11, 0x500000f2 },
1167 { 0x12, 0x500000f3 },
1172 STAC 9200 pin configs for
1173 102801A8
1174 102801DE
1175 102801E8
1177 static const struct hda_pintbl dell9200_d21_pin_configs[] = {
1178 { 0x08, 0x400001f0 },
1179 { 0x09, 0x400001f1 },
1180 { 0x0d, 0x02214030 },
1181 { 0x0e, 0x01014010 },
1182 { 0x0f, 0x02a19020 },
1183 { 0x10, 0x01a19021 },
1184 { 0x11, 0x90100140 },
1185 { 0x12, 0x01813122 },
1190 STAC 9200 pin configs for
1191 102801C0
1192 102801C1
1194 static const struct hda_pintbl dell9200_d22_pin_configs[] = {
1195 { 0x08, 0x400001f0 },
1196 { 0x09, 0x400001f1 },
1197 { 0x0d, 0x0221401f },
1198 { 0x0e, 0x01014010 },
1199 { 0x0f, 0x01813020 },
1200 { 0x10, 0x02a19021 },
1201 { 0x11, 0x90100140 },
1202 { 0x12, 0x400001f2 },
1207 STAC 9200 pin configs for
1208 102801C4 (Dell Dimension E310)
1209 102801C5
1210 102801C7
1211 102801D9
1212 102801DA
1213 102801E3
1215 static const struct hda_pintbl dell9200_d23_pin_configs[] = {
1216 { 0x08, 0x400001f0 },
1217 { 0x09, 0x400001f1 },
1218 { 0x0d, 0x0221401f },
1219 { 0x0e, 0x01014010 },
1220 { 0x0f, 0x01813020 },
1221 { 0x10, 0x01a19021 },
1222 { 0x11, 0x90100140 },
1223 { 0x12, 0x400001f2 },
1229 STAC 9200-32 pin configs for
1230 102801B5 (Dell Inspiron 630m)
1231 102801D8 (Dell Inspiron 640m)
1233 static const struct hda_pintbl dell9200_m21_pin_configs[] = {
1234 { 0x08, 0x40c003fa },
1235 { 0x09, 0x03441340 },
1236 { 0x0d, 0x0321121f },
1237 { 0x0e, 0x90170310 },
1238 { 0x0f, 0x408003fb },
1239 { 0x10, 0x03a11020 },
1240 { 0x11, 0x401003fc },
1241 { 0x12, 0x403003fd },
1246 STAC 9200-32 pin configs for
1247 102801C2 (Dell Latitude D620)
1248 102801C8
1249 102801CC (Dell Latitude D820)
1250 102801D4
1251 102801D6
1253 static const struct hda_pintbl dell9200_m22_pin_configs[] = {
1254 { 0x08, 0x40c003fa },
1255 { 0x09, 0x0144131f },
1256 { 0x0d, 0x0321121f },
1257 { 0x0e, 0x90170310 },
1258 { 0x0f, 0x90a70321 },
1259 { 0x10, 0x03a11020 },
1260 { 0x11, 0x401003fb },
1261 { 0x12, 0x40f000fc },
1266 STAC 9200-32 pin configs for
1267 102801CE (Dell XPS M1710)
1268 102801CF (Dell Precision M90)
1270 static const struct hda_pintbl dell9200_m23_pin_configs[] = {
1271 { 0x08, 0x40c003fa },
1272 { 0x09, 0x01441340 },
1273 { 0x0d, 0x0421421f },
1274 { 0x0e, 0x90170310 },
1275 { 0x0f, 0x408003fb },
1276 { 0x10, 0x04a1102e },
1277 { 0x11, 0x90170311 },
1278 { 0x12, 0x403003fc },
1283 STAC 9200-32 pin configs for
1284 102801C9
1285 102801CA
1286 102801CB (Dell Latitude 120L)
1287 102801D3
1289 static const struct hda_pintbl dell9200_m24_pin_configs[] = {
1290 { 0x08, 0x40c003fa },
1291 { 0x09, 0x404003fb },
1292 { 0x0d, 0x0321121f },
1293 { 0x0e, 0x90170310 },
1294 { 0x0f, 0x408003fc },
1295 { 0x10, 0x03a11020 },
1296 { 0x11, 0x401003fd },
1297 { 0x12, 0x403003fe },
1302 STAC 9200-32 pin configs for
1303 102801BD (Dell Inspiron E1505n)
1304 102801EE
1305 102801EF
1307 static const struct hda_pintbl dell9200_m25_pin_configs[] = {
1308 { 0x08, 0x40c003fa },
1309 { 0x09, 0x01441340 },
1310 { 0x0d, 0x0421121f },
1311 { 0x0e, 0x90170310 },
1312 { 0x0f, 0x408003fb },
1313 { 0x10, 0x04a11020 },
1314 { 0x11, 0x401003fc },
1315 { 0x12, 0x403003fd },
1320 STAC 9200-32 pin configs for
1321 102801F5 (Dell Inspiron 1501)
1322 102801F6
1324 static const struct hda_pintbl dell9200_m26_pin_configs[] = {
1325 { 0x08, 0x40c003fa },
1326 { 0x09, 0x404003fb },
1327 { 0x0d, 0x0421121f },
1328 { 0x0e, 0x90170310 },
1329 { 0x0f, 0x408003fc },
1330 { 0x10, 0x04a11020 },
1331 { 0x11, 0x401003fd },
1332 { 0x12, 0x403003fe },
1337 STAC 9200-32
1338 102801CD (Dell Inspiron E1705/9400)
1340 static const struct hda_pintbl dell9200_m27_pin_configs[] = {
1341 { 0x08, 0x40c003fa },
1342 { 0x09, 0x01441340 },
1343 { 0x0d, 0x0421121f },
1344 { 0x0e, 0x90170310 },
1345 { 0x0f, 0x90170310 },
1346 { 0x10, 0x04a11020 },
1347 { 0x11, 0x90170310 },
1348 { 0x12, 0x40f003fc },
1352 static const struct hda_pintbl oqo9200_pin_configs[] = {
1353 { 0x08, 0x40c000f0 },
1354 { 0x09, 0x404000f1 },
1355 { 0x0d, 0x0221121f },
1356 { 0x0e, 0x02211210 },
1357 { 0x0f, 0x90170111 },
1358 { 0x10, 0x90a70120 },
1359 { 0x11, 0x400000f2 },
1360 { 0x12, 0x400000f3 },
1365 static void stac9200_fixup_panasonic(struct hda_codec *codec,
1366 const struct hda_fixup *fix, int action)
1368 struct sigmatel_spec *spec = codec->spec;
1370 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1371 spec->gpio_mask = spec->gpio_dir = 0x09;
1372 spec->gpio_data = 0x00;
1373 /* CF-74 has no headphone detection, and the driver should *NOT*
1374 * do detection and HP/speaker toggle because the hardware does it.
1376 spec->gen.suppress_auto_mute = 1;
1381 static const struct hda_fixup stac9200_fixups[] = {
1382 [STAC_REF] = {
1383 .type = HDA_FIXUP_PINS,
1384 .v.pins = ref9200_pin_configs,
1386 [STAC_9200_OQO] = {
1387 .type = HDA_FIXUP_PINS,
1388 .v.pins = oqo9200_pin_configs,
1389 .chained = true,
1390 .chain_id = STAC_9200_EAPD_INIT,
1392 [STAC_9200_DELL_D21] = {
1393 .type = HDA_FIXUP_PINS,
1394 .v.pins = dell9200_d21_pin_configs,
1396 [STAC_9200_DELL_D22] = {
1397 .type = HDA_FIXUP_PINS,
1398 .v.pins = dell9200_d22_pin_configs,
1400 [STAC_9200_DELL_D23] = {
1401 .type = HDA_FIXUP_PINS,
1402 .v.pins = dell9200_d23_pin_configs,
1404 [STAC_9200_DELL_M21] = {
1405 .type = HDA_FIXUP_PINS,
1406 .v.pins = dell9200_m21_pin_configs,
1408 [STAC_9200_DELL_M22] = {
1409 .type = HDA_FIXUP_PINS,
1410 .v.pins = dell9200_m22_pin_configs,
1412 [STAC_9200_DELL_M23] = {
1413 .type = HDA_FIXUP_PINS,
1414 .v.pins = dell9200_m23_pin_configs,
1416 [STAC_9200_DELL_M24] = {
1417 .type = HDA_FIXUP_PINS,
1418 .v.pins = dell9200_m24_pin_configs,
1420 [STAC_9200_DELL_M25] = {
1421 .type = HDA_FIXUP_PINS,
1422 .v.pins = dell9200_m25_pin_configs,
1424 [STAC_9200_DELL_M26] = {
1425 .type = HDA_FIXUP_PINS,
1426 .v.pins = dell9200_m26_pin_configs,
1428 [STAC_9200_DELL_M27] = {
1429 .type = HDA_FIXUP_PINS,
1430 .v.pins = dell9200_m27_pin_configs,
1432 [STAC_9200_M4] = {
1433 .type = HDA_FIXUP_PINS,
1434 .v.pins = gateway9200_m4_pin_configs,
1435 .chained = true,
1436 .chain_id = STAC_9200_EAPD_INIT,
1438 [STAC_9200_M4_2] = {
1439 .type = HDA_FIXUP_PINS,
1440 .v.pins = gateway9200_m4_2_pin_configs,
1441 .chained = true,
1442 .chain_id = STAC_9200_EAPD_INIT,
1444 [STAC_9200_PANASONIC] = {
1445 .type = HDA_FIXUP_FUNC,
1446 .v.func = stac9200_fixup_panasonic,
1448 [STAC_9200_EAPD_INIT] = {
1449 .type = HDA_FIXUP_VERBS,
1450 .v.verbs = (const struct hda_verb[]) {
1451 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1457 static const struct hda_model_fixup stac9200_models[] = {
1458 { .id = STAC_REF, .name = "ref" },
1459 { .id = STAC_9200_OQO, .name = "oqo" },
1460 { .id = STAC_9200_DELL_D21, .name = "dell-d21" },
1461 { .id = STAC_9200_DELL_D22, .name = "dell-d22" },
1462 { .id = STAC_9200_DELL_D23, .name = "dell-d23" },
1463 { .id = STAC_9200_DELL_M21, .name = "dell-m21" },
1464 { .id = STAC_9200_DELL_M22, .name = "dell-m22" },
1465 { .id = STAC_9200_DELL_M23, .name = "dell-m23" },
1466 { .id = STAC_9200_DELL_M24, .name = "dell-m24" },
1467 { .id = STAC_9200_DELL_M25, .name = "dell-m25" },
1468 { .id = STAC_9200_DELL_M26, .name = "dell-m26" },
1469 { .id = STAC_9200_DELL_M27, .name = "dell-m27" },
1470 { .id = STAC_9200_M4, .name = "gateway-m4" },
1471 { .id = STAC_9200_M4_2, .name = "gateway-m4-2" },
1472 { .id = STAC_9200_PANASONIC, .name = "panasonic" },
1476 static const struct snd_pci_quirk stac9200_fixup_tbl[] = {
1477 /* SigmaTel reference board */
1478 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1479 "DFI LanParty", STAC_REF),
1480 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
1481 "DFI LanParty", STAC_REF),
1482 /* Dell laptops have BIOS problem */
1483 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
1484 "unknown Dell", STAC_9200_DELL_D21),
1485 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
1486 "Dell Inspiron 630m", STAC_9200_DELL_M21),
1487 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
1488 "Dell Inspiron E1505n", STAC_9200_DELL_M25),
1489 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
1490 "unknown Dell", STAC_9200_DELL_D22),
1491 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
1492 "unknown Dell", STAC_9200_DELL_D22),
1493 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
1494 "Dell Latitude D620", STAC_9200_DELL_M22),
1495 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
1496 "unknown Dell", STAC_9200_DELL_D23),
1497 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
1498 "unknown Dell", STAC_9200_DELL_D23),
1499 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
1500 "unknown Dell", STAC_9200_DELL_M22),
1501 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
1502 "unknown Dell", STAC_9200_DELL_M24),
1503 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
1504 "unknown Dell", STAC_9200_DELL_M24),
1505 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
1506 "Dell Latitude 120L", STAC_9200_DELL_M24),
1507 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
1508 "Dell Latitude D820", STAC_9200_DELL_M22),
1509 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
1510 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
1511 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
1512 "Dell XPS M1710", STAC_9200_DELL_M23),
1513 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
1514 "Dell Precision M90", STAC_9200_DELL_M23),
1515 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
1516 "unknown Dell", STAC_9200_DELL_M22),
1517 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
1518 "unknown Dell", STAC_9200_DELL_M22),
1519 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
1520 "unknown Dell", STAC_9200_DELL_M22),
1521 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
1522 "Dell Inspiron 640m", STAC_9200_DELL_M21),
1523 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
1524 "unknown Dell", STAC_9200_DELL_D23),
1525 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
1526 "unknown Dell", STAC_9200_DELL_D23),
1527 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
1528 "unknown Dell", STAC_9200_DELL_D21),
1529 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
1530 "unknown Dell", STAC_9200_DELL_D23),
1531 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
1532 "unknown Dell", STAC_9200_DELL_D21),
1533 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
1534 "unknown Dell", STAC_9200_DELL_M25),
1535 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
1536 "unknown Dell", STAC_9200_DELL_M25),
1537 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
1538 "Dell Inspiron 1501", STAC_9200_DELL_M26),
1539 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
1540 "unknown Dell", STAC_9200_DELL_M26),
1541 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0201,
1542 "Dell Latitude D430", STAC_9200_DELL_M22),
1543 /* Panasonic */
1544 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC),
1545 /* Gateway machines needs EAPD to be set on resume */
1546 SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_M4),
1547 SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", STAC_9200_M4_2),
1548 SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", STAC_9200_M4_2),
1549 /* OQO Mobile */
1550 SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO),
1551 {} /* terminator */
1554 static const struct hda_pintbl ref925x_pin_configs[] = {
1555 { 0x07, 0x40c003f0 },
1556 { 0x08, 0x424503f2 },
1557 { 0x0a, 0x01813022 },
1558 { 0x0b, 0x02a19021 },
1559 { 0x0c, 0x90a70320 },
1560 { 0x0d, 0x02214210 },
1561 { 0x10, 0x01019020 },
1562 { 0x11, 0x9033032e },
1566 static const struct hda_pintbl stac925xM1_pin_configs[] = {
1567 { 0x07, 0x40c003f4 },
1568 { 0x08, 0x424503f2 },
1569 { 0x0a, 0x400000f3 },
1570 { 0x0b, 0x02a19020 },
1571 { 0x0c, 0x40a000f0 },
1572 { 0x0d, 0x90100210 },
1573 { 0x10, 0x400003f1 },
1574 { 0x11, 0x9033032e },
1578 static const struct hda_pintbl stac925xM1_2_pin_configs[] = {
1579 { 0x07, 0x40c003f4 },
1580 { 0x08, 0x424503f2 },
1581 { 0x0a, 0x400000f3 },
1582 { 0x0b, 0x02a19020 },
1583 { 0x0c, 0x40a000f0 },
1584 { 0x0d, 0x90100210 },
1585 { 0x10, 0x400003f1 },
1586 { 0x11, 0x9033032e },
1590 static const struct hda_pintbl stac925xM2_pin_configs[] = {
1591 { 0x07, 0x40c003f4 },
1592 { 0x08, 0x424503f2 },
1593 { 0x0a, 0x400000f3 },
1594 { 0x0b, 0x02a19020 },
1595 { 0x0c, 0x40a000f0 },
1596 { 0x0d, 0x90100210 },
1597 { 0x10, 0x400003f1 },
1598 { 0x11, 0x9033032e },
1602 static const struct hda_pintbl stac925xM2_2_pin_configs[] = {
1603 { 0x07, 0x40c003f4 },
1604 { 0x08, 0x424503f2 },
1605 { 0x0a, 0x400000f3 },
1606 { 0x0b, 0x02a19020 },
1607 { 0x0c, 0x40a000f0 },
1608 { 0x0d, 0x90100210 },
1609 { 0x10, 0x400003f1 },
1610 { 0x11, 0x9033032e },
1614 static const struct hda_pintbl stac925xM3_pin_configs[] = {
1615 { 0x07, 0x40c003f4 },
1616 { 0x08, 0x424503f2 },
1617 { 0x0a, 0x400000f3 },
1618 { 0x0b, 0x02a19020 },
1619 { 0x0c, 0x40a000f0 },
1620 { 0x0d, 0x90100210 },
1621 { 0x10, 0x400003f1 },
1622 { 0x11, 0x503303f3 },
1626 static const struct hda_pintbl stac925xM5_pin_configs[] = {
1627 { 0x07, 0x40c003f4 },
1628 { 0x08, 0x424503f2 },
1629 { 0x0a, 0x400000f3 },
1630 { 0x0b, 0x02a19020 },
1631 { 0x0c, 0x40a000f0 },
1632 { 0x0d, 0x90100210 },
1633 { 0x10, 0x400003f1 },
1634 { 0x11, 0x9033032e },
1638 static const struct hda_pintbl stac925xM6_pin_configs[] = {
1639 { 0x07, 0x40c003f4 },
1640 { 0x08, 0x424503f2 },
1641 { 0x0a, 0x400000f3 },
1642 { 0x0b, 0x02a19020 },
1643 { 0x0c, 0x40a000f0 },
1644 { 0x0d, 0x90100210 },
1645 { 0x10, 0x400003f1 },
1646 { 0x11, 0x90330320 },
1650 static const struct hda_fixup stac925x_fixups[] = {
1651 [STAC_REF] = {
1652 .type = HDA_FIXUP_PINS,
1653 .v.pins = ref925x_pin_configs,
1655 [STAC_M1] = {
1656 .type = HDA_FIXUP_PINS,
1657 .v.pins = stac925xM1_pin_configs,
1659 [STAC_M1_2] = {
1660 .type = HDA_FIXUP_PINS,
1661 .v.pins = stac925xM1_2_pin_configs,
1663 [STAC_M2] = {
1664 .type = HDA_FIXUP_PINS,
1665 .v.pins = stac925xM2_pin_configs,
1667 [STAC_M2_2] = {
1668 .type = HDA_FIXUP_PINS,
1669 .v.pins = stac925xM2_2_pin_configs,
1671 [STAC_M3] = {
1672 .type = HDA_FIXUP_PINS,
1673 .v.pins = stac925xM3_pin_configs,
1675 [STAC_M5] = {
1676 .type = HDA_FIXUP_PINS,
1677 .v.pins = stac925xM5_pin_configs,
1679 [STAC_M6] = {
1680 .type = HDA_FIXUP_PINS,
1681 .v.pins = stac925xM6_pin_configs,
1685 static const struct hda_model_fixup stac925x_models[] = {
1686 { .id = STAC_REF, .name = "ref" },
1687 { .id = STAC_M1, .name = "m1" },
1688 { .id = STAC_M1_2, .name = "m1-2" },
1689 { .id = STAC_M2, .name = "m2" },
1690 { .id = STAC_M2_2, .name = "m2-2" },
1691 { .id = STAC_M3, .name = "m3" },
1692 { .id = STAC_M5, .name = "m5" },
1693 { .id = STAC_M6, .name = "m6" },
1697 static const struct snd_pci_quirk stac925x_fixup_tbl[] = {
1698 /* SigmaTel reference board */
1699 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
1700 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF),
1701 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
1703 /* Default table for unknown ID */
1704 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2),
1706 /* gateway machines are checked via codec ssid */
1707 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2),
1708 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5),
1709 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1),
1710 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_M2),
1711 SND_PCI_QUIRK(0x107b, 0x0367, "Gateway MX6453", STAC_M1_2),
1712 /* Not sure about the brand name for those */
1713 SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M1),
1714 SND_PCI_QUIRK(0x107b, 0x0507, "Gateway mobile", STAC_M3),
1715 SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M6),
1716 SND_PCI_QUIRK(0x107b, 0x0685, "Gateway mobile", STAC_M2_2),
1717 {} /* terminator */
1720 static const struct hda_pintbl ref92hd73xx_pin_configs[] = {
1721 { 0x0a, 0x02214030 },
1722 { 0x0b, 0x02a19040 },
1723 { 0x0c, 0x01a19020 },
1724 { 0x0d, 0x02214030 },
1725 { 0x0e, 0x0181302e },
1726 { 0x0f, 0x01014010 },
1727 { 0x10, 0x01014020 },
1728 { 0x11, 0x01014030 },
1729 { 0x12, 0x02319040 },
1730 { 0x13, 0x90a000f0 },
1731 { 0x14, 0x90a000f0 },
1732 { 0x22, 0x01452050 },
1733 { 0x23, 0x01452050 },
1737 static const struct hda_pintbl dell_m6_pin_configs[] = {
1738 { 0x0a, 0x0321101f },
1739 { 0x0b, 0x4f00000f },
1740 { 0x0c, 0x4f0000f0 },
1741 { 0x0d, 0x90170110 },
1742 { 0x0e, 0x03a11020 },
1743 { 0x0f, 0x0321101f },
1744 { 0x10, 0x4f0000f0 },
1745 { 0x11, 0x4f0000f0 },
1746 { 0x12, 0x4f0000f0 },
1747 { 0x13, 0x90a60160 },
1748 { 0x14, 0x4f0000f0 },
1749 { 0x22, 0x4f0000f0 },
1750 { 0x23, 0x4f0000f0 },
1754 static const struct hda_pintbl alienware_m17x_pin_configs[] = {
1755 { 0x0a, 0x0321101f },
1756 { 0x0b, 0x0321101f },
1757 { 0x0c, 0x03a11020 },
1758 { 0x0d, 0x03014020 },
1759 { 0x0e, 0x90170110 },
1760 { 0x0f, 0x4f0000f0 },
1761 { 0x10, 0x4f0000f0 },
1762 { 0x11, 0x4f0000f0 },
1763 { 0x12, 0x4f0000f0 },
1764 { 0x13, 0x90a60160 },
1765 { 0x14, 0x4f0000f0 },
1766 { 0x22, 0x4f0000f0 },
1767 { 0x23, 0x904601b0 },
1771 static const struct hda_pintbl intel_dg45id_pin_configs[] = {
1772 { 0x0a, 0x02214230 },
1773 { 0x0b, 0x02A19240 },
1774 { 0x0c, 0x01013214 },
1775 { 0x0d, 0x01014210 },
1776 { 0x0e, 0x01A19250 },
1777 { 0x0f, 0x01011212 },
1778 { 0x10, 0x01016211 },
1782 static const struct hda_pintbl stac92hd89xx_hp_front_jack_pin_configs[] = {
1783 { 0x0a, 0x02214030 },
1784 { 0x0b, 0x02A19010 },
1788 static const struct hda_pintbl stac92hd89xx_hp_z1_g2_right_mic_jack_pin_configs[] = {
1789 { 0x0e, 0x400000f0 },
1793 static void stac92hd73xx_fixup_ref(struct hda_codec *codec,
1794 const struct hda_fixup *fix, int action)
1796 struct sigmatel_spec *spec = codec->spec;
1798 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1799 return;
1801 snd_hda_apply_pincfgs(codec, ref92hd73xx_pin_configs);
1802 spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0;
1805 static void stac92hd73xx_fixup_dell(struct hda_codec *codec)
1807 struct sigmatel_spec *spec = codec->spec;
1809 snd_hda_apply_pincfgs(codec, dell_m6_pin_configs);
1810 spec->eapd_switch = 0;
1813 static void stac92hd73xx_fixup_dell_eq(struct hda_codec *codec,
1814 const struct hda_fixup *fix, int action)
1816 struct sigmatel_spec *spec = codec->spec;
1818 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1819 return;
1821 stac92hd73xx_fixup_dell(codec);
1822 snd_hda_add_verbs(codec, dell_eq_core_init);
1823 spec->volknob_init = 1;
1826 /* Analog Mics */
1827 static void stac92hd73xx_fixup_dell_m6_amic(struct hda_codec *codec,
1828 const struct hda_fixup *fix, int action)
1830 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1831 return;
1833 stac92hd73xx_fixup_dell(codec);
1834 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
1837 /* Digital Mics */
1838 static void stac92hd73xx_fixup_dell_m6_dmic(struct hda_codec *codec,
1839 const struct hda_fixup *fix, int action)
1841 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1842 return;
1844 stac92hd73xx_fixup_dell(codec);
1845 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
1848 /* Both */
1849 static void stac92hd73xx_fixup_dell_m6_both(struct hda_codec *codec,
1850 const struct hda_fixup *fix, int action)
1852 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1853 return;
1855 stac92hd73xx_fixup_dell(codec);
1856 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
1857 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
1860 static void stac92hd73xx_fixup_alienware_m17x(struct hda_codec *codec,
1861 const struct hda_fixup *fix, int action)
1863 struct sigmatel_spec *spec = codec->spec;
1865 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1866 return;
1868 snd_hda_apply_pincfgs(codec, alienware_m17x_pin_configs);
1869 spec->eapd_switch = 0;
1872 static void stac92hd73xx_fixup_no_jd(struct hda_codec *codec,
1873 const struct hda_fixup *fix, int action)
1875 if (action == HDA_FIXUP_ACT_PRE_PROBE)
1876 codec->no_jack_detect = 1;
1880 static void stac92hd73xx_disable_automute(struct hda_codec *codec,
1881 const struct hda_fixup *fix, int action)
1883 struct sigmatel_spec *spec = codec->spec;
1885 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1886 return;
1888 spec->gen.suppress_auto_mute = 1;
1891 static const struct hda_fixup stac92hd73xx_fixups[] = {
1892 [STAC_92HD73XX_REF] = {
1893 .type = HDA_FIXUP_FUNC,
1894 .v.func = stac92hd73xx_fixup_ref,
1896 [STAC_DELL_M6_AMIC] = {
1897 .type = HDA_FIXUP_FUNC,
1898 .v.func = stac92hd73xx_fixup_dell_m6_amic,
1900 [STAC_DELL_M6_DMIC] = {
1901 .type = HDA_FIXUP_FUNC,
1902 .v.func = stac92hd73xx_fixup_dell_m6_dmic,
1904 [STAC_DELL_M6_BOTH] = {
1905 .type = HDA_FIXUP_FUNC,
1906 .v.func = stac92hd73xx_fixup_dell_m6_both,
1908 [STAC_DELL_EQ] = {
1909 .type = HDA_FIXUP_FUNC,
1910 .v.func = stac92hd73xx_fixup_dell_eq,
1912 [STAC_ALIENWARE_M17X] = {
1913 .type = HDA_FIXUP_FUNC,
1914 .v.func = stac92hd73xx_fixup_alienware_m17x,
1916 [STAC_ELO_VUPOINT_15MX] = {
1917 .type = HDA_FIXUP_FUNC,
1918 .v.func = stac92hd73xx_disable_automute,
1920 [STAC_92HD73XX_INTEL] = {
1921 .type = HDA_FIXUP_PINS,
1922 .v.pins = intel_dg45id_pin_configs,
1924 [STAC_92HD73XX_NO_JD] = {
1925 .type = HDA_FIXUP_FUNC,
1926 .v.func = stac92hd73xx_fixup_no_jd,
1928 [STAC_92HD89XX_HP_FRONT_JACK] = {
1929 .type = HDA_FIXUP_PINS,
1930 .v.pins = stac92hd89xx_hp_front_jack_pin_configs,
1932 [STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK] = {
1933 .type = HDA_FIXUP_PINS,
1934 .v.pins = stac92hd89xx_hp_z1_g2_right_mic_jack_pin_configs,
1936 [STAC_92HD73XX_ASUS_MOBO] = {
1937 .type = HDA_FIXUP_PINS,
1938 .v.pins = (const struct hda_pintbl[]) {
1939 /* enable 5.1 and SPDIF out */
1940 { 0x0c, 0x01014411 },
1941 { 0x0d, 0x01014410 },
1942 { 0x0e, 0x01014412 },
1943 { 0x22, 0x014b1180 },
1949 static const struct hda_model_fixup stac92hd73xx_models[] = {
1950 { .id = STAC_92HD73XX_NO_JD, .name = "no-jd" },
1951 { .id = STAC_92HD73XX_REF, .name = "ref" },
1952 { .id = STAC_92HD73XX_INTEL, .name = "intel" },
1953 { .id = STAC_DELL_M6_AMIC, .name = "dell-m6-amic" },
1954 { .id = STAC_DELL_M6_DMIC, .name = "dell-m6-dmic" },
1955 { .id = STAC_DELL_M6_BOTH, .name = "dell-m6" },
1956 { .id = STAC_DELL_EQ, .name = "dell-eq" },
1957 { .id = STAC_ALIENWARE_M17X, .name = "alienware" },
1958 { .id = STAC_ELO_VUPOINT_15MX, .name = "elo-vupoint-15mx" },
1959 { .id = STAC_92HD73XX_ASUS_MOBO, .name = "asus-mobo" },
1963 static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = {
1964 /* SigmaTel reference board */
1965 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1966 "DFI LanParty", STAC_92HD73XX_REF),
1967 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
1968 "DFI LanParty", STAC_92HD73XX_REF),
1969 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5002,
1970 "Intel DG45ID", STAC_92HD73XX_INTEL),
1971 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5003,
1972 "Intel DG45FC", STAC_92HD73XX_INTEL),
1973 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254,
1974 "Dell Studio 1535", STAC_DELL_M6_DMIC),
1975 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255,
1976 "unknown Dell", STAC_DELL_M6_DMIC),
1977 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256,
1978 "unknown Dell", STAC_DELL_M6_BOTH),
1979 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257,
1980 "unknown Dell", STAC_DELL_M6_BOTH),
1981 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e,
1982 "unknown Dell", STAC_DELL_M6_AMIC),
1983 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f,
1984 "unknown Dell", STAC_DELL_M6_AMIC),
1985 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271,
1986 "unknown Dell", STAC_DELL_M6_DMIC),
1987 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0272,
1988 "unknown Dell", STAC_DELL_M6_DMIC),
1989 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f,
1990 "Dell Studio 1537", STAC_DELL_M6_DMIC),
1991 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a0,
1992 "Dell Studio 17", STAC_DELL_M6_DMIC),
1993 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02be,
1994 "Dell Studio 1555", STAC_DELL_M6_DMIC),
1995 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd,
1996 "Dell Studio 1557", STAC_DELL_M6_DMIC),
1997 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe,
1998 "Dell Studio XPS 1645", STAC_DELL_M6_DMIC),
1999 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413,
2000 "Dell Studio 1558", STAC_DELL_M6_DMIC),
2001 /* codec SSID matching */
2002 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1,
2003 "Alienware M17x", STAC_ALIENWARE_M17X),
2004 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
2005 "Alienware M17x", STAC_ALIENWARE_M17X),
2006 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490,
2007 "Alienware M17x R3", STAC_DELL_EQ),
2008 SND_PCI_QUIRK(0x1059, 0x1011,
2009 "ELO VuPoint 15MX", STAC_ELO_VUPOINT_15MX),
2010 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1927,
2011 "HP Z1 G2", STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK),
2012 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2b17,
2013 "unknown HP", STAC_92HD89XX_HP_FRONT_JACK),
2014 SND_PCI_QUIRK(PCI_VENDOR_ID_ASUSTEK, 0x83f8, "ASUS AT4NM10",
2015 STAC_92HD73XX_ASUS_MOBO),
2016 {} /* terminator */
2019 static const struct hda_pintbl ref92hd83xxx_pin_configs[] = {
2020 { 0x0a, 0x02214030 },
2021 { 0x0b, 0x02211010 },
2022 { 0x0c, 0x02a19020 },
2023 { 0x0d, 0x02170130 },
2024 { 0x0e, 0x01014050 },
2025 { 0x0f, 0x01819040 },
2026 { 0x10, 0x01014020 },
2027 { 0x11, 0x90a3014e },
2028 { 0x1f, 0x01451160 },
2029 { 0x20, 0x98560170 },
2033 static const struct hda_pintbl dell_s14_pin_configs[] = {
2034 { 0x0a, 0x0221403f },
2035 { 0x0b, 0x0221101f },
2036 { 0x0c, 0x02a19020 },
2037 { 0x0d, 0x90170110 },
2038 { 0x0e, 0x40f000f0 },
2039 { 0x0f, 0x40f000f0 },
2040 { 0x10, 0x40f000f0 },
2041 { 0x11, 0x90a60160 },
2042 { 0x1f, 0x40f000f0 },
2043 { 0x20, 0x40f000f0 },
2047 static const struct hda_pintbl dell_vostro_3500_pin_configs[] = {
2048 { 0x0a, 0x02a11020 },
2049 { 0x0b, 0x0221101f },
2050 { 0x0c, 0x400000f0 },
2051 { 0x0d, 0x90170110 },
2052 { 0x0e, 0x400000f1 },
2053 { 0x0f, 0x400000f2 },
2054 { 0x10, 0x400000f3 },
2055 { 0x11, 0x90a60160 },
2056 { 0x1f, 0x400000f4 },
2057 { 0x20, 0x400000f5 },
2061 static const struct hda_pintbl hp_dv7_4000_pin_configs[] = {
2062 { 0x0a, 0x03a12050 },
2063 { 0x0b, 0x0321201f },
2064 { 0x0c, 0x40f000f0 },
2065 { 0x0d, 0x90170110 },
2066 { 0x0e, 0x40f000f0 },
2067 { 0x0f, 0x40f000f0 },
2068 { 0x10, 0x90170110 },
2069 { 0x11, 0xd5a30140 },
2070 { 0x1f, 0x40f000f0 },
2071 { 0x20, 0x40f000f0 },
2075 static const struct hda_pintbl hp_zephyr_pin_configs[] = {
2076 { 0x0a, 0x01813050 },
2077 { 0x0b, 0x0421201f },
2078 { 0x0c, 0x04a1205e },
2079 { 0x0d, 0x96130310 },
2080 { 0x0e, 0x96130310 },
2081 { 0x0f, 0x0101401f },
2082 { 0x10, 0x1111611f },
2083 { 0x11, 0xd5a30130 },
2087 static const struct hda_pintbl hp_cNB11_intquad_pin_configs[] = {
2088 { 0x0a, 0x40f000f0 },
2089 { 0x0b, 0x0221101f },
2090 { 0x0c, 0x02a11020 },
2091 { 0x0d, 0x92170110 },
2092 { 0x0e, 0x40f000f0 },
2093 { 0x0f, 0x92170110 },
2094 { 0x10, 0x40f000f0 },
2095 { 0x11, 0xd5a30130 },
2096 { 0x1f, 0x40f000f0 },
2097 { 0x20, 0x40f000f0 },
2101 static void stac92hd83xxx_fixup_hp(struct hda_codec *codec,
2102 const struct hda_fixup *fix, int action)
2104 struct sigmatel_spec *spec = codec->spec;
2106 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2107 return;
2109 if (hp_bnb2011_with_dock(codec)) {
2110 snd_hda_codec_set_pincfg(codec, 0xa, 0x2101201f);
2111 snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);
2114 if (find_mute_led_cfg(codec, spec->default_polarity))
2115 codec_dbg(codec, "mute LED gpio %d polarity %d\n",
2116 spec->gpio_led,
2117 spec->gpio_led_polarity);
2119 /* allow auto-switching of dock line-in */
2120 spec->gen.line_in_auto_switch = true;
2123 static void stac92hd83xxx_fixup_hp_zephyr(struct hda_codec *codec,
2124 const struct hda_fixup *fix, int action)
2126 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2127 return;
2129 snd_hda_apply_pincfgs(codec, hp_zephyr_pin_configs);
2130 snd_hda_add_verbs(codec, stac92hd83xxx_hp_zephyr_init);
2133 static void stac92hd83xxx_fixup_hp_led(struct hda_codec *codec,
2134 const struct hda_fixup *fix, int action)
2136 struct sigmatel_spec *spec = codec->spec;
2138 if (action == HDA_FIXUP_ACT_PRE_PROBE)
2139 spec->default_polarity = 0;
2142 static void stac92hd83xxx_fixup_hp_inv_led(struct hda_codec *codec,
2143 const struct hda_fixup *fix, int action)
2145 struct sigmatel_spec *spec = codec->spec;
2147 if (action == HDA_FIXUP_ACT_PRE_PROBE)
2148 spec->default_polarity = 1;
2151 static void stac92hd83xxx_fixup_hp_mic_led(struct hda_codec *codec,
2152 const struct hda_fixup *fix, int action)
2154 struct sigmatel_spec *spec = codec->spec;
2156 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2157 spec->mic_mute_led_gpio = 0x08; /* GPIO3 */
2158 #ifdef CONFIG_PM
2159 /* resetting controller clears GPIO, so we need to keep on */
2160 codec->core.power_caps &= ~AC_PWRST_CLKSTOP;
2161 #endif
2165 static void stac92hd83xxx_fixup_hp_led_gpio10(struct hda_codec *codec,
2166 const struct hda_fixup *fix, int action)
2168 struct sigmatel_spec *spec = codec->spec;
2170 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2171 spec->gpio_led = 0x10; /* GPIO4 */
2172 spec->default_polarity = 0;
2176 static void stac92hd83xxx_fixup_headset_jack(struct hda_codec *codec,
2177 const struct hda_fixup *fix, int action)
2179 struct sigmatel_spec *spec = codec->spec;
2181 if (action == HDA_FIXUP_ACT_PRE_PROBE)
2182 spec->headset_jack = 1;
2185 static void stac92hd83xxx_fixup_gpio10_eapd(struct hda_codec *codec,
2186 const struct hda_fixup *fix,
2187 int action)
2189 struct sigmatel_spec *spec = codec->spec;
2191 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2192 return;
2193 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir =
2194 spec->gpio_data = 0x10;
2195 spec->eapd_switch = 0;
2198 static void hp_envy_ts_fixup_dac_bind(struct hda_codec *codec,
2199 const struct hda_fixup *fix,
2200 int action)
2202 struct sigmatel_spec *spec = codec->spec;
2203 static hda_nid_t preferred_pairs[] = {
2204 0xd, 0x13,
2208 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2209 return;
2211 spec->gen.preferred_dacs = preferred_pairs;
2214 static const struct hda_verb hp_bnb13_eq_verbs[] = {
2215 /* 44.1KHz base */
2216 { 0x22, 0x7A6, 0x3E },
2217 { 0x22, 0x7A7, 0x68 },
2218 { 0x22, 0x7A8, 0x17 },
2219 { 0x22, 0x7A9, 0x3E },
2220 { 0x22, 0x7AA, 0x68 },
2221 { 0x22, 0x7AB, 0x17 },
2222 { 0x22, 0x7AC, 0x00 },
2223 { 0x22, 0x7AD, 0x80 },
2224 { 0x22, 0x7A6, 0x83 },
2225 { 0x22, 0x7A7, 0x2F },
2226 { 0x22, 0x7A8, 0xD1 },
2227 { 0x22, 0x7A9, 0x83 },
2228 { 0x22, 0x7AA, 0x2F },
2229 { 0x22, 0x7AB, 0xD1 },
2230 { 0x22, 0x7AC, 0x01 },
2231 { 0x22, 0x7AD, 0x80 },
2232 { 0x22, 0x7A6, 0x3E },
2233 { 0x22, 0x7A7, 0x68 },
2234 { 0x22, 0x7A8, 0x17 },
2235 { 0x22, 0x7A9, 0x3E },
2236 { 0x22, 0x7AA, 0x68 },
2237 { 0x22, 0x7AB, 0x17 },
2238 { 0x22, 0x7AC, 0x02 },
2239 { 0x22, 0x7AD, 0x80 },
2240 { 0x22, 0x7A6, 0x7C },
2241 { 0x22, 0x7A7, 0xC6 },
2242 { 0x22, 0x7A8, 0x0C },
2243 { 0x22, 0x7A9, 0x7C },
2244 { 0x22, 0x7AA, 0xC6 },
2245 { 0x22, 0x7AB, 0x0C },
2246 { 0x22, 0x7AC, 0x03 },
2247 { 0x22, 0x7AD, 0x80 },
2248 { 0x22, 0x7A6, 0xC3 },
2249 { 0x22, 0x7A7, 0x25 },
2250 { 0x22, 0x7A8, 0xAF },
2251 { 0x22, 0x7A9, 0xC3 },
2252 { 0x22, 0x7AA, 0x25 },
2253 { 0x22, 0x7AB, 0xAF },
2254 { 0x22, 0x7AC, 0x04 },
2255 { 0x22, 0x7AD, 0x80 },
2256 { 0x22, 0x7A6, 0x3E },
2257 { 0x22, 0x7A7, 0x85 },
2258 { 0x22, 0x7A8, 0x73 },
2259 { 0x22, 0x7A9, 0x3E },
2260 { 0x22, 0x7AA, 0x85 },
2261 { 0x22, 0x7AB, 0x73 },
2262 { 0x22, 0x7AC, 0x05 },
2263 { 0x22, 0x7AD, 0x80 },
2264 { 0x22, 0x7A6, 0x85 },
2265 { 0x22, 0x7A7, 0x39 },
2266 { 0x22, 0x7A8, 0xC7 },
2267 { 0x22, 0x7A9, 0x85 },
2268 { 0x22, 0x7AA, 0x39 },
2269 { 0x22, 0x7AB, 0xC7 },
2270 { 0x22, 0x7AC, 0x06 },
2271 { 0x22, 0x7AD, 0x80 },
2272 { 0x22, 0x7A6, 0x3C },
2273 { 0x22, 0x7A7, 0x90 },
2274 { 0x22, 0x7A8, 0xB0 },
2275 { 0x22, 0x7A9, 0x3C },
2276 { 0x22, 0x7AA, 0x90 },
2277 { 0x22, 0x7AB, 0xB0 },
2278 { 0x22, 0x7AC, 0x07 },
2279 { 0x22, 0x7AD, 0x80 },
2280 { 0x22, 0x7A6, 0x7A },
2281 { 0x22, 0x7A7, 0xC6 },
2282 { 0x22, 0x7A8, 0x39 },
2283 { 0x22, 0x7A9, 0x7A },
2284 { 0x22, 0x7AA, 0xC6 },
2285 { 0x22, 0x7AB, 0x39 },
2286 { 0x22, 0x7AC, 0x08 },
2287 { 0x22, 0x7AD, 0x80 },
2288 { 0x22, 0x7A6, 0xC4 },
2289 { 0x22, 0x7A7, 0xE9 },
2290 { 0x22, 0x7A8, 0xDC },
2291 { 0x22, 0x7A9, 0xC4 },
2292 { 0x22, 0x7AA, 0xE9 },
2293 { 0x22, 0x7AB, 0xDC },
2294 { 0x22, 0x7AC, 0x09 },
2295 { 0x22, 0x7AD, 0x80 },
2296 { 0x22, 0x7A6, 0x3D },
2297 { 0x22, 0x7A7, 0xE1 },
2298 { 0x22, 0x7A8, 0x0D },
2299 { 0x22, 0x7A9, 0x3D },
2300 { 0x22, 0x7AA, 0xE1 },
2301 { 0x22, 0x7AB, 0x0D },
2302 { 0x22, 0x7AC, 0x0A },
2303 { 0x22, 0x7AD, 0x80 },
2304 { 0x22, 0x7A6, 0x89 },
2305 { 0x22, 0x7A7, 0xB6 },
2306 { 0x22, 0x7A8, 0xEB },
2307 { 0x22, 0x7A9, 0x89 },
2308 { 0x22, 0x7AA, 0xB6 },
2309 { 0x22, 0x7AB, 0xEB },
2310 { 0x22, 0x7AC, 0x0B },
2311 { 0x22, 0x7AD, 0x80 },
2312 { 0x22, 0x7A6, 0x39 },
2313 { 0x22, 0x7A7, 0x9D },
2314 { 0x22, 0x7A8, 0xFE },
2315 { 0x22, 0x7A9, 0x39 },
2316 { 0x22, 0x7AA, 0x9D },
2317 { 0x22, 0x7AB, 0xFE },
2318 { 0x22, 0x7AC, 0x0C },
2319 { 0x22, 0x7AD, 0x80 },
2320 { 0x22, 0x7A6, 0x76 },
2321 { 0x22, 0x7A7, 0x49 },
2322 { 0x22, 0x7A8, 0x15 },
2323 { 0x22, 0x7A9, 0x76 },
2324 { 0x22, 0x7AA, 0x49 },
2325 { 0x22, 0x7AB, 0x15 },
2326 { 0x22, 0x7AC, 0x0D },
2327 { 0x22, 0x7AD, 0x80 },
2328 { 0x22, 0x7A6, 0xC8 },
2329 { 0x22, 0x7A7, 0x80 },
2330 { 0x22, 0x7A8, 0xF5 },
2331 { 0x22, 0x7A9, 0xC8 },
2332 { 0x22, 0x7AA, 0x80 },
2333 { 0x22, 0x7AB, 0xF5 },
2334 { 0x22, 0x7AC, 0x0E },
2335 { 0x22, 0x7AD, 0x80 },
2336 { 0x22, 0x7A6, 0x40 },
2337 { 0x22, 0x7A7, 0x00 },
2338 { 0x22, 0x7A8, 0x00 },
2339 { 0x22, 0x7A9, 0x40 },
2340 { 0x22, 0x7AA, 0x00 },
2341 { 0x22, 0x7AB, 0x00 },
2342 { 0x22, 0x7AC, 0x0F },
2343 { 0x22, 0x7AD, 0x80 },
2344 { 0x22, 0x7A6, 0x90 },
2345 { 0x22, 0x7A7, 0x68 },
2346 { 0x22, 0x7A8, 0xF1 },
2347 { 0x22, 0x7A9, 0x90 },
2348 { 0x22, 0x7AA, 0x68 },
2349 { 0x22, 0x7AB, 0xF1 },
2350 { 0x22, 0x7AC, 0x10 },
2351 { 0x22, 0x7AD, 0x80 },
2352 { 0x22, 0x7A6, 0x34 },
2353 { 0x22, 0x7A7, 0x47 },
2354 { 0x22, 0x7A8, 0x6C },
2355 { 0x22, 0x7A9, 0x34 },
2356 { 0x22, 0x7AA, 0x47 },
2357 { 0x22, 0x7AB, 0x6C },
2358 { 0x22, 0x7AC, 0x11 },
2359 { 0x22, 0x7AD, 0x80 },
2360 { 0x22, 0x7A6, 0x6F },
2361 { 0x22, 0x7A7, 0x97 },
2362 { 0x22, 0x7A8, 0x0F },
2363 { 0x22, 0x7A9, 0x6F },
2364 { 0x22, 0x7AA, 0x97 },
2365 { 0x22, 0x7AB, 0x0F },
2366 { 0x22, 0x7AC, 0x12 },
2367 { 0x22, 0x7AD, 0x80 },
2368 { 0x22, 0x7A6, 0xCB },
2369 { 0x22, 0x7A7, 0xB8 },
2370 { 0x22, 0x7A8, 0x94 },
2371 { 0x22, 0x7A9, 0xCB },
2372 { 0x22, 0x7AA, 0xB8 },
2373 { 0x22, 0x7AB, 0x94 },
2374 { 0x22, 0x7AC, 0x13 },
2375 { 0x22, 0x7AD, 0x80 },
2376 { 0x22, 0x7A6, 0x40 },
2377 { 0x22, 0x7A7, 0x00 },
2378 { 0x22, 0x7A8, 0x00 },
2379 { 0x22, 0x7A9, 0x40 },
2380 { 0x22, 0x7AA, 0x00 },
2381 { 0x22, 0x7AB, 0x00 },
2382 { 0x22, 0x7AC, 0x14 },
2383 { 0x22, 0x7AD, 0x80 },
2384 { 0x22, 0x7A6, 0x95 },
2385 { 0x22, 0x7A7, 0x76 },
2386 { 0x22, 0x7A8, 0x5B },
2387 { 0x22, 0x7A9, 0x95 },
2388 { 0x22, 0x7AA, 0x76 },
2389 { 0x22, 0x7AB, 0x5B },
2390 { 0x22, 0x7AC, 0x15 },
2391 { 0x22, 0x7AD, 0x80 },
2392 { 0x22, 0x7A6, 0x31 },
2393 { 0x22, 0x7A7, 0xAC },
2394 { 0x22, 0x7A8, 0x31 },
2395 { 0x22, 0x7A9, 0x31 },
2396 { 0x22, 0x7AA, 0xAC },
2397 { 0x22, 0x7AB, 0x31 },
2398 { 0x22, 0x7AC, 0x16 },
2399 { 0x22, 0x7AD, 0x80 },
2400 { 0x22, 0x7A6, 0x6A },
2401 { 0x22, 0x7A7, 0x89 },
2402 { 0x22, 0x7A8, 0xA5 },
2403 { 0x22, 0x7A9, 0x6A },
2404 { 0x22, 0x7AA, 0x89 },
2405 { 0x22, 0x7AB, 0xA5 },
2406 { 0x22, 0x7AC, 0x17 },
2407 { 0x22, 0x7AD, 0x80 },
2408 { 0x22, 0x7A6, 0xCE },
2409 { 0x22, 0x7A7, 0x53 },
2410 { 0x22, 0x7A8, 0xCF },
2411 { 0x22, 0x7A9, 0xCE },
2412 { 0x22, 0x7AA, 0x53 },
2413 { 0x22, 0x7AB, 0xCF },
2414 { 0x22, 0x7AC, 0x18 },
2415 { 0x22, 0x7AD, 0x80 },
2416 { 0x22, 0x7A6, 0x40 },
2417 { 0x22, 0x7A7, 0x00 },
2418 { 0x22, 0x7A8, 0x00 },
2419 { 0x22, 0x7A9, 0x40 },
2420 { 0x22, 0x7AA, 0x00 },
2421 { 0x22, 0x7AB, 0x00 },
2422 { 0x22, 0x7AC, 0x19 },
2423 { 0x22, 0x7AD, 0x80 },
2424 /* 48KHz base */
2425 { 0x22, 0x7A6, 0x3E },
2426 { 0x22, 0x7A7, 0x88 },
2427 { 0x22, 0x7A8, 0xDC },
2428 { 0x22, 0x7A9, 0x3E },
2429 { 0x22, 0x7AA, 0x88 },
2430 { 0x22, 0x7AB, 0xDC },
2431 { 0x22, 0x7AC, 0x1A },
2432 { 0x22, 0x7AD, 0x80 },
2433 { 0x22, 0x7A6, 0x82 },
2434 { 0x22, 0x7A7, 0xEE },
2435 { 0x22, 0x7A8, 0x46 },
2436 { 0x22, 0x7A9, 0x82 },
2437 { 0x22, 0x7AA, 0xEE },
2438 { 0x22, 0x7AB, 0x46 },
2439 { 0x22, 0x7AC, 0x1B },
2440 { 0x22, 0x7AD, 0x80 },
2441 { 0x22, 0x7A6, 0x3E },
2442 { 0x22, 0x7A7, 0x88 },
2443 { 0x22, 0x7A8, 0xDC },
2444 { 0x22, 0x7A9, 0x3E },
2445 { 0x22, 0x7AA, 0x88 },
2446 { 0x22, 0x7AB, 0xDC },
2447 { 0x22, 0x7AC, 0x1C },
2448 { 0x22, 0x7AD, 0x80 },
2449 { 0x22, 0x7A6, 0x7D },
2450 { 0x22, 0x7A7, 0x09 },
2451 { 0x22, 0x7A8, 0x28 },
2452 { 0x22, 0x7A9, 0x7D },
2453 { 0x22, 0x7AA, 0x09 },
2454 { 0x22, 0x7AB, 0x28 },
2455 { 0x22, 0x7AC, 0x1D },
2456 { 0x22, 0x7AD, 0x80 },
2457 { 0x22, 0x7A6, 0xC2 },
2458 { 0x22, 0x7A7, 0xE5 },
2459 { 0x22, 0x7A8, 0xB4 },
2460 { 0x22, 0x7A9, 0xC2 },
2461 { 0x22, 0x7AA, 0xE5 },
2462 { 0x22, 0x7AB, 0xB4 },
2463 { 0x22, 0x7AC, 0x1E },
2464 { 0x22, 0x7AD, 0x80 },
2465 { 0x22, 0x7A6, 0x3E },
2466 { 0x22, 0x7A7, 0xA3 },
2467 { 0x22, 0x7A8, 0x1F },
2468 { 0x22, 0x7A9, 0x3E },
2469 { 0x22, 0x7AA, 0xA3 },
2470 { 0x22, 0x7AB, 0x1F },
2471 { 0x22, 0x7AC, 0x1F },
2472 { 0x22, 0x7AD, 0x80 },
2473 { 0x22, 0x7A6, 0x84 },
2474 { 0x22, 0x7A7, 0xCA },
2475 { 0x22, 0x7A8, 0xF1 },
2476 { 0x22, 0x7A9, 0x84 },
2477 { 0x22, 0x7AA, 0xCA },
2478 { 0x22, 0x7AB, 0xF1 },
2479 { 0x22, 0x7AC, 0x20 },
2480 { 0x22, 0x7AD, 0x80 },
2481 { 0x22, 0x7A6, 0x3C },
2482 { 0x22, 0x7A7, 0xD5 },
2483 { 0x22, 0x7A8, 0x9C },
2484 { 0x22, 0x7A9, 0x3C },
2485 { 0x22, 0x7AA, 0xD5 },
2486 { 0x22, 0x7AB, 0x9C },
2487 { 0x22, 0x7AC, 0x21 },
2488 { 0x22, 0x7AD, 0x80 },
2489 { 0x22, 0x7A6, 0x7B },
2490 { 0x22, 0x7A7, 0x35 },
2491 { 0x22, 0x7A8, 0x0F },
2492 { 0x22, 0x7A9, 0x7B },
2493 { 0x22, 0x7AA, 0x35 },
2494 { 0x22, 0x7AB, 0x0F },
2495 { 0x22, 0x7AC, 0x22 },
2496 { 0x22, 0x7AD, 0x80 },
2497 { 0x22, 0x7A6, 0xC4 },
2498 { 0x22, 0x7A7, 0x87 },
2499 { 0x22, 0x7A8, 0x45 },
2500 { 0x22, 0x7A9, 0xC4 },
2501 { 0x22, 0x7AA, 0x87 },
2502 { 0x22, 0x7AB, 0x45 },
2503 { 0x22, 0x7AC, 0x23 },
2504 { 0x22, 0x7AD, 0x80 },
2505 { 0x22, 0x7A6, 0x3E },
2506 { 0x22, 0x7A7, 0x0A },
2507 { 0x22, 0x7A8, 0x78 },
2508 { 0x22, 0x7A9, 0x3E },
2509 { 0x22, 0x7AA, 0x0A },
2510 { 0x22, 0x7AB, 0x78 },
2511 { 0x22, 0x7AC, 0x24 },
2512 { 0x22, 0x7AD, 0x80 },
2513 { 0x22, 0x7A6, 0x88 },
2514 { 0x22, 0x7A7, 0xE2 },
2515 { 0x22, 0x7A8, 0x05 },
2516 { 0x22, 0x7A9, 0x88 },
2517 { 0x22, 0x7AA, 0xE2 },
2518 { 0x22, 0x7AB, 0x05 },
2519 { 0x22, 0x7AC, 0x25 },
2520 { 0x22, 0x7AD, 0x80 },
2521 { 0x22, 0x7A6, 0x3A },
2522 { 0x22, 0x7A7, 0x1A },
2523 { 0x22, 0x7A8, 0xA3 },
2524 { 0x22, 0x7A9, 0x3A },
2525 { 0x22, 0x7AA, 0x1A },
2526 { 0x22, 0x7AB, 0xA3 },
2527 { 0x22, 0x7AC, 0x26 },
2528 { 0x22, 0x7AD, 0x80 },
2529 { 0x22, 0x7A6, 0x77 },
2530 { 0x22, 0x7A7, 0x1D },
2531 { 0x22, 0x7A8, 0xFB },
2532 { 0x22, 0x7A9, 0x77 },
2533 { 0x22, 0x7AA, 0x1D },
2534 { 0x22, 0x7AB, 0xFB },
2535 { 0x22, 0x7AC, 0x27 },
2536 { 0x22, 0x7AD, 0x80 },
2537 { 0x22, 0x7A6, 0xC7 },
2538 { 0x22, 0x7A7, 0xDA },
2539 { 0x22, 0x7A8, 0xE5 },
2540 { 0x22, 0x7A9, 0xC7 },
2541 { 0x22, 0x7AA, 0xDA },
2542 { 0x22, 0x7AB, 0xE5 },
2543 { 0x22, 0x7AC, 0x28 },
2544 { 0x22, 0x7AD, 0x80 },
2545 { 0x22, 0x7A6, 0x40 },
2546 { 0x22, 0x7A7, 0x00 },
2547 { 0x22, 0x7A8, 0x00 },
2548 { 0x22, 0x7A9, 0x40 },
2549 { 0x22, 0x7AA, 0x00 },
2550 { 0x22, 0x7AB, 0x00 },
2551 { 0x22, 0x7AC, 0x29 },
2552 { 0x22, 0x7AD, 0x80 },
2553 { 0x22, 0x7A6, 0x8E },
2554 { 0x22, 0x7A7, 0xD7 },
2555 { 0x22, 0x7A8, 0x22 },
2556 { 0x22, 0x7A9, 0x8E },
2557 { 0x22, 0x7AA, 0xD7 },
2558 { 0x22, 0x7AB, 0x22 },
2559 { 0x22, 0x7AC, 0x2A },
2560 { 0x22, 0x7AD, 0x80 },
2561 { 0x22, 0x7A6, 0x35 },
2562 { 0x22, 0x7A7, 0x26 },
2563 { 0x22, 0x7A8, 0xC6 },
2564 { 0x22, 0x7A9, 0x35 },
2565 { 0x22, 0x7AA, 0x26 },
2566 { 0x22, 0x7AB, 0xC6 },
2567 { 0x22, 0x7AC, 0x2B },
2568 { 0x22, 0x7AD, 0x80 },
2569 { 0x22, 0x7A6, 0x71 },
2570 { 0x22, 0x7A7, 0x28 },
2571 { 0x22, 0x7A8, 0xDE },
2572 { 0x22, 0x7A9, 0x71 },
2573 { 0x22, 0x7AA, 0x28 },
2574 { 0x22, 0x7AB, 0xDE },
2575 { 0x22, 0x7AC, 0x2C },
2576 { 0x22, 0x7AD, 0x80 },
2577 { 0x22, 0x7A6, 0xCA },
2578 { 0x22, 0x7A7, 0xD9 },
2579 { 0x22, 0x7A8, 0x3A },
2580 { 0x22, 0x7A9, 0xCA },
2581 { 0x22, 0x7AA, 0xD9 },
2582 { 0x22, 0x7AB, 0x3A },
2583 { 0x22, 0x7AC, 0x2D },
2584 { 0x22, 0x7AD, 0x80 },
2585 { 0x22, 0x7A6, 0x40 },
2586 { 0x22, 0x7A7, 0x00 },
2587 { 0x22, 0x7A8, 0x00 },
2588 { 0x22, 0x7A9, 0x40 },
2589 { 0x22, 0x7AA, 0x00 },
2590 { 0x22, 0x7AB, 0x00 },
2591 { 0x22, 0x7AC, 0x2E },
2592 { 0x22, 0x7AD, 0x80 },
2593 { 0x22, 0x7A6, 0x93 },
2594 { 0x22, 0x7A7, 0x5E },
2595 { 0x22, 0x7A8, 0xD8 },
2596 { 0x22, 0x7A9, 0x93 },
2597 { 0x22, 0x7AA, 0x5E },
2598 { 0x22, 0x7AB, 0xD8 },
2599 { 0x22, 0x7AC, 0x2F },
2600 { 0x22, 0x7AD, 0x80 },
2601 { 0x22, 0x7A6, 0x32 },
2602 { 0x22, 0x7A7, 0xB7 },
2603 { 0x22, 0x7A8, 0xB1 },
2604 { 0x22, 0x7A9, 0x32 },
2605 { 0x22, 0x7AA, 0xB7 },
2606 { 0x22, 0x7AB, 0xB1 },
2607 { 0x22, 0x7AC, 0x30 },
2608 { 0x22, 0x7AD, 0x80 },
2609 { 0x22, 0x7A6, 0x6C },
2610 { 0x22, 0x7A7, 0xA1 },
2611 { 0x22, 0x7A8, 0x28 },
2612 { 0x22, 0x7A9, 0x6C },
2613 { 0x22, 0x7AA, 0xA1 },
2614 { 0x22, 0x7AB, 0x28 },
2615 { 0x22, 0x7AC, 0x31 },
2616 { 0x22, 0x7AD, 0x80 },
2617 { 0x22, 0x7A6, 0xCD },
2618 { 0x22, 0x7A7, 0x48 },
2619 { 0x22, 0x7A8, 0x4F },
2620 { 0x22, 0x7A9, 0xCD },
2621 { 0x22, 0x7AA, 0x48 },
2622 { 0x22, 0x7AB, 0x4F },
2623 { 0x22, 0x7AC, 0x32 },
2624 { 0x22, 0x7AD, 0x80 },
2625 { 0x22, 0x7A6, 0x40 },
2626 { 0x22, 0x7A7, 0x00 },
2627 { 0x22, 0x7A8, 0x00 },
2628 { 0x22, 0x7A9, 0x40 },
2629 { 0x22, 0x7AA, 0x00 },
2630 { 0x22, 0x7AB, 0x00 },
2631 { 0x22, 0x7AC, 0x33 },
2632 { 0x22, 0x7AD, 0x80 },
2633 /* common */
2634 { 0x22, 0x782, 0xC1 },
2635 { 0x22, 0x771, 0x2C },
2636 { 0x22, 0x772, 0x2C },
2637 { 0x22, 0x788, 0x04 },
2638 { 0x01, 0x7B0, 0x08 },
2642 static const struct hda_fixup stac92hd83xxx_fixups[] = {
2643 [STAC_92HD83XXX_REF] = {
2644 .type = HDA_FIXUP_PINS,
2645 .v.pins = ref92hd83xxx_pin_configs,
2647 [STAC_92HD83XXX_PWR_REF] = {
2648 .type = HDA_FIXUP_PINS,
2649 .v.pins = ref92hd83xxx_pin_configs,
2651 [STAC_DELL_S14] = {
2652 .type = HDA_FIXUP_PINS,
2653 .v.pins = dell_s14_pin_configs,
2655 [STAC_DELL_VOSTRO_3500] = {
2656 .type = HDA_FIXUP_PINS,
2657 .v.pins = dell_vostro_3500_pin_configs,
2659 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = {
2660 .type = HDA_FIXUP_PINS,
2661 .v.pins = hp_cNB11_intquad_pin_configs,
2662 .chained = true,
2663 .chain_id = STAC_92HD83XXX_HP,
2665 [STAC_92HD83XXX_HP] = {
2666 .type = HDA_FIXUP_FUNC,
2667 .v.func = stac92hd83xxx_fixup_hp,
2669 [STAC_HP_DV7_4000] = {
2670 .type = HDA_FIXUP_PINS,
2671 .v.pins = hp_dv7_4000_pin_configs,
2672 .chained = true,
2673 .chain_id = STAC_92HD83XXX_HP,
2675 [STAC_HP_ZEPHYR] = {
2676 .type = HDA_FIXUP_FUNC,
2677 .v.func = stac92hd83xxx_fixup_hp_zephyr,
2678 .chained = true,
2679 .chain_id = STAC_92HD83XXX_HP,
2681 [STAC_92HD83XXX_HP_LED] = {
2682 .type = HDA_FIXUP_FUNC,
2683 .v.func = stac92hd83xxx_fixup_hp_led,
2684 .chained = true,
2685 .chain_id = STAC_92HD83XXX_HP,
2687 [STAC_92HD83XXX_HP_INV_LED] = {
2688 .type = HDA_FIXUP_FUNC,
2689 .v.func = stac92hd83xxx_fixup_hp_inv_led,
2690 .chained = true,
2691 .chain_id = STAC_92HD83XXX_HP,
2693 [STAC_92HD83XXX_HP_MIC_LED] = {
2694 .type = HDA_FIXUP_FUNC,
2695 .v.func = stac92hd83xxx_fixup_hp_mic_led,
2696 .chained = true,
2697 .chain_id = STAC_92HD83XXX_HP,
2699 [STAC_HP_LED_GPIO10] = {
2700 .type = HDA_FIXUP_FUNC,
2701 .v.func = stac92hd83xxx_fixup_hp_led_gpio10,
2702 .chained = true,
2703 .chain_id = STAC_92HD83XXX_HP,
2705 [STAC_92HD83XXX_HEADSET_JACK] = {
2706 .type = HDA_FIXUP_FUNC,
2707 .v.func = stac92hd83xxx_fixup_headset_jack,
2709 [STAC_HP_ENVY_BASS] = {
2710 .type = HDA_FIXUP_PINS,
2711 .v.pins = (const struct hda_pintbl[]) {
2712 { 0x0f, 0x90170111 },
2716 [STAC_HP_BNB13_EQ] = {
2717 .type = HDA_FIXUP_VERBS,
2718 .v.verbs = hp_bnb13_eq_verbs,
2719 .chained = true,
2720 .chain_id = STAC_92HD83XXX_HP_MIC_LED,
2722 [STAC_HP_ENVY_TS_BASS] = {
2723 .type = HDA_FIXUP_PINS,
2724 .v.pins = (const struct hda_pintbl[]) {
2725 { 0x10, 0x92170111 },
2729 [STAC_HP_ENVY_TS_DAC_BIND] = {
2730 .type = HDA_FIXUP_FUNC,
2731 .v.func = hp_envy_ts_fixup_dac_bind,
2732 .chained = true,
2733 .chain_id = STAC_HP_ENVY_TS_BASS,
2735 [STAC_92HD83XXX_GPIO10_EAPD] = {
2736 .type = HDA_FIXUP_FUNC,
2737 .v.func = stac92hd83xxx_fixup_gpio10_eapd,
2741 static const struct hda_model_fixup stac92hd83xxx_models[] = {
2742 { .id = STAC_92HD83XXX_REF, .name = "ref" },
2743 { .id = STAC_92HD83XXX_PWR_REF, .name = "mic-ref" },
2744 { .id = STAC_DELL_S14, .name = "dell-s14" },
2745 { .id = STAC_DELL_VOSTRO_3500, .name = "dell-vostro-3500" },
2746 { .id = STAC_92HD83XXX_HP_cNB11_INTQUAD, .name = "hp_cNB11_intquad" },
2747 { .id = STAC_HP_DV7_4000, .name = "hp-dv7-4000" },
2748 { .id = STAC_HP_ZEPHYR, .name = "hp-zephyr" },
2749 { .id = STAC_92HD83XXX_HP_LED, .name = "hp-led" },
2750 { .id = STAC_92HD83XXX_HP_INV_LED, .name = "hp-inv-led" },
2751 { .id = STAC_92HD83XXX_HP_MIC_LED, .name = "hp-mic-led" },
2752 { .id = STAC_92HD83XXX_HEADSET_JACK, .name = "headset-jack" },
2753 { .id = STAC_HP_ENVY_BASS, .name = "hp-envy-bass" },
2754 { .id = STAC_HP_BNB13_EQ, .name = "hp-bnb13-eq" },
2755 { .id = STAC_HP_ENVY_TS_BASS, .name = "hp-envy-ts-bass" },
2759 static const struct snd_pci_quirk stac92hd83xxx_fixup_tbl[] = {
2760 /* SigmaTel reference board */
2761 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2762 "DFI LanParty", STAC_92HD83XXX_REF),
2763 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
2764 "DFI LanParty", STAC_92HD83XXX_REF),
2765 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
2766 "unknown Dell", STAC_DELL_S14),
2767 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0532,
2768 "Dell Latitude E6230", STAC_92HD83XXX_HEADSET_JACK),
2769 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0533,
2770 "Dell Latitude E6330", STAC_92HD83XXX_HEADSET_JACK),
2771 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0534,
2772 "Dell Latitude E6430", STAC_92HD83XXX_HEADSET_JACK),
2773 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0535,
2774 "Dell Latitude E6530", STAC_92HD83XXX_HEADSET_JACK),
2775 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053c,
2776 "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
2777 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053d,
2778 "Dell Latitude E5530", STAC_92HD83XXX_HEADSET_JACK),
2779 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0549,
2780 "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
2781 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x057d,
2782 "Dell Latitude E6430s", STAC_92HD83XXX_HEADSET_JACK),
2783 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0584,
2784 "Dell Latitude E6430U", STAC_92HD83XXX_HEADSET_JACK),
2785 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028,
2786 "Dell Vostro 3500", STAC_DELL_VOSTRO_3500),
2787 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
2788 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2789 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657,
2790 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2791 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658,
2792 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2793 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659,
2794 "HP Pavilion dv7", STAC_HP_DV7_4000),
2795 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A,
2796 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2797 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
2798 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2799 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1888,
2800 "HP Envy Spectre", STAC_HP_ENVY_BASS),
2801 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1899,
2802 "HP Folio 13", STAC_HP_LED_GPIO10),
2803 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df,
2804 "HP Folio", STAC_HP_BNB13_EQ),
2805 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18F8,
2806 "HP bNB13", STAC_HP_BNB13_EQ),
2807 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1909,
2808 "HP bNB13", STAC_HP_BNB13_EQ),
2809 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x190A,
2810 "HP bNB13", STAC_HP_BNB13_EQ),
2811 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x190e,
2812 "HP ENVY TS", STAC_HP_ENVY_TS_BASS),
2813 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1967,
2814 "HP ENVY TS", STAC_HP_ENVY_TS_DAC_BIND),
2815 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1940,
2816 "HP bNB13", STAC_HP_BNB13_EQ),
2817 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1941,
2818 "HP bNB13", STAC_HP_BNB13_EQ),
2819 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1942,
2820 "HP bNB13", STAC_HP_BNB13_EQ),
2821 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1943,
2822 "HP bNB13", STAC_HP_BNB13_EQ),
2823 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1944,
2824 "HP bNB13", STAC_HP_BNB13_EQ),
2825 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1945,
2826 "HP bNB13", STAC_HP_BNB13_EQ),
2827 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1946,
2828 "HP bNB13", STAC_HP_BNB13_EQ),
2829 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1948,
2830 "HP bNB13", STAC_HP_BNB13_EQ),
2831 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1949,
2832 "HP bNB13", STAC_HP_BNB13_EQ),
2833 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194A,
2834 "HP bNB13", STAC_HP_BNB13_EQ),
2835 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194B,
2836 "HP bNB13", STAC_HP_BNB13_EQ),
2837 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194C,
2838 "HP bNB13", STAC_HP_BNB13_EQ),
2839 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194E,
2840 "HP bNB13", STAC_HP_BNB13_EQ),
2841 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194F,
2842 "HP bNB13", STAC_HP_BNB13_EQ),
2843 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1950,
2844 "HP bNB13", STAC_HP_BNB13_EQ),
2845 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1951,
2846 "HP bNB13", STAC_HP_BNB13_EQ),
2847 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x195A,
2848 "HP bNB13", STAC_HP_BNB13_EQ),
2849 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x195B,
2850 "HP bNB13", STAC_HP_BNB13_EQ),
2851 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x195C,
2852 "HP bNB13", STAC_HP_BNB13_EQ),
2853 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1991,
2854 "HP bNB13", STAC_HP_BNB13_EQ),
2855 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2103,
2856 "HP bNB13", STAC_HP_BNB13_EQ),
2857 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2104,
2858 "HP bNB13", STAC_HP_BNB13_EQ),
2859 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2105,
2860 "HP bNB13", STAC_HP_BNB13_EQ),
2861 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2106,
2862 "HP bNB13", STAC_HP_BNB13_EQ),
2863 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2107,
2864 "HP bNB13", STAC_HP_BNB13_EQ),
2865 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2108,
2866 "HP bNB13", STAC_HP_BNB13_EQ),
2867 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2109,
2868 "HP bNB13", STAC_HP_BNB13_EQ),
2869 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x210A,
2870 "HP bNB13", STAC_HP_BNB13_EQ),
2871 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x210B,
2872 "HP bNB13", STAC_HP_BNB13_EQ),
2873 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211C,
2874 "HP bNB13", STAC_HP_BNB13_EQ),
2875 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211D,
2876 "HP bNB13", STAC_HP_BNB13_EQ),
2877 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211E,
2878 "HP bNB13", STAC_HP_BNB13_EQ),
2879 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211F,
2880 "HP bNB13", STAC_HP_BNB13_EQ),
2881 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2120,
2882 "HP bNB13", STAC_HP_BNB13_EQ),
2883 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2121,
2884 "HP bNB13", STAC_HP_BNB13_EQ),
2885 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2122,
2886 "HP bNB13", STAC_HP_BNB13_EQ),
2887 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2123,
2888 "HP bNB13", STAC_HP_BNB13_EQ),
2889 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x213E,
2890 "HP bNB13", STAC_HP_BNB13_EQ),
2891 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x213F,
2892 "HP bNB13", STAC_HP_BNB13_EQ),
2893 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2140,
2894 "HP bNB13", STAC_HP_BNB13_EQ),
2895 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B2,
2896 "HP bNB13", STAC_HP_BNB13_EQ),
2897 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B3,
2898 "HP bNB13", STAC_HP_BNB13_EQ),
2899 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B5,
2900 "HP bNB13", STAC_HP_BNB13_EQ),
2901 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B6,
2902 "HP bNB13", STAC_HP_BNB13_EQ),
2903 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x1900,
2904 "HP", STAC_92HD83XXX_HP_MIC_LED),
2905 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x2000,
2906 "HP", STAC_92HD83XXX_HP_MIC_LED),
2907 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x2100,
2908 "HP", STAC_92HD83XXX_HP_MIC_LED),
2909 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388,
2910 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2911 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389,
2912 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2913 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355B,
2914 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2915 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355C,
2916 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2917 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355D,
2918 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2919 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355E,
2920 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2921 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355F,
2922 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2923 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3560,
2924 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2925 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358B,
2926 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2927 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358C,
2928 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2929 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358D,
2930 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2931 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3591,
2932 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2933 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3592,
2934 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2935 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
2936 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2937 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
2938 "HP", STAC_HP_ZEPHYR),
2939 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3660,
2940 "HP Mini", STAC_92HD83XXX_HP_LED),
2941 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x144E,
2942 "HP Pavilion dv5", STAC_92HD83XXX_HP_INV_LED),
2943 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x148a,
2944 "HP Mini", STAC_92HD83XXX_HP_LED),
2945 SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_HP, "HP", STAC_92HD83XXX_HP),
2946 /* match both for 0xfa91 and 0xfa93 */
2947 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_TOSHIBA, 0xfffd, 0xfa91,
2948 "Toshiba Satellite S50D", STAC_92HD83XXX_GPIO10_EAPD),
2949 {} /* terminator */
2952 /* HP dv7 bass switch - GPIO5 */
2953 #define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info
2954 static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol,
2955 struct snd_ctl_elem_value *ucontrol)
2957 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2958 struct sigmatel_spec *spec = codec->spec;
2959 ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20);
2960 return 0;
2963 static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol,
2964 struct snd_ctl_elem_value *ucontrol)
2966 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2967 struct sigmatel_spec *spec = codec->spec;
2968 unsigned int gpio_data;
2970 gpio_data = (spec->gpio_data & ~0x20) |
2971 (ucontrol->value.integer.value[0] ? 0x20 : 0);
2972 if (gpio_data == spec->gpio_data)
2973 return 0;
2974 spec->gpio_data = gpio_data;
2975 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
2976 return 1;
2979 static const struct snd_kcontrol_new stac_hp_bass_sw_ctrl = {
2980 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2981 .info = stac_hp_bass_gpio_info,
2982 .get = stac_hp_bass_gpio_get,
2983 .put = stac_hp_bass_gpio_put,
2986 static int stac_add_hp_bass_switch(struct hda_codec *codec)
2988 struct sigmatel_spec *spec = codec->spec;
2990 if (!snd_hda_gen_add_kctl(&spec->gen, "Bass Speaker Playback Switch",
2991 &stac_hp_bass_sw_ctrl))
2992 return -ENOMEM;
2994 spec->gpio_mask |= 0x20;
2995 spec->gpio_dir |= 0x20;
2996 spec->gpio_data |= 0x20;
2997 return 0;
3000 static const struct hda_pintbl ref92hd71bxx_pin_configs[] = {
3001 { 0x0a, 0x02214030 },
3002 { 0x0b, 0x02a19040 },
3003 { 0x0c, 0x01a19020 },
3004 { 0x0d, 0x01014010 },
3005 { 0x0e, 0x0181302e },
3006 { 0x0f, 0x01014010 },
3007 { 0x14, 0x01019020 },
3008 { 0x18, 0x90a000f0 },
3009 { 0x19, 0x90a000f0 },
3010 { 0x1e, 0x01452050 },
3011 { 0x1f, 0x01452050 },
3015 static const struct hda_pintbl dell_m4_1_pin_configs[] = {
3016 { 0x0a, 0x0421101f },
3017 { 0x0b, 0x04a11221 },
3018 { 0x0c, 0x40f000f0 },
3019 { 0x0d, 0x90170110 },
3020 { 0x0e, 0x23a1902e },
3021 { 0x0f, 0x23014250 },
3022 { 0x14, 0x40f000f0 },
3023 { 0x18, 0x90a000f0 },
3024 { 0x19, 0x40f000f0 },
3025 { 0x1e, 0x4f0000f0 },
3026 { 0x1f, 0x4f0000f0 },
3030 static const struct hda_pintbl dell_m4_2_pin_configs[] = {
3031 { 0x0a, 0x0421101f },
3032 { 0x0b, 0x04a11221 },
3033 { 0x0c, 0x90a70330 },
3034 { 0x0d, 0x90170110 },
3035 { 0x0e, 0x23a1902e },
3036 { 0x0f, 0x23014250 },
3037 { 0x14, 0x40f000f0 },
3038 { 0x18, 0x40f000f0 },
3039 { 0x19, 0x40f000f0 },
3040 { 0x1e, 0x044413b0 },
3041 { 0x1f, 0x044413b0 },
3045 static const struct hda_pintbl dell_m4_3_pin_configs[] = {
3046 { 0x0a, 0x0421101f },
3047 { 0x0b, 0x04a11221 },
3048 { 0x0c, 0x90a70330 },
3049 { 0x0d, 0x90170110 },
3050 { 0x0e, 0x40f000f0 },
3051 { 0x0f, 0x40f000f0 },
3052 { 0x14, 0x40f000f0 },
3053 { 0x18, 0x90a000f0 },
3054 { 0x19, 0x40f000f0 },
3055 { 0x1e, 0x044413b0 },
3056 { 0x1f, 0x044413b0 },
3060 static void stac92hd71bxx_fixup_ref(struct hda_codec *codec,
3061 const struct hda_fixup *fix, int action)
3063 struct sigmatel_spec *spec = codec->spec;
3065 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3066 return;
3068 snd_hda_apply_pincfgs(codec, ref92hd71bxx_pin_configs);
3069 spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0;
3072 static void stac92hd71bxx_fixup_hp_m4(struct hda_codec *codec,
3073 const struct hda_fixup *fix, int action)
3075 struct sigmatel_spec *spec = codec->spec;
3076 struct hda_jack_callback *jack;
3078 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3079 return;
3081 /* Enable VREF power saving on GPIO1 detect */
3082 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
3083 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
3084 jack = snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
3085 stac_vref_event);
3086 if (!IS_ERR(jack))
3087 jack->private_data = 0x02;
3089 spec->gpio_mask |= 0x02;
3091 /* enable internal microphone */
3092 snd_hda_codec_set_pincfg(codec, 0x0e, 0x01813040);
3095 static void stac92hd71bxx_fixup_hp_dv4(struct hda_codec *codec,
3096 const struct hda_fixup *fix, int action)
3098 struct sigmatel_spec *spec = codec->spec;
3100 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3101 return;
3102 spec->gpio_led = 0x01;
3105 static void stac92hd71bxx_fixup_hp_dv5(struct hda_codec *codec,
3106 const struct hda_fixup *fix, int action)
3108 unsigned int cap;
3110 switch (action) {
3111 case HDA_FIXUP_ACT_PRE_PROBE:
3112 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
3113 break;
3115 case HDA_FIXUP_ACT_PROBE:
3116 /* enable bass on HP dv7 */
3117 cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
3118 cap &= AC_GPIO_IO_COUNT;
3119 if (cap >= 6)
3120 stac_add_hp_bass_switch(codec);
3121 break;
3125 static void stac92hd71bxx_fixup_hp_hdx(struct hda_codec *codec,
3126 const struct hda_fixup *fix, int action)
3128 struct sigmatel_spec *spec = codec->spec;
3130 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3131 return;
3132 spec->gpio_led = 0x08;
3135 static bool is_hp_output(struct hda_codec *codec, hda_nid_t pin)
3137 unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, pin);
3139 /* count line-out, too, as BIOS sets often so */
3140 return get_defcfg_connect(pin_cfg) != AC_JACK_PORT_NONE &&
3141 (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT ||
3142 get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT);
3145 static void fixup_hp_headphone(struct hda_codec *codec, hda_nid_t pin)
3147 unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, pin);
3149 /* It was changed in the BIOS to just satisfy MS DTM.
3150 * Lets turn it back into slaved HP
3152 pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE)) |
3153 (AC_JACK_HP_OUT << AC_DEFCFG_DEVICE_SHIFT);
3154 pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC | AC_DEFCFG_SEQUENCE))) |
3155 0x1f;
3156 snd_hda_codec_set_pincfg(codec, pin, pin_cfg);
3159 static void stac92hd71bxx_fixup_hp(struct hda_codec *codec,
3160 const struct hda_fixup *fix, int action)
3162 struct sigmatel_spec *spec = codec->spec;
3164 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3165 return;
3167 /* when both output A and F are assigned, these are supposedly
3168 * dock and built-in headphones; fix both pin configs
3170 if (is_hp_output(codec, 0x0a) && is_hp_output(codec, 0x0f)) {
3171 fixup_hp_headphone(codec, 0x0a);
3172 fixup_hp_headphone(codec, 0x0f);
3175 if (find_mute_led_cfg(codec, 1))
3176 codec_dbg(codec, "mute LED gpio %d polarity %d\n",
3177 spec->gpio_led,
3178 spec->gpio_led_polarity);
3182 static const struct hda_fixup stac92hd71bxx_fixups[] = {
3183 [STAC_92HD71BXX_REF] = {
3184 .type = HDA_FIXUP_FUNC,
3185 .v.func = stac92hd71bxx_fixup_ref,
3187 [STAC_DELL_M4_1] = {
3188 .type = HDA_FIXUP_PINS,
3189 .v.pins = dell_m4_1_pin_configs,
3191 [STAC_DELL_M4_2] = {
3192 .type = HDA_FIXUP_PINS,
3193 .v.pins = dell_m4_2_pin_configs,
3195 [STAC_DELL_M4_3] = {
3196 .type = HDA_FIXUP_PINS,
3197 .v.pins = dell_m4_3_pin_configs,
3199 [STAC_HP_M4] = {
3200 .type = HDA_FIXUP_FUNC,
3201 .v.func = stac92hd71bxx_fixup_hp_m4,
3202 .chained = true,
3203 .chain_id = STAC_92HD71BXX_HP,
3205 [STAC_HP_DV4] = {
3206 .type = HDA_FIXUP_FUNC,
3207 .v.func = stac92hd71bxx_fixup_hp_dv4,
3208 .chained = true,
3209 .chain_id = STAC_HP_DV5,
3211 [STAC_HP_DV5] = {
3212 .type = HDA_FIXUP_FUNC,
3213 .v.func = stac92hd71bxx_fixup_hp_dv5,
3214 .chained = true,
3215 .chain_id = STAC_92HD71BXX_HP,
3217 [STAC_HP_HDX] = {
3218 .type = HDA_FIXUP_FUNC,
3219 .v.func = stac92hd71bxx_fixup_hp_hdx,
3220 .chained = true,
3221 .chain_id = STAC_92HD71BXX_HP,
3223 [STAC_92HD71BXX_HP] = {
3224 .type = HDA_FIXUP_FUNC,
3225 .v.func = stac92hd71bxx_fixup_hp,
3229 static const struct hda_model_fixup stac92hd71bxx_models[] = {
3230 { .id = STAC_92HD71BXX_REF, .name = "ref" },
3231 { .id = STAC_DELL_M4_1, .name = "dell-m4-1" },
3232 { .id = STAC_DELL_M4_2, .name = "dell-m4-2" },
3233 { .id = STAC_DELL_M4_3, .name = "dell-m4-3" },
3234 { .id = STAC_HP_M4, .name = "hp-m4" },
3235 { .id = STAC_HP_DV4, .name = "hp-dv4" },
3236 { .id = STAC_HP_DV5, .name = "hp-dv5" },
3237 { .id = STAC_HP_HDX, .name = "hp-hdx" },
3238 { .id = STAC_HP_DV4, .name = "hp-dv4-1222nr" },
3242 static const struct snd_pci_quirk stac92hd71bxx_fixup_tbl[] = {
3243 /* SigmaTel reference board */
3244 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3245 "DFI LanParty", STAC_92HD71BXX_REF),
3246 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3247 "DFI LanParty", STAC_92HD71BXX_REF),
3248 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720,
3249 "HP", STAC_HP_DV5),
3250 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
3251 "HP", STAC_HP_DV5),
3252 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
3253 "HP dv4-7", STAC_HP_DV4),
3254 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600,
3255 "HP dv4-7", STAC_HP_DV5),
3256 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610,
3257 "HP HDX", STAC_HP_HDX), /* HDX18 */
3258 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
3259 "HP mini 1000", STAC_HP_M4),
3260 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b,
3261 "HP HDX", STAC_HP_HDX), /* HDX16 */
3262 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620,
3263 "HP dv6", STAC_HP_DV5),
3264 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061,
3265 "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */
3266 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x363e,
3267 "HP DV6", STAC_HP_DV5),
3268 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010,
3269 "HP", STAC_HP_DV5),
3270 SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_HP, "HP", STAC_92HD71BXX_HP),
3271 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
3272 "unknown Dell", STAC_DELL_M4_1),
3273 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234,
3274 "unknown Dell", STAC_DELL_M4_1),
3275 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0250,
3276 "unknown Dell", STAC_DELL_M4_1),
3277 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024f,
3278 "unknown Dell", STAC_DELL_M4_1),
3279 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024d,
3280 "unknown Dell", STAC_DELL_M4_1),
3281 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0251,
3282 "unknown Dell", STAC_DELL_M4_1),
3283 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0277,
3284 "unknown Dell", STAC_DELL_M4_1),
3285 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0263,
3286 "unknown Dell", STAC_DELL_M4_2),
3287 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0265,
3288 "unknown Dell", STAC_DELL_M4_2),
3289 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0262,
3290 "unknown Dell", STAC_DELL_M4_2),
3291 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264,
3292 "unknown Dell", STAC_DELL_M4_2),
3293 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02aa,
3294 "unknown Dell", STAC_DELL_M4_3),
3295 {} /* terminator */
3298 static const struct hda_pintbl ref922x_pin_configs[] = {
3299 { 0x0a, 0x01014010 },
3300 { 0x0b, 0x01016011 },
3301 { 0x0c, 0x01012012 },
3302 { 0x0d, 0x0221401f },
3303 { 0x0e, 0x01813122 },
3304 { 0x0f, 0x01011014 },
3305 { 0x10, 0x01441030 },
3306 { 0x11, 0x01c41030 },
3307 { 0x15, 0x40000100 },
3308 { 0x1b, 0x40000100 },
3313 STAC 922X pin configs for
3314 102801A7
3315 102801AB
3316 102801A9
3317 102801D1
3318 102801D2
3320 static const struct hda_pintbl dell_922x_d81_pin_configs[] = {
3321 { 0x0a, 0x02214030 },
3322 { 0x0b, 0x01a19021 },
3323 { 0x0c, 0x01111012 },
3324 { 0x0d, 0x01114010 },
3325 { 0x0e, 0x02a19020 },
3326 { 0x0f, 0x01117011 },
3327 { 0x10, 0x400001f0 },
3328 { 0x11, 0x400001f1 },
3329 { 0x15, 0x01813122 },
3330 { 0x1b, 0x400001f2 },
3335 STAC 922X pin configs for
3336 102801AC
3337 102801D0
3339 static const struct hda_pintbl dell_922x_d82_pin_configs[] = {
3340 { 0x0a, 0x02214030 },
3341 { 0x0b, 0x01a19021 },
3342 { 0x0c, 0x01111012 },
3343 { 0x0d, 0x01114010 },
3344 { 0x0e, 0x02a19020 },
3345 { 0x0f, 0x01117011 },
3346 { 0x10, 0x01451140 },
3347 { 0x11, 0x400001f0 },
3348 { 0x15, 0x01813122 },
3349 { 0x1b, 0x400001f1 },
3354 STAC 922X pin configs for
3355 102801BF
3357 static const struct hda_pintbl dell_922x_m81_pin_configs[] = {
3358 { 0x0a, 0x0321101f },
3359 { 0x0b, 0x01112024 },
3360 { 0x0c, 0x01111222 },
3361 { 0x0d, 0x91174220 },
3362 { 0x0e, 0x03a11050 },
3363 { 0x0f, 0x01116221 },
3364 { 0x10, 0x90a70330 },
3365 { 0x11, 0x01452340 },
3366 { 0x15, 0x40C003f1 },
3367 { 0x1b, 0x405003f0 },
3372 STAC 9221 A1 pin configs for
3373 102801D7 (Dell XPS M1210)
3375 static const struct hda_pintbl dell_922x_m82_pin_configs[] = {
3376 { 0x0a, 0x02211211 },
3377 { 0x0b, 0x408103ff },
3378 { 0x0c, 0x02a1123e },
3379 { 0x0d, 0x90100310 },
3380 { 0x0e, 0x408003f1 },
3381 { 0x0f, 0x0221121f },
3382 { 0x10, 0x03451340 },
3383 { 0x11, 0x40c003f2 },
3384 { 0x15, 0x508003f3 },
3385 { 0x1b, 0x405003f4 },
3389 static const struct hda_pintbl d945gtp3_pin_configs[] = {
3390 { 0x0a, 0x0221401f },
3391 { 0x0b, 0x01a19022 },
3392 { 0x0c, 0x01813021 },
3393 { 0x0d, 0x01014010 },
3394 { 0x0e, 0x40000100 },
3395 { 0x0f, 0x40000100 },
3396 { 0x10, 0x40000100 },
3397 { 0x11, 0x40000100 },
3398 { 0x15, 0x02a19120 },
3399 { 0x1b, 0x40000100 },
3403 static const struct hda_pintbl d945gtp5_pin_configs[] = {
3404 { 0x0a, 0x0221401f },
3405 { 0x0b, 0x01011012 },
3406 { 0x0c, 0x01813024 },
3407 { 0x0d, 0x01014010 },
3408 { 0x0e, 0x01a19021 },
3409 { 0x0f, 0x01016011 },
3410 { 0x10, 0x01452130 },
3411 { 0x11, 0x40000100 },
3412 { 0x15, 0x02a19320 },
3413 { 0x1b, 0x40000100 },
3417 static const struct hda_pintbl intel_mac_v1_pin_configs[] = {
3418 { 0x0a, 0x0121e21f },
3419 { 0x0b, 0x400000ff },
3420 { 0x0c, 0x9017e110 },
3421 { 0x0d, 0x400000fd },
3422 { 0x0e, 0x400000fe },
3423 { 0x0f, 0x0181e020 },
3424 { 0x10, 0x1145e030 },
3425 { 0x11, 0x11c5e240 },
3426 { 0x15, 0x400000fc },
3427 { 0x1b, 0x400000fb },
3431 static const struct hda_pintbl intel_mac_v2_pin_configs[] = {
3432 { 0x0a, 0x0121e21f },
3433 { 0x0b, 0x90a7012e },
3434 { 0x0c, 0x9017e110 },
3435 { 0x0d, 0x400000fd },
3436 { 0x0e, 0x400000fe },
3437 { 0x0f, 0x0181e020 },
3438 { 0x10, 0x1145e230 },
3439 { 0x11, 0x500000fa },
3440 { 0x15, 0x400000fc },
3441 { 0x1b, 0x400000fb },
3445 static const struct hda_pintbl intel_mac_v3_pin_configs[] = {
3446 { 0x0a, 0x0121e21f },
3447 { 0x0b, 0x90a7012e },
3448 { 0x0c, 0x9017e110 },
3449 { 0x0d, 0x400000fd },
3450 { 0x0e, 0x400000fe },
3451 { 0x0f, 0x0181e020 },
3452 { 0x10, 0x1145e230 },
3453 { 0x11, 0x11c5e240 },
3454 { 0x15, 0x400000fc },
3455 { 0x1b, 0x400000fb },
3459 static const struct hda_pintbl intel_mac_v4_pin_configs[] = {
3460 { 0x0a, 0x0321e21f },
3461 { 0x0b, 0x03a1e02e },
3462 { 0x0c, 0x9017e110 },
3463 { 0x0d, 0x9017e11f },
3464 { 0x0e, 0x400000fe },
3465 { 0x0f, 0x0381e020 },
3466 { 0x10, 0x1345e230 },
3467 { 0x11, 0x13c5e240 },
3468 { 0x15, 0x400000fc },
3469 { 0x1b, 0x400000fb },
3473 static const struct hda_pintbl intel_mac_v5_pin_configs[] = {
3474 { 0x0a, 0x0321e21f },
3475 { 0x0b, 0x03a1e02e },
3476 { 0x0c, 0x9017e110 },
3477 { 0x0d, 0x9017e11f },
3478 { 0x0e, 0x400000fe },
3479 { 0x0f, 0x0381e020 },
3480 { 0x10, 0x1345e230 },
3481 { 0x11, 0x13c5e240 },
3482 { 0x15, 0x400000fc },
3483 { 0x1b, 0x400000fb },
3487 static const struct hda_pintbl ecs202_pin_configs[] = {
3488 { 0x0a, 0x0221401f },
3489 { 0x0b, 0x02a19020 },
3490 { 0x0c, 0x01a19020 },
3491 { 0x0d, 0x01114010 },
3492 { 0x0e, 0x408000f0 },
3493 { 0x0f, 0x01813022 },
3494 { 0x10, 0x074510a0 },
3495 { 0x11, 0x40c400f1 },
3496 { 0x15, 0x9037012e },
3497 { 0x1b, 0x40e000f2 },
3501 /* codec SSIDs for Intel Mac sharing the same PCI SSID 8384:7680 */
3502 static const struct snd_pci_quirk stac922x_intel_mac_fixup_tbl[] = {
3503 SND_PCI_QUIRK(0x0000, 0x0100, "Mac Mini", STAC_INTEL_MAC_V3),
3504 SND_PCI_QUIRK(0x106b, 0x0800, "Mac", STAC_INTEL_MAC_V1),
3505 SND_PCI_QUIRK(0x106b, 0x0600, "Mac", STAC_INTEL_MAC_V2),
3506 SND_PCI_QUIRK(0x106b, 0x0700, "Mac", STAC_INTEL_MAC_V2),
3507 SND_PCI_QUIRK(0x106b, 0x0e00, "Mac", STAC_INTEL_MAC_V3),
3508 SND_PCI_QUIRK(0x106b, 0x0f00, "Mac", STAC_INTEL_MAC_V3),
3509 SND_PCI_QUIRK(0x106b, 0x1600, "Mac", STAC_INTEL_MAC_V3),
3510 SND_PCI_QUIRK(0x106b, 0x1700, "Mac", STAC_INTEL_MAC_V3),
3511 SND_PCI_QUIRK(0x106b, 0x0200, "Mac", STAC_INTEL_MAC_V3),
3512 SND_PCI_QUIRK(0x106b, 0x1e00, "Mac", STAC_INTEL_MAC_V3),
3513 SND_PCI_QUIRK(0x106b, 0x1a00, "Mac", STAC_INTEL_MAC_V4),
3514 SND_PCI_QUIRK(0x106b, 0x0a00, "Mac", STAC_INTEL_MAC_V5),
3515 SND_PCI_QUIRK(0x106b, 0x2200, "Mac", STAC_INTEL_MAC_V5),
3519 static const struct hda_fixup stac922x_fixups[];
3521 /* remap the fixup from codec SSID and apply it */
3522 static void stac922x_fixup_intel_mac_auto(struct hda_codec *codec,
3523 const struct hda_fixup *fix,
3524 int action)
3526 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3527 return;
3529 codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
3530 snd_hda_pick_fixup(codec, NULL, stac922x_intel_mac_fixup_tbl,
3531 stac922x_fixups);
3532 if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET)
3533 snd_hda_apply_fixup(codec, action);
3536 static void stac922x_fixup_intel_mac_gpio(struct hda_codec *codec,
3537 const struct hda_fixup *fix,
3538 int action)
3540 struct sigmatel_spec *spec = codec->spec;
3542 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3543 spec->gpio_mask = spec->gpio_dir = 0x03;
3544 spec->gpio_data = 0x03;
3548 static const struct hda_fixup stac922x_fixups[] = {
3549 [STAC_D945_REF] = {
3550 .type = HDA_FIXUP_PINS,
3551 .v.pins = ref922x_pin_configs,
3553 [STAC_D945GTP3] = {
3554 .type = HDA_FIXUP_PINS,
3555 .v.pins = d945gtp3_pin_configs,
3557 [STAC_D945GTP5] = {
3558 .type = HDA_FIXUP_PINS,
3559 .v.pins = d945gtp5_pin_configs,
3561 [STAC_INTEL_MAC_AUTO] = {
3562 .type = HDA_FIXUP_FUNC,
3563 .v.func = stac922x_fixup_intel_mac_auto,
3565 [STAC_INTEL_MAC_V1] = {
3566 .type = HDA_FIXUP_PINS,
3567 .v.pins = intel_mac_v1_pin_configs,
3568 .chained = true,
3569 .chain_id = STAC_922X_INTEL_MAC_GPIO,
3571 [STAC_INTEL_MAC_V2] = {
3572 .type = HDA_FIXUP_PINS,
3573 .v.pins = intel_mac_v2_pin_configs,
3574 .chained = true,
3575 .chain_id = STAC_922X_INTEL_MAC_GPIO,
3577 [STAC_INTEL_MAC_V3] = {
3578 .type = HDA_FIXUP_PINS,
3579 .v.pins = intel_mac_v3_pin_configs,
3580 .chained = true,
3581 .chain_id = STAC_922X_INTEL_MAC_GPIO,
3583 [STAC_INTEL_MAC_V4] = {
3584 .type = HDA_FIXUP_PINS,
3585 .v.pins = intel_mac_v4_pin_configs,
3586 .chained = true,
3587 .chain_id = STAC_922X_INTEL_MAC_GPIO,
3589 [STAC_INTEL_MAC_V5] = {
3590 .type = HDA_FIXUP_PINS,
3591 .v.pins = intel_mac_v5_pin_configs,
3592 .chained = true,
3593 .chain_id = STAC_922X_INTEL_MAC_GPIO,
3595 [STAC_922X_INTEL_MAC_GPIO] = {
3596 .type = HDA_FIXUP_FUNC,
3597 .v.func = stac922x_fixup_intel_mac_gpio,
3599 [STAC_ECS_202] = {
3600 .type = HDA_FIXUP_PINS,
3601 .v.pins = ecs202_pin_configs,
3603 [STAC_922X_DELL_D81] = {
3604 .type = HDA_FIXUP_PINS,
3605 .v.pins = dell_922x_d81_pin_configs,
3607 [STAC_922X_DELL_D82] = {
3608 .type = HDA_FIXUP_PINS,
3609 .v.pins = dell_922x_d82_pin_configs,
3611 [STAC_922X_DELL_M81] = {
3612 .type = HDA_FIXUP_PINS,
3613 .v.pins = dell_922x_m81_pin_configs,
3615 [STAC_922X_DELL_M82] = {
3616 .type = HDA_FIXUP_PINS,
3617 .v.pins = dell_922x_m82_pin_configs,
3621 static const struct hda_model_fixup stac922x_models[] = {
3622 { .id = STAC_D945_REF, .name = "ref" },
3623 { .id = STAC_D945GTP5, .name = "5stack" },
3624 { .id = STAC_D945GTP3, .name = "3stack" },
3625 { .id = STAC_INTEL_MAC_V1, .name = "intel-mac-v1" },
3626 { .id = STAC_INTEL_MAC_V2, .name = "intel-mac-v2" },
3627 { .id = STAC_INTEL_MAC_V3, .name = "intel-mac-v3" },
3628 { .id = STAC_INTEL_MAC_V4, .name = "intel-mac-v4" },
3629 { .id = STAC_INTEL_MAC_V5, .name = "intel-mac-v5" },
3630 { .id = STAC_INTEL_MAC_AUTO, .name = "intel-mac-auto" },
3631 { .id = STAC_ECS_202, .name = "ecs202" },
3632 { .id = STAC_922X_DELL_D81, .name = "dell-d81" },
3633 { .id = STAC_922X_DELL_D82, .name = "dell-d82" },
3634 { .id = STAC_922X_DELL_M81, .name = "dell-m81" },
3635 { .id = STAC_922X_DELL_M82, .name = "dell-m82" },
3636 /* for backward compatibility */
3637 { .id = STAC_INTEL_MAC_V3, .name = "macmini" },
3638 { .id = STAC_INTEL_MAC_V5, .name = "macbook" },
3639 { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro-v1" },
3640 { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro" },
3641 { .id = STAC_INTEL_MAC_V2, .name = "imac-intel" },
3642 { .id = STAC_INTEL_MAC_V3, .name = "imac-intel-20" },
3646 static const struct snd_pci_quirk stac922x_fixup_tbl[] = {
3647 /* SigmaTel reference board */
3648 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3649 "DFI LanParty", STAC_D945_REF),
3650 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3651 "DFI LanParty", STAC_D945_REF),
3652 /* Intel 945G based systems */
3653 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
3654 "Intel D945G", STAC_D945GTP3),
3655 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
3656 "Intel D945G", STAC_D945GTP3),
3657 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
3658 "Intel D945G", STAC_D945GTP3),
3659 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
3660 "Intel D945G", STAC_D945GTP3),
3661 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
3662 "Intel D945G", STAC_D945GTP3),
3663 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
3664 "Intel D945G", STAC_D945GTP3),
3665 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
3666 "Intel D945G", STAC_D945GTP3),
3667 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
3668 "Intel D945G", STAC_D945GTP3),
3669 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
3670 "Intel D945G", STAC_D945GTP3),
3671 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
3672 "Intel D945G", STAC_D945GTP3),
3673 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
3674 "Intel D945G", STAC_D945GTP3),
3675 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
3676 "Intel D945G", STAC_D945GTP3),
3677 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
3678 "Intel D945G", STAC_D945GTP3),
3679 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
3680 "Intel D945G", STAC_D945GTP3),
3681 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
3682 "Intel D945G", STAC_D945GTP3),
3683 /* Intel D945G 5-stack systems */
3684 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
3685 "Intel D945G", STAC_D945GTP5),
3686 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
3687 "Intel D945G", STAC_D945GTP5),
3688 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
3689 "Intel D945G", STAC_D945GTP5),
3690 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
3691 "Intel D945G", STAC_D945GTP5),
3692 /* Intel 945P based systems */
3693 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
3694 "Intel D945P", STAC_D945GTP3),
3695 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
3696 "Intel D945P", STAC_D945GTP3),
3697 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
3698 "Intel D945P", STAC_D945GTP3),
3699 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
3700 "Intel D945P", STAC_D945GTP3),
3701 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
3702 "Intel D945P", STAC_D945GTP3),
3703 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
3704 "Intel D945P", STAC_D945GTP5),
3705 /* other intel */
3706 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0204,
3707 "Intel D945", STAC_D945_REF),
3708 /* other systems */
3710 /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */
3711 SND_PCI_QUIRK(0x8384, 0x7680, "Mac", STAC_INTEL_MAC_AUTO),
3713 /* Dell systems */
3714 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
3715 "unknown Dell", STAC_922X_DELL_D81),
3716 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
3717 "unknown Dell", STAC_922X_DELL_D81),
3718 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
3719 "unknown Dell", STAC_922X_DELL_D81),
3720 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
3721 "unknown Dell", STAC_922X_DELL_D82),
3722 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
3723 "unknown Dell", STAC_922X_DELL_M81),
3724 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
3725 "unknown Dell", STAC_922X_DELL_D82),
3726 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
3727 "unknown Dell", STAC_922X_DELL_D81),
3728 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
3729 "unknown Dell", STAC_922X_DELL_D81),
3730 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
3731 "Dell XPS M1210", STAC_922X_DELL_M82),
3732 /* ECS/PC Chips boards */
3733 SND_PCI_QUIRK_MASK(0x1019, 0xf000, 0x2000,
3734 "ECS/PC chips", STAC_ECS_202),
3735 {} /* terminator */
3738 static const struct hda_pintbl ref927x_pin_configs[] = {
3739 { 0x0a, 0x02214020 },
3740 { 0x0b, 0x02a19080 },
3741 { 0x0c, 0x0181304e },
3742 { 0x0d, 0x01014010 },
3743 { 0x0e, 0x01a19040 },
3744 { 0x0f, 0x01011012 },
3745 { 0x10, 0x01016011 },
3746 { 0x11, 0x0101201f },
3747 { 0x12, 0x183301f0 },
3748 { 0x13, 0x18a001f0 },
3749 { 0x14, 0x18a001f0 },
3750 { 0x21, 0x01442070 },
3751 { 0x22, 0x01c42190 },
3752 { 0x23, 0x40000100 },
3756 static const struct hda_pintbl d965_3st_pin_configs[] = {
3757 { 0x0a, 0x0221401f },
3758 { 0x0b, 0x02a19120 },
3759 { 0x0c, 0x40000100 },
3760 { 0x0d, 0x01014011 },
3761 { 0x0e, 0x01a19021 },
3762 { 0x0f, 0x01813024 },
3763 { 0x10, 0x40000100 },
3764 { 0x11, 0x40000100 },
3765 { 0x12, 0x40000100 },
3766 { 0x13, 0x40000100 },
3767 { 0x14, 0x40000100 },
3768 { 0x21, 0x40000100 },
3769 { 0x22, 0x40000100 },
3770 { 0x23, 0x40000100 },
3774 static const struct hda_pintbl d965_5st_pin_configs[] = {
3775 { 0x0a, 0x02214020 },
3776 { 0x0b, 0x02a19080 },
3777 { 0x0c, 0x0181304e },
3778 { 0x0d, 0x01014010 },
3779 { 0x0e, 0x01a19040 },
3780 { 0x0f, 0x01011012 },
3781 { 0x10, 0x01016011 },
3782 { 0x11, 0x40000100 },
3783 { 0x12, 0x40000100 },
3784 { 0x13, 0x40000100 },
3785 { 0x14, 0x40000100 },
3786 { 0x21, 0x01442070 },
3787 { 0x22, 0x40000100 },
3788 { 0x23, 0x40000100 },
3792 static const struct hda_pintbl d965_5st_no_fp_pin_configs[] = {
3793 { 0x0a, 0x40000100 },
3794 { 0x0b, 0x40000100 },
3795 { 0x0c, 0x0181304e },
3796 { 0x0d, 0x01014010 },
3797 { 0x0e, 0x01a19040 },
3798 { 0x0f, 0x01011012 },
3799 { 0x10, 0x01016011 },
3800 { 0x11, 0x40000100 },
3801 { 0x12, 0x40000100 },
3802 { 0x13, 0x40000100 },
3803 { 0x14, 0x40000100 },
3804 { 0x21, 0x01442070 },
3805 { 0x22, 0x40000100 },
3806 { 0x23, 0x40000100 },
3810 static const struct hda_pintbl dell_3st_pin_configs[] = {
3811 { 0x0a, 0x02211230 },
3812 { 0x0b, 0x02a11220 },
3813 { 0x0c, 0x01a19040 },
3814 { 0x0d, 0x01114210 },
3815 { 0x0e, 0x01111212 },
3816 { 0x0f, 0x01116211 },
3817 { 0x10, 0x01813050 },
3818 { 0x11, 0x01112214 },
3819 { 0x12, 0x403003fa },
3820 { 0x13, 0x90a60040 },
3821 { 0x14, 0x90a60040 },
3822 { 0x21, 0x404003fb },
3823 { 0x22, 0x40c003fc },
3824 { 0x23, 0x40000100 },
3828 static void stac927x_fixup_ref_no_jd(struct hda_codec *codec,
3829 const struct hda_fixup *fix, int action)
3831 /* no jack detecion for ref-no-jd model */
3832 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3833 codec->no_jack_detect = 1;
3836 static void stac927x_fixup_ref(struct hda_codec *codec,
3837 const struct hda_fixup *fix, int action)
3839 struct sigmatel_spec *spec = codec->spec;
3841 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3842 snd_hda_apply_pincfgs(codec, ref927x_pin_configs);
3843 spec->eapd_mask = spec->gpio_mask = 0;
3844 spec->gpio_dir = spec->gpio_data = 0;
3848 static void stac927x_fixup_dell_dmic(struct hda_codec *codec,
3849 const struct hda_fixup *fix, int action)
3851 struct sigmatel_spec *spec = codec->spec;
3853 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3854 return;
3856 if (codec->core.subsystem_id != 0x1028022f) {
3857 /* GPIO2 High = Enable EAPD */
3858 spec->eapd_mask = spec->gpio_mask = 0x04;
3859 spec->gpio_dir = spec->gpio_data = 0x04;
3862 snd_hda_add_verbs(codec, dell_3st_core_init);
3863 spec->volknob_init = 1;
3866 static void stac927x_fixup_volknob(struct hda_codec *codec,
3867 const struct hda_fixup *fix, int action)
3869 struct sigmatel_spec *spec = codec->spec;
3871 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3872 snd_hda_add_verbs(codec, stac927x_volknob_core_init);
3873 spec->volknob_init = 1;
3877 static const struct hda_fixup stac927x_fixups[] = {
3878 [STAC_D965_REF_NO_JD] = {
3879 .type = HDA_FIXUP_FUNC,
3880 .v.func = stac927x_fixup_ref_no_jd,
3881 .chained = true,
3882 .chain_id = STAC_D965_REF,
3884 [STAC_D965_REF] = {
3885 .type = HDA_FIXUP_FUNC,
3886 .v.func = stac927x_fixup_ref,
3888 [STAC_D965_3ST] = {
3889 .type = HDA_FIXUP_PINS,
3890 .v.pins = d965_3st_pin_configs,
3891 .chained = true,
3892 .chain_id = STAC_D965_VERBS,
3894 [STAC_D965_5ST] = {
3895 .type = HDA_FIXUP_PINS,
3896 .v.pins = d965_5st_pin_configs,
3897 .chained = true,
3898 .chain_id = STAC_D965_VERBS,
3900 [STAC_D965_VERBS] = {
3901 .type = HDA_FIXUP_VERBS,
3902 .v.verbs = d965_core_init,
3904 [STAC_D965_5ST_NO_FP] = {
3905 .type = HDA_FIXUP_PINS,
3906 .v.pins = d965_5st_no_fp_pin_configs,
3908 [STAC_DELL_3ST] = {
3909 .type = HDA_FIXUP_PINS,
3910 .v.pins = dell_3st_pin_configs,
3911 .chained = true,
3912 .chain_id = STAC_927X_DELL_DMIC,
3914 [STAC_DELL_BIOS] = {
3915 .type = HDA_FIXUP_PINS,
3916 .v.pins = (const struct hda_pintbl[]) {
3917 /* correct the front output jack as a hp out */
3918 { 0x0f, 0x0221101f },
3919 /* correct the front input jack as a mic */
3920 { 0x0e, 0x02a79130 },
3923 .chained = true,
3924 .chain_id = STAC_927X_DELL_DMIC,
3926 [STAC_DELL_BIOS_AMIC] = {
3927 .type = HDA_FIXUP_PINS,
3928 .v.pins = (const struct hda_pintbl[]) {
3929 /* configure the analog microphone on some laptops */
3930 { 0x0c, 0x90a79130 },
3933 .chained = true,
3934 .chain_id = STAC_DELL_BIOS,
3936 [STAC_DELL_BIOS_SPDIF] = {
3937 .type = HDA_FIXUP_PINS,
3938 .v.pins = (const struct hda_pintbl[]) {
3939 /* correct the device field to SPDIF out */
3940 { 0x21, 0x01442070 },
3943 .chained = true,
3944 .chain_id = STAC_DELL_BIOS,
3946 [STAC_927X_DELL_DMIC] = {
3947 .type = HDA_FIXUP_FUNC,
3948 .v.func = stac927x_fixup_dell_dmic,
3950 [STAC_927X_VOLKNOB] = {
3951 .type = HDA_FIXUP_FUNC,
3952 .v.func = stac927x_fixup_volknob,
3956 static const struct hda_model_fixup stac927x_models[] = {
3957 { .id = STAC_D965_REF_NO_JD, .name = "ref-no-jd" },
3958 { .id = STAC_D965_REF, .name = "ref" },
3959 { .id = STAC_D965_3ST, .name = "3stack" },
3960 { .id = STAC_D965_5ST, .name = "5stack" },
3961 { .id = STAC_D965_5ST_NO_FP, .name = "5stack-no-fp" },
3962 { .id = STAC_DELL_3ST, .name = "dell-3stack" },
3963 { .id = STAC_DELL_BIOS, .name = "dell-bios" },
3964 { .id = STAC_DELL_BIOS_AMIC, .name = "dell-bios-amic" },
3965 { .id = STAC_927X_VOLKNOB, .name = "volknob" },
3969 static const struct snd_pci_quirk stac927x_fixup_tbl[] = {
3970 /* SigmaTel reference board */
3971 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3972 "DFI LanParty", STAC_D965_REF),
3973 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3974 "DFI LanParty", STAC_D965_REF),
3975 /* Intel 946 based systems */
3976 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
3977 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
3978 /* 965 based 3 stack systems */
3979 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2100,
3980 "Intel D965", STAC_D965_3ST),
3981 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000,
3982 "Intel D965", STAC_D965_3ST),
3983 /* Dell 3 stack systems */
3984 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
3985 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
3986 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
3987 /* Dell 3 stack systems with verb table in BIOS */
3988 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
3989 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_BIOS),
3990 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
3991 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS_SPDIF),
3992 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS),
3993 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
3994 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
3995 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
3996 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS_SPDIF),
3997 /* 965 based 5 stack systems */
3998 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2300,
3999 "Intel D965", STAC_D965_5ST),
4000 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500,
4001 "Intel D965", STAC_D965_5ST),
4002 /* volume-knob fixes */
4003 SND_PCI_QUIRK_VENDOR(0x10cf, "FSC", STAC_927X_VOLKNOB),
4004 {} /* terminator */
4007 static const struct hda_pintbl ref9205_pin_configs[] = {
4008 { 0x0a, 0x40000100 },
4009 { 0x0b, 0x40000100 },
4010 { 0x0c, 0x01016011 },
4011 { 0x0d, 0x01014010 },
4012 { 0x0e, 0x01813122 },
4013 { 0x0f, 0x01a19021 },
4014 { 0x14, 0x01019020 },
4015 { 0x16, 0x40000100 },
4016 { 0x17, 0x90a000f0 },
4017 { 0x18, 0x90a000f0 },
4018 { 0x21, 0x01441030 },
4019 { 0x22, 0x01c41030 },
4024 STAC 9205 pin configs for
4025 102801F1
4026 102801F2
4027 102801FC
4028 102801FD
4029 10280204
4030 1028021F
4031 10280228 (Dell Vostro 1500)
4032 10280229 (Dell Vostro 1700)
4034 static const struct hda_pintbl dell_9205_m42_pin_configs[] = {
4035 { 0x0a, 0x0321101F },
4036 { 0x0b, 0x03A11020 },
4037 { 0x0c, 0x400003FA },
4038 { 0x0d, 0x90170310 },
4039 { 0x0e, 0x400003FB },
4040 { 0x0f, 0x400003FC },
4041 { 0x14, 0x400003FD },
4042 { 0x16, 0x40F000F9 },
4043 { 0x17, 0x90A60330 },
4044 { 0x18, 0x400003FF },
4045 { 0x21, 0x0144131F },
4046 { 0x22, 0x40C003FE },
4051 STAC 9205 pin configs for
4052 102801F9
4053 102801FA
4054 102801FE
4055 102801FF (Dell Precision M4300)
4056 10280206
4057 10280200
4058 10280201
4060 static const struct hda_pintbl dell_9205_m43_pin_configs[] = {
4061 { 0x0a, 0x0321101f },
4062 { 0x0b, 0x03a11020 },
4063 { 0x0c, 0x90a70330 },
4064 { 0x0d, 0x90170310 },
4065 { 0x0e, 0x400000fe },
4066 { 0x0f, 0x400000ff },
4067 { 0x14, 0x400000fd },
4068 { 0x16, 0x40f000f9 },
4069 { 0x17, 0x400000fa },
4070 { 0x18, 0x400000fc },
4071 { 0x21, 0x0144131f },
4072 { 0x22, 0x40c003f8 },
4073 /* Enable SPDIF in/out */
4074 { 0x1f, 0x01441030 },
4075 { 0x20, 0x1c410030 },
4079 static const struct hda_pintbl dell_9205_m44_pin_configs[] = {
4080 { 0x0a, 0x0421101f },
4081 { 0x0b, 0x04a11020 },
4082 { 0x0c, 0x400003fa },
4083 { 0x0d, 0x90170310 },
4084 { 0x0e, 0x400003fb },
4085 { 0x0f, 0x400003fc },
4086 { 0x14, 0x400003fd },
4087 { 0x16, 0x400003f9 },
4088 { 0x17, 0x90a60330 },
4089 { 0x18, 0x400003ff },
4090 { 0x21, 0x01441340 },
4091 { 0x22, 0x40c003fe },
4095 static void stac9205_fixup_ref(struct hda_codec *codec,
4096 const struct hda_fixup *fix, int action)
4098 struct sigmatel_spec *spec = codec->spec;
4100 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4101 snd_hda_apply_pincfgs(codec, ref9205_pin_configs);
4102 /* SPDIF-In enabled */
4103 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0;
4107 static void stac9205_fixup_dell_m43(struct hda_codec *codec,
4108 const struct hda_fixup *fix, int action)
4110 struct sigmatel_spec *spec = codec->spec;
4111 struct hda_jack_callback *jack;
4113 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4114 snd_hda_apply_pincfgs(codec, dell_9205_m43_pin_configs);
4116 /* Enable unsol response for GPIO4/Dock HP connection */
4117 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
4118 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
4119 jack = snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
4120 stac_vref_event);
4121 if (!IS_ERR(jack))
4122 jack->private_data = 0x01;
4124 spec->gpio_dir = 0x0b;
4125 spec->eapd_mask = 0x01;
4126 spec->gpio_mask = 0x1b;
4127 spec->gpio_mute = 0x10;
4128 /* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute,
4129 * GPIO3 Low = DRM
4131 spec->gpio_data = 0x01;
4135 static void stac9205_fixup_eapd(struct hda_codec *codec,
4136 const struct hda_fixup *fix, int action)
4138 struct sigmatel_spec *spec = codec->spec;
4140 if (action == HDA_FIXUP_ACT_PRE_PROBE)
4141 spec->eapd_switch = 0;
4144 static const struct hda_fixup stac9205_fixups[] = {
4145 [STAC_9205_REF] = {
4146 .type = HDA_FIXUP_FUNC,
4147 .v.func = stac9205_fixup_ref,
4149 [STAC_9205_DELL_M42] = {
4150 .type = HDA_FIXUP_PINS,
4151 .v.pins = dell_9205_m42_pin_configs,
4153 [STAC_9205_DELL_M43] = {
4154 .type = HDA_FIXUP_FUNC,
4155 .v.func = stac9205_fixup_dell_m43,
4157 [STAC_9205_DELL_M44] = {
4158 .type = HDA_FIXUP_PINS,
4159 .v.pins = dell_9205_m44_pin_configs,
4161 [STAC_9205_EAPD] = {
4162 .type = HDA_FIXUP_FUNC,
4163 .v.func = stac9205_fixup_eapd,
4168 static const struct hda_model_fixup stac9205_models[] = {
4169 { .id = STAC_9205_REF, .name = "ref" },
4170 { .id = STAC_9205_DELL_M42, .name = "dell-m42" },
4171 { .id = STAC_9205_DELL_M43, .name = "dell-m43" },
4172 { .id = STAC_9205_DELL_M44, .name = "dell-m44" },
4173 { .id = STAC_9205_EAPD, .name = "eapd" },
4177 static const struct snd_pci_quirk stac9205_fixup_tbl[] = {
4178 /* SigmaTel reference board */
4179 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
4180 "DFI LanParty", STAC_9205_REF),
4181 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xfb30,
4182 "SigmaTel", STAC_9205_REF),
4183 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
4184 "DFI LanParty", STAC_9205_REF),
4185 /* Dell */
4186 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
4187 "unknown Dell", STAC_9205_DELL_M42),
4188 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
4189 "unknown Dell", STAC_9205_DELL_M42),
4190 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
4191 "Dell Precision", STAC_9205_DELL_M43),
4192 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
4193 "Dell Precision", STAC_9205_DELL_M43),
4194 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
4195 "Dell Precision", STAC_9205_DELL_M43),
4196 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
4197 "unknown Dell", STAC_9205_DELL_M42),
4198 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
4199 "unknown Dell", STAC_9205_DELL_M42),
4200 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
4201 "Dell Precision", STAC_9205_DELL_M43),
4202 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
4203 "Dell Precision M4300", STAC_9205_DELL_M43),
4204 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
4205 "unknown Dell", STAC_9205_DELL_M42),
4206 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
4207 "Dell Precision", STAC_9205_DELL_M43),
4208 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
4209 "Dell Precision", STAC_9205_DELL_M43),
4210 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
4211 "Dell Precision", STAC_9205_DELL_M43),
4212 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
4213 "Dell Inspiron", STAC_9205_DELL_M44),
4214 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228,
4215 "Dell Vostro 1500", STAC_9205_DELL_M42),
4216 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0229,
4217 "Dell Vostro 1700", STAC_9205_DELL_M42),
4218 /* Gateway */
4219 SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD),
4220 SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD),
4221 {} /* terminator */
4224 static void stac92hd95_fixup_hp_led(struct hda_codec *codec,
4225 const struct hda_fixup *fix, int action)
4227 struct sigmatel_spec *spec = codec->spec;
4229 if (action != HDA_FIXUP_ACT_PRE_PROBE)
4230 return;
4232 if (find_mute_led_cfg(codec, spec->default_polarity))
4233 codec_dbg(codec, "mute LED gpio %d polarity %d\n",
4234 spec->gpio_led,
4235 spec->gpio_led_polarity);
4238 static const struct hda_fixup stac92hd95_fixups[] = {
4239 [STAC_92HD95_HP_LED] = {
4240 .type = HDA_FIXUP_FUNC,
4241 .v.func = stac92hd95_fixup_hp_led,
4243 [STAC_92HD95_HP_BASS] = {
4244 .type = HDA_FIXUP_VERBS,
4245 .v.verbs = (const struct hda_verb[]) {
4246 {0x1a, 0x795, 0x00}, /* HPF to 100Hz */
4249 .chained = true,
4250 .chain_id = STAC_92HD95_HP_LED,
4254 static const struct snd_pci_quirk stac92hd95_fixup_tbl[] = {
4255 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1911, "HP Spectre 13", STAC_92HD95_HP_BASS),
4256 {} /* terminator */
4259 static const struct hda_model_fixup stac92hd95_models[] = {
4260 { .id = STAC_92HD95_HP_LED, .name = "hp-led" },
4261 { .id = STAC_92HD95_HP_BASS, .name = "hp-bass" },
4266 static int stac_parse_auto_config(struct hda_codec *codec)
4268 struct sigmatel_spec *spec = codec->spec;
4269 int err;
4270 int flags = 0;
4272 if (spec->headset_jack)
4273 flags |= HDA_PINCFG_HEADSET_MIC;
4275 err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, flags);
4276 if (err < 0)
4277 return err;
4279 /* add hooks */
4280 spec->gen.pcm_playback_hook = stac_playback_pcm_hook;
4281 spec->gen.pcm_capture_hook = stac_capture_pcm_hook;
4283 spec->gen.automute_hook = stac_update_outputs;
4285 err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg);
4286 if (err < 0)
4287 return err;
4289 if (spec->vref_mute_led_nid) {
4290 err = snd_hda_gen_fix_pin_power(codec, spec->vref_mute_led_nid);
4291 if (err < 0)
4292 return err;
4295 /* setup analog beep controls */
4296 if (spec->anabeep_nid > 0) {
4297 err = stac_auto_create_beep_ctls(codec,
4298 spec->anabeep_nid);
4299 if (err < 0)
4300 return err;
4303 /* setup digital beep controls and input device */
4304 #ifdef CONFIG_SND_HDA_INPUT_BEEP
4305 if (spec->gen.beep_nid) {
4306 hda_nid_t nid = spec->gen.beep_nid;
4307 unsigned int caps;
4309 err = stac_auto_create_beep_ctls(codec, nid);
4310 if (err < 0)
4311 return err;
4312 if (codec->beep) {
4313 /* IDT/STAC codecs have linear beep tone parameter */
4314 codec->beep->linear_tone = spec->linear_tone_beep;
4315 /* if no beep switch is available, make its own one */
4316 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
4317 if (!(caps & AC_AMPCAP_MUTE)) {
4318 err = stac_beep_switch_ctl(codec);
4319 if (err < 0)
4320 return err;
4324 #endif
4326 if (spec->gpio_led)
4327 spec->gen.vmaster_mute.hook = stac_vmaster_hook;
4329 if (spec->aloopback_ctl &&
4330 snd_hda_get_bool_hint(codec, "loopback") == 1) {
4331 unsigned int wr_verb =
4332 spec->aloopback_ctl->private_value >> 16;
4333 if (snd_hdac_regmap_add_vendor_verb(&codec->core, wr_verb))
4334 return -ENOMEM;
4335 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, spec->aloopback_ctl))
4336 return -ENOMEM;
4339 if (spec->have_spdif_mux) {
4340 err = stac_create_spdif_mux_ctls(codec);
4341 if (err < 0)
4342 return err;
4345 stac_init_power_map(codec);
4347 return 0;
4350 static int stac_init(struct hda_codec *codec)
4352 struct sigmatel_spec *spec = codec->spec;
4353 int i;
4355 /* override some hints */
4356 stac_store_hints(codec);
4358 /* set up GPIO */
4359 /* turn on EAPD statically when spec->eapd_switch isn't set.
4360 * otherwise, unsol event will turn it on/off dynamically
4362 if (!spec->eapd_switch)
4363 spec->gpio_data |= spec->eapd_mask;
4364 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
4366 snd_hda_gen_init(codec);
4368 /* sync the power-map */
4369 if (spec->num_pwrs)
4370 snd_hda_codec_write(codec, codec->core.afg, 0,
4371 AC_VERB_IDT_SET_POWER_MAP,
4372 spec->power_map_bits);
4374 /* power down inactive ADCs */
4375 if (spec->powerdown_adcs) {
4376 for (i = 0; i < spec->gen.num_all_adcs; i++) {
4377 if (spec->active_adcs & (1 << i))
4378 continue;
4379 snd_hda_codec_write(codec, spec->gen.all_adcs[i], 0,
4380 AC_VERB_SET_POWER_STATE,
4381 AC_PWRST_D3);
4385 return 0;
4388 static void stac_shutup(struct hda_codec *codec)
4390 struct sigmatel_spec *spec = codec->spec;
4392 snd_hda_shutup_pins(codec);
4394 if (spec->eapd_mask)
4395 stac_gpio_set(codec, spec->gpio_mask,
4396 spec->gpio_dir, spec->gpio_data &
4397 ~spec->eapd_mask);
4400 #define stac_free snd_hda_gen_free
4402 #ifdef CONFIG_SND_PROC_FS
4403 static void stac92hd_proc_hook(struct snd_info_buffer *buffer,
4404 struct hda_codec *codec, hda_nid_t nid)
4406 if (nid == codec->core.afg)
4407 snd_iprintf(buffer, "Power-Map: 0x%02x\n",
4408 snd_hda_codec_read(codec, nid, 0,
4409 AC_VERB_IDT_GET_POWER_MAP, 0));
4412 static void analog_loop_proc_hook(struct snd_info_buffer *buffer,
4413 struct hda_codec *codec,
4414 unsigned int verb)
4416 snd_iprintf(buffer, "Analog Loopback: 0x%02x\n",
4417 snd_hda_codec_read(codec, codec->core.afg, 0, verb, 0));
4420 /* stac92hd71bxx, stac92hd73xx */
4421 static void stac92hd7x_proc_hook(struct snd_info_buffer *buffer,
4422 struct hda_codec *codec, hda_nid_t nid)
4424 stac92hd_proc_hook(buffer, codec, nid);
4425 if (nid == codec->core.afg)
4426 analog_loop_proc_hook(buffer, codec, 0xfa0);
4429 static void stac9205_proc_hook(struct snd_info_buffer *buffer,
4430 struct hda_codec *codec, hda_nid_t nid)
4432 if (nid == codec->core.afg)
4433 analog_loop_proc_hook(buffer, codec, 0xfe0);
4436 static void stac927x_proc_hook(struct snd_info_buffer *buffer,
4437 struct hda_codec *codec, hda_nid_t nid)
4439 if (nid == codec->core.afg)
4440 analog_loop_proc_hook(buffer, codec, 0xfeb);
4442 #else
4443 #define stac92hd_proc_hook NULL
4444 #define stac92hd7x_proc_hook NULL
4445 #define stac9205_proc_hook NULL
4446 #define stac927x_proc_hook NULL
4447 #endif
4449 #ifdef CONFIG_PM
4450 static int stac_suspend(struct hda_codec *codec)
4452 stac_shutup(codec);
4453 return 0;
4455 #else
4456 #define stac_suspend NULL
4457 #endif /* CONFIG_PM */
4459 static const struct hda_codec_ops stac_patch_ops = {
4460 .build_controls = snd_hda_gen_build_controls,
4461 .build_pcms = snd_hda_gen_build_pcms,
4462 .init = stac_init,
4463 .free = stac_free,
4464 .unsol_event = snd_hda_jack_unsol_event,
4465 #ifdef CONFIG_PM
4466 .suspend = stac_suspend,
4467 #endif
4468 .reboot_notify = stac_shutup,
4471 static int alloc_stac_spec(struct hda_codec *codec)
4473 struct sigmatel_spec *spec;
4475 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4476 if (!spec)
4477 return -ENOMEM;
4478 snd_hda_gen_spec_init(&spec->gen);
4479 codec->spec = spec;
4480 codec->no_trigger_sense = 1; /* seems common with STAC/IDT codecs */
4481 spec->gen.dac_min_mute = true;
4482 codec->patch_ops = stac_patch_ops;
4483 return 0;
4486 static int patch_stac9200(struct hda_codec *codec)
4488 struct sigmatel_spec *spec;
4489 int err;
4491 err = alloc_stac_spec(codec);
4492 if (err < 0)
4493 return err;
4495 spec = codec->spec;
4496 spec->linear_tone_beep = 1;
4497 spec->gen.own_eapd_ctl = 1;
4499 codec->power_filter = snd_hda_codec_eapd_power_filter;
4501 snd_hda_add_verbs(codec, stac9200_eapd_init);
4503 snd_hda_pick_fixup(codec, stac9200_models, stac9200_fixup_tbl,
4504 stac9200_fixups);
4505 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4507 err = stac_parse_auto_config(codec);
4508 if (err < 0) {
4509 stac_free(codec);
4510 return err;
4513 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4515 return 0;
4518 static int patch_stac925x(struct hda_codec *codec)
4520 struct sigmatel_spec *spec;
4521 int err;
4523 err = alloc_stac_spec(codec);
4524 if (err < 0)
4525 return err;
4527 spec = codec->spec;
4528 spec->linear_tone_beep = 1;
4529 spec->gen.own_eapd_ctl = 1;
4531 snd_hda_add_verbs(codec, stac925x_core_init);
4533 snd_hda_pick_fixup(codec, stac925x_models, stac925x_fixup_tbl,
4534 stac925x_fixups);
4535 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4537 err = stac_parse_auto_config(codec);
4538 if (err < 0) {
4539 stac_free(codec);
4540 return err;
4543 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4545 return 0;
4548 static int patch_stac92hd73xx(struct hda_codec *codec)
4550 struct sigmatel_spec *spec;
4551 int err;
4552 int num_dacs;
4554 err = alloc_stac_spec(codec);
4555 if (err < 0)
4556 return err;
4558 spec = codec->spec;
4559 /* enable power_save_node only for new 92HD89xx chips, as it causes
4560 * click noises on old 92HD73xx chips.
4562 if ((codec->core.vendor_id & 0xfffffff0) != 0x111d7670)
4563 codec->power_save_node = 1;
4564 spec->linear_tone_beep = 0;
4565 spec->gen.mixer_nid = 0x1d;
4566 spec->have_spdif_mux = 1;
4568 num_dacs = snd_hda_get_num_conns(codec, 0x0a) - 1;
4569 if (num_dacs < 3 || num_dacs > 5) {
4570 codec_warn(codec,
4571 "Could not determine number of channels defaulting to DAC count\n");
4572 num_dacs = 5;
4575 switch (num_dacs) {
4576 case 0x3: /* 6 Channel */
4577 spec->aloopback_ctl = &stac92hd73xx_6ch_loopback;
4578 break;
4579 case 0x4: /* 8 Channel */
4580 spec->aloopback_ctl = &stac92hd73xx_8ch_loopback;
4581 break;
4582 case 0x5: /* 10 Channel */
4583 spec->aloopback_ctl = &stac92hd73xx_10ch_loopback;
4584 break;
4587 spec->aloopback_mask = 0x01;
4588 spec->aloopback_shift = 8;
4590 spec->gen.beep_nid = 0x1c; /* digital beep */
4592 /* GPIO0 High = Enable EAPD */
4593 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
4594 spec->gpio_data = 0x01;
4596 spec->eapd_switch = 1;
4598 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
4599 spec->pwr_nids = stac92hd73xx_pwr_nids;
4601 spec->gen.own_eapd_ctl = 1;
4602 spec->gen.power_down_unused = 1;
4604 snd_hda_pick_fixup(codec, stac92hd73xx_models, stac92hd73xx_fixup_tbl,
4605 stac92hd73xx_fixups);
4606 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4608 if (!spec->volknob_init)
4609 snd_hda_add_verbs(codec, stac92hd73xx_core_init);
4611 err = stac_parse_auto_config(codec);
4612 if (err < 0) {
4613 stac_free(codec);
4614 return err;
4617 /* Don't GPIO-mute speakers if there are no internal speakers, because
4618 * the GPIO might be necessary for Headphone
4620 if (spec->eapd_switch && !has_builtin_speaker(codec))
4621 spec->eapd_switch = 0;
4623 codec->proc_widget_hook = stac92hd7x_proc_hook;
4625 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4627 return 0;
4630 static void stac_setup_gpio(struct hda_codec *codec)
4632 struct sigmatel_spec *spec = codec->spec;
4634 spec->gpio_mask |= spec->eapd_mask;
4635 if (spec->gpio_led) {
4636 if (!spec->vref_mute_led_nid) {
4637 spec->gpio_mask |= spec->gpio_led;
4638 spec->gpio_dir |= spec->gpio_led;
4639 spec->gpio_data |= spec->gpio_led;
4640 } else {
4641 codec->power_filter = stac_vref_led_power_filter;
4645 if (spec->mic_mute_led_gpio) {
4646 spec->gpio_mask |= spec->mic_mute_led_gpio;
4647 spec->gpio_dir |= spec->mic_mute_led_gpio;
4648 spec->mic_enabled = 0;
4649 spec->gpio_data |= spec->mic_mute_led_gpio;
4651 spec->gen.cap_sync_hook = stac_capture_led_hook;
4655 static int patch_stac92hd83xxx(struct hda_codec *codec)
4657 struct sigmatel_spec *spec;
4658 int err;
4660 err = alloc_stac_spec(codec);
4661 if (err < 0)
4662 return err;
4664 /* longer delay needed for D3 */
4665 codec->core.power_caps &= ~AC_PWRST_EPSS;
4667 spec = codec->spec;
4668 codec->power_save_node = 1;
4669 spec->linear_tone_beep = 0;
4670 spec->gen.own_eapd_ctl = 1;
4671 spec->gen.power_down_unused = 1;
4672 spec->gen.mixer_nid = 0x1b;
4674 spec->gen.beep_nid = 0x21; /* digital beep */
4675 spec->pwr_nids = stac92hd83xxx_pwr_nids;
4676 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
4677 spec->default_polarity = -1; /* no default cfg */
4679 snd_hda_add_verbs(codec, stac92hd83xxx_core_init);
4681 snd_hda_pick_fixup(codec, stac92hd83xxx_models, stac92hd83xxx_fixup_tbl,
4682 stac92hd83xxx_fixups);
4683 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4685 stac_setup_gpio(codec);
4687 err = stac_parse_auto_config(codec);
4688 if (err < 0) {
4689 stac_free(codec);
4690 return err;
4693 codec->proc_widget_hook = stac92hd_proc_hook;
4695 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4697 return 0;
4700 static const hda_nid_t stac92hd95_pwr_nids[] = {
4701 0x0a, 0x0b, 0x0c, 0x0d
4704 static int patch_stac92hd95(struct hda_codec *codec)
4706 struct sigmatel_spec *spec;
4707 int err;
4709 err = alloc_stac_spec(codec);
4710 if (err < 0)
4711 return err;
4713 /* longer delay needed for D3 */
4714 codec->core.power_caps &= ~AC_PWRST_EPSS;
4716 spec = codec->spec;
4717 codec->power_save_node = 1;
4718 spec->linear_tone_beep = 0;
4719 spec->gen.own_eapd_ctl = 1;
4720 spec->gen.power_down_unused = 1;
4722 spec->gen.beep_nid = 0x19; /* digital beep */
4723 spec->pwr_nids = stac92hd95_pwr_nids;
4724 spec->num_pwrs = ARRAY_SIZE(stac92hd95_pwr_nids);
4725 spec->default_polarity = 0;
4727 snd_hda_pick_fixup(codec, stac92hd95_models, stac92hd95_fixup_tbl,
4728 stac92hd95_fixups);
4729 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4731 stac_setup_gpio(codec);
4733 err = stac_parse_auto_config(codec);
4734 if (err < 0) {
4735 stac_free(codec);
4736 return err;
4739 codec->proc_widget_hook = stac92hd_proc_hook;
4741 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4743 return 0;
4746 static int patch_stac92hd71bxx(struct hda_codec *codec)
4748 struct sigmatel_spec *spec;
4749 const hda_nid_t *unmute_nids = stac92hd71bxx_unmute_nids;
4750 int err;
4752 err = alloc_stac_spec(codec);
4753 if (err < 0)
4754 return err;
4756 spec = codec->spec;
4757 /* disabled power_save_node since it causes noises on a Dell machine */
4758 /* codec->power_save_node = 1; */
4759 spec->linear_tone_beep = 0;
4760 spec->gen.own_eapd_ctl = 1;
4761 spec->gen.power_down_unused = 1;
4762 spec->gen.mixer_nid = 0x17;
4763 spec->have_spdif_mux = 1;
4765 /* GPIO0 = EAPD */
4766 spec->gpio_mask = 0x01;
4767 spec->gpio_dir = 0x01;
4768 spec->gpio_data = 0x01;
4770 switch (codec->core.vendor_id) {
4771 case 0x111d76b6: /* 4 Port without Analog Mixer */
4772 case 0x111d76b7:
4773 unmute_nids++;
4774 break;
4775 case 0x111d7608: /* 5 Port with Analog Mixer */
4776 if ((codec->core.revision_id & 0xf) == 0 ||
4777 (codec->core.revision_id & 0xf) == 1)
4778 spec->stream_delay = 40; /* 40 milliseconds */
4780 /* disable VSW */
4781 unmute_nids++;
4782 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0);
4783 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3);
4784 break;
4785 case 0x111d7603: /* 6 Port with Analog Mixer */
4786 if ((codec->core.revision_id & 0xf) == 1)
4787 spec->stream_delay = 40; /* 40 milliseconds */
4789 break;
4792 if (get_wcaps_type(get_wcaps(codec, 0x28)) == AC_WID_VOL_KNB)
4793 snd_hda_add_verbs(codec, stac92hd71bxx_core_init);
4795 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) {
4796 const hda_nid_t *p;
4797 for (p = unmute_nids; *p; p++)
4798 snd_hda_codec_amp_init_stereo(codec, *p, HDA_INPUT, 0,
4799 0xff, 0x00);
4802 spec->aloopback_ctl = &stac92hd71bxx_loopback;
4803 spec->aloopback_mask = 0x50;
4804 spec->aloopback_shift = 0;
4806 spec->powerdown_adcs = 1;
4807 spec->gen.beep_nid = 0x26; /* digital beep */
4808 spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
4809 spec->pwr_nids = stac92hd71bxx_pwr_nids;
4811 snd_hda_pick_fixup(codec, stac92hd71bxx_models, stac92hd71bxx_fixup_tbl,
4812 stac92hd71bxx_fixups);
4813 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4815 stac_setup_gpio(codec);
4817 err = stac_parse_auto_config(codec);
4818 if (err < 0) {
4819 stac_free(codec);
4820 return err;
4823 codec->proc_widget_hook = stac92hd7x_proc_hook;
4825 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4827 return 0;
4830 static int patch_stac922x(struct hda_codec *codec)
4832 struct sigmatel_spec *spec;
4833 int err;
4835 err = alloc_stac_spec(codec);
4836 if (err < 0)
4837 return err;
4839 spec = codec->spec;
4840 spec->linear_tone_beep = 1;
4841 spec->gen.own_eapd_ctl = 1;
4843 snd_hda_add_verbs(codec, stac922x_core_init);
4845 /* Fix Mux capture level; max to 2 */
4846 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
4847 (0 << AC_AMPCAP_OFFSET_SHIFT) |
4848 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4849 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4850 (0 << AC_AMPCAP_MUTE_SHIFT));
4852 snd_hda_pick_fixup(codec, stac922x_models, stac922x_fixup_tbl,
4853 stac922x_fixups);
4854 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4856 err = stac_parse_auto_config(codec);
4857 if (err < 0) {
4858 stac_free(codec);
4859 return err;
4862 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4864 return 0;
4867 static const char * const stac927x_spdif_labels[] = {
4868 "Digital Playback", "ADAT", "Analog Mux 1",
4869 "Analog Mux 2", "Analog Mux 3", NULL
4872 static int patch_stac927x(struct hda_codec *codec)
4874 struct sigmatel_spec *spec;
4875 int err;
4877 err = alloc_stac_spec(codec);
4878 if (err < 0)
4879 return err;
4881 spec = codec->spec;
4882 spec->linear_tone_beep = 1;
4883 spec->gen.own_eapd_ctl = 1;
4884 spec->have_spdif_mux = 1;
4885 spec->spdif_labels = stac927x_spdif_labels;
4887 spec->gen.beep_nid = 0x23; /* digital beep */
4889 /* GPIO0 High = Enable EAPD */
4890 spec->eapd_mask = spec->gpio_mask = 0x01;
4891 spec->gpio_dir = spec->gpio_data = 0x01;
4893 spec->aloopback_ctl = &stac927x_loopback;
4894 spec->aloopback_mask = 0x40;
4895 spec->aloopback_shift = 0;
4896 spec->eapd_switch = 1;
4898 snd_hda_pick_fixup(codec, stac927x_models, stac927x_fixup_tbl,
4899 stac927x_fixups);
4900 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4902 if (!spec->volknob_init)
4903 snd_hda_add_verbs(codec, stac927x_core_init);
4905 err = stac_parse_auto_config(codec);
4906 if (err < 0) {
4907 stac_free(codec);
4908 return err;
4911 codec->proc_widget_hook = stac927x_proc_hook;
4914 * !!FIXME!!
4915 * The STAC927x seem to require fairly long delays for certain
4916 * command sequences. With too short delays (even if the answer
4917 * is set to RIRB properly), it results in the silence output
4918 * on some hardwares like Dell.
4920 * The below flag enables the longer delay (see get_response
4921 * in hda_intel.c).
4923 codec->bus->needs_damn_long_delay = 1;
4925 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4927 return 0;
4930 static int patch_stac9205(struct hda_codec *codec)
4932 struct sigmatel_spec *spec;
4933 int err;
4935 err = alloc_stac_spec(codec);
4936 if (err < 0)
4937 return err;
4939 spec = codec->spec;
4940 spec->linear_tone_beep = 1;
4941 spec->gen.own_eapd_ctl = 1;
4942 spec->have_spdif_mux = 1;
4944 spec->gen.beep_nid = 0x23; /* digital beep */
4946 snd_hda_add_verbs(codec, stac9205_core_init);
4947 spec->aloopback_ctl = &stac9205_loopback;
4949 spec->aloopback_mask = 0x40;
4950 spec->aloopback_shift = 0;
4952 /* GPIO0 High = EAPD */
4953 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
4954 spec->gpio_data = 0x01;
4956 /* Turn on/off EAPD per HP plugging */
4957 spec->eapd_switch = 1;
4959 snd_hda_pick_fixup(codec, stac9205_models, stac9205_fixup_tbl,
4960 stac9205_fixups);
4961 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4963 err = stac_parse_auto_config(codec);
4964 if (err < 0) {
4965 stac_free(codec);
4966 return err;
4969 codec->proc_widget_hook = stac9205_proc_hook;
4971 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4973 return 0;
4977 * STAC9872 hack
4980 static const struct hda_verb stac9872_core_init[] = {
4981 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
4982 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
4986 static const struct hda_pintbl stac9872_vaio_pin_configs[] = {
4987 { 0x0a, 0x03211020 },
4988 { 0x0b, 0x411111f0 },
4989 { 0x0c, 0x411111f0 },
4990 { 0x0d, 0x03a15030 },
4991 { 0x0e, 0x411111f0 },
4992 { 0x0f, 0x90170110 },
4993 { 0x11, 0x411111f0 },
4994 { 0x13, 0x411111f0 },
4995 { 0x14, 0x90a7013e },
4999 static const struct hda_model_fixup stac9872_models[] = {
5000 { .id = STAC_9872_VAIO, .name = "vaio" },
5004 static const struct hda_fixup stac9872_fixups[] = {
5005 [STAC_9872_VAIO] = {
5006 .type = HDA_FIXUP_PINS,
5007 .v.pins = stac9872_vaio_pin_configs,
5011 static const struct snd_pci_quirk stac9872_fixup_tbl[] = {
5012 SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0,
5013 "Sony VAIO F/S", STAC_9872_VAIO),
5014 {} /* terminator */
5017 static int patch_stac9872(struct hda_codec *codec)
5019 struct sigmatel_spec *spec;
5020 int err;
5022 err = alloc_stac_spec(codec);
5023 if (err < 0)
5024 return err;
5026 spec = codec->spec;
5027 spec->linear_tone_beep = 1;
5028 spec->gen.own_eapd_ctl = 1;
5030 snd_hda_add_verbs(codec, stac9872_core_init);
5032 snd_hda_pick_fixup(codec, stac9872_models, stac9872_fixup_tbl,
5033 stac9872_fixups);
5034 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
5036 err = stac_parse_auto_config(codec);
5037 if (err < 0) {
5038 stac_free(codec);
5039 return -EINVAL;
5042 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
5044 return 0;
5049 * patch entries
5051 static const struct hda_device_id snd_hda_id_sigmatel[] = {
5052 HDA_CODEC_ENTRY(0x83847690, "STAC9200", patch_stac9200),
5053 HDA_CODEC_ENTRY(0x83847882, "STAC9220 A1", patch_stac922x),
5054 HDA_CODEC_ENTRY(0x83847680, "STAC9221 A1", patch_stac922x),
5055 HDA_CODEC_ENTRY(0x83847880, "STAC9220 A2", patch_stac922x),
5056 HDA_CODEC_ENTRY(0x83847681, "STAC9220D/9223D A2", patch_stac922x),
5057 HDA_CODEC_ENTRY(0x83847682, "STAC9221 A2", patch_stac922x),
5058 HDA_CODEC_ENTRY(0x83847683, "STAC9221D A2", patch_stac922x),
5059 HDA_CODEC_ENTRY(0x83847618, "STAC9227", patch_stac927x),
5060 HDA_CODEC_ENTRY(0x83847619, "STAC9227", patch_stac927x),
5061 HDA_CODEC_ENTRY(0x83847616, "STAC9228", patch_stac927x),
5062 HDA_CODEC_ENTRY(0x83847617, "STAC9228", patch_stac927x),
5063 HDA_CODEC_ENTRY(0x83847614, "STAC9229", patch_stac927x),
5064 HDA_CODEC_ENTRY(0x83847615, "STAC9229", patch_stac927x),
5065 HDA_CODEC_ENTRY(0x83847620, "STAC9274", patch_stac927x),
5066 HDA_CODEC_ENTRY(0x83847621, "STAC9274D", patch_stac927x),
5067 HDA_CODEC_ENTRY(0x83847622, "STAC9273X", patch_stac927x),
5068 HDA_CODEC_ENTRY(0x83847623, "STAC9273D", patch_stac927x),
5069 HDA_CODEC_ENTRY(0x83847624, "STAC9272X", patch_stac927x),
5070 HDA_CODEC_ENTRY(0x83847625, "STAC9272D", patch_stac927x),
5071 HDA_CODEC_ENTRY(0x83847626, "STAC9271X", patch_stac927x),
5072 HDA_CODEC_ENTRY(0x83847627, "STAC9271D", patch_stac927x),
5073 HDA_CODEC_ENTRY(0x83847628, "STAC9274X5NH", patch_stac927x),
5074 HDA_CODEC_ENTRY(0x83847629, "STAC9274D5NH", patch_stac927x),
5075 HDA_CODEC_ENTRY(0x83847632, "STAC9202", patch_stac925x),
5076 HDA_CODEC_ENTRY(0x83847633, "STAC9202D", patch_stac925x),
5077 HDA_CODEC_ENTRY(0x83847634, "STAC9250", patch_stac925x),
5078 HDA_CODEC_ENTRY(0x83847635, "STAC9250D", patch_stac925x),
5079 HDA_CODEC_ENTRY(0x83847636, "STAC9251", patch_stac925x),
5080 HDA_CODEC_ENTRY(0x83847637, "STAC9250D", patch_stac925x),
5081 HDA_CODEC_ENTRY(0x83847645, "92HD206X", patch_stac927x),
5082 HDA_CODEC_ENTRY(0x83847646, "92HD206D", patch_stac927x),
5083 /* The following does not take into account .id=0x83847661 when subsys =
5084 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
5085 * currently not fully supported.
5087 HDA_CODEC_ENTRY(0x83847661, "CXD9872RD/K", patch_stac9872),
5088 HDA_CODEC_ENTRY(0x83847662, "STAC9872AK", patch_stac9872),
5089 HDA_CODEC_ENTRY(0x83847664, "CXD9872AKD", patch_stac9872),
5090 HDA_CODEC_ENTRY(0x83847698, "STAC9205", patch_stac9205),
5091 HDA_CODEC_ENTRY(0x838476a0, "STAC9205", patch_stac9205),
5092 HDA_CODEC_ENTRY(0x838476a1, "STAC9205D", patch_stac9205),
5093 HDA_CODEC_ENTRY(0x838476a2, "STAC9204", patch_stac9205),
5094 HDA_CODEC_ENTRY(0x838476a3, "STAC9204D", patch_stac9205),
5095 HDA_CODEC_ENTRY(0x838476a4, "STAC9255", patch_stac9205),
5096 HDA_CODEC_ENTRY(0x838476a5, "STAC9255D", patch_stac9205),
5097 HDA_CODEC_ENTRY(0x838476a6, "STAC9254", patch_stac9205),
5098 HDA_CODEC_ENTRY(0x838476a7, "STAC9254D", patch_stac9205),
5099 HDA_CODEC_ENTRY(0x111d7603, "92HD75B3X5", patch_stac92hd71bxx),
5100 HDA_CODEC_ENTRY(0x111d7604, "92HD83C1X5", patch_stac92hd83xxx),
5101 HDA_CODEC_ENTRY(0x111d76d4, "92HD83C1C5", patch_stac92hd83xxx),
5102 HDA_CODEC_ENTRY(0x111d7605, "92HD81B1X5", patch_stac92hd83xxx),
5103 HDA_CODEC_ENTRY(0x111d76d5, "92HD81B1C5", patch_stac92hd83xxx),
5104 HDA_CODEC_ENTRY(0x111d76d1, "92HD87B1/3", patch_stac92hd83xxx),
5105 HDA_CODEC_ENTRY(0x111d76d9, "92HD87B2/4", patch_stac92hd83xxx),
5106 HDA_CODEC_ENTRY(0x111d7666, "92HD88B3", patch_stac92hd83xxx),
5107 HDA_CODEC_ENTRY(0x111d7667, "92HD88B1", patch_stac92hd83xxx),
5108 HDA_CODEC_ENTRY(0x111d7668, "92HD88B2", patch_stac92hd83xxx),
5109 HDA_CODEC_ENTRY(0x111d7669, "92HD88B4", patch_stac92hd83xxx),
5110 HDA_CODEC_ENTRY(0x111d7608, "92HD75B2X5", patch_stac92hd71bxx),
5111 HDA_CODEC_ENTRY(0x111d7674, "92HD73D1X5", patch_stac92hd73xx),
5112 HDA_CODEC_ENTRY(0x111d7675, "92HD73C1X5", patch_stac92hd73xx),
5113 HDA_CODEC_ENTRY(0x111d7676, "92HD73E1X5", patch_stac92hd73xx),
5114 HDA_CODEC_ENTRY(0x111d7695, "92HD95", patch_stac92hd95),
5115 HDA_CODEC_ENTRY(0x111d76b0, "92HD71B8X", patch_stac92hd71bxx),
5116 HDA_CODEC_ENTRY(0x111d76b1, "92HD71B8X", patch_stac92hd71bxx),
5117 HDA_CODEC_ENTRY(0x111d76b2, "92HD71B7X", patch_stac92hd71bxx),
5118 HDA_CODEC_ENTRY(0x111d76b3, "92HD71B7X", patch_stac92hd71bxx),
5119 HDA_CODEC_ENTRY(0x111d76b4, "92HD71B6X", patch_stac92hd71bxx),
5120 HDA_CODEC_ENTRY(0x111d76b5, "92HD71B6X", patch_stac92hd71bxx),
5121 HDA_CODEC_ENTRY(0x111d76b6, "92HD71B5X", patch_stac92hd71bxx),
5122 HDA_CODEC_ENTRY(0x111d76b7, "92HD71B5X", patch_stac92hd71bxx),
5123 HDA_CODEC_ENTRY(0x111d76c0, "92HD89C3", patch_stac92hd73xx),
5124 HDA_CODEC_ENTRY(0x111d76c1, "92HD89C2", patch_stac92hd73xx),
5125 HDA_CODEC_ENTRY(0x111d76c2, "92HD89C1", patch_stac92hd73xx),
5126 HDA_CODEC_ENTRY(0x111d76c3, "92HD89B3", patch_stac92hd73xx),
5127 HDA_CODEC_ENTRY(0x111d76c4, "92HD89B2", patch_stac92hd73xx),
5128 HDA_CODEC_ENTRY(0x111d76c5, "92HD89B1", patch_stac92hd73xx),
5129 HDA_CODEC_ENTRY(0x111d76c6, "92HD89E3", patch_stac92hd73xx),
5130 HDA_CODEC_ENTRY(0x111d76c7, "92HD89E2", patch_stac92hd73xx),
5131 HDA_CODEC_ENTRY(0x111d76c8, "92HD89E1", patch_stac92hd73xx),
5132 HDA_CODEC_ENTRY(0x111d76c9, "92HD89D3", patch_stac92hd73xx),
5133 HDA_CODEC_ENTRY(0x111d76ca, "92HD89D2", patch_stac92hd73xx),
5134 HDA_CODEC_ENTRY(0x111d76cb, "92HD89D1", patch_stac92hd73xx),
5135 HDA_CODEC_ENTRY(0x111d76cc, "92HD89F3", patch_stac92hd73xx),
5136 HDA_CODEC_ENTRY(0x111d76cd, "92HD89F2", patch_stac92hd73xx),
5137 HDA_CODEC_ENTRY(0x111d76ce, "92HD89F1", patch_stac92hd73xx),
5138 HDA_CODEC_ENTRY(0x111d76df, "92HD93BXX", patch_stac92hd83xxx),
5139 HDA_CODEC_ENTRY(0x111d76e0, "92HD91BXX", patch_stac92hd83xxx),
5140 HDA_CODEC_ENTRY(0x111d76e3, "92HD98BXX", patch_stac92hd83xxx),
5141 HDA_CODEC_ENTRY(0x111d76e5, "92HD99BXX", patch_stac92hd83xxx),
5142 HDA_CODEC_ENTRY(0x111d76e7, "92HD90BXX", patch_stac92hd83xxx),
5143 HDA_CODEC_ENTRY(0x111d76e8, "92HD66B1X5", patch_stac92hd83xxx),
5144 HDA_CODEC_ENTRY(0x111d76e9, "92HD66B2X5", patch_stac92hd83xxx),
5145 HDA_CODEC_ENTRY(0x111d76ea, "92HD66B3X5", patch_stac92hd83xxx),
5146 HDA_CODEC_ENTRY(0x111d76eb, "92HD66C1X5", patch_stac92hd83xxx),
5147 HDA_CODEC_ENTRY(0x111d76ec, "92HD66C2X5", patch_stac92hd83xxx),
5148 HDA_CODEC_ENTRY(0x111d76ed, "92HD66C3X5", patch_stac92hd83xxx),
5149 HDA_CODEC_ENTRY(0x111d76ee, "92HD66B1X3", patch_stac92hd83xxx),
5150 HDA_CODEC_ENTRY(0x111d76ef, "92HD66B2X3", patch_stac92hd83xxx),
5151 HDA_CODEC_ENTRY(0x111d76f0, "92HD66B3X3", patch_stac92hd83xxx),
5152 HDA_CODEC_ENTRY(0x111d76f1, "92HD66C1X3", patch_stac92hd83xxx),
5153 HDA_CODEC_ENTRY(0x111d76f2, "92HD66C2X3", patch_stac92hd83xxx),
5154 HDA_CODEC_ENTRY(0x111d76f3, "92HD66C3/65", patch_stac92hd83xxx),
5155 {} /* terminator */
5157 MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_sigmatel);
5159 MODULE_LICENSE("GPL");
5160 MODULE_DESCRIPTION("IDT/Sigmatel HD-audio codec");
5162 static struct hda_codec_driver sigmatel_driver = {
5163 .id = snd_hda_id_sigmatel,
5166 module_hda_codec_driver(sigmatel_driver);