Linux 3.11-rc3
[cris-mirror.git] / sound / pci / hda / patch_sigmatel.c
blob92b9b4324372e8f9d15aba987c3a55a4cb6945c0
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 <sound/tlv.h>
36 #include "hda_codec.h"
37 #include "hda_local.h"
38 #include "hda_auto_parser.h"
39 #include "hda_beep.h"
40 #include "hda_jack.h"
41 #include "hda_generic.h"
43 enum {
44 STAC_VREF_EVENT = 8,
45 STAC_PWR_EVENT,
48 enum {
49 STAC_REF,
50 STAC_9200_OQO,
51 STAC_9200_DELL_D21,
52 STAC_9200_DELL_D22,
53 STAC_9200_DELL_D23,
54 STAC_9200_DELL_M21,
55 STAC_9200_DELL_M22,
56 STAC_9200_DELL_M23,
57 STAC_9200_DELL_M24,
58 STAC_9200_DELL_M25,
59 STAC_9200_DELL_M26,
60 STAC_9200_DELL_M27,
61 STAC_9200_M4,
62 STAC_9200_M4_2,
63 STAC_9200_PANASONIC,
64 STAC_9200_EAPD_INIT,
65 STAC_9200_MODELS
68 enum {
69 STAC_9205_REF,
70 STAC_9205_DELL_M42,
71 STAC_9205_DELL_M43,
72 STAC_9205_DELL_M44,
73 STAC_9205_EAPD,
74 STAC_9205_MODELS
77 enum {
78 STAC_92HD73XX_NO_JD, /* no jack-detection */
79 STAC_92HD73XX_REF,
80 STAC_92HD73XX_INTEL,
81 STAC_DELL_M6_AMIC,
82 STAC_DELL_M6_DMIC,
83 STAC_DELL_M6_BOTH,
84 STAC_DELL_EQ,
85 STAC_ALIENWARE_M17X,
86 STAC_92HD73XX_MODELS
89 enum {
90 STAC_92HD83XXX_REF,
91 STAC_92HD83XXX_PWR_REF,
92 STAC_DELL_S14,
93 STAC_DELL_VOSTRO_3500,
94 STAC_92HD83XXX_HP_cNB11_INTQUAD,
95 STAC_HP_DV7_4000,
96 STAC_HP_ZEPHYR,
97 STAC_92HD83XXX_HP_LED,
98 STAC_92HD83XXX_HP_INV_LED,
99 STAC_92HD83XXX_HP_MIC_LED,
100 STAC_92HD83XXX_HEADSET_JACK,
101 STAC_92HD83XXX_HP,
102 STAC_HP_ENVY_BASS,
103 STAC_92HD83XXX_MODELS
106 enum {
107 STAC_92HD71BXX_REF,
108 STAC_DELL_M4_1,
109 STAC_DELL_M4_2,
110 STAC_DELL_M4_3,
111 STAC_HP_M4,
112 STAC_HP_DV4,
113 STAC_HP_DV5,
114 STAC_HP_HDX,
115 STAC_92HD71BXX_HP,
116 STAC_92HD71BXX_NO_DMIC,
117 STAC_92HD71BXX_NO_SMUX,
118 STAC_92HD71BXX_MODELS
121 enum {
122 STAC_925x_REF,
123 STAC_M1,
124 STAC_M1_2,
125 STAC_M2,
126 STAC_M2_2,
127 STAC_M3,
128 STAC_M5,
129 STAC_M6,
130 STAC_925x_MODELS
133 enum {
134 STAC_D945_REF,
135 STAC_D945GTP3,
136 STAC_D945GTP5,
137 STAC_INTEL_MAC_V1,
138 STAC_INTEL_MAC_V2,
139 STAC_INTEL_MAC_V3,
140 STAC_INTEL_MAC_V4,
141 STAC_INTEL_MAC_V5,
142 STAC_INTEL_MAC_AUTO,
143 STAC_ECS_202,
144 STAC_922X_DELL_D81,
145 STAC_922X_DELL_D82,
146 STAC_922X_DELL_M81,
147 STAC_922X_DELL_M82,
148 STAC_922X_INTEL_MAC_GPIO,
149 STAC_922X_MODELS
152 enum {
153 STAC_D965_REF_NO_JD, /* no jack-detection */
154 STAC_D965_REF,
155 STAC_D965_3ST,
156 STAC_D965_5ST,
157 STAC_D965_5ST_NO_FP,
158 STAC_D965_VERBS,
159 STAC_DELL_3ST,
160 STAC_DELL_BIOS,
161 STAC_DELL_BIOS_SPDIF,
162 STAC_927X_DELL_DMIC,
163 STAC_927X_VOLKNOB,
164 STAC_927X_MODELS
167 enum {
168 STAC_9872_VAIO,
169 STAC_9872_MODELS
172 struct sigmatel_spec {
173 struct hda_gen_spec gen;
175 unsigned int eapd_switch: 1;
176 unsigned int linear_tone_beep:1;
177 unsigned int headset_jack:1; /* 4-pin headset jack (hp + mono mic) */
178 unsigned int volknob_init:1; /* special volume-knob initialization */
179 unsigned int powerdown_adcs:1;
180 unsigned int have_spdif_mux:1;
182 /* gpio lines */
183 unsigned int eapd_mask;
184 unsigned int gpio_mask;
185 unsigned int gpio_dir;
186 unsigned int gpio_data;
187 unsigned int gpio_mute;
188 unsigned int gpio_led;
189 unsigned int gpio_led_polarity;
190 unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */
191 unsigned int vref_led;
192 int default_polarity;
194 unsigned int mic_mute_led_gpio; /* capture mute LED GPIO */
195 bool mic_mute_led_on; /* current mic mute state */
197 /* stream */
198 unsigned int stream_delay;
200 /* analog loopback */
201 const struct snd_kcontrol_new *aloopback_ctl;
202 unsigned int aloopback;
203 unsigned char aloopback_mask;
204 unsigned char aloopback_shift;
206 /* power management */
207 unsigned int power_map_bits;
208 unsigned int num_pwrs;
209 const hda_nid_t *pwr_nids;
210 unsigned int active_adcs;
212 /* beep widgets */
213 hda_nid_t anabeep_nid;
215 /* SPDIF-out mux */
216 const char * const *spdif_labels;
217 struct hda_input_mux spdif_mux;
218 unsigned int cur_smux[2];
221 #define AC_VERB_IDT_SET_POWER_MAP 0x7ec
222 #define AC_VERB_IDT_GET_POWER_MAP 0xfec
224 static const hda_nid_t stac92hd73xx_pwr_nids[8] = {
225 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
226 0x0f, 0x10, 0x11
229 static const hda_nid_t stac92hd83xxx_pwr_nids[7] = {
230 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
231 0x0f, 0x10
234 static const hda_nid_t stac92hd71bxx_pwr_nids[3] = {
235 0x0a, 0x0d, 0x0f
240 * PCM hooks
242 static void stac_playback_pcm_hook(struct hda_pcm_stream *hinfo,
243 struct hda_codec *codec,
244 struct snd_pcm_substream *substream,
245 int action)
247 struct sigmatel_spec *spec = codec->spec;
248 if (action == HDA_GEN_PCM_ACT_OPEN && spec->stream_delay)
249 msleep(spec->stream_delay);
252 static void stac_capture_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 int i, idx = 0;
260 if (!spec->powerdown_adcs)
261 return;
263 for (i = 0; i < spec->gen.num_all_adcs; i++) {
264 if (spec->gen.all_adcs[i] == hinfo->nid) {
265 idx = i;
266 break;
270 switch (action) {
271 case HDA_GEN_PCM_ACT_OPEN:
272 msleep(40);
273 snd_hda_codec_write(codec, hinfo->nid, 0,
274 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
275 spec->active_adcs |= (1 << idx);
276 break;
277 case HDA_GEN_PCM_ACT_CLOSE:
278 snd_hda_codec_write(codec, hinfo->nid, 0,
279 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
280 spec->active_adcs &= ~(1 << idx);
281 break;
286 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
287 * funky external mute control using GPIO pins.
290 static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
291 unsigned int dir_mask, unsigned int data)
293 unsigned int gpiostate, gpiomask, gpiodir;
295 snd_printdd("%s msk %x dir %x gpio %x\n", __func__, mask, dir_mask, data);
297 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
298 AC_VERB_GET_GPIO_DATA, 0);
299 gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask);
301 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
302 AC_VERB_GET_GPIO_MASK, 0);
303 gpiomask |= mask;
305 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
306 AC_VERB_GET_GPIO_DIRECTION, 0);
307 gpiodir |= dir_mask;
309 /* Configure GPIOx as CMOS */
310 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
312 snd_hda_codec_write(codec, codec->afg, 0,
313 AC_VERB_SET_GPIO_MASK, gpiomask);
314 snd_hda_codec_read(codec, codec->afg, 0,
315 AC_VERB_SET_GPIO_DIRECTION, gpiodir); /* sync */
317 msleep(1);
319 snd_hda_codec_read(codec, codec->afg, 0,
320 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
323 /* hook for controlling mic-mute LED GPIO */
324 static void stac_capture_led_hook(struct hda_codec *codec,
325 struct snd_ctl_elem_value *ucontrol)
327 struct sigmatel_spec *spec = codec->spec;
328 bool mute;
330 if (!ucontrol)
331 return;
333 mute = !(ucontrol->value.integer.value[0] ||
334 ucontrol->value.integer.value[1]);
335 if (spec->mic_mute_led_on != mute) {
336 spec->mic_mute_led_on = mute;
337 if (mute)
338 spec->gpio_data |= spec->mic_mute_led_gpio;
339 else
340 spec->gpio_data &= ~spec->mic_mute_led_gpio;
341 stac_gpio_set(codec, spec->gpio_mask,
342 spec->gpio_dir, spec->gpio_data);
346 static int stac_vrefout_set(struct hda_codec *codec,
347 hda_nid_t nid, unsigned int new_vref)
349 int error, pinctl;
351 snd_printdd("%s, nid %x ctl %x\n", __func__, nid, new_vref);
352 pinctl = snd_hda_codec_read(codec, nid, 0,
353 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
355 if (pinctl < 0)
356 return pinctl;
358 pinctl &= 0xff;
359 pinctl &= ~AC_PINCTL_VREFEN;
360 pinctl |= (new_vref & AC_PINCTL_VREFEN);
362 error = snd_hda_set_pin_ctl_cache(codec, nid, pinctl);
363 if (error < 0)
364 return error;
366 return 1;
369 /* update mute-LED accoring to the master switch */
370 static void stac_update_led_status(struct hda_codec *codec, int enabled)
372 struct sigmatel_spec *spec = codec->spec;
373 int muted = !enabled;
375 if (!spec->gpio_led)
376 return;
378 /* LED state is inverted on these systems */
379 if (spec->gpio_led_polarity)
380 muted = !muted;
382 if (!spec->vref_mute_led_nid) {
383 if (muted)
384 spec->gpio_data |= spec->gpio_led;
385 else
386 spec->gpio_data &= ~spec->gpio_led;
387 stac_gpio_set(codec, spec->gpio_mask,
388 spec->gpio_dir, spec->gpio_data);
389 } else {
390 spec->vref_led = muted ? AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
391 stac_vrefout_set(codec, spec->vref_mute_led_nid,
392 spec->vref_led);
396 /* vmaster hook to update mute LED */
397 static void stac_vmaster_hook(void *private_data, int val)
399 stac_update_led_status(private_data, val);
402 /* automute hook to handle GPIO mute and EAPD updates */
403 static void stac_update_outputs(struct hda_codec *codec)
405 struct sigmatel_spec *spec = codec->spec;
407 if (spec->gpio_mute)
408 spec->gen.master_mute =
409 !(snd_hda_codec_read(codec, codec->afg, 0,
410 AC_VERB_GET_GPIO_DATA, 0) & spec->gpio_mute);
412 snd_hda_gen_update_outputs(codec);
414 if (spec->eapd_mask && spec->eapd_switch) {
415 unsigned int val = spec->gpio_data;
416 if (spec->gen.speaker_muted)
417 val &= ~spec->eapd_mask;
418 else
419 val |= spec->eapd_mask;
420 if (spec->gpio_data != val) {
421 spec->gpio_data = val;
422 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir,
423 val);
428 static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
429 bool enable, bool do_write)
431 struct sigmatel_spec *spec = codec->spec;
432 unsigned int idx, val;
434 for (idx = 0; idx < spec->num_pwrs; idx++) {
435 if (spec->pwr_nids[idx] == nid)
436 break;
438 if (idx >= spec->num_pwrs)
439 return;
441 idx = 1 << idx;
443 val = spec->power_map_bits;
444 if (enable)
445 val &= ~idx;
446 else
447 val |= idx;
449 /* power down unused output ports */
450 if (val != spec->power_map_bits) {
451 spec->power_map_bits = val;
452 if (do_write)
453 snd_hda_codec_write(codec, codec->afg, 0,
454 AC_VERB_IDT_SET_POWER_MAP, val);
458 /* update power bit per jack plug/unplug */
459 static void jack_update_power(struct hda_codec *codec,
460 struct hda_jack_tbl *jack)
462 struct sigmatel_spec *spec = codec->spec;
463 int i;
465 if (!spec->num_pwrs)
466 return;
468 if (jack && jack->nid) {
469 stac_toggle_power_map(codec, jack->nid,
470 snd_hda_jack_detect(codec, jack->nid),
471 true);
472 return;
475 /* update all jacks */
476 for (i = 0; i < spec->num_pwrs; i++) {
477 hda_nid_t nid = spec->pwr_nids[i];
478 jack = snd_hda_jack_tbl_get(codec, nid);
479 if (!jack || !jack->action)
480 continue;
481 if (jack->action == STAC_PWR_EVENT ||
482 jack->action <= HDA_GEN_LAST_EVENT)
483 stac_toggle_power_map(codec, nid,
484 snd_hda_jack_detect(codec, nid),
485 false);
488 snd_hda_codec_write(codec, codec->afg, 0, AC_VERB_IDT_SET_POWER_MAP,
489 spec->power_map_bits);
492 static void stac_hp_automute(struct hda_codec *codec,
493 struct hda_jack_tbl *jack)
495 snd_hda_gen_hp_automute(codec, jack);
496 jack_update_power(codec, jack);
499 static void stac_line_automute(struct hda_codec *codec,
500 struct hda_jack_tbl *jack)
502 snd_hda_gen_line_automute(codec, jack);
503 jack_update_power(codec, jack);
506 static void stac_mic_autoswitch(struct hda_codec *codec,
507 struct hda_jack_tbl *jack)
509 snd_hda_gen_mic_autoswitch(codec, jack);
510 jack_update_power(codec, jack);
513 static void stac_vref_event(struct hda_codec *codec, struct hda_jack_tbl *event)
515 unsigned int data;
517 data = snd_hda_codec_read(codec, codec->afg, 0,
518 AC_VERB_GET_GPIO_DATA, 0);
519 /* toggle VREF state based on GPIOx status */
520 snd_hda_codec_write(codec, codec->afg, 0, 0x7e0,
521 !!(data & (1 << event->private_data)));
524 /* initialize the power map and enable the power event to jacks that
525 * haven't been assigned to automute
527 static void stac_init_power_map(struct hda_codec *codec)
529 struct sigmatel_spec *spec = codec->spec;
530 int i;
532 for (i = 0; i < spec->num_pwrs; i++) {
533 hda_nid_t nid = spec->pwr_nids[i];
534 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
535 def_conf = get_defcfg_connect(def_conf);
536 if (snd_hda_jack_tbl_get(codec, nid))
537 continue;
538 if (def_conf == AC_JACK_PORT_COMPLEX &&
539 !(spec->vref_mute_led_nid == nid ||
540 is_jack_detectable(codec, nid))) {
541 snd_hda_jack_detect_enable_callback(codec, nid,
542 STAC_PWR_EVENT,
543 jack_update_power);
544 } else {
545 if (def_conf == AC_JACK_PORT_NONE)
546 stac_toggle_power_map(codec, nid, false, false);
547 else
548 stac_toggle_power_map(codec, nid, true, false);
556 static inline bool get_int_hint(struct hda_codec *codec, const char *key,
557 int *valp)
559 return !snd_hda_get_int_hint(codec, key, valp);
562 /* override some hints from the hwdep entry */
563 static void stac_store_hints(struct hda_codec *codec)
565 struct sigmatel_spec *spec = codec->spec;
566 int val;
568 if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) {
569 spec->eapd_mask = spec->gpio_dir = spec->gpio_data =
570 spec->gpio_mask;
572 if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir))
573 spec->gpio_mask &= spec->gpio_mask;
574 if (get_int_hint(codec, "gpio_data", &spec->gpio_data))
575 spec->gpio_dir &= spec->gpio_mask;
576 if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask))
577 spec->eapd_mask &= spec->gpio_mask;
578 if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute))
579 spec->gpio_mute &= spec->gpio_mask;
580 val = snd_hda_get_bool_hint(codec, "eapd_switch");
581 if (val >= 0)
582 spec->eapd_switch = val;
586 * loopback controls
589 #define stac_aloopback_info snd_ctl_boolean_mono_info
591 static int stac_aloopback_get(struct snd_kcontrol *kcontrol,
592 struct snd_ctl_elem_value *ucontrol)
594 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
595 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
596 struct sigmatel_spec *spec = codec->spec;
598 ucontrol->value.integer.value[0] = !!(spec->aloopback &
599 (spec->aloopback_mask << idx));
600 return 0;
603 static int stac_aloopback_put(struct snd_kcontrol *kcontrol,
604 struct snd_ctl_elem_value *ucontrol)
606 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
607 struct sigmatel_spec *spec = codec->spec;
608 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
609 unsigned int dac_mode;
610 unsigned int val, idx_val;
612 idx_val = spec->aloopback_mask << idx;
613 if (ucontrol->value.integer.value[0])
614 val = spec->aloopback | idx_val;
615 else
616 val = spec->aloopback & ~idx_val;
617 if (spec->aloopback == val)
618 return 0;
620 spec->aloopback = val;
622 /* Only return the bits defined by the shift value of the
623 * first two bytes of the mask
625 dac_mode = snd_hda_codec_read(codec, codec->afg, 0,
626 kcontrol->private_value & 0xFFFF, 0x0);
627 dac_mode >>= spec->aloopback_shift;
629 if (spec->aloopback & idx_val) {
630 snd_hda_power_up(codec);
631 dac_mode |= idx_val;
632 } else {
633 snd_hda_power_down(codec);
634 dac_mode &= ~idx_val;
637 snd_hda_codec_write_cache(codec, codec->afg, 0,
638 kcontrol->private_value >> 16, dac_mode);
640 return 1;
643 #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \
645 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
646 .name = "Analog Loopback", \
647 .count = cnt, \
648 .info = stac_aloopback_info, \
649 .get = stac_aloopback_get, \
650 .put = stac_aloopback_put, \
651 .private_value = verb_read | (verb_write << 16), \
655 * Mute LED handling on HP laptops
658 /* check whether it's a HP laptop with a docking port */
659 static bool hp_bnb2011_with_dock(struct hda_codec *codec)
661 if (codec->vendor_id != 0x111d7605 &&
662 codec->vendor_id != 0x111d76d1)
663 return false;
665 switch (codec->subsystem_id) {
666 case 0x103c1618:
667 case 0x103c1619:
668 case 0x103c161a:
669 case 0x103c161b:
670 case 0x103c161c:
671 case 0x103c161d:
672 case 0x103c161e:
673 case 0x103c161f:
675 case 0x103c162a:
676 case 0x103c162b:
678 case 0x103c1630:
679 case 0x103c1631:
681 case 0x103c1633:
682 case 0x103c1634:
683 case 0x103c1635:
685 case 0x103c3587:
686 case 0x103c3588:
687 case 0x103c3589:
688 case 0x103c358a:
690 case 0x103c3667:
691 case 0x103c3668:
692 case 0x103c3669:
694 return true;
696 return false;
699 static bool hp_blike_system(u32 subsystem_id)
701 switch (subsystem_id) {
702 case 0x103c1520:
703 case 0x103c1521:
704 case 0x103c1523:
705 case 0x103c1524:
706 case 0x103c1525:
707 case 0x103c1722:
708 case 0x103c1723:
709 case 0x103c1724:
710 case 0x103c1725:
711 case 0x103c1726:
712 case 0x103c1727:
713 case 0x103c1728:
714 case 0x103c1729:
715 case 0x103c172a:
716 case 0x103c172b:
717 case 0x103c307e:
718 case 0x103c307f:
719 case 0x103c3080:
720 case 0x103c3081:
721 case 0x103c7007:
722 case 0x103c7008:
723 return true;
725 return false;
728 static void set_hp_led_gpio(struct hda_codec *codec)
730 struct sigmatel_spec *spec = codec->spec;
731 unsigned int gpio;
733 if (spec->gpio_led)
734 return;
736 gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP);
737 gpio &= AC_GPIO_IO_COUNT;
738 if (gpio > 3)
739 spec->gpio_led = 0x08; /* GPIO 3 */
740 else
741 spec->gpio_led = 0x01; /* GPIO 0 */
745 * This method searches for the mute LED GPIO configuration
746 * provided as OEM string in SMBIOS. The format of that string
747 * is HP_Mute_LED_P_G or HP_Mute_LED_P
748 * where P can be 0 or 1 and defines mute LED GPIO control state (low/high)
749 * that corresponds to the NOT muted state of the master volume
750 * and G is the index of the GPIO to use as the mute LED control (0..9)
751 * If _G portion is missing it is assigned based on the codec ID
753 * So, HP B-series like systems may have HP_Mute_LED_0 (current models)
754 * or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings
757 * The dv-series laptops don't seem to have the HP_Mute_LED* strings in
758 * SMBIOS - at least the ones I have seen do not have them - which include
759 * my own system (HP Pavilion dv6-1110ax) and my cousin's
760 * HP Pavilion dv9500t CTO.
761 * Need more information on whether it is true across the entire series.
762 * -- kunal
764 static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity)
766 struct sigmatel_spec *spec = codec->spec;
767 const struct dmi_device *dev = NULL;
769 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
770 get_int_hint(codec, "gpio_led_polarity",
771 &spec->gpio_led_polarity);
772 return 1;
775 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
776 if (sscanf(dev->name, "HP_Mute_LED_%d_%x",
777 &spec->gpio_led_polarity,
778 &spec->gpio_led) == 2) {
779 unsigned int max_gpio;
780 max_gpio = snd_hda_param_read(codec, codec->afg,
781 AC_PAR_GPIO_CAP);
782 max_gpio &= AC_GPIO_IO_COUNT;
783 if (spec->gpio_led < max_gpio)
784 spec->gpio_led = 1 << spec->gpio_led;
785 else
786 spec->vref_mute_led_nid = spec->gpio_led;
787 return 1;
789 if (sscanf(dev->name, "HP_Mute_LED_%d",
790 &spec->gpio_led_polarity) == 1) {
791 set_hp_led_gpio(codec);
792 return 1;
794 /* BIOS bug: unfilled OEM string */
795 if (strstr(dev->name, "HP_Mute_LED_P_G")) {
796 set_hp_led_gpio(codec);
797 if (default_polarity >= 0)
798 spec->gpio_led_polarity = default_polarity;
799 else
800 spec->gpio_led_polarity = 1;
801 return 1;
806 * Fallback case - if we don't find the DMI strings,
807 * we statically set the GPIO - if not a B-series system
808 * and default polarity is provided
810 if (!hp_blike_system(codec->subsystem_id) &&
811 (default_polarity == 0 || default_polarity == 1)) {
812 set_hp_led_gpio(codec);
813 spec->gpio_led_polarity = default_polarity;
814 return 1;
816 return 0;
819 /* check whether a built-in speaker is included in parsed pins */
820 static bool has_builtin_speaker(struct hda_codec *codec)
822 struct sigmatel_spec *spec = codec->spec;
823 hda_nid_t *nid_pin;
824 int nids, i;
826 if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) {
827 nid_pin = spec->gen.autocfg.line_out_pins;
828 nids = spec->gen.autocfg.line_outs;
829 } else {
830 nid_pin = spec->gen.autocfg.speaker_pins;
831 nids = spec->gen.autocfg.speaker_outs;
834 for (i = 0; i < nids; i++) {
835 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid_pin[i]);
836 if (snd_hda_get_input_pin_attr(def_conf) == INPUT_PIN_ATTR_INT)
837 return true;
839 return false;
843 * PC beep controls
846 /* create PC beep volume controls */
847 static int stac_auto_create_beep_ctls(struct hda_codec *codec,
848 hda_nid_t nid)
850 struct sigmatel_spec *spec = codec->spec;
851 u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
852 struct snd_kcontrol_new *knew;
853 static struct snd_kcontrol_new abeep_mute_ctl =
854 HDA_CODEC_MUTE(NULL, 0, 0, 0);
855 static struct snd_kcontrol_new dbeep_mute_ctl =
856 HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0);
857 static struct snd_kcontrol_new beep_vol_ctl =
858 HDA_CODEC_VOLUME(NULL, 0, 0, 0);
860 /* check for mute support for the the amp */
861 if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) {
862 const struct snd_kcontrol_new *temp;
863 if (spec->anabeep_nid == nid)
864 temp = &abeep_mute_ctl;
865 else
866 temp = &dbeep_mute_ctl;
867 knew = snd_hda_gen_add_kctl(&spec->gen,
868 "Beep Playback Switch", temp);
869 if (!knew)
870 return -ENOMEM;
871 knew->private_value =
872 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT);
875 /* check to see if there is volume support for the amp */
876 if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
877 knew = snd_hda_gen_add_kctl(&spec->gen,
878 "Beep Playback Volume",
879 &beep_vol_ctl);
880 if (!knew)
881 return -ENOMEM;
882 knew->private_value =
883 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT);
885 return 0;
888 #ifdef CONFIG_SND_HDA_INPUT_BEEP
889 #define stac_dig_beep_switch_info snd_ctl_boolean_mono_info
891 static int stac_dig_beep_switch_get(struct snd_kcontrol *kcontrol,
892 struct snd_ctl_elem_value *ucontrol)
894 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
895 ucontrol->value.integer.value[0] = codec->beep->enabled;
896 return 0;
899 static int stac_dig_beep_switch_put(struct snd_kcontrol *kcontrol,
900 struct snd_ctl_elem_value *ucontrol)
902 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
903 return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]);
906 static const struct snd_kcontrol_new stac_dig_beep_ctrl = {
907 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
908 .name = "Beep Playback Switch",
909 .info = stac_dig_beep_switch_info,
910 .get = stac_dig_beep_switch_get,
911 .put = stac_dig_beep_switch_put,
914 static int stac_beep_switch_ctl(struct hda_codec *codec)
916 struct sigmatel_spec *spec = codec->spec;
918 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &stac_dig_beep_ctrl))
919 return -ENOMEM;
920 return 0;
922 #endif
925 * SPDIF-out mux controls
928 static int stac_smux_enum_info(struct snd_kcontrol *kcontrol,
929 struct snd_ctl_elem_info *uinfo)
931 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
932 struct sigmatel_spec *spec = codec->spec;
933 return snd_hda_input_mux_info(&spec->spdif_mux, uinfo);
936 static int stac_smux_enum_get(struct snd_kcontrol *kcontrol,
937 struct snd_ctl_elem_value *ucontrol)
939 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
940 struct sigmatel_spec *spec = codec->spec;
941 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
943 ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx];
944 return 0;
947 static int stac_smux_enum_put(struct snd_kcontrol *kcontrol,
948 struct snd_ctl_elem_value *ucontrol)
950 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
951 struct sigmatel_spec *spec = codec->spec;
952 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
954 return snd_hda_input_mux_put(codec, &spec->spdif_mux, ucontrol,
955 spec->gen.autocfg.dig_out_pins[smux_idx],
956 &spec->cur_smux[smux_idx]);
959 static struct snd_kcontrol_new stac_smux_mixer = {
960 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
961 .name = "IEC958 Playback Source",
962 /* count set later */
963 .info = stac_smux_enum_info,
964 .get = stac_smux_enum_get,
965 .put = stac_smux_enum_put,
968 static const char * const stac_spdif_labels[] = {
969 "Digital Playback", "Analog Mux 1", "Analog Mux 2", NULL
972 static int stac_create_spdif_mux_ctls(struct hda_codec *codec)
974 struct sigmatel_spec *spec = codec->spec;
975 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
976 const char * const *labels = spec->spdif_labels;
977 struct snd_kcontrol_new *kctl;
978 int i, num_cons;
980 if (cfg->dig_outs < 1)
981 return 0;
983 num_cons = snd_hda_get_num_conns(codec, cfg->dig_out_pins[0]);
984 if (num_cons <= 1)
985 return 0;
987 if (!labels)
988 labels = stac_spdif_labels;
989 for (i = 0; i < num_cons; i++) {
990 if (snd_BUG_ON(!labels[i]))
991 return -EINVAL;
992 snd_hda_add_imux_item(&spec->spdif_mux, labels[i], i, NULL);
995 kctl = snd_hda_gen_add_kctl(&spec->gen, NULL, &stac_smux_mixer);
996 if (!kctl)
997 return -ENOMEM;
998 kctl->count = cfg->dig_outs;
1000 return 0;
1006 static const struct hda_verb stac9200_core_init[] = {
1007 /* set dac0mux for dac converter */
1008 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1012 static const struct hda_verb stac9200_eapd_init[] = {
1013 /* set dac0mux for dac converter */
1014 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1015 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1019 static const struct hda_verb dell_eq_core_init[] = {
1020 /* set master volume to max value without distortion
1021 * and direct control */
1022 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
1026 static const struct hda_verb stac92hd73xx_core_init[] = {
1027 /* set master volume and direct control */
1028 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1032 static const struct hda_verb stac92hd83xxx_core_init[] = {
1033 /* power state controls amps */
1034 { 0x01, AC_VERB_SET_EAPD, 1 << 2},
1038 static const struct hda_verb stac92hd83xxx_hp_zephyr_init[] = {
1039 { 0x22, 0x785, 0x43 },
1040 { 0x22, 0x782, 0xe0 },
1041 { 0x22, 0x795, 0x00 },
1045 static const struct hda_verb stac92hd71bxx_core_init[] = {
1046 /* set master volume and direct control */
1047 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1051 static const struct hda_verb stac92hd71bxx_unmute_core_init[] = {
1052 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */
1053 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1054 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1055 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1059 static const struct hda_verb stac925x_core_init[] = {
1060 /* set dac0mux for dac converter */
1061 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
1062 /* mute the master volume */
1063 { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1067 static const struct hda_verb stac922x_core_init[] = {
1068 /* set master volume and direct control */
1069 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1073 static const struct hda_verb d965_core_init[] = {
1074 /* unmute node 0x1b */
1075 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1076 /* select node 0x03 as DAC */
1077 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
1081 static const struct hda_verb dell_3st_core_init[] = {
1082 /* don't set delta bit */
1083 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
1084 /* unmute node 0x1b */
1085 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1086 /* select node 0x03 as DAC */
1087 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
1091 static const struct hda_verb stac927x_core_init[] = {
1092 /* set master volume and direct control */
1093 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1094 /* enable analog pc beep path */
1095 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
1099 static const struct hda_verb stac927x_volknob_core_init[] = {
1100 /* don't set delta bit */
1101 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
1102 /* enable analog pc beep path */
1103 {0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
1107 static const struct hda_verb stac9205_core_init[] = {
1108 /* set master volume and direct control */
1109 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1110 /* enable analog pc beep path */
1111 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
1115 static const struct snd_kcontrol_new stac92hd73xx_6ch_loopback =
1116 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3);
1118 static const struct snd_kcontrol_new stac92hd73xx_8ch_loopback =
1119 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4);
1121 static const struct snd_kcontrol_new stac92hd73xx_10ch_loopback =
1122 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5);
1124 static const struct snd_kcontrol_new stac92hd71bxx_loopback =
1125 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2);
1127 static const struct snd_kcontrol_new stac9205_loopback =
1128 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1);
1130 static const struct snd_kcontrol_new stac927x_loopback =
1131 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1);
1133 static const struct hda_pintbl ref9200_pin_configs[] = {
1134 { 0x08, 0x01c47010 },
1135 { 0x09, 0x01447010 },
1136 { 0x0d, 0x0221401f },
1137 { 0x0e, 0x01114010 },
1138 { 0x0f, 0x02a19020 },
1139 { 0x10, 0x01a19021 },
1140 { 0x11, 0x90100140 },
1141 { 0x12, 0x01813122 },
1145 static const struct hda_pintbl gateway9200_m4_pin_configs[] = {
1146 { 0x08, 0x400000fe },
1147 { 0x09, 0x404500f4 },
1148 { 0x0d, 0x400100f0 },
1149 { 0x0e, 0x90110010 },
1150 { 0x0f, 0x400100f1 },
1151 { 0x10, 0x02a1902e },
1152 { 0x11, 0x500000f2 },
1153 { 0x12, 0x500000f3 },
1157 static const struct hda_pintbl gateway9200_m4_2_pin_configs[] = {
1158 { 0x08, 0x400000fe },
1159 { 0x09, 0x404500f4 },
1160 { 0x0d, 0x400100f0 },
1161 { 0x0e, 0x90110010 },
1162 { 0x0f, 0x400100f1 },
1163 { 0x10, 0x02a1902e },
1164 { 0x11, 0x500000f2 },
1165 { 0x12, 0x500000f3 },
1170 STAC 9200 pin configs for
1171 102801A8
1172 102801DE
1173 102801E8
1175 static const struct hda_pintbl dell9200_d21_pin_configs[] = {
1176 { 0x08, 0x400001f0 },
1177 { 0x09, 0x400001f1 },
1178 { 0x0d, 0x02214030 },
1179 { 0x0e, 0x01014010 },
1180 { 0x0f, 0x02a19020 },
1181 { 0x10, 0x01a19021 },
1182 { 0x11, 0x90100140 },
1183 { 0x12, 0x01813122 },
1188 STAC 9200 pin configs for
1189 102801C0
1190 102801C1
1192 static const struct hda_pintbl dell9200_d22_pin_configs[] = {
1193 { 0x08, 0x400001f0 },
1194 { 0x09, 0x400001f1 },
1195 { 0x0d, 0x0221401f },
1196 { 0x0e, 0x01014010 },
1197 { 0x0f, 0x01813020 },
1198 { 0x10, 0x02a19021 },
1199 { 0x11, 0x90100140 },
1200 { 0x12, 0x400001f2 },
1205 STAC 9200 pin configs for
1206 102801C4 (Dell Dimension E310)
1207 102801C5
1208 102801C7
1209 102801D9
1210 102801DA
1211 102801E3
1213 static const struct hda_pintbl dell9200_d23_pin_configs[] = {
1214 { 0x08, 0x400001f0 },
1215 { 0x09, 0x400001f1 },
1216 { 0x0d, 0x0221401f },
1217 { 0x0e, 0x01014010 },
1218 { 0x0f, 0x01813020 },
1219 { 0x10, 0x01a19021 },
1220 { 0x11, 0x90100140 },
1221 { 0x12, 0x400001f2 },
1227 STAC 9200-32 pin configs for
1228 102801B5 (Dell Inspiron 630m)
1229 102801D8 (Dell Inspiron 640m)
1231 static const struct hda_pintbl dell9200_m21_pin_configs[] = {
1232 { 0x08, 0x40c003fa },
1233 { 0x09, 0x03441340 },
1234 { 0x0d, 0x0321121f },
1235 { 0x0e, 0x90170310 },
1236 { 0x0f, 0x408003fb },
1237 { 0x10, 0x03a11020 },
1238 { 0x11, 0x401003fc },
1239 { 0x12, 0x403003fd },
1244 STAC 9200-32 pin configs for
1245 102801C2 (Dell Latitude D620)
1246 102801C8
1247 102801CC (Dell Latitude D820)
1248 102801D4
1249 102801D6
1251 static const struct hda_pintbl dell9200_m22_pin_configs[] = {
1252 { 0x08, 0x40c003fa },
1253 { 0x09, 0x0144131f },
1254 { 0x0d, 0x0321121f },
1255 { 0x0e, 0x90170310 },
1256 { 0x0f, 0x90a70321 },
1257 { 0x10, 0x03a11020 },
1258 { 0x11, 0x401003fb },
1259 { 0x12, 0x40f000fc },
1264 STAC 9200-32 pin configs for
1265 102801CE (Dell XPS M1710)
1266 102801CF (Dell Precision M90)
1268 static const struct hda_pintbl dell9200_m23_pin_configs[] = {
1269 { 0x08, 0x40c003fa },
1270 { 0x09, 0x01441340 },
1271 { 0x0d, 0x0421421f },
1272 { 0x0e, 0x90170310 },
1273 { 0x0f, 0x408003fb },
1274 { 0x10, 0x04a1102e },
1275 { 0x11, 0x90170311 },
1276 { 0x12, 0x403003fc },
1281 STAC 9200-32 pin configs for
1282 102801C9
1283 102801CA
1284 102801CB (Dell Latitude 120L)
1285 102801D3
1287 static const struct hda_pintbl dell9200_m24_pin_configs[] = {
1288 { 0x08, 0x40c003fa },
1289 { 0x09, 0x404003fb },
1290 { 0x0d, 0x0321121f },
1291 { 0x0e, 0x90170310 },
1292 { 0x0f, 0x408003fc },
1293 { 0x10, 0x03a11020 },
1294 { 0x11, 0x401003fd },
1295 { 0x12, 0x403003fe },
1300 STAC 9200-32 pin configs for
1301 102801BD (Dell Inspiron E1505n)
1302 102801EE
1303 102801EF
1305 static const struct hda_pintbl dell9200_m25_pin_configs[] = {
1306 { 0x08, 0x40c003fa },
1307 { 0x09, 0x01441340 },
1308 { 0x0d, 0x0421121f },
1309 { 0x0e, 0x90170310 },
1310 { 0x0f, 0x408003fb },
1311 { 0x10, 0x04a11020 },
1312 { 0x11, 0x401003fc },
1313 { 0x12, 0x403003fd },
1318 STAC 9200-32 pin configs for
1319 102801F5 (Dell Inspiron 1501)
1320 102801F6
1322 static const struct hda_pintbl dell9200_m26_pin_configs[] = {
1323 { 0x08, 0x40c003fa },
1324 { 0x09, 0x404003fb },
1325 { 0x0d, 0x0421121f },
1326 { 0x0e, 0x90170310 },
1327 { 0x0f, 0x408003fc },
1328 { 0x10, 0x04a11020 },
1329 { 0x11, 0x401003fd },
1330 { 0x12, 0x403003fe },
1335 STAC 9200-32
1336 102801CD (Dell Inspiron E1705/9400)
1338 static const struct hda_pintbl dell9200_m27_pin_configs[] = {
1339 { 0x08, 0x40c003fa },
1340 { 0x09, 0x01441340 },
1341 { 0x0d, 0x0421121f },
1342 { 0x0e, 0x90170310 },
1343 { 0x0f, 0x90170310 },
1344 { 0x10, 0x04a11020 },
1345 { 0x11, 0x90170310 },
1346 { 0x12, 0x40f003fc },
1350 static const struct hda_pintbl oqo9200_pin_configs[] = {
1351 { 0x08, 0x40c000f0 },
1352 { 0x09, 0x404000f1 },
1353 { 0x0d, 0x0221121f },
1354 { 0x0e, 0x02211210 },
1355 { 0x0f, 0x90170111 },
1356 { 0x10, 0x90a70120 },
1357 { 0x11, 0x400000f2 },
1358 { 0x12, 0x400000f3 },
1363 static void stac9200_fixup_panasonic(struct hda_codec *codec,
1364 const struct hda_fixup *fix, int action)
1366 struct sigmatel_spec *spec = codec->spec;
1368 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1369 spec->gpio_mask = spec->gpio_dir = 0x09;
1370 spec->gpio_data = 0x00;
1371 /* CF-74 has no headphone detection, and the driver should *NOT*
1372 * do detection and HP/speaker toggle because the hardware does it.
1374 spec->gen.suppress_auto_mute = 1;
1379 static const struct hda_fixup stac9200_fixups[] = {
1380 [STAC_REF] = {
1381 .type = HDA_FIXUP_PINS,
1382 .v.pins = ref9200_pin_configs,
1384 [STAC_9200_OQO] = {
1385 .type = HDA_FIXUP_PINS,
1386 .v.pins = oqo9200_pin_configs,
1387 .chained = true,
1388 .chain_id = STAC_9200_EAPD_INIT,
1390 [STAC_9200_DELL_D21] = {
1391 .type = HDA_FIXUP_PINS,
1392 .v.pins = dell9200_d21_pin_configs,
1394 [STAC_9200_DELL_D22] = {
1395 .type = HDA_FIXUP_PINS,
1396 .v.pins = dell9200_d22_pin_configs,
1398 [STAC_9200_DELL_D23] = {
1399 .type = HDA_FIXUP_PINS,
1400 .v.pins = dell9200_d23_pin_configs,
1402 [STAC_9200_DELL_M21] = {
1403 .type = HDA_FIXUP_PINS,
1404 .v.pins = dell9200_m21_pin_configs,
1406 [STAC_9200_DELL_M22] = {
1407 .type = HDA_FIXUP_PINS,
1408 .v.pins = dell9200_m22_pin_configs,
1410 [STAC_9200_DELL_M23] = {
1411 .type = HDA_FIXUP_PINS,
1412 .v.pins = dell9200_m23_pin_configs,
1414 [STAC_9200_DELL_M24] = {
1415 .type = HDA_FIXUP_PINS,
1416 .v.pins = dell9200_m24_pin_configs,
1418 [STAC_9200_DELL_M25] = {
1419 .type = HDA_FIXUP_PINS,
1420 .v.pins = dell9200_m25_pin_configs,
1422 [STAC_9200_DELL_M26] = {
1423 .type = HDA_FIXUP_PINS,
1424 .v.pins = dell9200_m26_pin_configs,
1426 [STAC_9200_DELL_M27] = {
1427 .type = HDA_FIXUP_PINS,
1428 .v.pins = dell9200_m27_pin_configs,
1430 [STAC_9200_M4] = {
1431 .type = HDA_FIXUP_PINS,
1432 .v.pins = gateway9200_m4_pin_configs,
1433 .chained = true,
1434 .chain_id = STAC_9200_EAPD_INIT,
1436 [STAC_9200_M4_2] = {
1437 .type = HDA_FIXUP_PINS,
1438 .v.pins = gateway9200_m4_2_pin_configs,
1439 .chained = true,
1440 .chain_id = STAC_9200_EAPD_INIT,
1442 [STAC_9200_PANASONIC] = {
1443 .type = HDA_FIXUP_FUNC,
1444 .v.func = stac9200_fixup_panasonic,
1446 [STAC_9200_EAPD_INIT] = {
1447 .type = HDA_FIXUP_VERBS,
1448 .v.verbs = (const struct hda_verb[]) {
1449 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1455 static const struct hda_model_fixup stac9200_models[] = {
1456 { .id = STAC_REF, .name = "ref" },
1457 { .id = STAC_9200_OQO, .name = "oqo" },
1458 { .id = STAC_9200_DELL_D21, .name = "dell-d21" },
1459 { .id = STAC_9200_DELL_D22, .name = "dell-d22" },
1460 { .id = STAC_9200_DELL_D23, .name = "dell-d23" },
1461 { .id = STAC_9200_DELL_M21, .name = "dell-m21" },
1462 { .id = STAC_9200_DELL_M22, .name = "dell-m22" },
1463 { .id = STAC_9200_DELL_M23, .name = "dell-m23" },
1464 { .id = STAC_9200_DELL_M24, .name = "dell-m24" },
1465 { .id = STAC_9200_DELL_M25, .name = "dell-m25" },
1466 { .id = STAC_9200_DELL_M26, .name = "dell-m26" },
1467 { .id = STAC_9200_DELL_M27, .name = "dell-m27" },
1468 { .id = STAC_9200_M4, .name = "gateway-m4" },
1469 { .id = STAC_9200_M4_2, .name = "gateway-m4-2" },
1470 { .id = STAC_9200_PANASONIC, .name = "panasonic" },
1474 static const struct snd_pci_quirk stac9200_fixup_tbl[] = {
1475 /* SigmaTel reference board */
1476 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1477 "DFI LanParty", STAC_REF),
1478 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
1479 "DFI LanParty", STAC_REF),
1480 /* Dell laptops have BIOS problem */
1481 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
1482 "unknown Dell", STAC_9200_DELL_D21),
1483 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
1484 "Dell Inspiron 630m", STAC_9200_DELL_M21),
1485 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
1486 "Dell Inspiron E1505n", STAC_9200_DELL_M25),
1487 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
1488 "unknown Dell", STAC_9200_DELL_D22),
1489 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
1490 "unknown Dell", STAC_9200_DELL_D22),
1491 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
1492 "Dell Latitude D620", STAC_9200_DELL_M22),
1493 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
1494 "unknown Dell", STAC_9200_DELL_D23),
1495 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
1496 "unknown Dell", STAC_9200_DELL_D23),
1497 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
1498 "unknown Dell", STAC_9200_DELL_M22),
1499 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
1500 "unknown Dell", STAC_9200_DELL_M24),
1501 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
1502 "unknown Dell", STAC_9200_DELL_M24),
1503 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
1504 "Dell Latitude 120L", STAC_9200_DELL_M24),
1505 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
1506 "Dell Latitude D820", STAC_9200_DELL_M22),
1507 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
1508 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
1509 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
1510 "Dell XPS M1710", STAC_9200_DELL_M23),
1511 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
1512 "Dell Precision M90", STAC_9200_DELL_M23),
1513 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
1514 "unknown Dell", STAC_9200_DELL_M22),
1515 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
1516 "unknown Dell", STAC_9200_DELL_M22),
1517 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
1518 "unknown Dell", STAC_9200_DELL_M22),
1519 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
1520 "Dell Inspiron 640m", STAC_9200_DELL_M21),
1521 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
1522 "unknown Dell", STAC_9200_DELL_D23),
1523 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
1524 "unknown Dell", STAC_9200_DELL_D23),
1525 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
1526 "unknown Dell", STAC_9200_DELL_D21),
1527 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
1528 "unknown Dell", STAC_9200_DELL_D23),
1529 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
1530 "unknown Dell", STAC_9200_DELL_D21),
1531 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
1532 "unknown Dell", STAC_9200_DELL_M25),
1533 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
1534 "unknown Dell", STAC_9200_DELL_M25),
1535 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
1536 "Dell Inspiron 1501", STAC_9200_DELL_M26),
1537 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
1538 "unknown Dell", STAC_9200_DELL_M26),
1539 /* Panasonic */
1540 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC),
1541 /* Gateway machines needs EAPD to be set on resume */
1542 SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_M4),
1543 SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", STAC_9200_M4_2),
1544 SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", STAC_9200_M4_2),
1545 /* OQO Mobile */
1546 SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO),
1547 {} /* terminator */
1550 static const struct hda_pintbl ref925x_pin_configs[] = {
1551 { 0x07, 0x40c003f0 },
1552 { 0x08, 0x424503f2 },
1553 { 0x0a, 0x01813022 },
1554 { 0x0b, 0x02a19021 },
1555 { 0x0c, 0x90a70320 },
1556 { 0x0d, 0x02214210 },
1557 { 0x10, 0x01019020 },
1558 { 0x11, 0x9033032e },
1562 static const struct hda_pintbl stac925xM1_pin_configs[] = {
1563 { 0x07, 0x40c003f4 },
1564 { 0x08, 0x424503f2 },
1565 { 0x0a, 0x400000f3 },
1566 { 0x0b, 0x02a19020 },
1567 { 0x0c, 0x40a000f0 },
1568 { 0x0d, 0x90100210 },
1569 { 0x10, 0x400003f1 },
1570 { 0x11, 0x9033032e },
1574 static const struct hda_pintbl stac925xM1_2_pin_configs[] = {
1575 { 0x07, 0x40c003f4 },
1576 { 0x08, 0x424503f2 },
1577 { 0x0a, 0x400000f3 },
1578 { 0x0b, 0x02a19020 },
1579 { 0x0c, 0x40a000f0 },
1580 { 0x0d, 0x90100210 },
1581 { 0x10, 0x400003f1 },
1582 { 0x11, 0x9033032e },
1586 static const struct hda_pintbl stac925xM2_pin_configs[] = {
1587 { 0x07, 0x40c003f4 },
1588 { 0x08, 0x424503f2 },
1589 { 0x0a, 0x400000f3 },
1590 { 0x0b, 0x02a19020 },
1591 { 0x0c, 0x40a000f0 },
1592 { 0x0d, 0x90100210 },
1593 { 0x10, 0x400003f1 },
1594 { 0x11, 0x9033032e },
1598 static const struct hda_pintbl stac925xM2_2_pin_configs[] = {
1599 { 0x07, 0x40c003f4 },
1600 { 0x08, 0x424503f2 },
1601 { 0x0a, 0x400000f3 },
1602 { 0x0b, 0x02a19020 },
1603 { 0x0c, 0x40a000f0 },
1604 { 0x0d, 0x90100210 },
1605 { 0x10, 0x400003f1 },
1606 { 0x11, 0x9033032e },
1610 static const struct hda_pintbl stac925xM3_pin_configs[] = {
1611 { 0x07, 0x40c003f4 },
1612 { 0x08, 0x424503f2 },
1613 { 0x0a, 0x400000f3 },
1614 { 0x0b, 0x02a19020 },
1615 { 0x0c, 0x40a000f0 },
1616 { 0x0d, 0x90100210 },
1617 { 0x10, 0x400003f1 },
1618 { 0x11, 0x503303f3 },
1622 static const struct hda_pintbl stac925xM5_pin_configs[] = {
1623 { 0x07, 0x40c003f4 },
1624 { 0x08, 0x424503f2 },
1625 { 0x0a, 0x400000f3 },
1626 { 0x0b, 0x02a19020 },
1627 { 0x0c, 0x40a000f0 },
1628 { 0x0d, 0x90100210 },
1629 { 0x10, 0x400003f1 },
1630 { 0x11, 0x9033032e },
1634 static const struct hda_pintbl stac925xM6_pin_configs[] = {
1635 { 0x07, 0x40c003f4 },
1636 { 0x08, 0x424503f2 },
1637 { 0x0a, 0x400000f3 },
1638 { 0x0b, 0x02a19020 },
1639 { 0x0c, 0x40a000f0 },
1640 { 0x0d, 0x90100210 },
1641 { 0x10, 0x400003f1 },
1642 { 0x11, 0x90330320 },
1646 static const struct hda_fixup stac925x_fixups[] = {
1647 [STAC_REF] = {
1648 .type = HDA_FIXUP_PINS,
1649 .v.pins = ref925x_pin_configs,
1651 [STAC_M1] = {
1652 .type = HDA_FIXUP_PINS,
1653 .v.pins = stac925xM1_pin_configs,
1655 [STAC_M1_2] = {
1656 .type = HDA_FIXUP_PINS,
1657 .v.pins = stac925xM1_2_pin_configs,
1659 [STAC_M2] = {
1660 .type = HDA_FIXUP_PINS,
1661 .v.pins = stac925xM2_pin_configs,
1663 [STAC_M2_2] = {
1664 .type = HDA_FIXUP_PINS,
1665 .v.pins = stac925xM2_2_pin_configs,
1667 [STAC_M3] = {
1668 .type = HDA_FIXUP_PINS,
1669 .v.pins = stac925xM3_pin_configs,
1671 [STAC_M5] = {
1672 .type = HDA_FIXUP_PINS,
1673 .v.pins = stac925xM5_pin_configs,
1675 [STAC_M6] = {
1676 .type = HDA_FIXUP_PINS,
1677 .v.pins = stac925xM6_pin_configs,
1681 static const struct hda_model_fixup stac925x_models[] = {
1682 { .id = STAC_REF, .name = "ref" },
1683 { .id = STAC_M1, .name = "m1" },
1684 { .id = STAC_M1_2, .name = "m1-2" },
1685 { .id = STAC_M2, .name = "m2" },
1686 { .id = STAC_M2_2, .name = "m2-2" },
1687 { .id = STAC_M3, .name = "m3" },
1688 { .id = STAC_M5, .name = "m5" },
1689 { .id = STAC_M6, .name = "m6" },
1693 static const struct snd_pci_quirk stac925x_fixup_tbl[] = {
1694 /* SigmaTel reference board */
1695 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
1696 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF),
1697 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
1699 /* Default table for unknown ID */
1700 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2),
1702 /* gateway machines are checked via codec ssid */
1703 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2),
1704 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5),
1705 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1),
1706 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_M2),
1707 SND_PCI_QUIRK(0x107b, 0x0367, "Gateway MX6453", STAC_M1_2),
1708 /* Not sure about the brand name for those */
1709 SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M1),
1710 SND_PCI_QUIRK(0x107b, 0x0507, "Gateway mobile", STAC_M3),
1711 SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M6),
1712 SND_PCI_QUIRK(0x107b, 0x0685, "Gateway mobile", STAC_M2_2),
1713 {} /* terminator */
1716 static const struct hda_pintbl ref92hd73xx_pin_configs[] = {
1717 { 0x0a, 0x02214030 },
1718 { 0x0b, 0x02a19040 },
1719 { 0x0c, 0x01a19020 },
1720 { 0x0d, 0x02214030 },
1721 { 0x0e, 0x0181302e },
1722 { 0x0f, 0x01014010 },
1723 { 0x10, 0x01014020 },
1724 { 0x11, 0x01014030 },
1725 { 0x12, 0x02319040 },
1726 { 0x13, 0x90a000f0 },
1727 { 0x14, 0x90a000f0 },
1728 { 0x22, 0x01452050 },
1729 { 0x23, 0x01452050 },
1733 static const struct hda_pintbl dell_m6_pin_configs[] = {
1734 { 0x0a, 0x0321101f },
1735 { 0x0b, 0x4f00000f },
1736 { 0x0c, 0x4f0000f0 },
1737 { 0x0d, 0x90170110 },
1738 { 0x0e, 0x03a11020 },
1739 { 0x0f, 0x0321101f },
1740 { 0x10, 0x4f0000f0 },
1741 { 0x11, 0x4f0000f0 },
1742 { 0x12, 0x4f0000f0 },
1743 { 0x13, 0x90a60160 },
1744 { 0x14, 0x4f0000f0 },
1745 { 0x22, 0x4f0000f0 },
1746 { 0x23, 0x4f0000f0 },
1750 static const struct hda_pintbl alienware_m17x_pin_configs[] = {
1751 { 0x0a, 0x0321101f },
1752 { 0x0b, 0x0321101f },
1753 { 0x0c, 0x03a11020 },
1754 { 0x0d, 0x03014020 },
1755 { 0x0e, 0x90170110 },
1756 { 0x0f, 0x4f0000f0 },
1757 { 0x10, 0x4f0000f0 },
1758 { 0x11, 0x4f0000f0 },
1759 { 0x12, 0x4f0000f0 },
1760 { 0x13, 0x90a60160 },
1761 { 0x14, 0x4f0000f0 },
1762 { 0x22, 0x4f0000f0 },
1763 { 0x23, 0x904601b0 },
1767 static const struct hda_pintbl intel_dg45id_pin_configs[] = {
1768 { 0x0a, 0x02214230 },
1769 { 0x0b, 0x02A19240 },
1770 { 0x0c, 0x01013214 },
1771 { 0x0d, 0x01014210 },
1772 { 0x0e, 0x01A19250 },
1773 { 0x0f, 0x01011212 },
1774 { 0x10, 0x01016211 },
1778 static void stac92hd73xx_fixup_ref(struct hda_codec *codec,
1779 const struct hda_fixup *fix, int action)
1781 struct sigmatel_spec *spec = codec->spec;
1783 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1784 return;
1786 snd_hda_apply_pincfgs(codec, ref92hd73xx_pin_configs);
1787 spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0;
1790 static void stac92hd73xx_fixup_dell(struct hda_codec *codec)
1792 struct sigmatel_spec *spec = codec->spec;
1794 snd_hda_apply_pincfgs(codec, dell_m6_pin_configs);
1795 spec->eapd_switch = 0;
1798 static void stac92hd73xx_fixup_dell_eq(struct hda_codec *codec,
1799 const struct hda_fixup *fix, int action)
1801 struct sigmatel_spec *spec = codec->spec;
1803 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1804 return;
1806 stac92hd73xx_fixup_dell(codec);
1807 snd_hda_add_verbs(codec, dell_eq_core_init);
1808 spec->volknob_init = 1;
1811 /* Analog Mics */
1812 static void stac92hd73xx_fixup_dell_m6_amic(struct hda_codec *codec,
1813 const struct hda_fixup *fix, int action)
1815 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1816 return;
1818 stac92hd73xx_fixup_dell(codec);
1819 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
1822 /* Digital Mics */
1823 static void stac92hd73xx_fixup_dell_m6_dmic(struct hda_codec *codec,
1824 const struct hda_fixup *fix, int action)
1826 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1827 return;
1829 stac92hd73xx_fixup_dell(codec);
1830 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
1833 /* Both */
1834 static void stac92hd73xx_fixup_dell_m6_both(struct hda_codec *codec,
1835 const struct hda_fixup *fix, int action)
1837 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1838 return;
1840 stac92hd73xx_fixup_dell(codec);
1841 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
1842 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
1845 static void stac92hd73xx_fixup_alienware_m17x(struct hda_codec *codec,
1846 const struct hda_fixup *fix, int action)
1848 struct sigmatel_spec *spec = codec->spec;
1850 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1851 return;
1853 snd_hda_apply_pincfgs(codec, alienware_m17x_pin_configs);
1854 spec->eapd_switch = 0;
1857 static void stac92hd73xx_fixup_no_jd(struct hda_codec *codec,
1858 const struct hda_fixup *fix, int action)
1860 if (action == HDA_FIXUP_ACT_PRE_PROBE)
1861 codec->no_jack_detect = 1;
1864 static const struct hda_fixup stac92hd73xx_fixups[] = {
1865 [STAC_92HD73XX_REF] = {
1866 .type = HDA_FIXUP_FUNC,
1867 .v.func = stac92hd73xx_fixup_ref,
1869 [STAC_DELL_M6_AMIC] = {
1870 .type = HDA_FIXUP_FUNC,
1871 .v.func = stac92hd73xx_fixup_dell_m6_amic,
1873 [STAC_DELL_M6_DMIC] = {
1874 .type = HDA_FIXUP_FUNC,
1875 .v.func = stac92hd73xx_fixup_dell_m6_dmic,
1877 [STAC_DELL_M6_BOTH] = {
1878 .type = HDA_FIXUP_FUNC,
1879 .v.func = stac92hd73xx_fixup_dell_m6_both,
1881 [STAC_DELL_EQ] = {
1882 .type = HDA_FIXUP_FUNC,
1883 .v.func = stac92hd73xx_fixup_dell_eq,
1885 [STAC_ALIENWARE_M17X] = {
1886 .type = HDA_FIXUP_FUNC,
1887 .v.func = stac92hd73xx_fixup_alienware_m17x,
1889 [STAC_92HD73XX_INTEL] = {
1890 .type = HDA_FIXUP_PINS,
1891 .v.pins = intel_dg45id_pin_configs,
1893 [STAC_92HD73XX_NO_JD] = {
1894 .type = HDA_FIXUP_FUNC,
1895 .v.func = stac92hd73xx_fixup_no_jd,
1899 static const struct hda_model_fixup stac92hd73xx_models[] = {
1900 { .id = STAC_92HD73XX_NO_JD, .name = "no-jd" },
1901 { .id = STAC_92HD73XX_REF, .name = "ref" },
1902 { .id = STAC_92HD73XX_INTEL, .name = "intel" },
1903 { .id = STAC_DELL_M6_AMIC, .name = "dell-m6-amic" },
1904 { .id = STAC_DELL_M6_DMIC, .name = "dell-m6-dmic" },
1905 { .id = STAC_DELL_M6_BOTH, .name = "dell-m6" },
1906 { .id = STAC_DELL_EQ, .name = "dell-eq" },
1907 { .id = STAC_ALIENWARE_M17X, .name = "alienware" },
1911 static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = {
1912 /* SigmaTel reference board */
1913 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1914 "DFI LanParty", STAC_92HD73XX_REF),
1915 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
1916 "DFI LanParty", STAC_92HD73XX_REF),
1917 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5002,
1918 "Intel DG45ID", STAC_92HD73XX_INTEL),
1919 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5003,
1920 "Intel DG45FC", STAC_92HD73XX_INTEL),
1921 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254,
1922 "Dell Studio 1535", STAC_DELL_M6_DMIC),
1923 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255,
1924 "unknown Dell", STAC_DELL_M6_DMIC),
1925 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256,
1926 "unknown Dell", STAC_DELL_M6_BOTH),
1927 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257,
1928 "unknown Dell", STAC_DELL_M6_BOTH),
1929 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e,
1930 "unknown Dell", STAC_DELL_M6_AMIC),
1931 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f,
1932 "unknown Dell", STAC_DELL_M6_AMIC),
1933 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271,
1934 "unknown Dell", STAC_DELL_M6_DMIC),
1935 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0272,
1936 "unknown Dell", STAC_DELL_M6_DMIC),
1937 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f,
1938 "Dell Studio 1537", STAC_DELL_M6_DMIC),
1939 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a0,
1940 "Dell Studio 17", STAC_DELL_M6_DMIC),
1941 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02be,
1942 "Dell Studio 1555", STAC_DELL_M6_DMIC),
1943 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd,
1944 "Dell Studio 1557", STAC_DELL_M6_DMIC),
1945 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe,
1946 "Dell Studio XPS 1645", STAC_DELL_M6_DMIC),
1947 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413,
1948 "Dell Studio 1558", STAC_DELL_M6_DMIC),
1949 /* codec SSID matching */
1950 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1,
1951 "Alienware M17x", STAC_ALIENWARE_M17X),
1952 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
1953 "Alienware M17x", STAC_ALIENWARE_M17X),
1954 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490,
1955 "Alienware M17x R3", STAC_DELL_EQ),
1956 {} /* terminator */
1959 static const struct hda_pintbl ref92hd83xxx_pin_configs[] = {
1960 { 0x0a, 0x02214030 },
1961 { 0x0b, 0x02211010 },
1962 { 0x0c, 0x02a19020 },
1963 { 0x0d, 0x02170130 },
1964 { 0x0e, 0x01014050 },
1965 { 0x0f, 0x01819040 },
1966 { 0x10, 0x01014020 },
1967 { 0x11, 0x90a3014e },
1968 { 0x1f, 0x01451160 },
1969 { 0x20, 0x98560170 },
1973 static const struct hda_pintbl dell_s14_pin_configs[] = {
1974 { 0x0a, 0x0221403f },
1975 { 0x0b, 0x0221101f },
1976 { 0x0c, 0x02a19020 },
1977 { 0x0d, 0x90170110 },
1978 { 0x0e, 0x40f000f0 },
1979 { 0x0f, 0x40f000f0 },
1980 { 0x10, 0x40f000f0 },
1981 { 0x11, 0x90a60160 },
1982 { 0x1f, 0x40f000f0 },
1983 { 0x20, 0x40f000f0 },
1987 static const struct hda_pintbl dell_vostro_3500_pin_configs[] = {
1988 { 0x0a, 0x02a11020 },
1989 { 0x0b, 0x0221101f },
1990 { 0x0c, 0x400000f0 },
1991 { 0x0d, 0x90170110 },
1992 { 0x0e, 0x400000f1 },
1993 { 0x0f, 0x400000f2 },
1994 { 0x10, 0x400000f3 },
1995 { 0x11, 0x90a60160 },
1996 { 0x1f, 0x400000f4 },
1997 { 0x20, 0x400000f5 },
2001 static const struct hda_pintbl hp_dv7_4000_pin_configs[] = {
2002 { 0x0a, 0x03a12050 },
2003 { 0x0b, 0x0321201f },
2004 { 0x0c, 0x40f000f0 },
2005 { 0x0d, 0x90170110 },
2006 { 0x0e, 0x40f000f0 },
2007 { 0x0f, 0x40f000f0 },
2008 { 0x10, 0x90170110 },
2009 { 0x11, 0xd5a30140 },
2010 { 0x1f, 0x40f000f0 },
2011 { 0x20, 0x40f000f0 },
2015 static const struct hda_pintbl hp_zephyr_pin_configs[] = {
2016 { 0x0a, 0x01813050 },
2017 { 0x0b, 0x0421201f },
2018 { 0x0c, 0x04a1205e },
2019 { 0x0d, 0x96130310 },
2020 { 0x0e, 0x96130310 },
2021 { 0x0f, 0x0101401f },
2022 { 0x10, 0x1111611f },
2023 { 0x11, 0xd5a30130 },
2027 static const struct hda_pintbl hp_cNB11_intquad_pin_configs[] = {
2028 { 0x0a, 0x40f000f0 },
2029 { 0x0b, 0x0221101f },
2030 { 0x0c, 0x02a11020 },
2031 { 0x0d, 0x92170110 },
2032 { 0x0e, 0x40f000f0 },
2033 { 0x0f, 0x92170110 },
2034 { 0x10, 0x40f000f0 },
2035 { 0x11, 0xd5a30130 },
2036 { 0x1f, 0x40f000f0 },
2037 { 0x20, 0x40f000f0 },
2041 static void stac92hd83xxx_fixup_hp(struct hda_codec *codec,
2042 const struct hda_fixup *fix, int action)
2044 struct sigmatel_spec *spec = codec->spec;
2046 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2047 return;
2049 if (hp_bnb2011_with_dock(codec)) {
2050 snd_hda_codec_set_pincfg(codec, 0xa, 0x2101201f);
2051 snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);
2054 if (find_mute_led_cfg(codec, spec->default_polarity))
2055 snd_printd("mute LED gpio %d polarity %d\n",
2056 spec->gpio_led,
2057 spec->gpio_led_polarity);
2060 static void stac92hd83xxx_fixup_hp_zephyr(struct hda_codec *codec,
2061 const struct hda_fixup *fix, int action)
2063 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2064 return;
2066 snd_hda_apply_pincfgs(codec, hp_zephyr_pin_configs);
2067 snd_hda_add_verbs(codec, stac92hd83xxx_hp_zephyr_init);
2070 static void stac92hd83xxx_fixup_hp_led(struct hda_codec *codec,
2071 const struct hda_fixup *fix, int action)
2073 struct sigmatel_spec *spec = codec->spec;
2075 if (action == HDA_FIXUP_ACT_PRE_PROBE)
2076 spec->default_polarity = 0;
2079 static void stac92hd83xxx_fixup_hp_inv_led(struct hda_codec *codec,
2080 const struct hda_fixup *fix, int action)
2082 struct sigmatel_spec *spec = codec->spec;
2084 if (action == HDA_FIXUP_ACT_PRE_PROBE)
2085 spec->default_polarity = 1;
2088 static void stac92hd83xxx_fixup_hp_mic_led(struct hda_codec *codec,
2089 const struct hda_fixup *fix, int action)
2091 struct sigmatel_spec *spec = codec->spec;
2093 if (action == HDA_FIXUP_ACT_PRE_PROBE)
2094 spec->mic_mute_led_gpio = 0x08; /* GPIO3 */
2097 static void stac92hd83xxx_fixup_headset_jack(struct hda_codec *codec,
2098 const struct hda_fixup *fix, int action)
2100 struct sigmatel_spec *spec = codec->spec;
2102 if (action == HDA_FIXUP_ACT_PRE_PROBE)
2103 spec->headset_jack = 1;
2106 static const struct hda_fixup stac92hd83xxx_fixups[] = {
2107 [STAC_92HD83XXX_REF] = {
2108 .type = HDA_FIXUP_PINS,
2109 .v.pins = ref92hd83xxx_pin_configs,
2111 [STAC_92HD83XXX_PWR_REF] = {
2112 .type = HDA_FIXUP_PINS,
2113 .v.pins = ref92hd83xxx_pin_configs,
2115 [STAC_DELL_S14] = {
2116 .type = HDA_FIXUP_PINS,
2117 .v.pins = dell_s14_pin_configs,
2119 [STAC_DELL_VOSTRO_3500] = {
2120 .type = HDA_FIXUP_PINS,
2121 .v.pins = dell_vostro_3500_pin_configs,
2123 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = {
2124 .type = HDA_FIXUP_PINS,
2125 .v.pins = hp_cNB11_intquad_pin_configs,
2126 .chained = true,
2127 .chain_id = STAC_92HD83XXX_HP,
2129 [STAC_92HD83XXX_HP] = {
2130 .type = HDA_FIXUP_FUNC,
2131 .v.func = stac92hd83xxx_fixup_hp,
2133 [STAC_HP_DV7_4000] = {
2134 .type = HDA_FIXUP_PINS,
2135 .v.pins = hp_dv7_4000_pin_configs,
2136 .chained = true,
2137 .chain_id = STAC_92HD83XXX_HP,
2139 [STAC_HP_ZEPHYR] = {
2140 .type = HDA_FIXUP_FUNC,
2141 .v.func = stac92hd83xxx_fixup_hp_zephyr,
2142 .chained = true,
2143 .chain_id = STAC_92HD83XXX_HP,
2145 [STAC_92HD83XXX_HP_LED] = {
2146 .type = HDA_FIXUP_FUNC,
2147 .v.func = stac92hd83xxx_fixup_hp_led,
2148 .chained = true,
2149 .chain_id = STAC_92HD83XXX_HP,
2151 [STAC_92HD83XXX_HP_INV_LED] = {
2152 .type = HDA_FIXUP_FUNC,
2153 .v.func = stac92hd83xxx_fixup_hp_inv_led,
2154 .chained = true,
2155 .chain_id = STAC_92HD83XXX_HP,
2157 [STAC_92HD83XXX_HP_MIC_LED] = {
2158 .type = HDA_FIXUP_FUNC,
2159 .v.func = stac92hd83xxx_fixup_hp_mic_led,
2160 .chained = true,
2161 .chain_id = STAC_92HD83XXX_HP,
2163 [STAC_92HD83XXX_HEADSET_JACK] = {
2164 .type = HDA_FIXUP_FUNC,
2165 .v.func = stac92hd83xxx_fixup_headset_jack,
2167 [STAC_HP_ENVY_BASS] = {
2168 .type = HDA_FIXUP_PINS,
2169 .v.pins = (const struct hda_pintbl[]) {
2170 { 0x0f, 0x90170111 },
2176 static const struct hda_model_fixup stac92hd83xxx_models[] = {
2177 { .id = STAC_92HD83XXX_REF, .name = "ref" },
2178 { .id = STAC_92HD83XXX_PWR_REF, .name = "mic-ref" },
2179 { .id = STAC_DELL_S14, .name = "dell-s14" },
2180 { .id = STAC_DELL_VOSTRO_3500, .name = "dell-vostro-3500" },
2181 { .id = STAC_92HD83XXX_HP_cNB11_INTQUAD, .name = "hp_cNB11_intquad" },
2182 { .id = STAC_HP_DV7_4000, .name = "hp-dv7-4000" },
2183 { .id = STAC_HP_ZEPHYR, .name = "hp-zephyr" },
2184 { .id = STAC_92HD83XXX_HP_LED, .name = "hp-led" },
2185 { .id = STAC_92HD83XXX_HP_INV_LED, .name = "hp-inv-led" },
2186 { .id = STAC_92HD83XXX_HP_MIC_LED, .name = "hp-mic-led" },
2187 { .id = STAC_92HD83XXX_HEADSET_JACK, .name = "headset-jack" },
2188 { .id = STAC_HP_ENVY_BASS, .name = "hp-envy-bass" },
2192 static const struct snd_pci_quirk stac92hd83xxx_fixup_tbl[] = {
2193 /* SigmaTel reference board */
2194 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2195 "DFI LanParty", STAC_92HD83XXX_REF),
2196 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
2197 "DFI LanParty", STAC_92HD83XXX_REF),
2198 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
2199 "unknown Dell", STAC_DELL_S14),
2200 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0532,
2201 "Dell Latitude E6230", STAC_92HD83XXX_HEADSET_JACK),
2202 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0533,
2203 "Dell Latitude E6330", STAC_92HD83XXX_HEADSET_JACK),
2204 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0534,
2205 "Dell Latitude E6430", STAC_92HD83XXX_HEADSET_JACK),
2206 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0535,
2207 "Dell Latitude E6530", STAC_92HD83XXX_HEADSET_JACK),
2208 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053c,
2209 "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
2210 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053d,
2211 "Dell Latitude E5530", STAC_92HD83XXX_HEADSET_JACK),
2212 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0549,
2213 "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
2214 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x057d,
2215 "Dell Latitude E6430s", STAC_92HD83XXX_HEADSET_JACK),
2216 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0584,
2217 "Dell Latitude E6430U", STAC_92HD83XXX_HEADSET_JACK),
2218 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028,
2219 "Dell Vostro 3500", STAC_DELL_VOSTRO_3500),
2220 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
2221 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2222 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657,
2223 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2224 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658,
2225 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2226 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659,
2227 "HP Pavilion dv7", STAC_HP_DV7_4000),
2228 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A,
2229 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2230 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
2231 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2232 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1888,
2233 "HP Envy Spectre", STAC_HP_ENVY_BASS),
2234 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df,
2235 "HP Folio", STAC_92HD83XXX_HP_MIC_LED),
2236 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x1900,
2237 "HP", STAC_92HD83XXX_HP_MIC_LED),
2238 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x2000,
2239 "HP", STAC_92HD83XXX_HP_MIC_LED),
2240 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x2100,
2241 "HP", STAC_92HD83XXX_HP_MIC_LED),
2242 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388,
2243 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2244 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389,
2245 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2246 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355B,
2247 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2248 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355C,
2249 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2250 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355D,
2251 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2252 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355E,
2253 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2254 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355F,
2255 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2256 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3560,
2257 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2258 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358B,
2259 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2260 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358C,
2261 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2262 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358D,
2263 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2264 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3591,
2265 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2266 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3592,
2267 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2268 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
2269 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2270 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
2271 "HP", STAC_HP_ZEPHYR),
2272 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3660,
2273 "HP Mini", STAC_92HD83XXX_HP_LED),
2274 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x144E,
2275 "HP Pavilion dv5", STAC_92HD83XXX_HP_INV_LED),
2276 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x148a,
2277 "HP Mini", STAC_92HD83XXX_HP_LED),
2278 SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_HP, "HP", STAC_92HD83XXX_HP),
2279 {} /* terminator */
2282 /* HP dv7 bass switch - GPIO5 */
2283 #define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info
2284 static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol,
2285 struct snd_ctl_elem_value *ucontrol)
2287 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2288 struct sigmatel_spec *spec = codec->spec;
2289 ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20);
2290 return 0;
2293 static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol,
2294 struct snd_ctl_elem_value *ucontrol)
2296 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2297 struct sigmatel_spec *spec = codec->spec;
2298 unsigned int gpio_data;
2300 gpio_data = (spec->gpio_data & ~0x20) |
2301 (ucontrol->value.integer.value[0] ? 0x20 : 0);
2302 if (gpio_data == spec->gpio_data)
2303 return 0;
2304 spec->gpio_data = gpio_data;
2305 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
2306 return 1;
2309 static const struct snd_kcontrol_new stac_hp_bass_sw_ctrl = {
2310 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2311 .info = stac_hp_bass_gpio_info,
2312 .get = stac_hp_bass_gpio_get,
2313 .put = stac_hp_bass_gpio_put,
2316 static int stac_add_hp_bass_switch(struct hda_codec *codec)
2318 struct sigmatel_spec *spec = codec->spec;
2320 if (!snd_hda_gen_add_kctl(&spec->gen, "Bass Speaker Playback Switch",
2321 &stac_hp_bass_sw_ctrl))
2322 return -ENOMEM;
2324 spec->gpio_mask |= 0x20;
2325 spec->gpio_dir |= 0x20;
2326 spec->gpio_data |= 0x20;
2327 return 0;
2330 static const struct hda_pintbl ref92hd71bxx_pin_configs[] = {
2331 { 0x0a, 0x02214030 },
2332 { 0x0b, 0x02a19040 },
2333 { 0x0c, 0x01a19020 },
2334 { 0x0d, 0x01014010 },
2335 { 0x0e, 0x0181302e },
2336 { 0x0f, 0x01014010 },
2337 { 0x14, 0x01019020 },
2338 { 0x18, 0x90a000f0 },
2339 { 0x19, 0x90a000f0 },
2340 { 0x1e, 0x01452050 },
2341 { 0x1f, 0x01452050 },
2345 static const struct hda_pintbl dell_m4_1_pin_configs[] = {
2346 { 0x0a, 0x0421101f },
2347 { 0x0b, 0x04a11221 },
2348 { 0x0c, 0x40f000f0 },
2349 { 0x0d, 0x90170110 },
2350 { 0x0e, 0x23a1902e },
2351 { 0x0f, 0x23014250 },
2352 { 0x14, 0x40f000f0 },
2353 { 0x18, 0x90a000f0 },
2354 { 0x19, 0x40f000f0 },
2355 { 0x1e, 0x4f0000f0 },
2356 { 0x1f, 0x4f0000f0 },
2360 static const struct hda_pintbl dell_m4_2_pin_configs[] = {
2361 { 0x0a, 0x0421101f },
2362 { 0x0b, 0x04a11221 },
2363 { 0x0c, 0x90a70330 },
2364 { 0x0d, 0x90170110 },
2365 { 0x0e, 0x23a1902e },
2366 { 0x0f, 0x23014250 },
2367 { 0x14, 0x40f000f0 },
2368 { 0x18, 0x40f000f0 },
2369 { 0x19, 0x40f000f0 },
2370 { 0x1e, 0x044413b0 },
2371 { 0x1f, 0x044413b0 },
2375 static const struct hda_pintbl dell_m4_3_pin_configs[] = {
2376 { 0x0a, 0x0421101f },
2377 { 0x0b, 0x04a11221 },
2378 { 0x0c, 0x90a70330 },
2379 { 0x0d, 0x90170110 },
2380 { 0x0e, 0x40f000f0 },
2381 { 0x0f, 0x40f000f0 },
2382 { 0x14, 0x40f000f0 },
2383 { 0x18, 0x90a000f0 },
2384 { 0x19, 0x40f000f0 },
2385 { 0x1e, 0x044413b0 },
2386 { 0x1f, 0x044413b0 },
2390 static void stac92hd71bxx_fixup_ref(struct hda_codec *codec,
2391 const struct hda_fixup *fix, int action)
2393 struct sigmatel_spec *spec = codec->spec;
2395 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2396 return;
2398 snd_hda_apply_pincfgs(codec, ref92hd71bxx_pin_configs);
2399 spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0;
2402 static void stac92hd71bxx_fixup_hp_m4(struct hda_codec *codec,
2403 const struct hda_fixup *fix, int action)
2405 struct sigmatel_spec *spec = codec->spec;
2406 struct hda_jack_tbl *jack;
2408 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2409 return;
2411 /* Enable VREF power saving on GPIO1 detect */
2412 snd_hda_codec_write_cache(codec, codec->afg, 0,
2413 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
2414 snd_hda_jack_detect_enable_callback(codec, codec->afg,
2415 STAC_VREF_EVENT,
2416 stac_vref_event);
2417 jack = snd_hda_jack_tbl_get(codec, codec->afg);
2418 if (jack)
2419 jack->private_data = 0x02;
2421 spec->gpio_mask |= 0x02;
2423 /* enable internal microphone */
2424 snd_hda_codec_set_pincfg(codec, 0x0e, 0x01813040);
2427 static void stac92hd71bxx_fixup_hp_dv4(struct hda_codec *codec,
2428 const struct hda_fixup *fix, int action)
2430 struct sigmatel_spec *spec = codec->spec;
2432 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2433 return;
2434 spec->gpio_led = 0x01;
2437 static void stac92hd71bxx_fixup_hp_dv5(struct hda_codec *codec,
2438 const struct hda_fixup *fix, int action)
2440 unsigned int cap;
2442 switch (action) {
2443 case HDA_FIXUP_ACT_PRE_PROBE:
2444 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
2445 break;
2447 case HDA_FIXUP_ACT_PROBE:
2448 /* enable bass on HP dv7 */
2449 cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
2450 cap &= AC_GPIO_IO_COUNT;
2451 if (cap >= 6)
2452 stac_add_hp_bass_switch(codec);
2453 break;
2457 static void stac92hd71bxx_fixup_hp_hdx(struct hda_codec *codec,
2458 const struct hda_fixup *fix, int action)
2460 struct sigmatel_spec *spec = codec->spec;
2462 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2463 return;
2464 spec->gpio_led = 0x08;
2468 static void stac92hd71bxx_fixup_hp(struct hda_codec *codec,
2469 const struct hda_fixup *fix, int action)
2471 struct sigmatel_spec *spec = codec->spec;
2473 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2474 return;
2476 if (hp_blike_system(codec->subsystem_id)) {
2477 unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f);
2478 if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT ||
2479 get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER ||
2480 get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT) {
2481 /* It was changed in the BIOS to just satisfy MS DTM.
2482 * Lets turn it back into slaved HP
2484 pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE))
2485 | (AC_JACK_HP_OUT <<
2486 AC_DEFCFG_DEVICE_SHIFT);
2487 pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC
2488 | AC_DEFCFG_SEQUENCE)))
2489 | 0x1f;
2490 snd_hda_codec_set_pincfg(codec, 0x0f, pin_cfg);
2494 if (find_mute_led_cfg(codec, 1))
2495 snd_printd("mute LED gpio %d polarity %d\n",
2496 spec->gpio_led,
2497 spec->gpio_led_polarity);
2501 static const struct hda_fixup stac92hd71bxx_fixups[] = {
2502 [STAC_92HD71BXX_REF] = {
2503 .type = HDA_FIXUP_FUNC,
2504 .v.func = stac92hd71bxx_fixup_ref,
2506 [STAC_DELL_M4_1] = {
2507 .type = HDA_FIXUP_PINS,
2508 .v.pins = dell_m4_1_pin_configs,
2510 [STAC_DELL_M4_2] = {
2511 .type = HDA_FIXUP_PINS,
2512 .v.pins = dell_m4_2_pin_configs,
2514 [STAC_DELL_M4_3] = {
2515 .type = HDA_FIXUP_PINS,
2516 .v.pins = dell_m4_3_pin_configs,
2518 [STAC_HP_M4] = {
2519 .type = HDA_FIXUP_FUNC,
2520 .v.func = stac92hd71bxx_fixup_hp_m4,
2521 .chained = true,
2522 .chain_id = STAC_92HD71BXX_HP,
2524 [STAC_HP_DV4] = {
2525 .type = HDA_FIXUP_FUNC,
2526 .v.func = stac92hd71bxx_fixup_hp_dv4,
2527 .chained = true,
2528 .chain_id = STAC_HP_DV5,
2530 [STAC_HP_DV5] = {
2531 .type = HDA_FIXUP_FUNC,
2532 .v.func = stac92hd71bxx_fixup_hp_dv5,
2533 .chained = true,
2534 .chain_id = STAC_92HD71BXX_HP,
2536 [STAC_HP_HDX] = {
2537 .type = HDA_FIXUP_FUNC,
2538 .v.func = stac92hd71bxx_fixup_hp_hdx,
2539 .chained = true,
2540 .chain_id = STAC_92HD71BXX_HP,
2542 [STAC_92HD71BXX_HP] = {
2543 .type = HDA_FIXUP_FUNC,
2544 .v.func = stac92hd71bxx_fixup_hp,
2548 static const struct hda_model_fixup stac92hd71bxx_models[] = {
2549 { .id = STAC_92HD71BXX_REF, .name = "ref" },
2550 { .id = STAC_DELL_M4_1, .name = "dell-m4-1" },
2551 { .id = STAC_DELL_M4_2, .name = "dell-m4-2" },
2552 { .id = STAC_DELL_M4_3, .name = "dell-m4-3" },
2553 { .id = STAC_HP_M4, .name = "hp-m4" },
2554 { .id = STAC_HP_DV4, .name = "hp-dv4" },
2555 { .id = STAC_HP_DV5, .name = "hp-dv5" },
2556 { .id = STAC_HP_HDX, .name = "hp-hdx" },
2557 { .id = STAC_HP_DV4, .name = "hp-dv4-1222nr" },
2561 static const struct snd_pci_quirk stac92hd71bxx_fixup_tbl[] = {
2562 /* SigmaTel reference board */
2563 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2564 "DFI LanParty", STAC_92HD71BXX_REF),
2565 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
2566 "DFI LanParty", STAC_92HD71BXX_REF),
2567 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720,
2568 "HP", STAC_HP_DV5),
2569 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
2570 "HP", STAC_HP_DV5),
2571 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
2572 "HP dv4-7", STAC_HP_DV4),
2573 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600,
2574 "HP dv4-7", STAC_HP_DV5),
2575 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610,
2576 "HP HDX", STAC_HP_HDX), /* HDX18 */
2577 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
2578 "HP mini 1000", STAC_HP_M4),
2579 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b,
2580 "HP HDX", STAC_HP_HDX), /* HDX16 */
2581 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620,
2582 "HP dv6", STAC_HP_DV5),
2583 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061,
2584 "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */
2585 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x363e,
2586 "HP DV6", STAC_HP_DV5),
2587 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010,
2588 "HP", STAC_HP_DV5),
2589 SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_HP, "HP", STAC_92HD71BXX_HP),
2590 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
2591 "unknown Dell", STAC_DELL_M4_1),
2592 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234,
2593 "unknown Dell", STAC_DELL_M4_1),
2594 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0250,
2595 "unknown Dell", STAC_DELL_M4_1),
2596 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024f,
2597 "unknown Dell", STAC_DELL_M4_1),
2598 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024d,
2599 "unknown Dell", STAC_DELL_M4_1),
2600 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0251,
2601 "unknown Dell", STAC_DELL_M4_1),
2602 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0277,
2603 "unknown Dell", STAC_DELL_M4_1),
2604 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0263,
2605 "unknown Dell", STAC_DELL_M4_2),
2606 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0265,
2607 "unknown Dell", STAC_DELL_M4_2),
2608 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0262,
2609 "unknown Dell", STAC_DELL_M4_2),
2610 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264,
2611 "unknown Dell", STAC_DELL_M4_2),
2612 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02aa,
2613 "unknown Dell", STAC_DELL_M4_3),
2614 {} /* terminator */
2617 static const struct hda_pintbl ref922x_pin_configs[] = {
2618 { 0x0a, 0x01014010 },
2619 { 0x0b, 0x01016011 },
2620 { 0x0c, 0x01012012 },
2621 { 0x0d, 0x0221401f },
2622 { 0x0e, 0x01813122 },
2623 { 0x0f, 0x01011014 },
2624 { 0x10, 0x01441030 },
2625 { 0x11, 0x01c41030 },
2626 { 0x15, 0x40000100 },
2627 { 0x1b, 0x40000100 },
2632 STAC 922X pin configs for
2633 102801A7
2634 102801AB
2635 102801A9
2636 102801D1
2637 102801D2
2639 static const struct hda_pintbl dell_922x_d81_pin_configs[] = {
2640 { 0x0a, 0x02214030 },
2641 { 0x0b, 0x01a19021 },
2642 { 0x0c, 0x01111012 },
2643 { 0x0d, 0x01114010 },
2644 { 0x0e, 0x02a19020 },
2645 { 0x0f, 0x01117011 },
2646 { 0x10, 0x400001f0 },
2647 { 0x11, 0x400001f1 },
2648 { 0x15, 0x01813122 },
2649 { 0x1b, 0x400001f2 },
2654 STAC 922X pin configs for
2655 102801AC
2656 102801D0
2658 static const struct hda_pintbl dell_922x_d82_pin_configs[] = {
2659 { 0x0a, 0x02214030 },
2660 { 0x0b, 0x01a19021 },
2661 { 0x0c, 0x01111012 },
2662 { 0x0d, 0x01114010 },
2663 { 0x0e, 0x02a19020 },
2664 { 0x0f, 0x01117011 },
2665 { 0x10, 0x01451140 },
2666 { 0x11, 0x400001f0 },
2667 { 0x15, 0x01813122 },
2668 { 0x1b, 0x400001f1 },
2673 STAC 922X pin configs for
2674 102801BF
2676 static const struct hda_pintbl dell_922x_m81_pin_configs[] = {
2677 { 0x0a, 0x0321101f },
2678 { 0x0b, 0x01112024 },
2679 { 0x0c, 0x01111222 },
2680 { 0x0d, 0x91174220 },
2681 { 0x0e, 0x03a11050 },
2682 { 0x0f, 0x01116221 },
2683 { 0x10, 0x90a70330 },
2684 { 0x11, 0x01452340 },
2685 { 0x15, 0x40C003f1 },
2686 { 0x1b, 0x405003f0 },
2691 STAC 9221 A1 pin configs for
2692 102801D7 (Dell XPS M1210)
2694 static const struct hda_pintbl dell_922x_m82_pin_configs[] = {
2695 { 0x0a, 0x02211211 },
2696 { 0x0b, 0x408103ff },
2697 { 0x0c, 0x02a1123e },
2698 { 0x0d, 0x90100310 },
2699 { 0x0e, 0x408003f1 },
2700 { 0x0f, 0x0221121f },
2701 { 0x10, 0x03451340 },
2702 { 0x11, 0x40c003f2 },
2703 { 0x15, 0x508003f3 },
2704 { 0x1b, 0x405003f4 },
2708 static const struct hda_pintbl d945gtp3_pin_configs[] = {
2709 { 0x0a, 0x0221401f },
2710 { 0x0b, 0x01a19022 },
2711 { 0x0c, 0x01813021 },
2712 { 0x0d, 0x01014010 },
2713 { 0x0e, 0x40000100 },
2714 { 0x0f, 0x40000100 },
2715 { 0x10, 0x40000100 },
2716 { 0x11, 0x40000100 },
2717 { 0x15, 0x02a19120 },
2718 { 0x1b, 0x40000100 },
2722 static const struct hda_pintbl d945gtp5_pin_configs[] = {
2723 { 0x0a, 0x0221401f },
2724 { 0x0b, 0x01011012 },
2725 { 0x0c, 0x01813024 },
2726 { 0x0d, 0x01014010 },
2727 { 0x0e, 0x01a19021 },
2728 { 0x0f, 0x01016011 },
2729 { 0x10, 0x01452130 },
2730 { 0x11, 0x40000100 },
2731 { 0x15, 0x02a19320 },
2732 { 0x1b, 0x40000100 },
2736 static const struct hda_pintbl intel_mac_v1_pin_configs[] = {
2737 { 0x0a, 0x0121e21f },
2738 { 0x0b, 0x400000ff },
2739 { 0x0c, 0x9017e110 },
2740 { 0x0d, 0x400000fd },
2741 { 0x0e, 0x400000fe },
2742 { 0x0f, 0x0181e020 },
2743 { 0x10, 0x1145e030 },
2744 { 0x11, 0x11c5e240 },
2745 { 0x15, 0x400000fc },
2746 { 0x1b, 0x400000fb },
2750 static const struct hda_pintbl intel_mac_v2_pin_configs[] = {
2751 { 0x0a, 0x0121e21f },
2752 { 0x0b, 0x90a7012e },
2753 { 0x0c, 0x9017e110 },
2754 { 0x0d, 0x400000fd },
2755 { 0x0e, 0x400000fe },
2756 { 0x0f, 0x0181e020 },
2757 { 0x10, 0x1145e230 },
2758 { 0x11, 0x500000fa },
2759 { 0x15, 0x400000fc },
2760 { 0x1b, 0x400000fb },
2764 static const struct hda_pintbl intel_mac_v3_pin_configs[] = {
2765 { 0x0a, 0x0121e21f },
2766 { 0x0b, 0x90a7012e },
2767 { 0x0c, 0x9017e110 },
2768 { 0x0d, 0x400000fd },
2769 { 0x0e, 0x400000fe },
2770 { 0x0f, 0x0181e020 },
2771 { 0x10, 0x1145e230 },
2772 { 0x11, 0x11c5e240 },
2773 { 0x15, 0x400000fc },
2774 { 0x1b, 0x400000fb },
2778 static const struct hda_pintbl intel_mac_v4_pin_configs[] = {
2779 { 0x0a, 0x0321e21f },
2780 { 0x0b, 0x03a1e02e },
2781 { 0x0c, 0x9017e110 },
2782 { 0x0d, 0x9017e11f },
2783 { 0x0e, 0x400000fe },
2784 { 0x0f, 0x0381e020 },
2785 { 0x10, 0x1345e230 },
2786 { 0x11, 0x13c5e240 },
2787 { 0x15, 0x400000fc },
2788 { 0x1b, 0x400000fb },
2792 static const struct hda_pintbl intel_mac_v5_pin_configs[] = {
2793 { 0x0a, 0x0321e21f },
2794 { 0x0b, 0x03a1e02e },
2795 { 0x0c, 0x9017e110 },
2796 { 0x0d, 0x9017e11f },
2797 { 0x0e, 0x400000fe },
2798 { 0x0f, 0x0381e020 },
2799 { 0x10, 0x1345e230 },
2800 { 0x11, 0x13c5e240 },
2801 { 0x15, 0x400000fc },
2802 { 0x1b, 0x400000fb },
2806 static const struct hda_pintbl ecs202_pin_configs[] = {
2807 { 0x0a, 0x0221401f },
2808 { 0x0b, 0x02a19020 },
2809 { 0x0c, 0x01a19020 },
2810 { 0x0d, 0x01114010 },
2811 { 0x0e, 0x408000f0 },
2812 { 0x0f, 0x01813022 },
2813 { 0x10, 0x074510a0 },
2814 { 0x11, 0x40c400f1 },
2815 { 0x15, 0x9037012e },
2816 { 0x1b, 0x40e000f2 },
2820 /* codec SSIDs for Intel Mac sharing the same PCI SSID 8384:7680 */
2821 static const struct snd_pci_quirk stac922x_intel_mac_fixup_tbl[] = {
2822 SND_PCI_QUIRK(0x106b, 0x0800, "Mac", STAC_INTEL_MAC_V1),
2823 SND_PCI_QUIRK(0x106b, 0x0600, "Mac", STAC_INTEL_MAC_V2),
2824 SND_PCI_QUIRK(0x106b, 0x0700, "Mac", STAC_INTEL_MAC_V2),
2825 SND_PCI_QUIRK(0x106b, 0x0e00, "Mac", STAC_INTEL_MAC_V3),
2826 SND_PCI_QUIRK(0x106b, 0x0f00, "Mac", STAC_INTEL_MAC_V3),
2827 SND_PCI_QUIRK(0x106b, 0x1600, "Mac", STAC_INTEL_MAC_V3),
2828 SND_PCI_QUIRK(0x106b, 0x1700, "Mac", STAC_INTEL_MAC_V3),
2829 SND_PCI_QUIRK(0x106b, 0x0200, "Mac", STAC_INTEL_MAC_V3),
2830 SND_PCI_QUIRK(0x106b, 0x1e00, "Mac", STAC_INTEL_MAC_V3),
2831 SND_PCI_QUIRK(0x106b, 0x1a00, "Mac", STAC_INTEL_MAC_V4),
2832 SND_PCI_QUIRK(0x106b, 0x0a00, "Mac", STAC_INTEL_MAC_V5),
2833 SND_PCI_QUIRK(0x106b, 0x2200, "Mac", STAC_INTEL_MAC_V5),
2837 static const struct hda_fixup stac922x_fixups[];
2839 /* remap the fixup from codec SSID and apply it */
2840 static void stac922x_fixup_intel_mac_auto(struct hda_codec *codec,
2841 const struct hda_fixup *fix,
2842 int action)
2844 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2845 return;
2846 snd_hda_pick_fixup(codec, NULL, stac922x_intel_mac_fixup_tbl,
2847 stac922x_fixups);
2848 if (codec->fixup_id != STAC_INTEL_MAC_AUTO)
2849 snd_hda_apply_fixup(codec, action);
2852 static void stac922x_fixup_intel_mac_gpio(struct hda_codec *codec,
2853 const struct hda_fixup *fix,
2854 int action)
2856 struct sigmatel_spec *spec = codec->spec;
2858 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2859 spec->gpio_mask = spec->gpio_dir = 0x03;
2860 spec->gpio_data = 0x03;
2864 static const struct hda_fixup stac922x_fixups[] = {
2865 [STAC_D945_REF] = {
2866 .type = HDA_FIXUP_PINS,
2867 .v.pins = ref922x_pin_configs,
2869 [STAC_D945GTP3] = {
2870 .type = HDA_FIXUP_PINS,
2871 .v.pins = d945gtp3_pin_configs,
2873 [STAC_D945GTP5] = {
2874 .type = HDA_FIXUP_PINS,
2875 .v.pins = d945gtp5_pin_configs,
2877 [STAC_INTEL_MAC_AUTO] = {
2878 .type = HDA_FIXUP_FUNC,
2879 .v.func = stac922x_fixup_intel_mac_auto,
2881 [STAC_INTEL_MAC_V1] = {
2882 .type = HDA_FIXUP_PINS,
2883 .v.pins = intel_mac_v1_pin_configs,
2884 .chained = true,
2885 .chain_id = STAC_922X_INTEL_MAC_GPIO,
2887 [STAC_INTEL_MAC_V2] = {
2888 .type = HDA_FIXUP_PINS,
2889 .v.pins = intel_mac_v2_pin_configs,
2890 .chained = true,
2891 .chain_id = STAC_922X_INTEL_MAC_GPIO,
2893 [STAC_INTEL_MAC_V3] = {
2894 .type = HDA_FIXUP_PINS,
2895 .v.pins = intel_mac_v3_pin_configs,
2896 .chained = true,
2897 .chain_id = STAC_922X_INTEL_MAC_GPIO,
2899 [STAC_INTEL_MAC_V4] = {
2900 .type = HDA_FIXUP_PINS,
2901 .v.pins = intel_mac_v4_pin_configs,
2902 .chained = true,
2903 .chain_id = STAC_922X_INTEL_MAC_GPIO,
2905 [STAC_INTEL_MAC_V5] = {
2906 .type = HDA_FIXUP_PINS,
2907 .v.pins = intel_mac_v5_pin_configs,
2908 .chained = true,
2909 .chain_id = STAC_922X_INTEL_MAC_GPIO,
2911 [STAC_922X_INTEL_MAC_GPIO] = {
2912 .type = HDA_FIXUP_FUNC,
2913 .v.func = stac922x_fixup_intel_mac_gpio,
2915 [STAC_ECS_202] = {
2916 .type = HDA_FIXUP_PINS,
2917 .v.pins = ecs202_pin_configs,
2919 [STAC_922X_DELL_D81] = {
2920 .type = HDA_FIXUP_PINS,
2921 .v.pins = dell_922x_d81_pin_configs,
2923 [STAC_922X_DELL_D82] = {
2924 .type = HDA_FIXUP_PINS,
2925 .v.pins = dell_922x_d82_pin_configs,
2927 [STAC_922X_DELL_M81] = {
2928 .type = HDA_FIXUP_PINS,
2929 .v.pins = dell_922x_m81_pin_configs,
2931 [STAC_922X_DELL_M82] = {
2932 .type = HDA_FIXUP_PINS,
2933 .v.pins = dell_922x_m82_pin_configs,
2937 static const struct hda_model_fixup stac922x_models[] = {
2938 { .id = STAC_D945_REF, .name = "ref" },
2939 { .id = STAC_D945GTP5, .name = "5stack" },
2940 { .id = STAC_D945GTP3, .name = "3stack" },
2941 { .id = STAC_INTEL_MAC_V1, .name = "intel-mac-v1" },
2942 { .id = STAC_INTEL_MAC_V2, .name = "intel-mac-v2" },
2943 { .id = STAC_INTEL_MAC_V3, .name = "intel-mac-v3" },
2944 { .id = STAC_INTEL_MAC_V4, .name = "intel-mac-v4" },
2945 { .id = STAC_INTEL_MAC_V5, .name = "intel-mac-v5" },
2946 { .id = STAC_INTEL_MAC_AUTO, .name = "intel-mac-auto" },
2947 { .id = STAC_ECS_202, .name = "ecs202" },
2948 { .id = STAC_922X_DELL_D81, .name = "dell-d81" },
2949 { .id = STAC_922X_DELL_D82, .name = "dell-d82" },
2950 { .id = STAC_922X_DELL_M81, .name = "dell-m81" },
2951 { .id = STAC_922X_DELL_M82, .name = "dell-m82" },
2952 /* for backward compatibility */
2953 { .id = STAC_INTEL_MAC_V3, .name = "macmini" },
2954 { .id = STAC_INTEL_MAC_V5, .name = "macbook" },
2955 { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro-v1" },
2956 { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro" },
2957 { .id = STAC_INTEL_MAC_V2, .name = "imac-intel" },
2958 { .id = STAC_INTEL_MAC_V3, .name = "imac-intel-20" },
2962 static const struct snd_pci_quirk stac922x_fixup_tbl[] = {
2963 /* SigmaTel reference board */
2964 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2965 "DFI LanParty", STAC_D945_REF),
2966 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
2967 "DFI LanParty", STAC_D945_REF),
2968 /* Intel 945G based systems */
2969 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
2970 "Intel D945G", STAC_D945GTP3),
2971 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
2972 "Intel D945G", STAC_D945GTP3),
2973 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
2974 "Intel D945G", STAC_D945GTP3),
2975 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
2976 "Intel D945G", STAC_D945GTP3),
2977 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
2978 "Intel D945G", STAC_D945GTP3),
2979 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
2980 "Intel D945G", STAC_D945GTP3),
2981 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
2982 "Intel D945G", STAC_D945GTP3),
2983 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
2984 "Intel D945G", STAC_D945GTP3),
2985 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
2986 "Intel D945G", STAC_D945GTP3),
2987 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
2988 "Intel D945G", STAC_D945GTP3),
2989 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
2990 "Intel D945G", STAC_D945GTP3),
2991 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
2992 "Intel D945G", STAC_D945GTP3),
2993 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
2994 "Intel D945G", STAC_D945GTP3),
2995 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
2996 "Intel D945G", STAC_D945GTP3),
2997 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
2998 "Intel D945G", STAC_D945GTP3),
2999 /* Intel D945G 5-stack systems */
3000 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
3001 "Intel D945G", STAC_D945GTP5),
3002 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
3003 "Intel D945G", STAC_D945GTP5),
3004 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
3005 "Intel D945G", STAC_D945GTP5),
3006 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
3007 "Intel D945G", STAC_D945GTP5),
3008 /* Intel 945P based systems */
3009 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
3010 "Intel D945P", STAC_D945GTP3),
3011 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
3012 "Intel D945P", STAC_D945GTP3),
3013 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
3014 "Intel D945P", STAC_D945GTP3),
3015 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
3016 "Intel D945P", STAC_D945GTP3),
3017 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
3018 "Intel D945P", STAC_D945GTP3),
3019 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
3020 "Intel D945P", STAC_D945GTP5),
3021 /* other intel */
3022 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0204,
3023 "Intel D945", STAC_D945_REF),
3024 /* other systems */
3026 /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */
3027 SND_PCI_QUIRK(0x8384, 0x7680, "Mac", STAC_INTEL_MAC_AUTO),
3029 /* Dell systems */
3030 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
3031 "unknown Dell", STAC_922X_DELL_D81),
3032 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
3033 "unknown Dell", STAC_922X_DELL_D81),
3034 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
3035 "unknown Dell", STAC_922X_DELL_D81),
3036 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
3037 "unknown Dell", STAC_922X_DELL_D82),
3038 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
3039 "unknown Dell", STAC_922X_DELL_M81),
3040 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
3041 "unknown Dell", STAC_922X_DELL_D82),
3042 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
3043 "unknown Dell", STAC_922X_DELL_D81),
3044 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
3045 "unknown Dell", STAC_922X_DELL_D81),
3046 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
3047 "Dell XPS M1210", STAC_922X_DELL_M82),
3048 /* ECS/PC Chips boards */
3049 SND_PCI_QUIRK_MASK(0x1019, 0xf000, 0x2000,
3050 "ECS/PC chips", STAC_ECS_202),
3051 {} /* terminator */
3054 static const struct hda_pintbl ref927x_pin_configs[] = {
3055 { 0x0a, 0x02214020 },
3056 { 0x0b, 0x02a19080 },
3057 { 0x0c, 0x0181304e },
3058 { 0x0d, 0x01014010 },
3059 { 0x0e, 0x01a19040 },
3060 { 0x0f, 0x01011012 },
3061 { 0x10, 0x01016011 },
3062 { 0x11, 0x0101201f },
3063 { 0x12, 0x183301f0 },
3064 { 0x13, 0x18a001f0 },
3065 { 0x14, 0x18a001f0 },
3066 { 0x21, 0x01442070 },
3067 { 0x22, 0x01c42190 },
3068 { 0x23, 0x40000100 },
3072 static const struct hda_pintbl d965_3st_pin_configs[] = {
3073 { 0x0a, 0x0221401f },
3074 { 0x0b, 0x02a19120 },
3075 { 0x0c, 0x40000100 },
3076 { 0x0d, 0x01014011 },
3077 { 0x0e, 0x01a19021 },
3078 { 0x0f, 0x01813024 },
3079 { 0x10, 0x40000100 },
3080 { 0x11, 0x40000100 },
3081 { 0x12, 0x40000100 },
3082 { 0x13, 0x40000100 },
3083 { 0x14, 0x40000100 },
3084 { 0x21, 0x40000100 },
3085 { 0x22, 0x40000100 },
3086 { 0x23, 0x40000100 },
3090 static const struct hda_pintbl d965_5st_pin_configs[] = {
3091 { 0x0a, 0x02214020 },
3092 { 0x0b, 0x02a19080 },
3093 { 0x0c, 0x0181304e },
3094 { 0x0d, 0x01014010 },
3095 { 0x0e, 0x01a19040 },
3096 { 0x0f, 0x01011012 },
3097 { 0x10, 0x01016011 },
3098 { 0x11, 0x40000100 },
3099 { 0x12, 0x40000100 },
3100 { 0x13, 0x40000100 },
3101 { 0x14, 0x40000100 },
3102 { 0x21, 0x01442070 },
3103 { 0x22, 0x40000100 },
3104 { 0x23, 0x40000100 },
3108 static const struct hda_pintbl d965_5st_no_fp_pin_configs[] = {
3109 { 0x0a, 0x40000100 },
3110 { 0x0b, 0x40000100 },
3111 { 0x0c, 0x0181304e },
3112 { 0x0d, 0x01014010 },
3113 { 0x0e, 0x01a19040 },
3114 { 0x0f, 0x01011012 },
3115 { 0x10, 0x01016011 },
3116 { 0x11, 0x40000100 },
3117 { 0x12, 0x40000100 },
3118 { 0x13, 0x40000100 },
3119 { 0x14, 0x40000100 },
3120 { 0x21, 0x01442070 },
3121 { 0x22, 0x40000100 },
3122 { 0x23, 0x40000100 },
3126 static const struct hda_pintbl dell_3st_pin_configs[] = {
3127 { 0x0a, 0x02211230 },
3128 { 0x0b, 0x02a11220 },
3129 { 0x0c, 0x01a19040 },
3130 { 0x0d, 0x01114210 },
3131 { 0x0e, 0x01111212 },
3132 { 0x0f, 0x01116211 },
3133 { 0x10, 0x01813050 },
3134 { 0x11, 0x01112214 },
3135 { 0x12, 0x403003fa },
3136 { 0x13, 0x90a60040 },
3137 { 0x14, 0x90a60040 },
3138 { 0x21, 0x404003fb },
3139 { 0x22, 0x40c003fc },
3140 { 0x23, 0x40000100 },
3144 static void stac927x_fixup_ref_no_jd(struct hda_codec *codec,
3145 const struct hda_fixup *fix, int action)
3147 /* no jack detecion for ref-no-jd model */
3148 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3149 codec->no_jack_detect = 1;
3152 static void stac927x_fixup_ref(struct hda_codec *codec,
3153 const struct hda_fixup *fix, int action)
3155 struct sigmatel_spec *spec = codec->spec;
3157 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3158 snd_hda_apply_pincfgs(codec, ref927x_pin_configs);
3159 spec->eapd_mask = spec->gpio_mask = 0;
3160 spec->gpio_dir = spec->gpio_data = 0;
3164 static void stac927x_fixup_dell_dmic(struct hda_codec *codec,
3165 const struct hda_fixup *fix, int action)
3167 struct sigmatel_spec *spec = codec->spec;
3169 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3170 return;
3172 if (codec->subsystem_id != 0x1028022f) {
3173 /* GPIO2 High = Enable EAPD */
3174 spec->eapd_mask = spec->gpio_mask = 0x04;
3175 spec->gpio_dir = spec->gpio_data = 0x04;
3178 snd_hda_add_verbs(codec, dell_3st_core_init);
3179 spec->volknob_init = 1;
3182 static void stac927x_fixup_volknob(struct hda_codec *codec,
3183 const struct hda_fixup *fix, int action)
3185 struct sigmatel_spec *spec = codec->spec;
3187 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3188 snd_hda_add_verbs(codec, stac927x_volknob_core_init);
3189 spec->volknob_init = 1;
3193 static const struct hda_fixup stac927x_fixups[] = {
3194 [STAC_D965_REF_NO_JD] = {
3195 .type = HDA_FIXUP_FUNC,
3196 .v.func = stac927x_fixup_ref_no_jd,
3197 .chained = true,
3198 .chain_id = STAC_D965_REF,
3200 [STAC_D965_REF] = {
3201 .type = HDA_FIXUP_FUNC,
3202 .v.func = stac927x_fixup_ref,
3204 [STAC_D965_3ST] = {
3205 .type = HDA_FIXUP_PINS,
3206 .v.pins = d965_3st_pin_configs,
3207 .chained = true,
3208 .chain_id = STAC_D965_VERBS,
3210 [STAC_D965_5ST] = {
3211 .type = HDA_FIXUP_PINS,
3212 .v.pins = d965_5st_pin_configs,
3213 .chained = true,
3214 .chain_id = STAC_D965_VERBS,
3216 [STAC_D965_VERBS] = {
3217 .type = HDA_FIXUP_VERBS,
3218 .v.verbs = d965_core_init,
3220 [STAC_D965_5ST_NO_FP] = {
3221 .type = HDA_FIXUP_PINS,
3222 .v.pins = d965_5st_no_fp_pin_configs,
3224 [STAC_DELL_3ST] = {
3225 .type = HDA_FIXUP_PINS,
3226 .v.pins = dell_3st_pin_configs,
3227 .chained = true,
3228 .chain_id = STAC_927X_DELL_DMIC,
3230 [STAC_DELL_BIOS] = {
3231 .type = HDA_FIXUP_PINS,
3232 .v.pins = (const struct hda_pintbl[]) {
3233 /* configure the analog microphone on some laptops */
3234 { 0x0c, 0x90a79130 },
3235 /* correct the front output jack as a hp out */
3236 { 0x0f, 0x0221101f },
3237 /* correct the front input jack as a mic */
3238 { 0x0e, 0x02a79130 },
3241 .chained = true,
3242 .chain_id = STAC_927X_DELL_DMIC,
3244 [STAC_DELL_BIOS_SPDIF] = {
3245 .type = HDA_FIXUP_PINS,
3246 .v.pins = (const struct hda_pintbl[]) {
3247 /* correct the device field to SPDIF out */
3248 { 0x21, 0x01442070 },
3251 .chained = true,
3252 .chain_id = STAC_DELL_BIOS,
3254 [STAC_927X_DELL_DMIC] = {
3255 .type = HDA_FIXUP_FUNC,
3256 .v.func = stac927x_fixup_dell_dmic,
3258 [STAC_927X_VOLKNOB] = {
3259 .type = HDA_FIXUP_FUNC,
3260 .v.func = stac927x_fixup_volknob,
3264 static const struct hda_model_fixup stac927x_models[] = {
3265 { .id = STAC_D965_REF_NO_JD, .name = "ref-no-jd" },
3266 { .id = STAC_D965_REF, .name = "ref" },
3267 { .id = STAC_D965_3ST, .name = "3stack" },
3268 { .id = STAC_D965_5ST, .name = "5stack" },
3269 { .id = STAC_D965_5ST_NO_FP, .name = "5stack-no-fp" },
3270 { .id = STAC_DELL_3ST, .name = "dell-3stack" },
3271 { .id = STAC_DELL_BIOS, .name = "dell-bios" },
3272 { .id = STAC_927X_VOLKNOB, .name = "volknob" },
3276 static const struct snd_pci_quirk stac927x_fixup_tbl[] = {
3277 /* SigmaTel reference board */
3278 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3279 "DFI LanParty", STAC_D965_REF),
3280 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3281 "DFI LanParty", STAC_D965_REF),
3282 /* Intel 946 based systems */
3283 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
3284 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
3285 /* 965 based 3 stack systems */
3286 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2100,
3287 "Intel D965", STAC_D965_3ST),
3288 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000,
3289 "Intel D965", STAC_D965_3ST),
3290 /* Dell 3 stack systems */
3291 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
3292 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
3293 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
3294 /* Dell 3 stack systems with verb table in BIOS */
3295 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
3296 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_BIOS),
3297 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
3298 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS_SPDIF),
3299 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS),
3300 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
3301 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
3302 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
3303 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS_SPDIF),
3304 /* 965 based 5 stack systems */
3305 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2300,
3306 "Intel D965", STAC_D965_5ST),
3307 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500,
3308 "Intel D965", STAC_D965_5ST),
3309 /* volume-knob fixes */
3310 SND_PCI_QUIRK_VENDOR(0x10cf, "FSC", STAC_927X_VOLKNOB),
3311 {} /* terminator */
3314 static const struct hda_pintbl ref9205_pin_configs[] = {
3315 { 0x0a, 0x40000100 },
3316 { 0x0b, 0x40000100 },
3317 { 0x0c, 0x01016011 },
3318 { 0x0d, 0x01014010 },
3319 { 0x0e, 0x01813122 },
3320 { 0x0f, 0x01a19021 },
3321 { 0x14, 0x01019020 },
3322 { 0x16, 0x40000100 },
3323 { 0x17, 0x90a000f0 },
3324 { 0x18, 0x90a000f0 },
3325 { 0x21, 0x01441030 },
3326 { 0x22, 0x01c41030 },
3331 STAC 9205 pin configs for
3332 102801F1
3333 102801F2
3334 102801FC
3335 102801FD
3336 10280204
3337 1028021F
3338 10280228 (Dell Vostro 1500)
3339 10280229 (Dell Vostro 1700)
3341 static const struct hda_pintbl dell_9205_m42_pin_configs[] = {
3342 { 0x0a, 0x0321101F },
3343 { 0x0b, 0x03A11020 },
3344 { 0x0c, 0x400003FA },
3345 { 0x0d, 0x90170310 },
3346 { 0x0e, 0x400003FB },
3347 { 0x0f, 0x400003FC },
3348 { 0x14, 0x400003FD },
3349 { 0x16, 0x40F000F9 },
3350 { 0x17, 0x90A60330 },
3351 { 0x18, 0x400003FF },
3352 { 0x21, 0x0144131F },
3353 { 0x22, 0x40C003FE },
3358 STAC 9205 pin configs for
3359 102801F9
3360 102801FA
3361 102801FE
3362 102801FF (Dell Precision M4300)
3363 10280206
3364 10280200
3365 10280201
3367 static const struct hda_pintbl dell_9205_m43_pin_configs[] = {
3368 { 0x0a, 0x0321101f },
3369 { 0x0b, 0x03a11020 },
3370 { 0x0c, 0x90a70330 },
3371 { 0x0d, 0x90170310 },
3372 { 0x0e, 0x400000fe },
3373 { 0x0f, 0x400000ff },
3374 { 0x14, 0x400000fd },
3375 { 0x16, 0x40f000f9 },
3376 { 0x17, 0x400000fa },
3377 { 0x18, 0x400000fc },
3378 { 0x21, 0x0144131f },
3379 { 0x22, 0x40c003f8 },
3380 /* Enable SPDIF in/out */
3381 { 0x1f, 0x01441030 },
3382 { 0x20, 0x1c410030 },
3386 static const struct hda_pintbl dell_9205_m44_pin_configs[] = {
3387 { 0x0a, 0x0421101f },
3388 { 0x0b, 0x04a11020 },
3389 { 0x0c, 0x400003fa },
3390 { 0x0d, 0x90170310 },
3391 { 0x0e, 0x400003fb },
3392 { 0x0f, 0x400003fc },
3393 { 0x14, 0x400003fd },
3394 { 0x16, 0x400003f9 },
3395 { 0x17, 0x90a60330 },
3396 { 0x18, 0x400003ff },
3397 { 0x21, 0x01441340 },
3398 { 0x22, 0x40c003fe },
3402 static void stac9205_fixup_ref(struct hda_codec *codec,
3403 const struct hda_fixup *fix, int action)
3405 struct sigmatel_spec *spec = codec->spec;
3407 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3408 snd_hda_apply_pincfgs(codec, ref9205_pin_configs);
3409 /* SPDIF-In enabled */
3410 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0;
3414 static void stac9205_fixup_dell_m43(struct hda_codec *codec,
3415 const struct hda_fixup *fix, int action)
3417 struct sigmatel_spec *spec = codec->spec;
3418 struct hda_jack_tbl *jack;
3420 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3421 snd_hda_apply_pincfgs(codec, dell_9205_m43_pin_configs);
3423 /* Enable unsol response for GPIO4/Dock HP connection */
3424 snd_hda_codec_write_cache(codec, codec->afg, 0,
3425 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
3426 snd_hda_jack_detect_enable_callback(codec, codec->afg,
3427 STAC_VREF_EVENT,
3428 stac_vref_event);
3429 jack = snd_hda_jack_tbl_get(codec, codec->afg);
3430 if (jack)
3431 jack->private_data = 0x01;
3433 spec->gpio_dir = 0x0b;
3434 spec->eapd_mask = 0x01;
3435 spec->gpio_mask = 0x1b;
3436 spec->gpio_mute = 0x10;
3437 /* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute,
3438 * GPIO3 Low = DRM
3440 spec->gpio_data = 0x01;
3444 static void stac9205_fixup_eapd(struct hda_codec *codec,
3445 const struct hda_fixup *fix, int action)
3447 struct sigmatel_spec *spec = codec->spec;
3449 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3450 spec->eapd_switch = 0;
3453 static const struct hda_fixup stac9205_fixups[] = {
3454 [STAC_9205_REF] = {
3455 .type = HDA_FIXUP_FUNC,
3456 .v.func = stac9205_fixup_ref,
3458 [STAC_9205_DELL_M42] = {
3459 .type = HDA_FIXUP_PINS,
3460 .v.pins = dell_9205_m42_pin_configs,
3462 [STAC_9205_DELL_M43] = {
3463 .type = HDA_FIXUP_FUNC,
3464 .v.func = stac9205_fixup_dell_m43,
3466 [STAC_9205_DELL_M44] = {
3467 .type = HDA_FIXUP_PINS,
3468 .v.pins = dell_9205_m44_pin_configs,
3470 [STAC_9205_EAPD] = {
3471 .type = HDA_FIXUP_FUNC,
3472 .v.func = stac9205_fixup_eapd,
3477 static const struct hda_model_fixup stac9205_models[] = {
3478 { .id = STAC_9205_REF, .name = "ref" },
3479 { .id = STAC_9205_DELL_M42, .name = "dell-m42" },
3480 { .id = STAC_9205_DELL_M43, .name = "dell-m43" },
3481 { .id = STAC_9205_DELL_M44, .name = "dell-m44" },
3482 { .id = STAC_9205_EAPD, .name = "eapd" },
3486 static const struct snd_pci_quirk stac9205_fixup_tbl[] = {
3487 /* SigmaTel reference board */
3488 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3489 "DFI LanParty", STAC_9205_REF),
3490 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xfb30,
3491 "SigmaTel", STAC_9205_REF),
3492 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3493 "DFI LanParty", STAC_9205_REF),
3494 /* Dell */
3495 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
3496 "unknown Dell", STAC_9205_DELL_M42),
3497 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
3498 "unknown Dell", STAC_9205_DELL_M42),
3499 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
3500 "Dell Precision", STAC_9205_DELL_M43),
3501 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
3502 "Dell Precision", STAC_9205_DELL_M43),
3503 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
3504 "Dell Precision", STAC_9205_DELL_M43),
3505 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
3506 "unknown Dell", STAC_9205_DELL_M42),
3507 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
3508 "unknown Dell", STAC_9205_DELL_M42),
3509 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
3510 "Dell Precision", STAC_9205_DELL_M43),
3511 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
3512 "Dell Precision M4300", STAC_9205_DELL_M43),
3513 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
3514 "unknown Dell", STAC_9205_DELL_M42),
3515 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
3516 "Dell Precision", STAC_9205_DELL_M43),
3517 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
3518 "Dell Precision", STAC_9205_DELL_M43),
3519 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
3520 "Dell Precision", STAC_9205_DELL_M43),
3521 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
3522 "Dell Inspiron", STAC_9205_DELL_M44),
3523 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228,
3524 "Dell Vostro 1500", STAC_9205_DELL_M42),
3525 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0229,
3526 "Dell Vostro 1700", STAC_9205_DELL_M42),
3527 /* Gateway */
3528 SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD),
3529 SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD),
3530 {} /* terminator */
3533 static int stac_parse_auto_config(struct hda_codec *codec)
3535 struct sigmatel_spec *spec = codec->spec;
3536 int err;
3537 int flags = 0;
3539 if (spec->headset_jack)
3540 flags |= HDA_PINCFG_HEADSET_MIC;
3542 err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, flags);
3543 if (err < 0)
3544 return err;
3546 /* add hooks */
3547 spec->gen.pcm_playback_hook = stac_playback_pcm_hook;
3548 spec->gen.pcm_capture_hook = stac_capture_pcm_hook;
3550 spec->gen.automute_hook = stac_update_outputs;
3551 spec->gen.hp_automute_hook = stac_hp_automute;
3552 spec->gen.line_automute_hook = stac_line_automute;
3553 spec->gen.mic_autoswitch_hook = stac_mic_autoswitch;
3555 err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg);
3556 if (err < 0)
3557 return err;
3559 /* minimum value is actually mute */
3560 spec->gen.vmaster_tlv[3] |= TLV_DB_SCALE_MUTE;
3562 /* setup analog beep controls */
3563 if (spec->anabeep_nid > 0) {
3564 err = stac_auto_create_beep_ctls(codec,
3565 spec->anabeep_nid);
3566 if (err < 0)
3567 return err;
3570 /* setup digital beep controls and input device */
3571 #ifdef CONFIG_SND_HDA_INPUT_BEEP
3572 if (spec->gen.beep_nid) {
3573 hda_nid_t nid = spec->gen.beep_nid;
3574 unsigned int caps;
3576 err = stac_auto_create_beep_ctls(codec, nid);
3577 if (err < 0)
3578 return err;
3579 if (codec->beep) {
3580 /* IDT/STAC codecs have linear beep tone parameter */
3581 codec->beep->linear_tone = spec->linear_tone_beep;
3582 /* if no beep switch is available, make its own one */
3583 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
3584 if (!(caps & AC_AMPCAP_MUTE)) {
3585 err = stac_beep_switch_ctl(codec);
3586 if (err < 0)
3587 return err;
3591 #endif
3593 if (spec->gpio_led)
3594 spec->gen.vmaster_mute.hook = stac_vmaster_hook;
3596 if (spec->aloopback_ctl &&
3597 snd_hda_get_bool_hint(codec, "loopback") == 1) {
3598 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, spec->aloopback_ctl))
3599 return -ENOMEM;
3602 if (spec->have_spdif_mux) {
3603 err = stac_create_spdif_mux_ctls(codec);
3604 if (err < 0)
3605 return err;
3608 stac_init_power_map(codec);
3610 return 0;
3614 static int stac_init(struct hda_codec *codec)
3616 struct sigmatel_spec *spec = codec->spec;
3617 int i;
3619 /* override some hints */
3620 stac_store_hints(codec);
3622 /* set up GPIO */
3623 /* turn on EAPD statically when spec->eapd_switch isn't set.
3624 * otherwise, unsol event will turn it on/off dynamically
3626 if (!spec->eapd_switch)
3627 spec->gpio_data |= spec->eapd_mask;
3628 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
3630 snd_hda_gen_init(codec);
3632 /* sync the power-map */
3633 if (spec->num_pwrs)
3634 snd_hda_codec_write(codec, codec->afg, 0,
3635 AC_VERB_IDT_SET_POWER_MAP,
3636 spec->power_map_bits);
3638 /* power down inactive ADCs */
3639 if (spec->powerdown_adcs) {
3640 for (i = 0; i < spec->gen.num_all_adcs; i++) {
3641 if (spec->active_adcs & (1 << i))
3642 continue;
3643 snd_hda_codec_write(codec, spec->gen.all_adcs[i], 0,
3644 AC_VERB_SET_POWER_STATE,
3645 AC_PWRST_D3);
3649 return 0;
3652 static void stac_shutup(struct hda_codec *codec)
3654 struct sigmatel_spec *spec = codec->spec;
3656 snd_hda_shutup_pins(codec);
3658 if (spec->eapd_mask)
3659 stac_gpio_set(codec, spec->gpio_mask,
3660 spec->gpio_dir, spec->gpio_data &
3661 ~spec->eapd_mask);
3664 #define stac_free snd_hda_gen_free
3666 #ifdef CONFIG_PROC_FS
3667 static void stac92hd_proc_hook(struct snd_info_buffer *buffer,
3668 struct hda_codec *codec, hda_nid_t nid)
3670 if (nid == codec->afg)
3671 snd_iprintf(buffer, "Power-Map: 0x%02x\n",
3672 snd_hda_codec_read(codec, nid, 0,
3673 AC_VERB_IDT_GET_POWER_MAP, 0));
3676 static void analog_loop_proc_hook(struct snd_info_buffer *buffer,
3677 struct hda_codec *codec,
3678 unsigned int verb)
3680 snd_iprintf(buffer, "Analog Loopback: 0x%02x\n",
3681 snd_hda_codec_read(codec, codec->afg, 0, verb, 0));
3684 /* stac92hd71bxx, stac92hd73xx */
3685 static void stac92hd7x_proc_hook(struct snd_info_buffer *buffer,
3686 struct hda_codec *codec, hda_nid_t nid)
3688 stac92hd_proc_hook(buffer, codec, nid);
3689 if (nid == codec->afg)
3690 analog_loop_proc_hook(buffer, codec, 0xfa0);
3693 static void stac9205_proc_hook(struct snd_info_buffer *buffer,
3694 struct hda_codec *codec, hda_nid_t nid)
3696 if (nid == codec->afg)
3697 analog_loop_proc_hook(buffer, codec, 0xfe0);
3700 static void stac927x_proc_hook(struct snd_info_buffer *buffer,
3701 struct hda_codec *codec, hda_nid_t nid)
3703 if (nid == codec->afg)
3704 analog_loop_proc_hook(buffer, codec, 0xfeb);
3706 #else
3707 #define stac92hd_proc_hook NULL
3708 #define stac92hd7x_proc_hook NULL
3709 #define stac9205_proc_hook NULL
3710 #define stac927x_proc_hook NULL
3711 #endif
3713 #ifdef CONFIG_PM
3714 static int stac_suspend(struct hda_codec *codec)
3716 stac_shutup(codec);
3717 return 0;
3720 static void stac_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3721 unsigned int power_state)
3723 unsigned int afg_power_state = power_state;
3724 struct sigmatel_spec *spec = codec->spec;
3726 if (power_state == AC_PWRST_D3) {
3727 if (spec->vref_mute_led_nid) {
3728 /* with vref-out pin used for mute led control
3729 * codec AFG is prevented from D3 state
3731 afg_power_state = AC_PWRST_D1;
3733 /* this delay seems necessary to avoid click noise at power-down */
3734 msleep(100);
3736 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
3737 afg_power_state);
3738 snd_hda_codec_set_power_to_all(codec, fg, power_state);
3740 #else
3741 #define stac_suspend NULL
3742 #define stac_set_power_state NULL
3743 #endif /* CONFIG_PM */
3745 static const struct hda_codec_ops stac_patch_ops = {
3746 .build_controls = snd_hda_gen_build_controls,
3747 .build_pcms = snd_hda_gen_build_pcms,
3748 .init = stac_init,
3749 .free = stac_free,
3750 .unsol_event = snd_hda_jack_unsol_event,
3751 #ifdef CONFIG_PM
3752 .suspend = stac_suspend,
3753 #endif
3754 .reboot_notify = stac_shutup,
3757 static int alloc_stac_spec(struct hda_codec *codec)
3759 struct sigmatel_spec *spec;
3761 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3762 if (!spec)
3763 return -ENOMEM;
3764 snd_hda_gen_spec_init(&spec->gen);
3765 codec->spec = spec;
3766 codec->no_trigger_sense = 1; /* seems common with STAC/IDT codecs */
3767 return 0;
3770 static int patch_stac9200(struct hda_codec *codec)
3772 struct sigmatel_spec *spec;
3773 int err;
3775 err = alloc_stac_spec(codec);
3776 if (err < 0)
3777 return err;
3779 spec = codec->spec;
3780 spec->linear_tone_beep = 1;
3781 spec->gen.own_eapd_ctl = 1;
3783 codec->patch_ops = stac_patch_ops;
3784 codec->power_filter = snd_hda_codec_eapd_power_filter;
3786 snd_hda_add_verbs(codec, stac9200_eapd_init);
3788 snd_hda_pick_fixup(codec, stac9200_models, stac9200_fixup_tbl,
3789 stac9200_fixups);
3790 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
3792 err = stac_parse_auto_config(codec);
3793 if (err < 0) {
3794 stac_free(codec);
3795 return err;
3798 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
3800 return 0;
3803 static int patch_stac925x(struct hda_codec *codec)
3805 struct sigmatel_spec *spec;
3806 int err;
3808 err = alloc_stac_spec(codec);
3809 if (err < 0)
3810 return err;
3812 spec = codec->spec;
3813 spec->linear_tone_beep = 1;
3814 spec->gen.own_eapd_ctl = 1;
3816 codec->patch_ops = stac_patch_ops;
3818 snd_hda_add_verbs(codec, stac925x_core_init);
3820 snd_hda_pick_fixup(codec, stac925x_models, stac925x_fixup_tbl,
3821 stac925x_fixups);
3822 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
3824 err = stac_parse_auto_config(codec);
3825 if (err < 0) {
3826 stac_free(codec);
3827 return err;
3830 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
3832 return 0;
3835 static int patch_stac92hd73xx(struct hda_codec *codec)
3837 struct sigmatel_spec *spec;
3838 int err;
3839 int num_dacs;
3841 err = alloc_stac_spec(codec);
3842 if (err < 0)
3843 return err;
3845 spec = codec->spec;
3846 spec->linear_tone_beep = 0;
3847 spec->gen.mixer_nid = 0x1d;
3848 spec->have_spdif_mux = 1;
3850 num_dacs = snd_hda_get_num_conns(codec, 0x0a) - 1;
3851 if (num_dacs < 3 || num_dacs > 5) {
3852 printk(KERN_WARNING "hda_codec: Could not determine "
3853 "number of channels defaulting to DAC count\n");
3854 num_dacs = 5;
3857 switch (num_dacs) {
3858 case 0x3: /* 6 Channel */
3859 spec->aloopback_ctl = &stac92hd73xx_6ch_loopback;
3860 break;
3861 case 0x4: /* 8 Channel */
3862 spec->aloopback_ctl = &stac92hd73xx_8ch_loopback;
3863 break;
3864 case 0x5: /* 10 Channel */
3865 spec->aloopback_ctl = &stac92hd73xx_10ch_loopback;
3866 break;
3869 spec->aloopback_mask = 0x01;
3870 spec->aloopback_shift = 8;
3872 spec->gen.beep_nid = 0x1c; /* digital beep */
3874 /* GPIO0 High = Enable EAPD */
3875 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
3876 spec->gpio_data = 0x01;
3878 spec->eapd_switch = 1;
3880 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
3881 spec->pwr_nids = stac92hd73xx_pwr_nids;
3883 spec->gen.own_eapd_ctl = 1;
3884 spec->gen.power_down_unused = 1;
3886 codec->patch_ops = stac_patch_ops;
3888 snd_hda_pick_fixup(codec, stac92hd73xx_models, stac92hd73xx_fixup_tbl,
3889 stac92hd73xx_fixups);
3890 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
3892 if (!spec->volknob_init)
3893 snd_hda_add_verbs(codec, stac92hd73xx_core_init);
3895 err = stac_parse_auto_config(codec);
3896 if (err < 0) {
3897 stac_free(codec);
3898 return err;
3901 /* Don't GPIO-mute speakers if there are no internal speakers, because
3902 * the GPIO might be necessary for Headphone
3904 if (spec->eapd_switch && !has_builtin_speaker(codec))
3905 spec->eapd_switch = 0;
3907 codec->proc_widget_hook = stac92hd7x_proc_hook;
3909 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
3911 return 0;
3914 static void stac_setup_gpio(struct hda_codec *codec)
3916 struct sigmatel_spec *spec = codec->spec;
3918 spec->gpio_mask |= spec->eapd_mask;
3919 if (spec->gpio_led) {
3920 if (!spec->vref_mute_led_nid) {
3921 spec->gpio_mask |= spec->gpio_led;
3922 spec->gpio_dir |= spec->gpio_led;
3923 spec->gpio_data |= spec->gpio_led;
3924 } else {
3925 codec->patch_ops.set_power_state =
3926 stac_set_power_state;
3930 if (spec->mic_mute_led_gpio) {
3931 spec->gpio_mask |= spec->mic_mute_led_gpio;
3932 spec->gpio_dir |= spec->mic_mute_led_gpio;
3933 spec->mic_mute_led_on = true;
3934 spec->gpio_data |= spec->mic_mute_led_gpio;
3936 spec->gen.cap_sync_hook = stac_capture_led_hook;
3940 static int patch_stac92hd83xxx(struct hda_codec *codec)
3942 struct sigmatel_spec *spec;
3943 int err;
3945 err = alloc_stac_spec(codec);
3946 if (err < 0)
3947 return err;
3949 codec->epss = 0; /* longer delay needed for D3 */
3951 spec = codec->spec;
3952 spec->linear_tone_beep = 0;
3953 spec->gen.own_eapd_ctl = 1;
3954 spec->gen.power_down_unused = 1;
3955 spec->gen.mixer_nid = 0x1b;
3957 spec->gen.beep_nid = 0x21; /* digital beep */
3958 spec->pwr_nids = stac92hd83xxx_pwr_nids;
3959 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
3960 spec->default_polarity = -1; /* no default cfg */
3962 codec->patch_ops = stac_patch_ops;
3964 snd_hda_add_verbs(codec, stac92hd83xxx_core_init);
3966 snd_hda_pick_fixup(codec, stac92hd83xxx_models, stac92hd83xxx_fixup_tbl,
3967 stac92hd83xxx_fixups);
3968 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
3970 stac_setup_gpio(codec);
3972 err = stac_parse_auto_config(codec);
3973 if (err < 0) {
3974 stac_free(codec);
3975 return err;
3978 codec->proc_widget_hook = stac92hd_proc_hook;
3980 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
3982 return 0;
3985 static const hda_nid_t stac92hd95_pwr_nids[] = {
3986 0x0a, 0x0b, 0x0c, 0x0d
3989 static int patch_stac92hd95(struct hda_codec *codec)
3991 struct sigmatel_spec *spec;
3992 int err;
3994 err = alloc_stac_spec(codec);
3995 if (err < 0)
3996 return err;
3998 codec->epss = 0; /* longer delay needed for D3 */
4000 spec = codec->spec;
4001 spec->linear_tone_beep = 0;
4002 spec->gen.own_eapd_ctl = 1;
4003 spec->gen.power_down_unused = 1;
4005 spec->gen.beep_nid = 0x19; /* digital beep */
4006 spec->pwr_nids = stac92hd95_pwr_nids;
4007 spec->num_pwrs = ARRAY_SIZE(stac92hd95_pwr_nids);
4008 spec->default_polarity = -1; /* no default cfg */
4010 codec->patch_ops = stac_patch_ops;
4012 err = stac_parse_auto_config(codec);
4013 if (err < 0) {
4014 stac_free(codec);
4015 return err;
4018 codec->proc_widget_hook = stac92hd_proc_hook;
4020 return 0;
4023 static int patch_stac92hd71bxx(struct hda_codec *codec)
4025 struct sigmatel_spec *spec;
4026 const struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init;
4027 int err;
4029 err = alloc_stac_spec(codec);
4030 if (err < 0)
4031 return err;
4033 spec = codec->spec;
4034 spec->linear_tone_beep = 0;
4035 spec->gen.own_eapd_ctl = 1;
4036 spec->gen.power_down_unused = 1;
4037 spec->gen.mixer_nid = 0x17;
4038 spec->have_spdif_mux = 1;
4040 codec->patch_ops = stac_patch_ops;
4042 /* GPIO0 = EAPD */
4043 spec->gpio_mask = 0x01;
4044 spec->gpio_dir = 0x01;
4045 spec->gpio_data = 0x01;
4047 switch (codec->vendor_id) {
4048 case 0x111d76b6: /* 4 Port without Analog Mixer */
4049 case 0x111d76b7:
4050 unmute_init++;
4051 break;
4052 case 0x111d7608: /* 5 Port with Analog Mixer */
4053 if ((codec->revision_id & 0xf) == 0 ||
4054 (codec->revision_id & 0xf) == 1)
4055 spec->stream_delay = 40; /* 40 milliseconds */
4057 /* disable VSW */
4058 unmute_init++;
4059 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0);
4060 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3);
4061 break;
4062 case 0x111d7603: /* 6 Port with Analog Mixer */
4063 if ((codec->revision_id & 0xf) == 1)
4064 spec->stream_delay = 40; /* 40 milliseconds */
4066 break;
4069 if (get_wcaps_type(get_wcaps(codec, 0x28)) == AC_WID_VOL_KNB)
4070 snd_hda_add_verbs(codec, stac92hd71bxx_core_init);
4072 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP)
4073 snd_hda_sequence_write_cache(codec, unmute_init);
4075 spec->aloopback_ctl = &stac92hd71bxx_loopback;
4076 spec->aloopback_mask = 0x50;
4077 spec->aloopback_shift = 0;
4079 spec->powerdown_adcs = 1;
4080 spec->gen.beep_nid = 0x26; /* digital beep */
4081 spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
4082 spec->pwr_nids = stac92hd71bxx_pwr_nids;
4084 snd_hda_pick_fixup(codec, stac92hd71bxx_models, stac92hd71bxx_fixup_tbl,
4085 stac92hd71bxx_fixups);
4086 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4088 stac_setup_gpio(codec);
4090 err = stac_parse_auto_config(codec);
4091 if (err < 0) {
4092 stac_free(codec);
4093 return err;
4096 codec->proc_widget_hook = stac92hd7x_proc_hook;
4098 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4100 return 0;
4103 static int patch_stac922x(struct hda_codec *codec)
4105 struct sigmatel_spec *spec;
4106 int err;
4108 err = alloc_stac_spec(codec);
4109 if (err < 0)
4110 return err;
4112 spec = codec->spec;
4113 spec->linear_tone_beep = 1;
4114 spec->gen.own_eapd_ctl = 1;
4116 codec->patch_ops = stac_patch_ops;
4118 snd_hda_add_verbs(codec, stac922x_core_init);
4120 /* Fix Mux capture level; max to 2 */
4121 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
4122 (0 << AC_AMPCAP_OFFSET_SHIFT) |
4123 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4124 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4125 (0 << AC_AMPCAP_MUTE_SHIFT));
4127 snd_hda_pick_fixup(codec, stac922x_models, stac922x_fixup_tbl,
4128 stac922x_fixups);
4129 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4131 err = stac_parse_auto_config(codec);
4132 if (err < 0) {
4133 stac_free(codec);
4134 return err;
4137 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4139 return 0;
4142 static const char * const stac927x_spdif_labels[] = {
4143 "Digital Playback", "ADAT", "Analog Mux 1",
4144 "Analog Mux 2", "Analog Mux 3", NULL
4147 static int patch_stac927x(struct hda_codec *codec)
4149 struct sigmatel_spec *spec;
4150 int err;
4152 err = alloc_stac_spec(codec);
4153 if (err < 0)
4154 return err;
4156 spec = codec->spec;
4157 spec->linear_tone_beep = 1;
4158 spec->gen.own_eapd_ctl = 1;
4159 spec->have_spdif_mux = 1;
4160 spec->spdif_labels = stac927x_spdif_labels;
4162 spec->gen.beep_nid = 0x23; /* digital beep */
4164 /* GPIO0 High = Enable EAPD */
4165 spec->eapd_mask = spec->gpio_mask = 0x01;
4166 spec->gpio_dir = spec->gpio_data = 0x01;
4168 spec->aloopback_ctl = &stac927x_loopback;
4169 spec->aloopback_mask = 0x40;
4170 spec->aloopback_shift = 0;
4171 spec->eapd_switch = 1;
4173 codec->patch_ops = stac_patch_ops;
4175 snd_hda_pick_fixup(codec, stac927x_models, stac927x_fixup_tbl,
4176 stac927x_fixups);
4177 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4179 if (!spec->volknob_init)
4180 snd_hda_add_verbs(codec, stac927x_core_init);
4182 err = stac_parse_auto_config(codec);
4183 if (err < 0) {
4184 stac_free(codec);
4185 return err;
4188 codec->proc_widget_hook = stac927x_proc_hook;
4191 * !!FIXME!!
4192 * The STAC927x seem to require fairly long delays for certain
4193 * command sequences. With too short delays (even if the answer
4194 * is set to RIRB properly), it results in the silence output
4195 * on some hardwares like Dell.
4197 * The below flag enables the longer delay (see get_response
4198 * in hda_intel.c).
4200 codec->bus->needs_damn_long_delay = 1;
4202 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4204 return 0;
4207 static int patch_stac9205(struct hda_codec *codec)
4209 struct sigmatel_spec *spec;
4210 int err;
4212 err = alloc_stac_spec(codec);
4213 if (err < 0)
4214 return err;
4216 spec = codec->spec;
4217 spec->linear_tone_beep = 1;
4218 spec->gen.own_eapd_ctl = 1;
4219 spec->have_spdif_mux = 1;
4221 spec->gen.beep_nid = 0x23; /* digital beep */
4223 snd_hda_add_verbs(codec, stac9205_core_init);
4224 spec->aloopback_ctl = &stac9205_loopback;
4226 spec->aloopback_mask = 0x40;
4227 spec->aloopback_shift = 0;
4229 /* GPIO0 High = EAPD */
4230 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
4231 spec->gpio_data = 0x01;
4233 /* Turn on/off EAPD per HP plugging */
4234 spec->eapd_switch = 1;
4236 codec->patch_ops = stac_patch_ops;
4238 snd_hda_pick_fixup(codec, stac9205_models, stac9205_fixup_tbl,
4239 stac9205_fixups);
4240 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4242 err = stac_parse_auto_config(codec);
4243 if (err < 0) {
4244 stac_free(codec);
4245 return err;
4248 codec->proc_widget_hook = stac9205_proc_hook;
4250 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4252 return 0;
4256 * STAC9872 hack
4259 static const struct hda_verb stac9872_core_init[] = {
4260 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
4261 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
4265 static const struct hda_pintbl stac9872_vaio_pin_configs[] = {
4266 { 0x0a, 0x03211020 },
4267 { 0x0b, 0x411111f0 },
4268 { 0x0c, 0x411111f0 },
4269 { 0x0d, 0x03a15030 },
4270 { 0x0e, 0x411111f0 },
4271 { 0x0f, 0x90170110 },
4272 { 0x11, 0x411111f0 },
4273 { 0x13, 0x411111f0 },
4274 { 0x14, 0x90a7013e },
4278 static const struct hda_model_fixup stac9872_models[] = {
4279 { .id = STAC_9872_VAIO, .name = "vaio" },
4283 static const struct hda_fixup stac9872_fixups[] = {
4284 [STAC_9872_VAIO] = {
4285 .type = HDA_FIXUP_PINS,
4286 .v.pins = stac9872_vaio_pin_configs,
4290 static const struct snd_pci_quirk stac9872_fixup_tbl[] = {
4291 SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0,
4292 "Sony VAIO F/S", STAC_9872_VAIO),
4293 {} /* terminator */
4296 static int patch_stac9872(struct hda_codec *codec)
4298 struct sigmatel_spec *spec;
4299 int err;
4301 err = alloc_stac_spec(codec);
4302 if (err < 0)
4303 return err;
4305 spec = codec->spec;
4306 spec->linear_tone_beep = 1;
4307 spec->gen.own_eapd_ctl = 1;
4309 codec->patch_ops = stac_patch_ops;
4311 snd_hda_add_verbs(codec, stac9872_core_init);
4313 snd_hda_pick_fixup(codec, stac9872_models, stac9872_fixup_tbl,
4314 stac9872_fixups);
4315 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4317 err = stac_parse_auto_config(codec);
4318 if (err < 0) {
4319 stac_free(codec);
4320 return -EINVAL;
4323 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4325 return 0;
4330 * patch entries
4332 static const struct hda_codec_preset snd_hda_preset_sigmatel[] = {
4333 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
4334 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
4335 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
4336 { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x },
4337 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
4338 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
4339 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
4340 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x },
4341 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x },
4342 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x },
4343 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x },
4344 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x },
4345 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x },
4346 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
4347 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
4348 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
4349 { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x },
4350 { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x },
4351 { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x },
4352 { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x },
4353 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x },
4354 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x },
4355 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x },
4356 { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x },
4357 { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x },
4358 { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x },
4359 { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
4360 { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
4361 { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
4362 { .id = 0x83847645, .name = "92HD206X", .patch = patch_stac927x },
4363 { .id = 0x83847646, .name = "92HD206D", .patch = patch_stac927x },
4364 /* The following does not take into account .id=0x83847661 when subsys =
4365 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
4366 * currently not fully supported.
4368 { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 },
4369 { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 },
4370 { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 },
4371 { .id = 0x83847698, .name = "STAC9205", .patch = patch_stac9205 },
4372 { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 },
4373 { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 },
4374 { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 },
4375 { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 },
4376 { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 },
4377 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
4378 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
4379 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
4380 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx},
4381 { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx},
4382 { .id = 0x111d76d4, .name = "92HD83C1C5", .patch = patch_stac92hd83xxx},
4383 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx},
4384 { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx},
4385 { .id = 0x111d76d1, .name = "92HD87B1/3", .patch = patch_stac92hd83xxx},
4386 { .id = 0x111d76d9, .name = "92HD87B2/4", .patch = patch_stac92hd83xxx},
4387 { .id = 0x111d7666, .name = "92HD88B3", .patch = patch_stac92hd83xxx},
4388 { .id = 0x111d7667, .name = "92HD88B1", .patch = patch_stac92hd83xxx},
4389 { .id = 0x111d7668, .name = "92HD88B2", .patch = patch_stac92hd83xxx},
4390 { .id = 0x111d7669, .name = "92HD88B4", .patch = patch_stac92hd83xxx},
4391 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx},
4392 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
4393 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },
4394 { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx },
4395 { .id = 0x111d7695, .name = "92HD95", .patch = patch_stac92hd95 },
4396 { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
4397 { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
4398 { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
4399 { .id = 0x111d76b3, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
4400 { .id = 0x111d76b4, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
4401 { .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
4402 { .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
4403 { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
4404 { .id = 0x111d76c0, .name = "92HD89C3", .patch = patch_stac92hd73xx },
4405 { .id = 0x111d76c1, .name = "92HD89C2", .patch = patch_stac92hd73xx },
4406 { .id = 0x111d76c2, .name = "92HD89C1", .patch = patch_stac92hd73xx },
4407 { .id = 0x111d76c3, .name = "92HD89B3", .patch = patch_stac92hd73xx },
4408 { .id = 0x111d76c4, .name = "92HD89B2", .patch = patch_stac92hd73xx },
4409 { .id = 0x111d76c5, .name = "92HD89B1", .patch = patch_stac92hd73xx },
4410 { .id = 0x111d76c6, .name = "92HD89E3", .patch = patch_stac92hd73xx },
4411 { .id = 0x111d76c7, .name = "92HD89E2", .patch = patch_stac92hd73xx },
4412 { .id = 0x111d76c8, .name = "92HD89E1", .patch = patch_stac92hd73xx },
4413 { .id = 0x111d76c9, .name = "92HD89D3", .patch = patch_stac92hd73xx },
4414 { .id = 0x111d76ca, .name = "92HD89D2", .patch = patch_stac92hd73xx },
4415 { .id = 0x111d76cb, .name = "92HD89D1", .patch = patch_stac92hd73xx },
4416 { .id = 0x111d76cc, .name = "92HD89F3", .patch = patch_stac92hd73xx },
4417 { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx },
4418 { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx },
4419 { .id = 0x111d76df, .name = "92HD93BXX", .patch = patch_stac92hd83xxx},
4420 { .id = 0x111d76e0, .name = "92HD91BXX", .patch = patch_stac92hd83xxx},
4421 { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx},
4422 { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx},
4423 { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx},
4424 { .id = 0x111d76e8, .name = "92HD66B1X5", .patch = patch_stac92hd83xxx},
4425 { .id = 0x111d76e9, .name = "92HD66B2X5", .patch = patch_stac92hd83xxx},
4426 { .id = 0x111d76ea, .name = "92HD66B3X5", .patch = patch_stac92hd83xxx},
4427 { .id = 0x111d76eb, .name = "92HD66C1X5", .patch = patch_stac92hd83xxx},
4428 { .id = 0x111d76ec, .name = "92HD66C2X5", .patch = patch_stac92hd83xxx},
4429 { .id = 0x111d76ed, .name = "92HD66C3X5", .patch = patch_stac92hd83xxx},
4430 { .id = 0x111d76ee, .name = "92HD66B1X3", .patch = patch_stac92hd83xxx},
4431 { .id = 0x111d76ef, .name = "92HD66B2X3", .patch = patch_stac92hd83xxx},
4432 { .id = 0x111d76f0, .name = "92HD66B3X3", .patch = patch_stac92hd83xxx},
4433 { .id = 0x111d76f1, .name = "92HD66C1X3", .patch = patch_stac92hd83xxx},
4434 { .id = 0x111d76f2, .name = "92HD66C2X3", .patch = patch_stac92hd83xxx},
4435 { .id = 0x111d76f3, .name = "92HD66C3/65", .patch = patch_stac92hd83xxx},
4436 {} /* terminator */
4439 MODULE_ALIAS("snd-hda-codec-id:8384*");
4440 MODULE_ALIAS("snd-hda-codec-id:111d*");
4442 MODULE_LICENSE("GPL");
4443 MODULE_DESCRIPTION("IDT/Sigmatel HD-audio codec");
4445 static struct hda_codec_preset_list sigmatel_list = {
4446 .preset = snd_hda_preset_sigmatel,
4447 .owner = THIS_MODULE,
4450 static int __init patch_sigmatel_init(void)
4452 return snd_hda_add_codec_preset(&sigmatel_list);
4455 static void __exit patch_sigmatel_exit(void)
4457 snd_hda_delete_codec_preset(&sigmatel_list);
4460 module_init(patch_sigmatel_init)
4461 module_exit(patch_sigmatel_exit)