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 <sound/driver.h>
28 #include <linux/init.h>
29 #include <linux/delay.h>
30 #include <linux/slab.h>
31 #include <linux/pci.h>
32 #include <sound/core.h>
33 #include <sound/asoundef.h>
34 #include "hda_codec.h"
35 #include "hda_local.h"
37 #define NUM_CONTROL_ALLOC 32
38 #define STAC_HP_EVENT 0x37
81 /* for backward compatibility */
103 struct sigmatel_spec {
104 struct snd_kcontrol_new *mixers[4];
105 unsigned int num_mixers;
108 unsigned int surr_switch: 1;
109 unsigned int line_switch: 1;
110 unsigned int mic_switch: 1;
111 unsigned int alt_switch: 1;
112 unsigned int hp_detect: 1;
113 unsigned int gpio_mute: 1;
115 unsigned int gpio_mask, gpio_data;
118 struct hda_multi_out multiout;
119 hda_nid_t dac_nids[5];
123 unsigned int num_adcs;
125 unsigned int num_muxes;
126 hda_nid_t *dmic_nids;
127 unsigned int num_dmics;
129 hda_nid_t dig_in_nid;
133 unsigned int num_pins;
134 unsigned int *pin_configs;
135 unsigned int *bios_pin_configs;
137 /* codec specific stuff */
138 struct hda_verb *init;
139 struct snd_kcontrol_new *mixer;
142 struct hda_input_mux *dinput_mux;
143 unsigned int cur_dmux;
144 struct hda_input_mux *input_mux;
145 unsigned int cur_mux[3];
148 unsigned int io_switch[2];
149 unsigned int clfe_swap;
150 unsigned int aloopback;
152 struct hda_pcm pcm_rec[2]; /* PCM information */
154 /* dynamic controls and input_mux */
155 struct auto_pin_cfg autocfg;
156 unsigned int num_kctl_alloc, num_kctl_used;
157 struct snd_kcontrol_new *kctl_alloc;
158 struct hda_input_mux private_dimux;
159 struct hda_input_mux private_imux;
162 static hda_nid_t stac9200_adc_nids[1] = {
166 static hda_nid_t stac9200_mux_nids[1] = {
170 static hda_nid_t stac9200_dac_nids[1] = {
174 static hda_nid_t stac925x_adc_nids[1] = {
178 static hda_nid_t stac925x_mux_nids[1] = {
182 static hda_nid_t stac925x_dac_nids[1] = {
186 #define STAC925X_NUM_DMICS 1
187 static hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = {
191 static hda_nid_t stac922x_adc_nids[2] = {
195 static hda_nid_t stac922x_mux_nids[2] = {
199 static hda_nid_t stac927x_adc_nids[3] = {
203 static hda_nid_t stac927x_mux_nids[3] = {
207 static hda_nid_t stac9205_adc_nids[2] = {
211 static hda_nid_t stac9205_mux_nids[2] = {
215 #define STAC9205_NUM_DMICS 2
216 static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
220 static hda_nid_t stac9200_pin_nids[8] = {
221 0x08, 0x09, 0x0d, 0x0e,
222 0x0f, 0x10, 0x11, 0x12,
225 static hda_nid_t stac925x_pin_nids[8] = {
226 0x07, 0x08, 0x0a, 0x0b,
227 0x0c, 0x0d, 0x10, 0x11,
230 static hda_nid_t stac922x_pin_nids[10] = {
231 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
232 0x0f, 0x10, 0x11, 0x15, 0x1b,
235 static hda_nid_t stac927x_pin_nids[14] = {
236 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
237 0x0f, 0x10, 0x11, 0x12, 0x13,
238 0x14, 0x21, 0x22, 0x23,
241 static hda_nid_t stac9205_pin_nids[12] = {
242 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
243 0x0f, 0x14, 0x16, 0x17, 0x18,
247 static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
248 struct snd_ctl_elem_info *uinfo)
250 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
251 struct sigmatel_spec *spec = codec->spec;
252 return snd_hda_input_mux_info(spec->dinput_mux, uinfo);
255 static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol,
256 struct snd_ctl_elem_value *ucontrol)
258 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
259 struct sigmatel_spec *spec = codec->spec;
261 ucontrol->value.enumerated.item[0] = spec->cur_dmux;
265 static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
266 struct snd_ctl_elem_value *ucontrol)
268 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
269 struct sigmatel_spec *spec = codec->spec;
271 return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol,
272 spec->dmux_nid, &spec->cur_dmux);
275 static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
277 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
278 struct sigmatel_spec *spec = codec->spec;
279 return snd_hda_input_mux_info(spec->input_mux, uinfo);
282 static int stac92xx_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
284 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
285 struct sigmatel_spec *spec = codec->spec;
286 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
288 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
292 static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
294 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
295 struct sigmatel_spec *spec = codec->spec;
296 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
298 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
299 spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]);
302 #define stac92xx_aloopback_info snd_ctl_boolean_mono_info
304 static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol,
305 struct snd_ctl_elem_value *ucontrol)
307 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
308 struct sigmatel_spec *spec = codec->spec;
310 ucontrol->value.integer.value[0] = spec->aloopback;
314 static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol,
315 struct snd_ctl_elem_value *ucontrol)
317 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
318 struct sigmatel_spec *spec = codec->spec;
319 unsigned int dac_mode;
321 if (spec->aloopback == ucontrol->value.integer.value[0])
324 spec->aloopback = ucontrol->value.integer.value[0];
327 dac_mode = snd_hda_codec_read(codec, codec->afg, 0,
328 kcontrol->private_value & 0xFFFF, 0x0);
330 if (spec->aloopback) {
331 snd_hda_power_up(codec);
334 snd_hda_power_down(codec);
338 snd_hda_codec_write_cache(codec, codec->afg, 0,
339 kcontrol->private_value >> 16, dac_mode);
344 static int stac92xx_volknob_info(struct snd_kcontrol *kcontrol,
345 struct snd_ctl_elem_info *uinfo)
347 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
349 uinfo->value.integer.min = 0;
350 uinfo->value.integer.max = 127;
354 static int stac92xx_volknob_get(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol)
357 ucontrol->value.integer.value[0] = kcontrol->private_value & 0xff;
361 static int stac92xx_volknob_put(struct snd_kcontrol *kcontrol,
362 struct snd_ctl_elem_value *ucontrol)
364 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
365 unsigned int val = kcontrol->private_value & 0xff;
367 if (val == ucontrol->value.integer.value[0])
370 val = ucontrol->value.integer.value[0];
371 kcontrol->private_value &= ~0xff;
372 kcontrol->private_value |= val;
374 snd_hda_codec_write_cache(codec, kcontrol->private_value >> 16, 0,
375 AC_VERB_SET_VOLUME_KNOB_CONTROL, val | 0x80);
380 static struct hda_verb stac9200_core_init[] = {
381 /* set dac0mux for dac converter */
382 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
386 static struct hda_verb stac9200_eapd_init[] = {
387 /* set dac0mux for dac converter */
388 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
389 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
393 static struct hda_verb stac925x_core_init[] = {
394 /* set dac0mux for dac converter */
395 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
399 static struct hda_verb stac922x_core_init[] = {
400 /* set master volume and direct control */
401 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
405 static struct hda_verb d965_core_init[] = {
406 /* set master volume and direct control */
407 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
408 /* unmute node 0x1b */
409 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
410 /* select node 0x03 as DAC */
411 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
415 static struct hda_verb stac927x_core_init[] = {
416 /* set master volume and direct control */
417 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
421 static struct hda_verb stac9205_core_init[] = {
422 /* set master volume and direct control */
423 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
427 #define STAC_INPUT_SOURCE(cnt) \
429 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
430 .name = "Input Source", \
432 .info = stac92xx_mux_enum_info, \
433 .get = stac92xx_mux_enum_get, \
434 .put = stac92xx_mux_enum_put, \
437 #define STAC_ANALOG_LOOPBACK(verb_read,verb_write) \
439 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
440 .name = "Analog Loopback", \
442 .info = stac92xx_aloopback_info, \
443 .get = stac92xx_aloopback_get, \
444 .put = stac92xx_aloopback_put, \
445 .private_value = verb_read | (verb_write << 16), \
448 #define STAC_VOLKNOB(knob_nid) \
450 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
451 .name = "Master Playback Volume", \
453 .info = stac92xx_volknob_info, \
454 .get = stac92xx_volknob_get, \
455 .put = stac92xx_volknob_put, \
456 .private_value = 127 | (knob_nid << 16), \
460 static struct snd_kcontrol_new stac9200_mixer[] = {
461 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
462 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
463 STAC_INPUT_SOURCE(1),
464 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
465 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
466 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT),
470 static struct snd_kcontrol_new stac925x_mixer[] = {
471 STAC_INPUT_SOURCE(1),
472 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
473 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT),
474 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT),
478 static struct snd_kcontrol_new stac9205_mixer[] = {
480 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
481 .name = "Digital Input Source",
483 .info = stac92xx_dmux_enum_info,
484 .get = stac92xx_dmux_enum_get,
485 .put = stac92xx_dmux_enum_put,
487 STAC_INPUT_SOURCE(2),
488 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0),
491 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT),
492 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT),
493 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x19, 0x0, HDA_OUTPUT),
495 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT),
496 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT),
497 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x1A, 0x0, HDA_OUTPUT),
502 /* This needs to be generated dynamically based on sequence */
503 static struct snd_kcontrol_new stac922x_mixer[] = {
504 STAC_INPUT_SOURCE(2),
506 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT),
507 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT),
508 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x12, 0x0, HDA_OUTPUT),
510 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT),
511 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT),
512 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x13, 0x0, HDA_OUTPUT),
517 static struct snd_kcontrol_new stac927x_mixer[] = {
518 STAC_INPUT_SOURCE(3),
520 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB),
522 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT),
523 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT),
524 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x15, 0x0, HDA_OUTPUT),
526 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT),
527 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT),
528 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x16, 0x0, HDA_OUTPUT),
530 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT),
531 HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT),
532 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x2, 0x17, 0x0, HDA_OUTPUT),
536 static int stac92xx_build_controls(struct hda_codec *codec)
538 struct sigmatel_spec *spec = codec->spec;
542 err = snd_hda_add_new_ctls(codec, spec->mixer);
546 for (i = 0; i < spec->num_mixers; i++) {
547 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
552 if (spec->multiout.dig_out_nid) {
553 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
557 if (spec->dig_in_nid) {
558 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
565 static unsigned int ref9200_pin_configs[8] = {
566 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
567 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
571 STAC 9200 pin configs for
576 static unsigned int dell9200_d21_pin_configs[8] = {
577 0x400001f0, 0x400001f1, 0x02214030, 0x01014010,
578 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
582 STAC 9200 pin configs for
586 static unsigned int dell9200_d22_pin_configs[8] = {
587 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
588 0x01813020, 0x02a19021, 0x90100140, 0x400001f2,
592 STAC 9200 pin configs for
593 102801C4 (Dell Dimension E310)
600 static unsigned int dell9200_d23_pin_configs[8] = {
601 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
602 0x01813020, 0x01a19021, 0x90100140, 0x400001f2,
607 STAC 9200-32 pin configs for
608 102801B5 (Dell Inspiron 630m)
609 102801D8 (Dell Inspiron 640m)
611 static unsigned int dell9200_m21_pin_configs[8] = {
612 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310,
613 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd,
617 STAC 9200-32 pin configs for
618 102801C2 (Dell Latitude D620)
620 102801CC (Dell Latitude D820)
624 static unsigned int dell9200_m22_pin_configs[8] = {
625 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310,
626 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc,
630 STAC 9200-32 pin configs for
631 102801CE (Dell XPS M1710)
632 102801CF (Dell Precision M90)
634 static unsigned int dell9200_m23_pin_configs[8] = {
635 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310,
636 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc,
640 STAC 9200-32 pin configs for
643 102801CB (Dell Latitude 120L)
646 static unsigned int dell9200_m24_pin_configs[8] = {
647 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310,
648 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe,
652 STAC 9200-32 pin configs for
653 102801BD (Dell Inspiron E1505n)
657 static unsigned int dell9200_m25_pin_configs[8] = {
658 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
659 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd,
663 STAC 9200-32 pin configs for
664 102801F5 (Dell Inspiron 1501)
667 static unsigned int dell9200_m26_pin_configs[8] = {
668 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310,
669 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe,
674 102801CD (Dell Inspiron E1705/9400)
676 static unsigned int dell9200_m27_pin_configs[8] = {
677 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
678 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc,
682 static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
683 [STAC_REF] = ref9200_pin_configs,
684 [STAC_9200_DELL_D21] = dell9200_d21_pin_configs,
685 [STAC_9200_DELL_D22] = dell9200_d22_pin_configs,
686 [STAC_9200_DELL_D23] = dell9200_d23_pin_configs,
687 [STAC_9200_DELL_M21] = dell9200_m21_pin_configs,
688 [STAC_9200_DELL_M22] = dell9200_m22_pin_configs,
689 [STAC_9200_DELL_M23] = dell9200_m23_pin_configs,
690 [STAC_9200_DELL_M24] = dell9200_m24_pin_configs,
691 [STAC_9200_DELL_M25] = dell9200_m25_pin_configs,
692 [STAC_9200_DELL_M26] = dell9200_m26_pin_configs,
693 [STAC_9200_DELL_M27] = dell9200_m27_pin_configs,
696 static const char *stac9200_models[STAC_9200_MODELS] = {
698 [STAC_9200_DELL_D21] = "dell-d21",
699 [STAC_9200_DELL_D22] = "dell-d22",
700 [STAC_9200_DELL_D23] = "dell-d23",
701 [STAC_9200_DELL_M21] = "dell-m21",
702 [STAC_9200_DELL_M22] = "dell-m22",
703 [STAC_9200_DELL_M23] = "dell-m23",
704 [STAC_9200_DELL_M24] = "dell-m24",
705 [STAC_9200_DELL_M25] = "dell-m25",
706 [STAC_9200_DELL_M26] = "dell-m26",
707 [STAC_9200_DELL_M27] = "dell-m27",
708 [STAC_9200_GATEWAY] = "gateway",
711 static struct snd_pci_quirk stac9200_cfg_tbl[] = {
712 /* SigmaTel reference board */
713 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
714 "DFI LanParty", STAC_REF),
715 /* Dell laptops have BIOS problem */
716 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
717 "unknown Dell", STAC_9200_DELL_D21),
718 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
719 "Dell Inspiron 630m", STAC_9200_DELL_M21),
720 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
721 "Dell Inspiron E1505n", STAC_9200_DELL_M25),
722 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
723 "unknown Dell", STAC_9200_DELL_D22),
724 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
725 "unknown Dell", STAC_9200_DELL_D22),
726 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
727 "Dell Latitude D620", STAC_9200_DELL_M22),
728 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
729 "unknown Dell", STAC_9200_DELL_D23),
730 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
731 "unknown Dell", STAC_9200_DELL_D23),
732 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
733 "unknown Dell", STAC_9200_DELL_M22),
734 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
735 "unknown Dell", STAC_9200_DELL_M24),
736 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
737 "unknown Dell", STAC_9200_DELL_M24),
738 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
739 "Dell Latitude 120L", STAC_9200_DELL_M24),
740 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
741 "Dell Latitude D820", STAC_9200_DELL_M22),
742 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
743 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
744 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
745 "Dell XPS M1710", STAC_9200_DELL_M23),
746 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
747 "Dell Precision M90", STAC_9200_DELL_M23),
748 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
749 "unknown Dell", STAC_9200_DELL_M22),
750 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
751 "unknown Dell", STAC_9200_DELL_M22),
752 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
753 "unknown Dell", STAC_9200_DELL_M22),
754 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
755 "Dell Inspiron 640m", STAC_9200_DELL_M21),
756 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
757 "unknown Dell", STAC_9200_DELL_D23),
758 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
759 "unknown Dell", STAC_9200_DELL_D23),
760 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
761 "unknown Dell", STAC_9200_DELL_D21),
762 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
763 "unknown Dell", STAC_9200_DELL_D23),
764 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
765 "unknown Dell", STAC_9200_DELL_D21),
766 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
767 "unknown Dell", STAC_9200_DELL_M25),
768 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
769 "unknown Dell", STAC_9200_DELL_M25),
770 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
771 "Dell Inspiron 1501", STAC_9200_DELL_M26),
772 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
773 "unknown Dell", STAC_9200_DELL_M26),
775 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_REF),
776 /* Gateway machines needs EAPD to be set on resume */
777 SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY),
778 SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*",
780 SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707",
785 static unsigned int ref925x_pin_configs[8] = {
786 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
787 0x90a70320, 0x02214210, 0x400003f1, 0x9033032e,
790 static unsigned int stac925x_MA6_pin_configs[8] = {
791 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
792 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e,
795 static unsigned int stac925x_PA6_pin_configs[8] = {
796 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
797 0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e,
800 static unsigned int stac925xM2_2_pin_configs[8] = {
801 0x40c003f3, 0x424503f2, 0x04180011, 0x02a19020,
802 0x50a103f0, 0x90100212, 0x400003f1, 0x9033032e,
805 static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
806 [STAC_REF] = ref925x_pin_configs,
807 [STAC_M2_2] = stac925xM2_2_pin_configs,
808 [STAC_MA6] = stac925x_MA6_pin_configs,
809 [STAC_PA6] = stac925x_PA6_pin_configs,
812 static const char *stac925x_models[STAC_925x_MODELS] = {
814 [STAC_M2_2] = "m2-2",
819 static struct snd_pci_quirk stac925x_cfg_tbl[] = {
820 /* SigmaTel reference board */
821 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
822 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
823 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF),
824 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF),
825 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6),
826 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_PA6),
827 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2),
831 static unsigned int ref922x_pin_configs[10] = {
832 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
833 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
834 0x40000100, 0x40000100,
838 STAC 922X pin configs for
845 static unsigned int dell_922x_d81_pin_configs[10] = {
846 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
847 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1,
848 0x01813122, 0x400001f2,
852 STAC 922X pin configs for
856 static unsigned int dell_922x_d82_pin_configs[10] = {
857 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
858 0x02a19020, 0x01117011, 0x01451140, 0x400001f0,
859 0x01813122, 0x400001f1,
863 STAC 922X pin configs for
866 static unsigned int dell_922x_m81_pin_configs[10] = {
867 0x0321101f, 0x01112024, 0x01111222, 0x91174220,
868 0x03a11050, 0x01116221, 0x90a70330, 0x01452340,
869 0x40C003f1, 0x405003f0,
873 STAC 9221 A1 pin configs for
874 102801D7 (Dell XPS M1210)
876 static unsigned int dell_922x_m82_pin_configs[10] = {
877 0x0221121f, 0x408103ff, 0x02111212, 0x90100310,
878 0x408003f1, 0x02111211, 0x03451340, 0x40c003f2,
879 0x508003f3, 0x405003f4,
882 static unsigned int d945gtp3_pin_configs[10] = {
883 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
884 0x40000100, 0x40000100, 0x40000100, 0x40000100,
885 0x02a19120, 0x40000100,
888 static unsigned int d945gtp5_pin_configs[10] = {
889 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
890 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
891 0x02a19320, 0x40000100,
894 static unsigned int intel_mac_v1_pin_configs[10] = {
895 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd,
896 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240,
897 0x400000fc, 0x400000fb,
900 static unsigned int intel_mac_v2_pin_configs[10] = {
901 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
902 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa,
903 0x400000fc, 0x400000fb,
906 static unsigned int intel_mac_v3_pin_configs[10] = {
907 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
908 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240,
909 0x400000fc, 0x400000fb,
912 static unsigned int intel_mac_v4_pin_configs[10] = {
913 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
914 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
915 0x400000fc, 0x400000fb,
918 static unsigned int intel_mac_v5_pin_configs[10] = {
919 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
920 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
921 0x400000fc, 0x400000fb,
925 static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
926 [STAC_D945_REF] = ref922x_pin_configs,
927 [STAC_D945GTP3] = d945gtp3_pin_configs,
928 [STAC_D945GTP5] = d945gtp5_pin_configs,
929 [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs,
930 [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs,
931 [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs,
932 [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs,
933 [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs,
934 /* for backward compatibility */
935 [STAC_MACMINI] = intel_mac_v3_pin_configs,
936 [STAC_MACBOOK] = intel_mac_v5_pin_configs,
937 [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs,
938 [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs,
939 [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs,
940 [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs,
941 [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs,
942 [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs,
943 [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs,
944 [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs,
947 static const char *stac922x_models[STAC_922X_MODELS] = {
948 [STAC_D945_REF] = "ref",
949 [STAC_D945GTP5] = "5stack",
950 [STAC_D945GTP3] = "3stack",
951 [STAC_INTEL_MAC_V1] = "intel-mac-v1",
952 [STAC_INTEL_MAC_V2] = "intel-mac-v2",
953 [STAC_INTEL_MAC_V3] = "intel-mac-v3",
954 [STAC_INTEL_MAC_V4] = "intel-mac-v4",
955 [STAC_INTEL_MAC_V5] = "intel-mac-v5",
956 /* for backward compatibility */
957 [STAC_MACMINI] = "macmini",
958 [STAC_MACBOOK] = "macbook",
959 [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1",
960 [STAC_MACBOOK_PRO_V2] = "macbook-pro",
961 [STAC_IMAC_INTEL] = "imac-intel",
962 [STAC_IMAC_INTEL_20] = "imac-intel-20",
963 [STAC_922X_DELL_D81] = "dell-d81",
964 [STAC_922X_DELL_D82] = "dell-d82",
965 [STAC_922X_DELL_M81] = "dell-m81",
966 [STAC_922X_DELL_M82] = "dell-m82",
969 static struct snd_pci_quirk stac922x_cfg_tbl[] = {
970 /* SigmaTel reference board */
971 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
972 "DFI LanParty", STAC_D945_REF),
973 /* Intel 945G based systems */
974 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
975 "Intel D945G", STAC_D945GTP3),
976 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
977 "Intel D945G", STAC_D945GTP3),
978 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
979 "Intel D945G", STAC_D945GTP3),
980 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
981 "Intel D945G", STAC_D945GTP3),
982 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
983 "Intel D945G", STAC_D945GTP3),
984 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
985 "Intel D945G", STAC_D945GTP3),
986 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
987 "Intel D945G", STAC_D945GTP3),
988 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
989 "Intel D945G", STAC_D945GTP3),
990 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
991 "Intel D945G", STAC_D945GTP3),
992 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
993 "Intel D945G", STAC_D945GTP3),
994 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
995 "Intel D945G", STAC_D945GTP3),
996 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
997 "Intel D945G", STAC_D945GTP3),
998 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
999 "Intel D945G", STAC_D945GTP3),
1000 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
1001 "Intel D945G", STAC_D945GTP3),
1002 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
1003 "Intel D945G", STAC_D945GTP3),
1004 /* Intel D945G 5-stack systems */
1005 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
1006 "Intel D945G", STAC_D945GTP5),
1007 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
1008 "Intel D945G", STAC_D945GTP5),
1009 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
1010 "Intel D945G", STAC_D945GTP5),
1011 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
1012 "Intel D945G", STAC_D945GTP5),
1013 /* Intel 945P based systems */
1014 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
1015 "Intel D945P", STAC_D945GTP3),
1016 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
1017 "Intel D945P", STAC_D945GTP3),
1018 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
1019 "Intel D945P", STAC_D945GTP3),
1020 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
1021 "Intel D945P", STAC_D945GTP3),
1022 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
1023 "Intel D945P", STAC_D945GTP3),
1024 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
1025 "Intel D945P", STAC_D945GTP5),
1027 /* Apple Mac Mini (early 2006) */
1028 SND_PCI_QUIRK(0x8384, 0x7680,
1029 "Mac Mini", STAC_INTEL_MAC_V3),
1031 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
1032 "unknown Dell", STAC_922X_DELL_D81),
1033 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
1034 "unknown Dell", STAC_922X_DELL_D81),
1035 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
1036 "unknown Dell", STAC_922X_DELL_D81),
1037 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
1038 "unknown Dell", STAC_922X_DELL_D82),
1039 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
1040 "unknown Dell", STAC_922X_DELL_M81),
1041 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
1042 "unknown Dell", STAC_922X_DELL_D82),
1043 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
1044 "unknown Dell", STAC_922X_DELL_D81),
1045 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
1046 "unknown Dell", STAC_922X_DELL_D81),
1047 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
1048 "Dell XPS M1210", STAC_922X_DELL_M82),
1052 static unsigned int ref927x_pin_configs[14] = {
1053 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1054 0x01a19040, 0x01011012, 0x01016011, 0x0101201f,
1055 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070,
1056 0x01c42190, 0x40000100,
1059 static unsigned int d965_3st_pin_configs[14] = {
1060 0x0221401f, 0x02a19120, 0x40000100, 0x01014011,
1061 0x01a19021, 0x01813024, 0x40000100, 0x40000100,
1062 0x40000100, 0x40000100, 0x40000100, 0x40000100,
1063 0x40000100, 0x40000100
1066 static unsigned int d965_5st_pin_configs[14] = {
1067 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1068 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
1069 0x40000100, 0x40000100, 0x40000100, 0x01442070,
1070 0x40000100, 0x40000100
1073 static unsigned int dell_3st_pin_configs[14] = {
1074 0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
1075 0x01111212, 0x01116211, 0x01813050, 0x01112214,
1076 0x403003fa, 0x40000100, 0x40000100, 0x404003fb,
1077 0x40c003fc, 0x40000100
1080 static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
1081 [STAC_D965_REF] = ref927x_pin_configs,
1082 [STAC_D965_3ST] = d965_3st_pin_configs,
1083 [STAC_D965_5ST] = d965_5st_pin_configs,
1084 [STAC_DELL_3ST] = dell_3st_pin_configs,
1087 static const char *stac927x_models[STAC_927X_MODELS] = {
1088 [STAC_D965_REF] = "ref",
1089 [STAC_D965_3ST] = "3stack",
1090 [STAC_D965_5ST] = "5stack",
1091 [STAC_DELL_3ST] = "dell-3stack",
1094 static struct snd_pci_quirk stac927x_cfg_tbl[] = {
1095 /* SigmaTel reference board */
1096 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1097 "DFI LanParty", STAC_D965_REF),
1098 /* Intel 946 based systems */
1099 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
1100 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
1101 /* 965 based 3 stack systems */
1102 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2116, "Intel D965", STAC_D965_3ST),
1103 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2115, "Intel D965", STAC_D965_3ST),
1104 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2114, "Intel D965", STAC_D965_3ST),
1105 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2113, "Intel D965", STAC_D965_3ST),
1106 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2112, "Intel D965", STAC_D965_3ST),
1107 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2111, "Intel D965", STAC_D965_3ST),
1108 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2110, "Intel D965", STAC_D965_3ST),
1109 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2009, "Intel D965", STAC_D965_3ST),
1110 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2008, "Intel D965", STAC_D965_3ST),
1111 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2007, "Intel D965", STAC_D965_3ST),
1112 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2006, "Intel D965", STAC_D965_3ST),
1113 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2005, "Intel D965", STAC_D965_3ST),
1114 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2004, "Intel D965", STAC_D965_3ST),
1115 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST),
1116 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST),
1117 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST),
1118 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_D965_3ST),
1119 /* Dell 3 stack systems */
1120 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
1121 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
1122 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
1123 /* 965 based 5 stack systems */
1124 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_D965_5ST),
1125 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST),
1126 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST),
1127 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST),
1128 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2304, "Intel D965", STAC_D965_5ST),
1129 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2305, "Intel D965", STAC_D965_5ST),
1130 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2501, "Intel D965", STAC_D965_5ST),
1131 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2502, "Intel D965", STAC_D965_5ST),
1132 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2503, "Intel D965", STAC_D965_5ST),
1133 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2504, "Intel D965", STAC_D965_5ST),
1137 static unsigned int ref9205_pin_configs[12] = {
1138 0x40000100, 0x40000100, 0x01016011, 0x01014010,
1139 0x01813122, 0x01a19021, 0x40000100, 0x40000100,
1140 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
1144 STAC 9205 pin configs for
1152 static unsigned int dell_9205_m42_pin_configs[12] = {
1153 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310,
1154 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9,
1155 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE,
1159 STAC 9205 pin configs for
1163 102801FF (Dell Precision M4300)
1168 static unsigned int dell_9205_m43_pin_configs[12] = {
1169 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310,
1170 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9,
1171 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8,
1174 static unsigned int dell_9205_m44_pin_configs[12] = {
1175 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310,
1176 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9,
1177 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe,
1180 static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
1181 [STAC_9205_REF] = ref9205_pin_configs,
1182 [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs,
1183 [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs,
1184 [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs,
1187 static const char *stac9205_models[STAC_9205_MODELS] = {
1188 [STAC_9205_REF] = "ref",
1189 [STAC_9205_DELL_M42] = "dell-m42",
1190 [STAC_9205_DELL_M43] = "dell-m43",
1191 [STAC_9205_DELL_M44] = "dell-m44",
1194 static struct snd_pci_quirk stac9205_cfg_tbl[] = {
1195 /* SigmaTel reference board */
1196 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1197 "DFI LanParty", STAC_9205_REF),
1198 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1199 "unknown Dell", STAC_9205_DELL_M42),
1200 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1201 "unknown Dell", STAC_9205_DELL_M42),
1202 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
1203 "Dell Precision", STAC_9205_DELL_M43),
1204 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
1205 "Dell Precision", STAC_9205_DELL_M43),
1206 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
1207 "Dell Precision", STAC_9205_DELL_M43),
1208 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
1209 "Dell Precision", STAC_9205_DELL_M43),
1210 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
1211 "Dell Precision", STAC_9205_DELL_M43),
1212 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1213 "unknown Dell", STAC_9205_DELL_M42),
1214 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1215 "unknown Dell", STAC_9205_DELL_M42),
1216 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
1217 "Dell Precision", STAC_9205_DELL_M43),
1218 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
1219 "Dell Precision M4300", STAC_9205_DELL_M43),
1220 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
1221 "Dell Precision", STAC_9205_DELL_M43),
1222 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1223 "Dell Inspiron", STAC_9205_DELL_M44),
1224 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1225 "Dell Inspiron", STAC_9205_DELL_M44),
1226 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1227 "Dell Inspiron", STAC_9205_DELL_M44),
1228 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1229 "Dell Inspiron", STAC_9205_DELL_M44),
1230 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
1231 "unknown Dell", STAC_9205_DELL_M42),
1232 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
1233 "Dell Inspiron", STAC_9205_DELL_M44),
1237 static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
1240 struct sigmatel_spec *spec = codec->spec;
1242 if (! spec->bios_pin_configs) {
1243 spec->bios_pin_configs = kcalloc(spec->num_pins,
1244 sizeof(*spec->bios_pin_configs), GFP_KERNEL);
1245 if (! spec->bios_pin_configs)
1249 for (i = 0; i < spec->num_pins; i++) {
1250 hda_nid_t nid = spec->pin_nids[i];
1251 unsigned int pin_cfg;
1253 pin_cfg = snd_hda_codec_read(codec, nid, 0,
1254 AC_VERB_GET_CONFIG_DEFAULT, 0x00);
1255 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n",
1257 spec->bios_pin_configs[i] = pin_cfg;
1263 static void stac92xx_set_config_reg(struct hda_codec *codec,
1264 hda_nid_t pin_nid, unsigned int pin_config)
1267 snd_hda_codec_write(codec, pin_nid, 0,
1268 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
1269 pin_config & 0x000000ff);
1270 snd_hda_codec_write(codec, pin_nid, 0,
1271 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
1272 (pin_config & 0x0000ff00) >> 8);
1273 snd_hda_codec_write(codec, pin_nid, 0,
1274 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
1275 (pin_config & 0x00ff0000) >> 16);
1276 snd_hda_codec_write(codec, pin_nid, 0,
1277 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
1279 i = snd_hda_codec_read(codec, pin_nid, 0,
1280 AC_VERB_GET_CONFIG_DEFAULT,
1282 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n",
1286 static void stac92xx_set_config_regs(struct hda_codec *codec)
1289 struct sigmatel_spec *spec = codec->spec;
1291 if (!spec->pin_configs)
1294 for (i = 0; i < spec->num_pins; i++)
1295 stac92xx_set_config_reg(codec, spec->pin_nids[i],
1296 spec->pin_configs[i]);
1299 static void stac92xx_enable_gpio_mask(struct hda_codec *codec)
1301 struct sigmatel_spec *spec = codec->spec;
1302 /* Configure GPIOx as output */
1303 snd_hda_codec_write_cache(codec, codec->afg, 0,
1304 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_mask);
1305 /* Configure GPIOx as CMOS */
1306 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7e7, 0x00000000);
1308 snd_hda_codec_write_cache(codec, codec->afg, 0,
1309 AC_VERB_SET_GPIO_DATA, spec->gpio_data);
1311 snd_hda_codec_write_cache(codec, codec->afg, 0,
1312 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
1316 * Analog playback callbacks
1318 static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
1319 struct hda_codec *codec,
1320 struct snd_pcm_substream *substream)
1322 struct sigmatel_spec *spec = codec->spec;
1323 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
1326 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1327 struct hda_codec *codec,
1328 unsigned int stream_tag,
1329 unsigned int format,
1330 struct snd_pcm_substream *substream)
1332 struct sigmatel_spec *spec = codec->spec;
1333 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream);
1336 static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1337 struct hda_codec *codec,
1338 struct snd_pcm_substream *substream)
1340 struct sigmatel_spec *spec = codec->spec;
1341 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1345 * Digital playback callbacks
1347 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1348 struct hda_codec *codec,
1349 struct snd_pcm_substream *substream)
1351 struct sigmatel_spec *spec = codec->spec;
1352 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1355 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1356 struct hda_codec *codec,
1357 struct snd_pcm_substream *substream)
1359 struct sigmatel_spec *spec = codec->spec;
1360 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1363 static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1364 struct hda_codec *codec,
1365 unsigned int stream_tag,
1366 unsigned int format,
1367 struct snd_pcm_substream *substream)
1369 struct sigmatel_spec *spec = codec->spec;
1370 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1371 stream_tag, format, substream);
1376 * Analog capture callbacks
1378 static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1379 struct hda_codec *codec,
1380 unsigned int stream_tag,
1381 unsigned int format,
1382 struct snd_pcm_substream *substream)
1384 struct sigmatel_spec *spec = codec->spec;
1386 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1387 stream_tag, 0, format);
1391 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1392 struct hda_codec *codec,
1393 struct snd_pcm_substream *substream)
1395 struct sigmatel_spec *spec = codec->spec;
1397 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
1401 static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
1405 /* NID is set in stac92xx_build_pcms */
1407 .open = stac92xx_dig_playback_pcm_open,
1408 .close = stac92xx_dig_playback_pcm_close,
1409 .prepare = stac92xx_dig_playback_pcm_prepare
1413 static struct hda_pcm_stream stac92xx_pcm_digital_capture = {
1417 /* NID is set in stac92xx_build_pcms */
1420 static struct hda_pcm_stream stac92xx_pcm_analog_playback = {
1424 .nid = 0x02, /* NID to query formats and rates */
1426 .open = stac92xx_playback_pcm_open,
1427 .prepare = stac92xx_playback_pcm_prepare,
1428 .cleanup = stac92xx_playback_pcm_cleanup
1432 static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
1436 .nid = 0x06, /* NID to query formats and rates */
1438 .open = stac92xx_playback_pcm_open,
1439 .prepare = stac92xx_playback_pcm_prepare,
1440 .cleanup = stac92xx_playback_pcm_cleanup
1444 static struct hda_pcm_stream stac92xx_pcm_analog_capture = {
1447 /* NID + .substreams is set in stac92xx_build_pcms */
1449 .prepare = stac92xx_capture_pcm_prepare,
1450 .cleanup = stac92xx_capture_pcm_cleanup
1454 static int stac92xx_build_pcms(struct hda_codec *codec)
1456 struct sigmatel_spec *spec = codec->spec;
1457 struct hda_pcm *info = spec->pcm_rec;
1459 codec->num_pcms = 1;
1460 codec->pcm_info = info;
1462 info->name = "STAC92xx Analog";
1463 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
1464 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
1465 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1466 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs;
1468 if (spec->alt_switch) {
1471 info->name = "STAC92xx Analog Alt";
1472 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback;
1475 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1478 info->name = "STAC92xx Digital";
1479 if (spec->multiout.dig_out_nid) {
1480 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
1481 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
1483 if (spec->dig_in_nid) {
1484 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture;
1485 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
1492 static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
1494 unsigned int pincap = snd_hda_param_read(codec, nid,
1496 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
1497 if (pincap & AC_PINCAP_VREF_100)
1498 return AC_PINCTL_VREF_100;
1499 if (pincap & AC_PINCAP_VREF_80)
1500 return AC_PINCTL_VREF_80;
1501 if (pincap & AC_PINCAP_VREF_50)
1502 return AC_PINCTL_VREF_50;
1503 if (pincap & AC_PINCAP_VREF_GRD)
1504 return AC_PINCTL_VREF_GRD;
1508 static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
1511 snd_hda_codec_write_cache(codec, nid, 0,
1512 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
1515 #define stac92xx_io_switch_info snd_ctl_boolean_mono_info
1517 static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1519 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1520 struct sigmatel_spec *spec = codec->spec;
1521 int io_idx = kcontrol-> private_value & 0xff;
1523 ucontrol->value.integer.value[0] = spec->io_switch[io_idx];
1527 static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1529 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1530 struct sigmatel_spec *spec = codec->spec;
1531 hda_nid_t nid = kcontrol->private_value >> 8;
1532 int io_idx = kcontrol-> private_value & 0xff;
1533 unsigned short val = ucontrol->value.integer.value[0];
1535 spec->io_switch[io_idx] = val;
1538 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
1540 unsigned int pinctl = AC_PINCTL_IN_EN;
1541 if (io_idx) /* set VREF for mic */
1542 pinctl |= stac92xx_get_vref(codec, nid);
1543 stac92xx_auto_set_pinctl(codec, nid, pinctl);
1548 #define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info
1550 static int stac92xx_clfe_switch_get(struct snd_kcontrol *kcontrol,
1551 struct snd_ctl_elem_value *ucontrol)
1553 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1554 struct sigmatel_spec *spec = codec->spec;
1556 ucontrol->value.integer.value[0] = spec->clfe_swap;
1560 static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
1561 struct snd_ctl_elem_value *ucontrol)
1563 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1564 struct sigmatel_spec *spec = codec->spec;
1565 hda_nid_t nid = kcontrol->private_value & 0xff;
1567 if (spec->clfe_swap == ucontrol->value.integer.value[0])
1570 spec->clfe_swap = ucontrol->value.integer.value[0];
1572 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1573 spec->clfe_swap ? 0x4 : 0x0);
1578 #define STAC_CODEC_IO_SWITCH(xname, xpval) \
1579 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1582 .info = stac92xx_io_switch_info, \
1583 .get = stac92xx_io_switch_get, \
1584 .put = stac92xx_io_switch_put, \
1585 .private_value = xpval, \
1588 #define STAC_CODEC_CLFE_SWITCH(xname, xpval) \
1589 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1592 .info = stac92xx_clfe_switch_info, \
1593 .get = stac92xx_clfe_switch_get, \
1594 .put = stac92xx_clfe_switch_put, \
1595 .private_value = xpval, \
1599 STAC_CTL_WIDGET_VOL,
1600 STAC_CTL_WIDGET_MUTE,
1601 STAC_CTL_WIDGET_IO_SWITCH,
1602 STAC_CTL_WIDGET_CLFE_SWITCH
1605 static struct snd_kcontrol_new stac92xx_control_templates[] = {
1606 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
1607 HDA_CODEC_MUTE(NULL, 0, 0, 0),
1608 STAC_CODEC_IO_SWITCH(NULL, 0),
1609 STAC_CODEC_CLFE_SWITCH(NULL, 0),
1612 /* add dynamic controls */
1613 static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val)
1615 struct snd_kcontrol_new *knew;
1617 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
1618 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
1620 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
1623 if (spec->kctl_alloc) {
1624 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
1625 kfree(spec->kctl_alloc);
1627 spec->kctl_alloc = knew;
1628 spec->num_kctl_alloc = num;
1631 knew = &spec->kctl_alloc[spec->num_kctl_used];
1632 *knew = stac92xx_control_templates[type];
1633 knew->name = kstrdup(name, GFP_KERNEL);
1636 knew->private_value = val;
1637 spec->num_kctl_used++;
1641 /* flag inputs as additional dynamic lineouts */
1642 static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
1644 struct sigmatel_spec *spec = codec->spec;
1645 unsigned int wcaps, wtype;
1646 int i, num_dacs = 0;
1648 /* use the wcaps cache to count all DACs available for line-outs */
1649 for (i = 0; i < codec->num_nodes; i++) {
1650 wcaps = codec->wcaps[i];
1651 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
1652 if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL))
1656 snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
1658 switch (cfg->line_outs) {
1660 /* add line-in as side */
1661 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
1662 cfg->line_out_pins[cfg->line_outs] =
1663 cfg->input_pins[AUTO_PIN_LINE];
1664 spec->line_switch = 1;
1669 /* add line-in as clfe and mic as side */
1670 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
1671 cfg->line_out_pins[cfg->line_outs] =
1672 cfg->input_pins[AUTO_PIN_LINE];
1673 spec->line_switch = 1;
1676 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
1677 cfg->line_out_pins[cfg->line_outs] =
1678 cfg->input_pins[AUTO_PIN_MIC];
1679 spec->mic_switch = 1;
1684 /* add line-in as surr and mic as clfe */
1685 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
1686 cfg->line_out_pins[cfg->line_outs] =
1687 cfg->input_pins[AUTO_PIN_LINE];
1688 spec->line_switch = 1;
1691 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
1692 cfg->line_out_pins[cfg->line_outs] =
1693 cfg->input_pins[AUTO_PIN_MIC];
1694 spec->mic_switch = 1;
1704 static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
1708 for (i = 0; i < spec->multiout.num_dacs; i++) {
1709 if (spec->multiout.dac_nids[i] == nid)
1717 * Fill in the dac_nids table from the parsed pin configuration
1718 * This function only works when every pin in line_out_pins[]
1719 * contains atleast one DAC in its connection list. Some 92xx
1720 * codecs are not connected directly to a DAC, such as the 9200
1721 * and 9202/925x. For those, dac_nids[] must be hard-coded.
1723 static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
1724 struct auto_pin_cfg *cfg)
1726 struct sigmatel_spec *spec = codec->spec;
1727 int i, j, conn_len = 0;
1728 hda_nid_t nid, conn[HDA_MAX_CONNECTIONS];
1729 unsigned int wcaps, wtype;
1731 for (i = 0; i < cfg->line_outs; i++) {
1732 nid = cfg->line_out_pins[i];
1733 conn_len = snd_hda_get_connections(codec, nid, conn,
1734 HDA_MAX_CONNECTIONS);
1735 for (j = 0; j < conn_len; j++) {
1736 wcaps = snd_hda_param_read(codec, conn[j],
1737 AC_PAR_AUDIO_WIDGET_CAP);
1738 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
1740 if (wtype != AC_WID_AUD_OUT ||
1741 (wcaps & AC_WCAP_DIGITAL))
1743 /* conn[j] is a DAC routed to this line-out */
1744 if (!is_in_dac_nids(spec, conn[j]))
1748 if (j == conn_len) {
1749 if (spec->multiout.num_dacs > 0) {
1750 /* we have already working output pins,
1751 * so let's drop the broken ones again
1753 cfg->line_outs = spec->multiout.num_dacs;
1756 /* error out, no available DAC found */
1758 "%s: No available DAC for pin 0x%x\n",
1763 spec->multiout.dac_nids[i] = conn[j];
1764 spec->multiout.num_dacs++;
1766 /* select this DAC in the pin's input mux */
1767 snd_hda_codec_write_cache(codec, nid, 0,
1768 AC_VERB_SET_CONNECT_SEL, j);
1773 snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
1774 spec->multiout.num_dacs,
1775 spec->multiout.dac_nids[0],
1776 spec->multiout.dac_nids[1],
1777 spec->multiout.dac_nids[2],
1778 spec->multiout.dac_nids[3],
1779 spec->multiout.dac_nids[4]);
1783 /* create volume control/switch for the given prefx type */
1784 static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_t nid, int chs)
1789 sprintf(name, "%s Playback Volume", pfx);
1790 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name,
1791 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1794 sprintf(name, "%s Playback Switch", pfx);
1795 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name,
1796 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1802 /* add playback controls from the parsed DAC table */
1803 static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
1804 const struct auto_pin_cfg *cfg)
1806 static const char *chname[4] = {
1807 "Front", "Surround", NULL /*CLFE*/, "Side"
1812 struct sigmatel_spec *spec = codec->spec;
1813 unsigned int wid_caps;
1816 for (i = 0; i < cfg->line_outs; i++) {
1817 if (!spec->multiout.dac_nids[i])
1820 nid = spec->multiout.dac_nids[i];
1824 err = create_controls(spec, "Center", nid, 1);
1827 err = create_controls(spec, "LFE", nid, 2);
1831 wid_caps = get_wcaps(codec, nid);
1833 if (wid_caps & AC_WCAP_LR_SWAP) {
1834 err = stac92xx_add_control(spec,
1835 STAC_CTL_WIDGET_CLFE_SWITCH,
1836 "Swap Center/LFE Playback Switch", nid);
1843 err = create_controls(spec, chname[i], nid, 3);
1849 if (spec->line_switch)
1850 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Line In as Output Switch", cfg->input_pins[AUTO_PIN_LINE] << 8)) < 0)
1853 if (spec->mic_switch)
1854 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Mic as Output Switch", (cfg->input_pins[AUTO_PIN_MIC] << 8) | 1)) < 0)
1860 static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
1862 if (is_in_dac_nids(spec, nid))
1864 if (spec->multiout.hp_nid == nid)
1869 static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
1871 if (!spec->multiout.hp_nid)
1872 spec->multiout.hp_nid = nid;
1873 else if (spec->multiout.num_dacs > 4) {
1874 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
1877 spec->multiout.dac_nids[spec->multiout.num_dacs] = nid;
1878 spec->multiout.num_dacs++;
1883 /* add playback controls for Speaker and HP outputs */
1884 static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
1885 struct auto_pin_cfg *cfg)
1887 struct sigmatel_spec *spec = codec->spec;
1889 int i, old_num_dacs, err;
1891 old_num_dacs = spec->multiout.num_dacs;
1892 for (i = 0; i < cfg->hp_outs; i++) {
1893 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]);
1894 if (wid_caps & AC_WCAP_UNSOL_CAP)
1895 spec->hp_detect = 1;
1896 nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
1897 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1898 if (check_in_dac_nids(spec, nid))
1902 add_spec_dacs(spec, nid);
1904 for (i = 0; i < cfg->speaker_outs; i++) {
1905 nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
1906 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1907 if (check_in_dac_nids(spec, nid))
1911 add_spec_dacs(spec, nid);
1913 for (i = 0; i < cfg->line_outs; i++) {
1914 nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0,
1915 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1916 if (check_in_dac_nids(spec, nid))
1920 add_spec_dacs(spec, nid);
1922 for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) {
1923 static const char *pfxs[] = {
1924 "Speaker", "External Speaker", "Speaker2",
1926 err = create_controls(spec, pfxs[i - old_num_dacs],
1927 spec->multiout.dac_nids[i], 3);
1931 if (spec->multiout.hp_nid) {
1933 if (old_num_dacs == spec->multiout.num_dacs)
1937 err = create_controls(spec, pfx, spec->multiout.hp_nid, 3);
1945 /* labels for dmic mux inputs */
1946 static const char *stac92xx_dmic_labels[5] = {
1947 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
1948 "Digital Mic 3", "Digital Mic 4"
1951 /* create playback/capture controls for input pins on dmic capable codecs */
1952 static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
1953 const struct auto_pin_cfg *cfg)
1955 struct sigmatel_spec *spec = codec->spec;
1956 struct hda_input_mux *dimux = &spec->private_dimux;
1957 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
1960 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0];
1961 dimux->items[dimux->num_items].index = 0;
1964 for (i = 0; i < spec->num_dmics; i++) {
1967 unsigned int def_conf;
1969 def_conf = snd_hda_codec_read(codec,
1972 AC_VERB_GET_CONFIG_DEFAULT,
1974 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
1977 num_cons = snd_hda_get_connections(codec,
1980 HDA_MAX_NUM_INPUTS);
1981 for (j = 0; j < num_cons; j++)
1982 if (con_lst[j] == spec->dmic_nids[i]) {
1988 dimux->items[dimux->num_items].label =
1989 stac92xx_dmic_labels[dimux->num_items];
1990 dimux->items[dimux->num_items].index = index;
1997 /* create playback/capture controls for input pins */
1998 static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
2000 struct sigmatel_spec *spec = codec->spec;
2001 struct hda_input_mux *imux = &spec->private_imux;
2002 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
2005 for (i = 0; i < AUTO_PIN_LAST; i++) {
2008 if (!cfg->input_pins[i])
2011 for (j = 0; j < spec->num_muxes; j++) {
2013 num_cons = snd_hda_get_connections(codec,
2016 HDA_MAX_NUM_INPUTS);
2017 for (k = 0; k < num_cons; k++)
2018 if (con_lst[k] == cfg->input_pins[i]) {
2025 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2026 imux->items[imux->num_items].index = index;
2030 if (imux->num_items) {
2032 * Set the current input for the muxes.
2033 * The STAC9221 has two input muxes with identical source
2034 * NID lists. Hopefully this won't get confused.
2036 for (i = 0; i < spec->num_muxes; i++) {
2037 snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0,
2038 AC_VERB_SET_CONNECT_SEL,
2039 imux->items[0].index);
2046 static void stac92xx_auto_init_multi_out(struct hda_codec *codec)
2048 struct sigmatel_spec *spec = codec->spec;
2051 for (i = 0; i < spec->autocfg.line_outs; i++) {
2052 hda_nid_t nid = spec->autocfg.line_out_pins[i];
2053 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
2057 static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
2059 struct sigmatel_spec *spec = codec->spec;
2062 for (i = 0; i < spec->autocfg.hp_outs; i++) {
2064 pin = spec->autocfg.hp_pins[i];
2065 if (pin) /* connect to front */
2066 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
2068 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
2070 pin = spec->autocfg.speaker_pins[i];
2071 if (pin) /* connect to front */
2072 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN);
2076 static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in)
2078 struct sigmatel_spec *spec = codec->spec;
2081 if ((err = snd_hda_parse_pin_def_config(codec,
2083 spec->dmic_nids)) < 0)
2085 if (! spec->autocfg.line_outs)
2086 return 0; /* can't find valid pin config */
2088 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
2090 if (spec->multiout.num_dacs == 0)
2091 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
2094 err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg);
2099 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
2104 err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
2109 if (spec->num_dmics > 0)
2110 if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
2111 &spec->autocfg)) < 0)
2114 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2115 if (spec->multiout.max_channels > 2)
2116 spec->surr_switch = 1;
2118 if (spec->autocfg.dig_out_pin)
2119 spec->multiout.dig_out_nid = dig_out;
2120 if (spec->autocfg.dig_in_pin)
2121 spec->dig_in_nid = dig_in;
2123 if (spec->kctl_alloc)
2124 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2126 spec->input_mux = &spec->private_imux;
2127 spec->dinput_mux = &spec->private_dimux;
2132 /* add playback controls for HP output */
2133 static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
2134 struct auto_pin_cfg *cfg)
2136 struct sigmatel_spec *spec = codec->spec;
2137 hda_nid_t pin = cfg->hp_pins[0];
2138 unsigned int wid_caps;
2143 wid_caps = get_wcaps(codec, pin);
2144 if (wid_caps & AC_WCAP_UNSOL_CAP)
2145 spec->hp_detect = 1;
2150 /* add playback controls for LFE output */
2151 static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec,
2152 struct auto_pin_cfg *cfg)
2154 struct sigmatel_spec *spec = codec->spec;
2156 hda_nid_t lfe_pin = 0x0;
2160 * search speaker outs and line outs for a mono speaker pin
2161 * with an amp. If one is found, add LFE controls
2164 for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) {
2165 hda_nid_t pin = spec->autocfg.speaker_pins[i];
2166 unsigned long wcaps = get_wcaps(codec, pin);
2167 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
2168 if (wcaps == AC_WCAP_OUT_AMP)
2169 /* found a mono speaker with an amp, must be lfe */
2173 /* if speaker_outs is 0, then speakers may be in line_outs */
2174 if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) {
2175 for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) {
2176 hda_nid_t pin = spec->autocfg.line_out_pins[i];
2178 cfg = snd_hda_codec_read(codec, pin, 0,
2179 AC_VERB_GET_CONFIG_DEFAULT,
2181 if (get_defcfg_device(cfg) == AC_JACK_SPEAKER) {
2182 unsigned long wcaps = get_wcaps(codec, pin);
2183 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
2184 if (wcaps == AC_WCAP_OUT_AMP)
2185 /* found a mono speaker with an amp,
2193 err = create_controls(spec, "LFE", lfe_pin, 1);
2201 static int stac9200_parse_auto_config(struct hda_codec *codec)
2203 struct sigmatel_spec *spec = codec->spec;
2206 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
2209 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
2212 if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)
2215 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
2218 if (spec->autocfg.dig_out_pin)
2219 spec->multiout.dig_out_nid = 0x05;
2220 if (spec->autocfg.dig_in_pin)
2221 spec->dig_in_nid = 0x04;
2223 if (spec->kctl_alloc)
2224 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2226 spec->input_mux = &spec->private_imux;
2227 spec->dinput_mux = &spec->private_dimux;
2233 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
2234 * funky external mute control using GPIO pins.
2237 static void stac922x_gpio_mute(struct hda_codec *codec, int pin, int muted)
2239 unsigned int gpiostate, gpiomask, gpiodir;
2241 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
2242 AC_VERB_GET_GPIO_DATA, 0);
2245 gpiostate |= (1 << pin);
2247 gpiostate &= ~(1 << pin);
2249 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
2250 AC_VERB_GET_GPIO_MASK, 0);
2251 gpiomask |= (1 << pin);
2253 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
2254 AC_VERB_GET_GPIO_DIRECTION, 0);
2255 gpiodir |= (1 << pin);
2257 /* AppleHDA seems to do this -- WTF is this verb?? */
2258 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
2260 snd_hda_codec_write(codec, codec->afg, 0,
2261 AC_VERB_SET_GPIO_MASK, gpiomask);
2262 snd_hda_codec_write(codec, codec->afg, 0,
2263 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
2267 snd_hda_codec_write(codec, codec->afg, 0,
2268 AC_VERB_SET_GPIO_DATA, gpiostate);
2271 static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
2274 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)
2275 snd_hda_codec_write_cache(codec, nid, 0,
2276 AC_VERB_SET_UNSOLICITED_ENABLE,
2277 (AC_USRSP_EN | event));
2280 static int stac92xx_init(struct hda_codec *codec)
2282 struct sigmatel_spec *spec = codec->spec;
2283 struct auto_pin_cfg *cfg = &spec->autocfg;
2286 snd_hda_sequence_write(codec, spec->init);
2289 if (spec->hp_detect) {
2290 /* Enable unsolicited responses on the HP widget */
2291 for (i = 0; i < cfg->hp_outs; i++)
2292 enable_pin_detect(codec, cfg->hp_pins[i],
2294 /* force to enable the first line-out; the others are set up
2297 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
2299 stac92xx_auto_init_hp_out(codec);
2300 /* fake event to set up pins */
2301 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2303 stac92xx_auto_init_multi_out(codec);
2304 stac92xx_auto_init_hp_out(codec);
2306 for (i = 0; i < AUTO_PIN_LAST; i++) {
2307 hda_nid_t nid = cfg->input_pins[i];
2309 unsigned int pinctl = AC_PINCTL_IN_EN;
2310 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
2311 pinctl |= stac92xx_get_vref(codec, nid);
2312 stac92xx_auto_set_pinctl(codec, nid, pinctl);
2315 if (spec->num_dmics > 0)
2316 for (i = 0; i < spec->num_dmics; i++)
2317 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
2320 if (cfg->dig_out_pin)
2321 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
2323 if (cfg->dig_in_pin)
2324 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
2327 if (spec->gpio_mute) {
2328 stac922x_gpio_mute(codec, 0, 0);
2329 stac922x_gpio_mute(codec, 1, 0);
2335 static void stac92xx_free(struct hda_codec *codec)
2337 struct sigmatel_spec *spec = codec->spec;
2343 if (spec->kctl_alloc) {
2344 for (i = 0; i < spec->num_kctl_used; i++)
2345 kfree(spec->kctl_alloc[i].name);
2346 kfree(spec->kctl_alloc);
2349 if (spec->bios_pin_configs)
2350 kfree(spec->bios_pin_configs);
2355 static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
2358 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
2359 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
2361 if (pin_ctl & AC_PINCTL_IN_EN) {
2363 * we need to check the current set-up direction of
2364 * shared input pins since they can be switched via
2365 * "xxx as Output" mixer switch
2367 struct sigmatel_spec *spec = codec->spec;
2368 struct auto_pin_cfg *cfg = &spec->autocfg;
2369 if ((nid == cfg->input_pins[AUTO_PIN_LINE] &&
2370 spec->line_switch) ||
2371 (nid == cfg->input_pins[AUTO_PIN_MIC] &&
2376 /* if setting pin direction bits, clear the current
2377 direction bits first */
2378 if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
2379 pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
2381 snd_hda_codec_write_cache(codec, nid, 0,
2382 AC_VERB_SET_PIN_WIDGET_CONTROL,
2386 static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
2389 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
2390 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
2391 snd_hda_codec_write_cache(codec, nid, 0,
2392 AC_VERB_SET_PIN_WIDGET_CONTROL,
2396 static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
2400 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00)
2406 static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
2408 struct sigmatel_spec *spec = codec->spec;
2409 struct auto_pin_cfg *cfg = &spec->autocfg;
2413 for (i = 0; i < cfg->hp_outs; i++) {
2414 presence = get_pin_presence(codec, cfg->hp_pins[i]);
2420 /* disable lineouts, enable hp */
2421 for (i = 0; i < cfg->line_outs; i++)
2422 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
2424 for (i = 0; i < cfg->speaker_outs; i++)
2425 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
2428 /* enable lineouts, disable hp */
2429 for (i = 0; i < cfg->line_outs; i++)
2430 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
2432 for (i = 0; i < cfg->speaker_outs; i++)
2433 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
2438 static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
2440 switch (res >> 26) {
2442 stac92xx_hp_detect(codec, res);
2447 #ifdef SND_HDA_NEEDS_RESUME
2448 static int stac92xx_resume(struct hda_codec *codec)
2450 struct sigmatel_spec *spec = codec->spec;
2452 stac92xx_set_config_regs(codec);
2453 snd_hda_sequence_write(codec, spec->init);
2454 if (spec->gpio_mute) {
2455 stac922x_gpio_mute(codec, 0, 0);
2456 stac922x_gpio_mute(codec, 1, 0);
2458 snd_hda_codec_resume_amp(codec);
2459 snd_hda_codec_resume_cache(codec);
2460 /* invoke unsolicited event to reset the HP state */
2461 if (spec->hp_detect)
2462 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2467 static struct hda_codec_ops stac92xx_patch_ops = {
2468 .build_controls = stac92xx_build_controls,
2469 .build_pcms = stac92xx_build_pcms,
2470 .init = stac92xx_init,
2471 .free = stac92xx_free,
2472 .unsol_event = stac92xx_unsol_event,
2473 #ifdef SND_HDA_NEEDS_RESUME
2474 .resume = stac92xx_resume,
2478 static int patch_stac9200(struct hda_codec *codec)
2480 struct sigmatel_spec *spec;
2483 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2488 spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
2489 spec->pin_nids = stac9200_pin_nids;
2490 spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
2493 if (spec->board_config < 0) {
2494 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
2495 err = stac92xx_save_bios_config_regs(codec);
2497 stac92xx_free(codec);
2500 spec->pin_configs = spec->bios_pin_configs;
2502 spec->pin_configs = stac9200_brd_tbl[spec->board_config];
2503 stac92xx_set_config_regs(codec);
2506 spec->multiout.max_channels = 2;
2507 spec->multiout.num_dacs = 1;
2508 spec->multiout.dac_nids = stac9200_dac_nids;
2509 spec->adc_nids = stac9200_adc_nids;
2510 spec->mux_nids = stac9200_mux_nids;
2511 spec->num_muxes = 1;
2512 spec->num_dmics = 0;
2515 if (spec->board_config == STAC_9200_GATEWAY)
2516 spec->init = stac9200_eapd_init;
2518 spec->init = stac9200_core_init;
2519 spec->mixer = stac9200_mixer;
2521 err = stac9200_parse_auto_config(codec);
2523 stac92xx_free(codec);
2527 codec->patch_ops = stac92xx_patch_ops;
2532 static int patch_stac925x(struct hda_codec *codec)
2534 struct sigmatel_spec *spec;
2537 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2542 spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
2543 spec->pin_nids = stac925x_pin_nids;
2544 spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
2548 if (spec->board_config < 0) {
2549 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x,"
2550 "using BIOS defaults\n");
2551 err = stac92xx_save_bios_config_regs(codec);
2553 stac92xx_free(codec);
2556 spec->pin_configs = spec->bios_pin_configs;
2557 } else if (stac925x_brd_tbl[spec->board_config] != NULL){
2558 spec->pin_configs = stac925x_brd_tbl[spec->board_config];
2559 stac92xx_set_config_regs(codec);
2562 spec->multiout.max_channels = 2;
2563 spec->multiout.num_dacs = 1;
2564 spec->multiout.dac_nids = stac925x_dac_nids;
2565 spec->adc_nids = stac925x_adc_nids;
2566 spec->mux_nids = stac925x_mux_nids;
2567 spec->num_muxes = 1;
2569 switch (codec->vendor_id) {
2570 case 0x83847632: /* STAC9202 */
2571 case 0x83847633: /* STAC9202D */
2572 case 0x83847636: /* STAC9251 */
2573 case 0x83847637: /* STAC9251D */
2574 spec->num_dmics = STAC925X_NUM_DMICS;
2575 spec->dmic_nids = stac925x_dmic_nids;
2578 spec->num_dmics = 0;
2582 spec->init = stac925x_core_init;
2583 spec->mixer = stac925x_mixer;
2585 err = stac92xx_parse_auto_config(codec, 0x8, 0x7);
2587 if (spec->board_config < 0) {
2588 printk(KERN_WARNING "hda_codec: No auto-config is "
2589 "available, default to model=ref\n");
2590 spec->board_config = STAC_925x_REF;
2596 stac92xx_free(codec);
2600 codec->patch_ops = stac92xx_patch_ops;
2605 static int patch_stac922x(struct hda_codec *codec)
2607 struct sigmatel_spec *spec;
2610 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2615 spec->num_pins = ARRAY_SIZE(stac922x_pin_nids);
2616 spec->pin_nids = stac922x_pin_nids;
2617 spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
2620 if (spec->board_config == STAC_INTEL_MAC_V3) {
2621 spec->gpio_mute = 1;
2622 /* Intel Macs have all same PCI SSID, so we need to check
2623 * codec SSID to distinguish the exact models
2625 printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id);
2626 switch (codec->subsystem_id) {
2629 spec->board_config = STAC_INTEL_MAC_V1;
2633 spec->board_config = STAC_INTEL_MAC_V2;
2641 spec->board_config = STAC_INTEL_MAC_V3;
2645 spec->board_config = STAC_INTEL_MAC_V4;
2649 spec->board_config = STAC_INTEL_MAC_V5;
2655 if (spec->board_config < 0) {
2656 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, "
2657 "using BIOS defaults\n");
2658 err = stac92xx_save_bios_config_regs(codec);
2660 stac92xx_free(codec);
2663 spec->pin_configs = spec->bios_pin_configs;
2664 } else if (stac922x_brd_tbl[spec->board_config] != NULL) {
2665 spec->pin_configs = stac922x_brd_tbl[spec->board_config];
2666 stac92xx_set_config_regs(codec);
2669 spec->adc_nids = stac922x_adc_nids;
2670 spec->mux_nids = stac922x_mux_nids;
2671 spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
2672 spec->num_adcs = ARRAY_SIZE(stac922x_adc_nids);
2673 spec->num_dmics = 0;
2675 spec->init = stac922x_core_init;
2676 spec->mixer = stac922x_mixer;
2678 spec->multiout.dac_nids = spec->dac_nids;
2680 err = stac92xx_parse_auto_config(codec, 0x08, 0x09);
2682 if (spec->board_config < 0) {
2683 printk(KERN_WARNING "hda_codec: No auto-config is "
2684 "available, default to model=ref\n");
2685 spec->board_config = STAC_D945_REF;
2691 stac92xx_free(codec);
2695 codec->patch_ops = stac92xx_patch_ops;
2697 /* Fix Mux capture level; max to 2 */
2698 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
2699 (0 << AC_AMPCAP_OFFSET_SHIFT) |
2700 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2701 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2702 (0 << AC_AMPCAP_MUTE_SHIFT));
2707 static int patch_stac927x(struct hda_codec *codec)
2709 struct sigmatel_spec *spec;
2712 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2717 spec->num_pins = ARRAY_SIZE(stac927x_pin_nids);
2718 spec->pin_nids = stac927x_pin_nids;
2719 spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS,
2723 if (spec->board_config < 0) {
2724 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n");
2725 err = stac92xx_save_bios_config_regs(codec);
2727 stac92xx_free(codec);
2730 spec->pin_configs = spec->bios_pin_configs;
2731 } else if (stac927x_brd_tbl[spec->board_config] != NULL) {
2732 spec->pin_configs = stac927x_brd_tbl[spec->board_config];
2733 stac92xx_set_config_regs(codec);
2736 switch (spec->board_config) {
2738 spec->adc_nids = stac927x_adc_nids;
2739 spec->mux_nids = stac927x_mux_nids;
2740 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2741 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
2742 spec->num_dmics = 0;
2743 spec->init = d965_core_init;
2744 spec->mixer = stac927x_mixer;
2747 spec->adc_nids = stac927x_adc_nids;
2748 spec->mux_nids = stac927x_mux_nids;
2749 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2750 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
2751 spec->num_dmics = 0;
2752 spec->init = d965_core_init;
2753 spec->mixer = stac927x_mixer;
2756 spec->adc_nids = stac927x_adc_nids;
2757 spec->mux_nids = stac927x_mux_nids;
2758 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2759 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
2760 spec->num_dmics = 0;
2761 spec->init = stac927x_core_init;
2762 spec->mixer = stac927x_mixer;
2765 spec->multiout.dac_nids = spec->dac_nids;
2766 /* GPIO0 High = Enable EAPD */
2767 spec->gpio_mask = spec->gpio_data = 0x00000001;
2768 stac92xx_enable_gpio_mask(codec);
2770 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
2772 if (spec->board_config < 0) {
2773 printk(KERN_WARNING "hda_codec: No auto-config is "
2774 "available, default to model=ref\n");
2775 spec->board_config = STAC_D965_REF;
2781 stac92xx_free(codec);
2785 codec->patch_ops = stac92xx_patch_ops;
2790 static int patch_stac9205(struct hda_codec *codec)
2792 struct sigmatel_spec *spec;
2795 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2800 spec->num_pins = ARRAY_SIZE(stac9205_pin_nids);
2801 spec->pin_nids = stac9205_pin_nids;
2802 spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
2806 if (spec->board_config < 0) {
2807 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n");
2808 err = stac92xx_save_bios_config_regs(codec);
2810 stac92xx_free(codec);
2813 spec->pin_configs = spec->bios_pin_configs;
2815 spec->pin_configs = stac9205_brd_tbl[spec->board_config];
2816 stac92xx_set_config_regs(codec);
2819 spec->adc_nids = stac9205_adc_nids;
2820 spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids);
2821 spec->mux_nids = stac9205_mux_nids;
2822 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
2823 spec->dmic_nids = stac9205_dmic_nids;
2824 spec->num_dmics = STAC9205_NUM_DMICS;
2825 spec->dmux_nid = 0x1d;
2827 spec->init = stac9205_core_init;
2828 spec->mixer = stac9205_mixer;
2830 spec->multiout.dac_nids = spec->dac_nids;
2832 switch (spec->board_config){
2833 case STAC_9205_DELL_M43:
2834 /* Enable SPDIF in/out */
2835 stac92xx_set_config_reg(codec, 0x1f, 0x01441030);
2836 stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
2838 spec->gpio_mask = 0x00000007; /* GPIO0-2 */
2839 /* GPIO0 High = EAPD, GPIO1 Low = DRM,
2840 * GPIO2 High = Headphone Mute
2842 spec->gpio_data = 0x00000005;
2845 /* GPIO0 High = EAPD */
2846 spec->gpio_mask = spec->gpio_data = 0x00000001;
2850 stac92xx_enable_gpio_mask(codec);
2851 err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
2853 if (spec->board_config < 0) {
2854 printk(KERN_WARNING "hda_codec: No auto-config is "
2855 "available, default to model=ref\n");
2856 spec->board_config = STAC_9205_REF;
2862 stac92xx_free(codec);
2866 codec->patch_ops = stac92xx_patch_ops;
2875 /* static config for Sony VAIO FE550G and Sony VAIO AR */
2876 static hda_nid_t vaio_dacs[] = { 0x2 };
2877 #define VAIO_HP_DAC 0x5
2878 static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ };
2879 static hda_nid_t vaio_mux_nids[] = { 0x15 };
2881 static struct hda_input_mux vaio_mux = {
2884 /* { "HP", 0x0 }, */
2885 { "Mic Jack", 0x1 },
2886 { "Internal Mic", 0x2 },
2891 static struct hda_verb vaio_init[] = {
2892 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
2893 {0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT},
2894 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
2895 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
2896 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
2897 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
2898 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
2899 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
2900 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
2901 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
2902 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
2903 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
2907 static struct hda_verb vaio_ar_init[] = {
2908 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
2909 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
2910 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
2911 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
2912 /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */
2913 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
2914 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
2915 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
2916 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
2917 /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */
2918 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
2919 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
2920 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
2924 /* bind volumes of both NID 0x02 and 0x05 */
2925 static struct hda_bind_ctls vaio_bind_master_vol = {
2926 .ops = &snd_hda_bind_vol,
2928 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
2929 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
2934 /* bind volumes of both NID 0x02 and 0x05 */
2935 static struct hda_bind_ctls vaio_bind_master_sw = {
2936 .ops = &snd_hda_bind_sw,
2938 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
2939 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
2944 static struct snd_kcontrol_new vaio_mixer[] = {
2945 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
2946 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
2947 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
2948 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
2949 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
2951 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2952 .name = "Capture Source",
2954 .info = stac92xx_mux_enum_info,
2955 .get = stac92xx_mux_enum_get,
2956 .put = stac92xx_mux_enum_put,
2961 static struct snd_kcontrol_new vaio_ar_mixer[] = {
2962 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
2963 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
2964 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
2965 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
2966 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
2967 /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT),
2968 HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/
2970 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2971 .name = "Capture Source",
2973 .info = stac92xx_mux_enum_info,
2974 .get = stac92xx_mux_enum_get,
2975 .put = stac92xx_mux_enum_put,
2980 static struct hda_codec_ops stac9872_patch_ops = {
2981 .build_controls = stac92xx_build_controls,
2982 .build_pcms = stac92xx_build_pcms,
2983 .init = stac92xx_init,
2984 .free = stac92xx_free,
2985 #ifdef SND_HDA_NEEDS_RESUME
2986 .resume = stac92xx_resume,
2990 static int stac9872_vaio_init(struct hda_codec *codec)
2994 err = stac92xx_init(codec);
2997 if (codec->patch_ops.unsol_event)
2998 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
3002 static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
3004 if (get_pin_presence(codec, 0x0a)) {
3005 stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
3006 stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
3008 stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
3009 stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
3013 static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res)
3015 switch (res >> 26) {
3017 stac9872_vaio_hp_detect(codec, res);
3022 static struct hda_codec_ops stac9872_vaio_patch_ops = {
3023 .build_controls = stac92xx_build_controls,
3024 .build_pcms = stac92xx_build_pcms,
3025 .init = stac9872_vaio_init,
3026 .free = stac92xx_free,
3027 .unsol_event = stac9872_vaio_unsol_event,
3029 .resume = stac92xx_resume,
3033 enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */
3035 /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */
3037 /* Unknown. id=0x83847661 and subsys=0x104D1200. */
3039 /* AR Series. id=0x83847664 and subsys=104D1300 */
3044 static const char *stac9872_models[STAC_9872_MODELS] = {
3045 [CXD9872RD_VAIO] = "vaio",
3046 [CXD9872AKD_VAIO] = "vaio-ar",
3049 static struct snd_pci_quirk stac9872_cfg_tbl[] = {
3050 SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
3051 SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
3052 SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
3053 SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO),
3057 static int patch_stac9872(struct hda_codec *codec)
3059 struct sigmatel_spec *spec;
3062 board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
3065 if (board_config < 0)
3066 /* unknown config, let generic-parser do its job... */
3067 return snd_hda_parse_generic_codec(codec);
3069 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3074 switch (board_config) {
3075 case CXD9872RD_VAIO:
3076 case STAC9872AK_VAIO:
3077 case STAC9872K_VAIO:
3078 spec->mixer = vaio_mixer;
3079 spec->init = vaio_init;
3080 spec->multiout.max_channels = 2;
3081 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
3082 spec->multiout.dac_nids = vaio_dacs;
3083 spec->multiout.hp_nid = VAIO_HP_DAC;
3084 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
3085 spec->adc_nids = vaio_adcs;
3086 spec->input_mux = &vaio_mux;
3087 spec->mux_nids = vaio_mux_nids;
3088 codec->patch_ops = stac9872_vaio_patch_ops;
3091 case CXD9872AKD_VAIO:
3092 spec->mixer = vaio_ar_mixer;
3093 spec->init = vaio_ar_init;
3094 spec->multiout.max_channels = 2;
3095 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
3096 spec->multiout.dac_nids = vaio_dacs;
3097 spec->multiout.hp_nid = VAIO_HP_DAC;
3098 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
3099 spec->adc_nids = vaio_adcs;
3100 spec->input_mux = &vaio_mux;
3101 spec->mux_nids = vaio_mux_nids;
3102 codec->patch_ops = stac9872_patch_ops;
3113 struct hda_codec_preset snd_hda_preset_sigmatel[] = {
3114 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
3115 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
3116 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
3117 { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x },
3118 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
3119 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
3120 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
3121 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x },
3122 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x },
3123 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x },
3124 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x },
3125 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x },
3126 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x },
3127 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
3128 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
3129 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
3130 { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x },
3131 { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x },
3132 { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x },
3133 { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x },
3134 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x },
3135 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x },
3136 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x },
3137 { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x },
3138 { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x },
3139 { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x },
3140 { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
3141 { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
3142 { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
3143 /* The following does not take into account .id=0x83847661 when subsys =
3144 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
3145 * currently not fully supported.
3147 { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 },
3148 { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 },
3149 { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 },
3150 { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 },
3151 { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 },
3152 { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 },
3153 { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 },
3154 { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 },
3155 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
3156 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
3157 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },