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 static hda_nid_t stac925x_dmic_nids[1] = {
190 static hda_nid_t stac922x_adc_nids[2] = {
194 static hda_nid_t stac922x_mux_nids[2] = {
198 static hda_nid_t stac927x_adc_nids[3] = {
202 static hda_nid_t stac927x_mux_nids[3] = {
206 static hda_nid_t stac9205_adc_nids[2] = {
210 static hda_nid_t stac9205_mux_nids[2] = {
214 static hda_nid_t stac9205_dmic_nids[2] = {
218 static hda_nid_t stac9200_pin_nids[8] = {
219 0x08, 0x09, 0x0d, 0x0e,
220 0x0f, 0x10, 0x11, 0x12,
223 static hda_nid_t stac925x_pin_nids[8] = {
224 0x07, 0x08, 0x0a, 0x0b,
225 0x0c, 0x0d, 0x10, 0x11,
228 static hda_nid_t stac922x_pin_nids[10] = {
229 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
230 0x0f, 0x10, 0x11, 0x15, 0x1b,
233 static hda_nid_t stac927x_pin_nids[14] = {
234 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
235 0x0f, 0x10, 0x11, 0x12, 0x13,
236 0x14, 0x21, 0x22, 0x23,
239 static hda_nid_t stac9205_pin_nids[12] = {
240 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
241 0x0f, 0x14, 0x16, 0x17, 0x18,
245 static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
246 struct snd_ctl_elem_info *uinfo)
248 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
249 struct sigmatel_spec *spec = codec->spec;
250 return snd_hda_input_mux_info(spec->dinput_mux, uinfo);
253 static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol,
254 struct snd_ctl_elem_value *ucontrol)
256 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
257 struct sigmatel_spec *spec = codec->spec;
259 ucontrol->value.enumerated.item[0] = spec->cur_dmux;
263 static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
264 struct snd_ctl_elem_value *ucontrol)
266 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
267 struct sigmatel_spec *spec = codec->spec;
269 return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol,
270 spec->dmux_nid, &spec->cur_dmux);
273 static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
275 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
276 struct sigmatel_spec *spec = codec->spec;
277 return snd_hda_input_mux_info(spec->input_mux, uinfo);
280 static int stac92xx_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
282 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
283 struct sigmatel_spec *spec = codec->spec;
284 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
286 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
290 static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
292 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
293 struct sigmatel_spec *spec = codec->spec;
294 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
296 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
297 spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]);
300 #define stac92xx_aloopback_info snd_ctl_boolean_mono_info
302 static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol,
303 struct snd_ctl_elem_value *ucontrol)
305 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
306 struct sigmatel_spec *spec = codec->spec;
308 ucontrol->value.integer.value[0] = spec->aloopback;
312 static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol,
313 struct snd_ctl_elem_value *ucontrol)
315 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
316 struct sigmatel_spec *spec = codec->spec;
317 unsigned int dac_mode;
319 if (spec->aloopback == ucontrol->value.integer.value[0])
322 spec->aloopback = ucontrol->value.integer.value[0];
325 dac_mode = snd_hda_codec_read(codec, codec->afg, 0,
326 kcontrol->private_value & 0xFFFF, 0x0);
328 if (spec->aloopback) {
329 snd_hda_power_up(codec);
332 snd_hda_power_down(codec);
336 snd_hda_codec_write_cache(codec, codec->afg, 0,
337 kcontrol->private_value >> 16, dac_mode);
342 static int stac92xx_volknob_info(struct snd_kcontrol *kcontrol,
343 struct snd_ctl_elem_info *uinfo)
345 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
347 uinfo->value.integer.min = 0;
348 uinfo->value.integer.max = 127;
352 static int stac92xx_volknob_get(struct snd_kcontrol *kcontrol,
353 struct snd_ctl_elem_value *ucontrol)
355 ucontrol->value.integer.value[0] = kcontrol->private_value & 0xff;
359 static int stac92xx_volknob_put(struct snd_kcontrol *kcontrol,
360 struct snd_ctl_elem_value *ucontrol)
362 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
363 unsigned int val = kcontrol->private_value & 0xff;
365 if (val == ucontrol->value.integer.value[0])
368 val = ucontrol->value.integer.value[0];
369 kcontrol->private_value &= ~0xff;
370 kcontrol->private_value |= val;
372 snd_hda_codec_write_cache(codec, kcontrol->private_value >> 16, 0,
373 AC_VERB_SET_VOLUME_KNOB_CONTROL, val | 0x80);
378 static struct hda_verb stac9200_core_init[] = {
379 /* set dac0mux for dac converter */
380 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
384 static struct hda_verb stac9200_eapd_init[] = {
385 /* set dac0mux for dac converter */
386 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
387 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
391 static struct hda_verb stac925x_core_init[] = {
392 /* set dac0mux for dac converter */
393 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
397 static struct hda_verb stac922x_core_init[] = {
398 /* set master volume and direct control */
399 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
403 static struct hda_verb d965_core_init[] = {
404 /* set master volume and direct control */
405 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
406 /* unmute node 0x1b */
407 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
408 /* select node 0x03 as DAC */
409 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
413 static struct hda_verb stac927x_core_init[] = {
414 /* set master volume and direct control */
415 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
419 static struct hda_verb stac9205_core_init[] = {
420 /* set master volume and direct control */
421 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
425 #define STAC_INPUT_SOURCE(cnt) \
427 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
428 .name = "Input Source", \
430 .info = stac92xx_mux_enum_info, \
431 .get = stac92xx_mux_enum_get, \
432 .put = stac92xx_mux_enum_put, \
435 #define STAC_ANALOG_LOOPBACK(verb_read,verb_write) \
437 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
438 .name = "Analog Loopback", \
440 .info = stac92xx_aloopback_info, \
441 .get = stac92xx_aloopback_get, \
442 .put = stac92xx_aloopback_put, \
443 .private_value = verb_read | (verb_write << 16), \
446 #define STAC_VOLKNOB(knob_nid) \
448 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
449 .name = "Master Playback Volume", \
451 .info = stac92xx_volknob_info, \
452 .get = stac92xx_volknob_get, \
453 .put = stac92xx_volknob_put, \
454 .private_value = 127 | (knob_nid << 16), \
458 static struct snd_kcontrol_new stac9200_mixer[] = {
459 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
460 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
461 STAC_INPUT_SOURCE(1),
462 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
463 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
464 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT),
468 static struct snd_kcontrol_new stac925x_mixer[] = {
469 STAC_INPUT_SOURCE(1),
470 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
471 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT),
472 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT),
476 static struct snd_kcontrol_new stac9205_mixer[] = {
478 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
479 .name = "Digital Input Source",
481 .info = stac92xx_dmux_enum_info,
482 .get = stac92xx_dmux_enum_get,
483 .put = stac92xx_dmux_enum_put,
485 STAC_INPUT_SOURCE(2),
486 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0),
489 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT),
490 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT),
491 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x19, 0x0, HDA_OUTPUT),
493 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT),
494 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT),
495 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x1A, 0x0, HDA_OUTPUT),
500 /* This needs to be generated dynamically based on sequence */
501 static struct snd_kcontrol_new stac922x_mixer[] = {
502 STAC_INPUT_SOURCE(2),
504 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT),
505 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT),
506 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x12, 0x0, HDA_OUTPUT),
508 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT),
509 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT),
510 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x13, 0x0, HDA_OUTPUT),
515 static struct snd_kcontrol_new stac927x_mixer[] = {
516 STAC_INPUT_SOURCE(3),
518 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB),
520 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT),
521 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT),
522 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x15, 0x0, HDA_OUTPUT),
524 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT),
525 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT),
526 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x16, 0x0, HDA_OUTPUT),
528 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT),
529 HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT),
530 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x2, 0x17, 0x0, HDA_OUTPUT),
534 static int stac92xx_build_controls(struct hda_codec *codec)
536 struct sigmatel_spec *spec = codec->spec;
540 err = snd_hda_add_new_ctls(codec, spec->mixer);
544 for (i = 0; i < spec->num_mixers; i++) {
545 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
550 if (spec->multiout.dig_out_nid) {
551 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
555 if (spec->dig_in_nid) {
556 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
563 static unsigned int ref9200_pin_configs[8] = {
564 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
565 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
569 STAC 9200 pin configs for
574 static unsigned int dell9200_d21_pin_configs[8] = {
575 0x400001f0, 0x400001f1, 0x02214030, 0x01014010,
576 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
580 STAC 9200 pin configs for
584 static unsigned int dell9200_d22_pin_configs[8] = {
585 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
586 0x01813020, 0x02a19021, 0x90100140, 0x400001f2,
590 STAC 9200 pin configs for
591 102801C4 (Dell Dimension E310)
598 static unsigned int dell9200_d23_pin_configs[8] = {
599 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
600 0x01813020, 0x01a19021, 0x90100140, 0x400001f2,
605 STAC 9200-32 pin configs for
606 102801B5 (Dell Inspiron 630m)
607 102801D8 (Dell Inspiron 640m)
609 static unsigned int dell9200_m21_pin_configs[8] = {
610 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310,
611 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd,
615 STAC 9200-32 pin configs for
616 102801C2 (Dell Latitude D620)
618 102801CC (Dell Latitude D820)
622 static unsigned int dell9200_m22_pin_configs[8] = {
623 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310,
624 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc,
628 STAC 9200-32 pin configs for
629 102801CE (Dell XPS M1710)
630 102801CF (Dell Precision M90)
632 static unsigned int dell9200_m23_pin_configs[8] = {
633 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310,
634 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc,
638 STAC 9200-32 pin configs for
641 102801CB (Dell Latitude 120L)
644 static unsigned int dell9200_m24_pin_configs[8] = {
645 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310,
646 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe,
650 STAC 9200-32 pin configs for
651 102801BD (Dell Inspiron E1505n)
655 static unsigned int dell9200_m25_pin_configs[8] = {
656 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
657 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd,
661 STAC 9200-32 pin configs for
662 102801F5 (Dell Inspiron 1501)
665 static unsigned int dell9200_m26_pin_configs[8] = {
666 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310,
667 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe,
672 102801CD (Dell Inspiron E1705/9400)
674 static unsigned int dell9200_m27_pin_configs[8] = {
675 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
676 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc,
680 static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
681 [STAC_REF] = ref9200_pin_configs,
682 [STAC_9200_DELL_D21] = dell9200_d21_pin_configs,
683 [STAC_9200_DELL_D22] = dell9200_d22_pin_configs,
684 [STAC_9200_DELL_D23] = dell9200_d23_pin_configs,
685 [STAC_9200_DELL_M21] = dell9200_m21_pin_configs,
686 [STAC_9200_DELL_M22] = dell9200_m22_pin_configs,
687 [STAC_9200_DELL_M23] = dell9200_m23_pin_configs,
688 [STAC_9200_DELL_M24] = dell9200_m24_pin_configs,
689 [STAC_9200_DELL_M25] = dell9200_m25_pin_configs,
690 [STAC_9200_DELL_M26] = dell9200_m26_pin_configs,
691 [STAC_9200_DELL_M27] = dell9200_m27_pin_configs,
694 static const char *stac9200_models[STAC_9200_MODELS] = {
696 [STAC_9200_DELL_D21] = "dell-d21",
697 [STAC_9200_DELL_D22] = "dell-d22",
698 [STAC_9200_DELL_D23] = "dell-d23",
699 [STAC_9200_DELL_M21] = "dell-m21",
700 [STAC_9200_DELL_M22] = "dell-m22",
701 [STAC_9200_DELL_M23] = "dell-m23",
702 [STAC_9200_DELL_M24] = "dell-m24",
703 [STAC_9200_DELL_M25] = "dell-m25",
704 [STAC_9200_DELL_M26] = "dell-m26",
705 [STAC_9200_DELL_M27] = "dell-m27",
706 [STAC_9200_GATEWAY] = "gateway",
709 static struct snd_pci_quirk stac9200_cfg_tbl[] = {
710 /* SigmaTel reference board */
711 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
712 "DFI LanParty", STAC_REF),
713 /* Dell laptops have BIOS problem */
714 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
715 "unknown Dell", STAC_9200_DELL_D21),
716 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
717 "Dell Inspiron 630m", STAC_9200_DELL_M21),
718 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
719 "Dell Inspiron E1505n", STAC_9200_DELL_M25),
720 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
721 "unknown Dell", STAC_9200_DELL_D22),
722 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
723 "unknown Dell", STAC_9200_DELL_D22),
724 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
725 "Dell Latitude D620", STAC_9200_DELL_M22),
726 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
727 "unknown Dell", STAC_9200_DELL_D23),
728 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
729 "unknown Dell", STAC_9200_DELL_D23),
730 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
731 "unknown Dell", STAC_9200_DELL_M22),
732 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
733 "unknown Dell", STAC_9200_DELL_M24),
734 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
735 "unknown Dell", STAC_9200_DELL_M24),
736 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
737 "Dell Latitude 120L", STAC_9200_DELL_M24),
738 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
739 "Dell Latitude D820", STAC_9200_DELL_M22),
740 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
741 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
742 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
743 "Dell XPS M1710", STAC_9200_DELL_M23),
744 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
745 "Dell Precision M90", STAC_9200_DELL_M23),
746 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
747 "unknown Dell", STAC_9200_DELL_M22),
748 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
749 "unknown Dell", STAC_9200_DELL_M22),
750 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
751 "unknown Dell", STAC_9200_DELL_M22),
752 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
753 "Dell Inspiron 640m", STAC_9200_DELL_M21),
754 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
755 "unknown Dell", STAC_9200_DELL_D23),
756 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
757 "unknown Dell", STAC_9200_DELL_D23),
758 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
759 "unknown Dell", STAC_9200_DELL_D21),
760 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
761 "unknown Dell", STAC_9200_DELL_D23),
762 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
763 "unknown Dell", STAC_9200_DELL_D21),
764 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
765 "unknown Dell", STAC_9200_DELL_M25),
766 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
767 "unknown Dell", STAC_9200_DELL_M25),
768 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
769 "Dell Inspiron 1501", STAC_9200_DELL_M26),
770 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
771 "unknown Dell", STAC_9200_DELL_M26),
773 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_REF),
774 /* Gateway machines needs EAPD to be set on resume */
775 SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY),
776 SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*",
778 SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707",
783 static unsigned int ref925x_pin_configs[8] = {
784 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
785 0x90a70320, 0x02214210, 0x400003f1, 0x9033032e,
788 static unsigned int stac925x_MA6_pin_configs[8] = {
789 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
790 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e,
793 static unsigned int stac925x_PA6_pin_configs[8] = {
794 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
795 0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e,
798 static unsigned int stac925xM2_2_pin_configs[8] = {
799 0x40c003f3, 0x424503f2, 0x04180011, 0x02a19020,
800 0x50a103f0, 0x90100212, 0x400003f1, 0x9033032e,
803 static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
804 [STAC_REF] = ref925x_pin_configs,
805 [STAC_M2_2] = stac925xM2_2_pin_configs,
806 [STAC_MA6] = stac925x_MA6_pin_configs,
807 [STAC_PA6] = stac925x_PA6_pin_configs,
810 static const char *stac925x_models[STAC_925x_MODELS] = {
812 [STAC_M2_2] = "m2-2",
817 static struct snd_pci_quirk stac925x_cfg_tbl[] = {
818 /* SigmaTel reference board */
819 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
820 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
821 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF),
822 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF),
823 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6),
824 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_PA6),
825 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2),
829 static unsigned int ref922x_pin_configs[10] = {
830 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
831 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
832 0x40000100, 0x40000100,
836 STAC 922X pin configs for
843 static unsigned int dell_922x_d81_pin_configs[10] = {
844 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
845 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1,
846 0x01813122, 0x400001f2,
850 STAC 922X pin configs for
854 static unsigned int dell_922x_d82_pin_configs[10] = {
855 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
856 0x02a19020, 0x01117011, 0x01451140, 0x400001f0,
857 0x01813122, 0x400001f1,
861 STAC 922X pin configs for
864 static unsigned int dell_922x_m81_pin_configs[10] = {
865 0x0321101f, 0x01112024, 0x01111222, 0x91174220,
866 0x03a11050, 0x01116221, 0x90a70330, 0x01452340,
867 0x40C003f1, 0x405003f0,
871 STAC 9221 A1 pin configs for
872 102801D7 (Dell XPS M1210)
874 static unsigned int dell_922x_m82_pin_configs[10] = {
875 0x0221121f, 0x408103ff, 0x02111212, 0x90100310,
876 0x408003f1, 0x02111211, 0x03451340, 0x40c003f2,
877 0x508003f3, 0x405003f4,
880 static unsigned int d945gtp3_pin_configs[10] = {
881 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
882 0x40000100, 0x40000100, 0x40000100, 0x40000100,
883 0x02a19120, 0x40000100,
886 static unsigned int d945gtp5_pin_configs[10] = {
887 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
888 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
889 0x02a19320, 0x40000100,
892 static unsigned int intel_mac_v1_pin_configs[10] = {
893 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd,
894 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240,
895 0x400000fc, 0x400000fb,
898 static unsigned int intel_mac_v2_pin_configs[10] = {
899 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
900 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa,
901 0x400000fc, 0x400000fb,
904 static unsigned int intel_mac_v3_pin_configs[10] = {
905 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
906 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240,
907 0x400000fc, 0x400000fb,
910 static unsigned int intel_mac_v4_pin_configs[10] = {
911 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
912 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
913 0x400000fc, 0x400000fb,
916 static unsigned int intel_mac_v5_pin_configs[10] = {
917 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
918 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
919 0x400000fc, 0x400000fb,
923 static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
924 [STAC_D945_REF] = ref922x_pin_configs,
925 [STAC_D945GTP3] = d945gtp3_pin_configs,
926 [STAC_D945GTP5] = d945gtp5_pin_configs,
927 [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs,
928 [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs,
929 [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs,
930 [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs,
931 [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs,
932 /* for backward compatibility */
933 [STAC_MACMINI] = intel_mac_v3_pin_configs,
934 [STAC_MACBOOK] = intel_mac_v5_pin_configs,
935 [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs,
936 [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs,
937 [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs,
938 [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs,
939 [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs,
940 [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs,
941 [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs,
942 [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs,
945 static const char *stac922x_models[STAC_922X_MODELS] = {
946 [STAC_D945_REF] = "ref",
947 [STAC_D945GTP5] = "5stack",
948 [STAC_D945GTP3] = "3stack",
949 [STAC_INTEL_MAC_V1] = "intel-mac-v1",
950 [STAC_INTEL_MAC_V2] = "intel-mac-v2",
951 [STAC_INTEL_MAC_V3] = "intel-mac-v3",
952 [STAC_INTEL_MAC_V4] = "intel-mac-v4",
953 [STAC_INTEL_MAC_V5] = "intel-mac-v5",
954 /* for backward compatibility */
955 [STAC_MACMINI] = "macmini",
956 [STAC_MACBOOK] = "macbook",
957 [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1",
958 [STAC_MACBOOK_PRO_V2] = "macbook-pro",
959 [STAC_IMAC_INTEL] = "imac-intel",
960 [STAC_IMAC_INTEL_20] = "imac-intel-20",
961 [STAC_922X_DELL_D81] = "dell-d81",
962 [STAC_922X_DELL_D82] = "dell-d82",
963 [STAC_922X_DELL_M81] = "dell-m81",
964 [STAC_922X_DELL_M82] = "dell-m82",
967 static struct snd_pci_quirk stac922x_cfg_tbl[] = {
968 /* SigmaTel reference board */
969 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
970 "DFI LanParty", STAC_D945_REF),
971 /* Intel 945G based systems */
972 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
973 "Intel D945G", STAC_D945GTP3),
974 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
975 "Intel D945G", STAC_D945GTP3),
976 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
977 "Intel D945G", STAC_D945GTP3),
978 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
979 "Intel D945G", STAC_D945GTP3),
980 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
981 "Intel D945G", STAC_D945GTP3),
982 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
983 "Intel D945G", STAC_D945GTP3),
984 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
985 "Intel D945G", STAC_D945GTP3),
986 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
987 "Intel D945G", STAC_D945GTP3),
988 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
989 "Intel D945G", STAC_D945GTP3),
990 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
991 "Intel D945G", STAC_D945GTP3),
992 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
993 "Intel D945G", STAC_D945GTP3),
994 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
995 "Intel D945G", STAC_D945GTP3),
996 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
997 "Intel D945G", STAC_D945GTP3),
998 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
999 "Intel D945G", STAC_D945GTP3),
1000 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
1001 "Intel D945G", STAC_D945GTP3),
1002 /* Intel D945G 5-stack systems */
1003 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
1004 "Intel D945G", STAC_D945GTP5),
1005 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
1006 "Intel D945G", STAC_D945GTP5),
1007 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
1008 "Intel D945G", STAC_D945GTP5),
1009 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
1010 "Intel D945G", STAC_D945GTP5),
1011 /* Intel 945P based systems */
1012 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
1013 "Intel D945P", STAC_D945GTP3),
1014 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
1015 "Intel D945P", STAC_D945GTP3),
1016 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
1017 "Intel D945P", STAC_D945GTP3),
1018 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
1019 "Intel D945P", STAC_D945GTP3),
1020 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
1021 "Intel D945P", STAC_D945GTP3),
1022 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
1023 "Intel D945P", STAC_D945GTP5),
1025 /* Apple Mac Mini (early 2006) */
1026 SND_PCI_QUIRK(0x8384, 0x7680,
1027 "Mac Mini", STAC_INTEL_MAC_V3),
1029 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
1030 "unknown Dell", STAC_922X_DELL_D81),
1031 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
1032 "unknown Dell", STAC_922X_DELL_D81),
1033 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
1034 "unknown Dell", STAC_922X_DELL_D81),
1035 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
1036 "unknown Dell", STAC_922X_DELL_D82),
1037 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
1038 "unknown Dell", STAC_922X_DELL_M81),
1039 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
1040 "unknown Dell", STAC_922X_DELL_D82),
1041 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
1042 "unknown Dell", STAC_922X_DELL_D81),
1043 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
1044 "unknown Dell", STAC_922X_DELL_D81),
1045 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
1046 "Dell XPS M1210", STAC_922X_DELL_M82),
1050 static unsigned int ref927x_pin_configs[14] = {
1051 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1052 0x01a19040, 0x01011012, 0x01016011, 0x0101201f,
1053 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070,
1054 0x01c42190, 0x40000100,
1057 static unsigned int d965_3st_pin_configs[14] = {
1058 0x0221401f, 0x02a19120, 0x40000100, 0x01014011,
1059 0x01a19021, 0x01813024, 0x40000100, 0x40000100,
1060 0x40000100, 0x40000100, 0x40000100, 0x40000100,
1061 0x40000100, 0x40000100
1064 static unsigned int d965_5st_pin_configs[14] = {
1065 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1066 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
1067 0x40000100, 0x40000100, 0x40000100, 0x01442070,
1068 0x40000100, 0x40000100
1071 static unsigned int dell_3st_pin_configs[14] = {
1072 0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
1073 0x01111212, 0x01116211, 0x01813050, 0x01112214,
1074 0x403003fa, 0x40000100, 0x40000100, 0x404003fb,
1075 0x40c003fc, 0x40000100
1078 static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
1079 [STAC_D965_REF] = ref927x_pin_configs,
1080 [STAC_D965_3ST] = d965_3st_pin_configs,
1081 [STAC_D965_5ST] = d965_5st_pin_configs,
1082 [STAC_DELL_3ST] = dell_3st_pin_configs,
1085 static const char *stac927x_models[STAC_927X_MODELS] = {
1086 [STAC_D965_REF] = "ref",
1087 [STAC_D965_3ST] = "3stack",
1088 [STAC_D965_5ST] = "5stack",
1089 [STAC_DELL_3ST] = "dell-3stack",
1092 static struct snd_pci_quirk stac927x_cfg_tbl[] = {
1093 /* SigmaTel reference board */
1094 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1095 "DFI LanParty", STAC_D965_REF),
1096 /* Intel 946 based systems */
1097 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
1098 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
1099 /* 965 based 3 stack systems */
1100 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2116, "Intel D965", STAC_D965_3ST),
1101 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2115, "Intel D965", STAC_D965_3ST),
1102 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2114, "Intel D965", STAC_D965_3ST),
1103 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2113, "Intel D965", STAC_D965_3ST),
1104 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2112, "Intel D965", STAC_D965_3ST),
1105 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2111, "Intel D965", STAC_D965_3ST),
1106 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2110, "Intel D965", STAC_D965_3ST),
1107 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2009, "Intel D965", STAC_D965_3ST),
1108 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2008, "Intel D965", STAC_D965_3ST),
1109 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2007, "Intel D965", STAC_D965_3ST),
1110 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2006, "Intel D965", STAC_D965_3ST),
1111 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2005, "Intel D965", STAC_D965_3ST),
1112 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2004, "Intel D965", STAC_D965_3ST),
1113 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST),
1114 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST),
1115 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST),
1116 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_D965_3ST),
1117 /* Dell 3 stack systems */
1118 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
1119 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
1120 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
1121 /* 965 based 5 stack systems */
1122 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_D965_5ST),
1123 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST),
1124 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST),
1125 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST),
1126 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2304, "Intel D965", STAC_D965_5ST),
1127 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2305, "Intel D965", STAC_D965_5ST),
1128 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2501, "Intel D965", STAC_D965_5ST),
1129 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2502, "Intel D965", STAC_D965_5ST),
1130 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2503, "Intel D965", STAC_D965_5ST),
1131 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2504, "Intel D965", STAC_D965_5ST),
1135 static unsigned int ref9205_pin_configs[12] = {
1136 0x40000100, 0x40000100, 0x01016011, 0x01014010,
1137 0x01813122, 0x01a19021, 0x40000100, 0x40000100,
1138 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
1142 STAC 9205 pin configs for
1150 static unsigned int dell_9205_m42_pin_configs[12] = {
1151 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310,
1152 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9,
1153 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE,
1157 STAC 9205 pin configs for
1161 102801FF (Dell Precision M4300)
1166 static unsigned int dell_9205_m43_pin_configs[12] = {
1167 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310,
1168 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9,
1169 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8,
1172 static unsigned int dell_9205_m44_pin_configs[12] = {
1173 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310,
1174 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9,
1175 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe,
1178 static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
1179 [STAC_9205_REF] = ref9205_pin_configs,
1180 [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs,
1181 [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs,
1182 [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs,
1185 static const char *stac9205_models[STAC_9205_MODELS] = {
1186 [STAC_9205_REF] = "ref",
1187 [STAC_9205_DELL_M42] = "dell-m42",
1188 [STAC_9205_DELL_M43] = "dell-m43",
1189 [STAC_9205_DELL_M44] = "dell-m44",
1192 static struct snd_pci_quirk stac9205_cfg_tbl[] = {
1193 /* SigmaTel reference board */
1194 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1195 "DFI LanParty", STAC_9205_REF),
1196 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1197 "unknown Dell", STAC_9205_DELL_M42),
1198 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1199 "unknown Dell", STAC_9205_DELL_M42),
1200 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
1201 "Dell Precision", STAC_9205_DELL_M43),
1202 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
1203 "Dell Precision", STAC_9205_DELL_M43),
1204 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
1205 "Dell Precision", STAC_9205_DELL_M43),
1206 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
1207 "Dell Precision", STAC_9205_DELL_M43),
1208 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
1209 "Dell Precision", STAC_9205_DELL_M43),
1210 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1211 "unknown Dell", STAC_9205_DELL_M42),
1212 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1213 "unknown Dell", STAC_9205_DELL_M42),
1214 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
1215 "Dell Precision", STAC_9205_DELL_M43),
1216 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
1217 "Dell Precision M4300", STAC_9205_DELL_M43),
1218 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
1219 "Dell Precision", STAC_9205_DELL_M43),
1220 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1221 "Dell Inspiron", STAC_9205_DELL_M44),
1222 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1223 "Dell Inspiron", STAC_9205_DELL_M44),
1224 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1225 "Dell Inspiron", STAC_9205_DELL_M44),
1226 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1227 "Dell Inspiron", STAC_9205_DELL_M44),
1228 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
1229 "unknown Dell", STAC_9205_DELL_M42),
1230 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
1231 "Dell Inspiron", STAC_9205_DELL_M44),
1235 static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
1238 struct sigmatel_spec *spec = codec->spec;
1240 if (! spec->bios_pin_configs) {
1241 spec->bios_pin_configs = kcalloc(spec->num_pins,
1242 sizeof(*spec->bios_pin_configs), GFP_KERNEL);
1243 if (! spec->bios_pin_configs)
1247 for (i = 0; i < spec->num_pins; i++) {
1248 hda_nid_t nid = spec->pin_nids[i];
1249 unsigned int pin_cfg;
1251 pin_cfg = snd_hda_codec_read(codec, nid, 0,
1252 AC_VERB_GET_CONFIG_DEFAULT, 0x00);
1253 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n",
1255 spec->bios_pin_configs[i] = pin_cfg;
1261 static void stac92xx_set_config_reg(struct hda_codec *codec,
1262 hda_nid_t pin_nid, unsigned int pin_config)
1265 snd_hda_codec_write(codec, pin_nid, 0,
1266 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
1267 pin_config & 0x000000ff);
1268 snd_hda_codec_write(codec, pin_nid, 0,
1269 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
1270 (pin_config & 0x0000ff00) >> 8);
1271 snd_hda_codec_write(codec, pin_nid, 0,
1272 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
1273 (pin_config & 0x00ff0000) >> 16);
1274 snd_hda_codec_write(codec, pin_nid, 0,
1275 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
1277 i = snd_hda_codec_read(codec, pin_nid, 0,
1278 AC_VERB_GET_CONFIG_DEFAULT,
1280 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n",
1284 static void stac92xx_set_config_regs(struct hda_codec *codec)
1287 struct sigmatel_spec *spec = codec->spec;
1289 if (!spec->pin_configs)
1292 for (i = 0; i < spec->num_pins; i++)
1293 stac92xx_set_config_reg(codec, spec->pin_nids[i],
1294 spec->pin_configs[i]);
1297 static void stac92xx_enable_gpio_mask(struct hda_codec *codec)
1299 struct sigmatel_spec *spec = codec->spec;
1300 /* Configure GPIOx as output */
1301 snd_hda_codec_write_cache(codec, codec->afg, 0,
1302 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_mask);
1303 /* Configure GPIOx as CMOS */
1304 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7e7, 0x00000000);
1306 snd_hda_codec_write_cache(codec, codec->afg, 0,
1307 AC_VERB_SET_GPIO_DATA, spec->gpio_data);
1309 snd_hda_codec_write_cache(codec, codec->afg, 0,
1310 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
1314 * Analog playback callbacks
1316 static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
1317 struct hda_codec *codec,
1318 struct snd_pcm_substream *substream)
1320 struct sigmatel_spec *spec = codec->spec;
1321 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
1324 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1325 struct hda_codec *codec,
1326 unsigned int stream_tag,
1327 unsigned int format,
1328 struct snd_pcm_substream *substream)
1330 struct sigmatel_spec *spec = codec->spec;
1331 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream);
1334 static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1335 struct hda_codec *codec,
1336 struct snd_pcm_substream *substream)
1338 struct sigmatel_spec *spec = codec->spec;
1339 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1343 * Digital playback callbacks
1345 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1346 struct hda_codec *codec,
1347 struct snd_pcm_substream *substream)
1349 struct sigmatel_spec *spec = codec->spec;
1350 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1353 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1354 struct hda_codec *codec,
1355 struct snd_pcm_substream *substream)
1357 struct sigmatel_spec *spec = codec->spec;
1358 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1361 static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1362 struct hda_codec *codec,
1363 unsigned int stream_tag,
1364 unsigned int format,
1365 struct snd_pcm_substream *substream)
1367 struct sigmatel_spec *spec = codec->spec;
1368 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1369 stream_tag, format, substream);
1374 * Analog capture callbacks
1376 static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1377 struct hda_codec *codec,
1378 unsigned int stream_tag,
1379 unsigned int format,
1380 struct snd_pcm_substream *substream)
1382 struct sigmatel_spec *spec = codec->spec;
1384 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1385 stream_tag, 0, format);
1389 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1390 struct hda_codec *codec,
1391 struct snd_pcm_substream *substream)
1393 struct sigmatel_spec *spec = codec->spec;
1395 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
1399 static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
1403 /* NID is set in stac92xx_build_pcms */
1405 .open = stac92xx_dig_playback_pcm_open,
1406 .close = stac92xx_dig_playback_pcm_close,
1407 .prepare = stac92xx_dig_playback_pcm_prepare
1411 static struct hda_pcm_stream stac92xx_pcm_digital_capture = {
1415 /* NID is set in stac92xx_build_pcms */
1418 static struct hda_pcm_stream stac92xx_pcm_analog_playback = {
1422 .nid = 0x02, /* NID to query formats and rates */
1424 .open = stac92xx_playback_pcm_open,
1425 .prepare = stac92xx_playback_pcm_prepare,
1426 .cleanup = stac92xx_playback_pcm_cleanup
1430 static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
1434 .nid = 0x06, /* NID to query formats and rates */
1436 .open = stac92xx_playback_pcm_open,
1437 .prepare = stac92xx_playback_pcm_prepare,
1438 .cleanup = stac92xx_playback_pcm_cleanup
1442 static struct hda_pcm_stream stac92xx_pcm_analog_capture = {
1445 /* NID + .substreams is set in stac92xx_build_pcms */
1447 .prepare = stac92xx_capture_pcm_prepare,
1448 .cleanup = stac92xx_capture_pcm_cleanup
1452 static int stac92xx_build_pcms(struct hda_codec *codec)
1454 struct sigmatel_spec *spec = codec->spec;
1455 struct hda_pcm *info = spec->pcm_rec;
1457 codec->num_pcms = 1;
1458 codec->pcm_info = info;
1460 info->name = "STAC92xx Analog";
1461 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
1462 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
1463 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1464 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs;
1466 if (spec->alt_switch) {
1469 info->name = "STAC92xx Analog Alt";
1470 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback;
1473 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1476 info->name = "STAC92xx Digital";
1477 if (spec->multiout.dig_out_nid) {
1478 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
1479 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
1481 if (spec->dig_in_nid) {
1482 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture;
1483 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
1490 static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
1492 unsigned int pincap = snd_hda_param_read(codec, nid,
1494 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
1495 if (pincap & AC_PINCAP_VREF_100)
1496 return AC_PINCTL_VREF_100;
1497 if (pincap & AC_PINCAP_VREF_80)
1498 return AC_PINCTL_VREF_80;
1499 if (pincap & AC_PINCAP_VREF_50)
1500 return AC_PINCTL_VREF_50;
1501 if (pincap & AC_PINCAP_VREF_GRD)
1502 return AC_PINCTL_VREF_GRD;
1506 static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
1509 snd_hda_codec_write_cache(codec, nid, 0,
1510 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
1513 #define stac92xx_io_switch_info snd_ctl_boolean_mono_info
1515 static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1517 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1518 struct sigmatel_spec *spec = codec->spec;
1519 int io_idx = kcontrol-> private_value & 0xff;
1521 ucontrol->value.integer.value[0] = spec->io_switch[io_idx];
1525 static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1527 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1528 struct sigmatel_spec *spec = codec->spec;
1529 hda_nid_t nid = kcontrol->private_value >> 8;
1530 int io_idx = kcontrol-> private_value & 0xff;
1531 unsigned short val = ucontrol->value.integer.value[0];
1533 spec->io_switch[io_idx] = val;
1536 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
1538 unsigned int pinctl = AC_PINCTL_IN_EN;
1539 if (io_idx) /* set VREF for mic */
1540 pinctl |= stac92xx_get_vref(codec, nid);
1541 stac92xx_auto_set_pinctl(codec, nid, pinctl);
1546 #define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info
1548 static int stac92xx_clfe_switch_get(struct snd_kcontrol *kcontrol,
1549 struct snd_ctl_elem_value *ucontrol)
1551 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1552 struct sigmatel_spec *spec = codec->spec;
1554 ucontrol->value.integer.value[0] = spec->clfe_swap;
1558 static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
1559 struct snd_ctl_elem_value *ucontrol)
1561 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1562 struct sigmatel_spec *spec = codec->spec;
1563 hda_nid_t nid = kcontrol->private_value & 0xff;
1565 if (spec->clfe_swap == ucontrol->value.integer.value[0])
1568 spec->clfe_swap = ucontrol->value.integer.value[0];
1570 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1571 spec->clfe_swap ? 0x4 : 0x0);
1576 #define STAC_CODEC_IO_SWITCH(xname, xpval) \
1577 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1580 .info = stac92xx_io_switch_info, \
1581 .get = stac92xx_io_switch_get, \
1582 .put = stac92xx_io_switch_put, \
1583 .private_value = xpval, \
1586 #define STAC_CODEC_CLFE_SWITCH(xname, xpval) \
1587 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1590 .info = stac92xx_clfe_switch_info, \
1591 .get = stac92xx_clfe_switch_get, \
1592 .put = stac92xx_clfe_switch_put, \
1593 .private_value = xpval, \
1597 STAC_CTL_WIDGET_VOL,
1598 STAC_CTL_WIDGET_MUTE,
1599 STAC_CTL_WIDGET_IO_SWITCH,
1600 STAC_CTL_WIDGET_CLFE_SWITCH
1603 static struct snd_kcontrol_new stac92xx_control_templates[] = {
1604 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
1605 HDA_CODEC_MUTE(NULL, 0, 0, 0),
1606 STAC_CODEC_IO_SWITCH(NULL, 0),
1607 STAC_CODEC_CLFE_SWITCH(NULL, 0),
1610 /* add dynamic controls */
1611 static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val)
1613 struct snd_kcontrol_new *knew;
1615 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
1616 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
1618 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
1621 if (spec->kctl_alloc) {
1622 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
1623 kfree(spec->kctl_alloc);
1625 spec->kctl_alloc = knew;
1626 spec->num_kctl_alloc = num;
1629 knew = &spec->kctl_alloc[spec->num_kctl_used];
1630 *knew = stac92xx_control_templates[type];
1631 knew->name = kstrdup(name, GFP_KERNEL);
1634 knew->private_value = val;
1635 spec->num_kctl_used++;
1639 /* flag inputs as additional dynamic lineouts */
1640 static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
1642 struct sigmatel_spec *spec = codec->spec;
1643 unsigned int wcaps, wtype;
1644 int i, num_dacs = 0;
1646 /* use the wcaps cache to count all DACs available for line-outs */
1647 for (i = 0; i < codec->num_nodes; i++) {
1648 wcaps = codec->wcaps[i];
1649 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
1650 if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL))
1654 snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
1656 switch (cfg->line_outs) {
1658 /* add line-in as side */
1659 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
1660 cfg->line_out_pins[cfg->line_outs] =
1661 cfg->input_pins[AUTO_PIN_LINE];
1662 spec->line_switch = 1;
1667 /* add line-in as clfe and mic as side */
1668 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
1669 cfg->line_out_pins[cfg->line_outs] =
1670 cfg->input_pins[AUTO_PIN_LINE];
1671 spec->line_switch = 1;
1674 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
1675 cfg->line_out_pins[cfg->line_outs] =
1676 cfg->input_pins[AUTO_PIN_MIC];
1677 spec->mic_switch = 1;
1682 /* add line-in as surr and mic as clfe */
1683 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
1684 cfg->line_out_pins[cfg->line_outs] =
1685 cfg->input_pins[AUTO_PIN_LINE];
1686 spec->line_switch = 1;
1689 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
1690 cfg->line_out_pins[cfg->line_outs] =
1691 cfg->input_pins[AUTO_PIN_MIC];
1692 spec->mic_switch = 1;
1702 static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
1706 for (i = 0; i < spec->multiout.num_dacs; i++) {
1707 if (spec->multiout.dac_nids[i] == nid)
1715 * Fill in the dac_nids table from the parsed pin configuration
1716 * This function only works when every pin in line_out_pins[]
1717 * contains atleast one DAC in its connection list. Some 92xx
1718 * codecs are not connected directly to a DAC, such as the 9200
1719 * and 9202/925x. For those, dac_nids[] must be hard-coded.
1721 static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
1722 struct auto_pin_cfg *cfg)
1724 struct sigmatel_spec *spec = codec->spec;
1725 int i, j, conn_len = 0;
1726 hda_nid_t nid, conn[HDA_MAX_CONNECTIONS];
1727 unsigned int wcaps, wtype;
1729 for (i = 0; i < cfg->line_outs; i++) {
1730 nid = cfg->line_out_pins[i];
1731 conn_len = snd_hda_get_connections(codec, nid, conn,
1732 HDA_MAX_CONNECTIONS);
1733 for (j = 0; j < conn_len; j++) {
1734 wcaps = snd_hda_param_read(codec, conn[j],
1735 AC_PAR_AUDIO_WIDGET_CAP);
1736 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
1738 if (wtype != AC_WID_AUD_OUT ||
1739 (wcaps & AC_WCAP_DIGITAL))
1741 /* conn[j] is a DAC routed to this line-out */
1742 if (!is_in_dac_nids(spec, conn[j]))
1746 if (j == conn_len) {
1747 if (spec->multiout.num_dacs > 0) {
1748 /* we have already working output pins,
1749 * so let's drop the broken ones again
1751 cfg->line_outs = spec->multiout.num_dacs;
1754 /* error out, no available DAC found */
1756 "%s: No available DAC for pin 0x%x\n",
1761 spec->multiout.dac_nids[i] = conn[j];
1762 spec->multiout.num_dacs++;
1764 /* select this DAC in the pin's input mux */
1765 snd_hda_codec_write_cache(codec, nid, 0,
1766 AC_VERB_SET_CONNECT_SEL, j);
1771 snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
1772 spec->multiout.num_dacs,
1773 spec->multiout.dac_nids[0],
1774 spec->multiout.dac_nids[1],
1775 spec->multiout.dac_nids[2],
1776 spec->multiout.dac_nids[3],
1777 spec->multiout.dac_nids[4]);
1781 /* create volume control/switch for the given prefx type */
1782 static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_t nid, int chs)
1787 sprintf(name, "%s Playback Volume", pfx);
1788 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name,
1789 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1792 sprintf(name, "%s Playback Switch", pfx);
1793 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name,
1794 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1800 /* add playback controls from the parsed DAC table */
1801 static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
1802 const struct auto_pin_cfg *cfg)
1804 static const char *chname[4] = {
1805 "Front", "Surround", NULL /*CLFE*/, "Side"
1810 struct sigmatel_spec *spec = codec->spec;
1811 unsigned int wid_caps;
1814 for (i = 0; i < cfg->line_outs; i++) {
1815 if (!spec->multiout.dac_nids[i])
1818 nid = spec->multiout.dac_nids[i];
1822 err = create_controls(spec, "Center", nid, 1);
1825 err = create_controls(spec, "LFE", nid, 2);
1829 wid_caps = get_wcaps(codec, nid);
1831 if (wid_caps & AC_WCAP_LR_SWAP) {
1832 err = stac92xx_add_control(spec,
1833 STAC_CTL_WIDGET_CLFE_SWITCH,
1834 "Swap Center/LFE Playback Switch", nid);
1841 err = create_controls(spec, chname[i], nid, 3);
1847 if (spec->line_switch)
1848 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Line In as Output Switch", cfg->input_pins[AUTO_PIN_LINE] << 8)) < 0)
1851 if (spec->mic_switch)
1852 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Mic as Output Switch", (cfg->input_pins[AUTO_PIN_MIC] << 8) | 1)) < 0)
1858 static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
1860 if (is_in_dac_nids(spec, nid))
1862 if (spec->multiout.hp_nid == nid)
1867 static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
1869 if (!spec->multiout.hp_nid)
1870 spec->multiout.hp_nid = nid;
1871 else if (spec->multiout.num_dacs > 4) {
1872 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
1875 spec->multiout.dac_nids[spec->multiout.num_dacs] = nid;
1876 spec->multiout.num_dacs++;
1881 /* add playback controls for Speaker and HP outputs */
1882 static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
1883 struct auto_pin_cfg *cfg)
1885 struct sigmatel_spec *spec = codec->spec;
1887 int i, old_num_dacs, err;
1889 old_num_dacs = spec->multiout.num_dacs;
1890 for (i = 0; i < cfg->hp_outs; i++) {
1891 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]);
1892 if (wid_caps & AC_WCAP_UNSOL_CAP)
1893 spec->hp_detect = 1;
1894 nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
1895 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1896 if (check_in_dac_nids(spec, nid))
1900 add_spec_dacs(spec, nid);
1902 for (i = 0; i < cfg->speaker_outs; i++) {
1903 nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
1904 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1905 if (check_in_dac_nids(spec, nid))
1909 add_spec_dacs(spec, nid);
1911 for (i = 0; i < cfg->line_outs; i++) {
1912 nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0,
1913 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1914 if (check_in_dac_nids(spec, nid))
1918 add_spec_dacs(spec, nid);
1920 for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) {
1921 static const char *pfxs[] = {
1922 "Speaker", "External Speaker", "Speaker2",
1924 err = create_controls(spec, pfxs[i - old_num_dacs],
1925 spec->multiout.dac_nids[i], 3);
1929 if (spec->multiout.hp_nid) {
1931 if (old_num_dacs == spec->multiout.num_dacs)
1935 err = create_controls(spec, pfx, spec->multiout.hp_nid, 3);
1943 /* labels for dmic mux inputs */
1944 static const char *stac92xx_dmic_labels[5] = {
1945 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
1946 "Digital Mic 3", "Digital Mic 4"
1949 /* create playback/capture controls for input pins on dmic capable codecs */
1950 static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
1951 const struct auto_pin_cfg *cfg)
1953 struct sigmatel_spec *spec = codec->spec;
1954 struct hda_input_mux *dimux = &spec->private_dimux;
1955 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
1958 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0];
1959 dimux->items[dimux->num_items].index = 0;
1962 for (i = 0; i < spec->num_dmics; i++) {
1965 unsigned int def_conf;
1967 def_conf = snd_hda_codec_read(codec,
1970 AC_VERB_GET_CONFIG_DEFAULT,
1972 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
1975 num_cons = snd_hda_get_connections(codec,
1978 HDA_MAX_NUM_INPUTS);
1979 for (j = 0; j < num_cons; j++)
1980 if (con_lst[j] == spec->dmic_nids[i]) {
1986 dimux->items[dimux->num_items].label =
1987 stac92xx_dmic_labels[dimux->num_items];
1988 dimux->items[dimux->num_items].index = index;
1995 /* create playback/capture controls for input pins */
1996 static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
1998 struct sigmatel_spec *spec = codec->spec;
1999 struct hda_input_mux *imux = &spec->private_imux;
2000 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
2003 for (i = 0; i < AUTO_PIN_LAST; i++) {
2006 if (!cfg->input_pins[i])
2009 for (j = 0; j < spec->num_muxes; j++) {
2011 num_cons = snd_hda_get_connections(codec,
2014 HDA_MAX_NUM_INPUTS);
2015 for (k = 0; k < num_cons; k++)
2016 if (con_lst[k] == cfg->input_pins[i]) {
2023 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2024 imux->items[imux->num_items].index = index;
2028 if (imux->num_items) {
2030 * Set the current input for the muxes.
2031 * The STAC9221 has two input muxes with identical source
2032 * NID lists. Hopefully this won't get confused.
2034 for (i = 0; i < spec->num_muxes; i++) {
2035 snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0,
2036 AC_VERB_SET_CONNECT_SEL,
2037 imux->items[0].index);
2044 static void stac92xx_auto_init_multi_out(struct hda_codec *codec)
2046 struct sigmatel_spec *spec = codec->spec;
2049 for (i = 0; i < spec->autocfg.line_outs; i++) {
2050 hda_nid_t nid = spec->autocfg.line_out_pins[i];
2051 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
2055 static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
2057 struct sigmatel_spec *spec = codec->spec;
2060 for (i = 0; i < spec->autocfg.hp_outs; i++) {
2062 pin = spec->autocfg.hp_pins[i];
2063 if (pin) /* connect to front */
2064 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
2066 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
2068 pin = spec->autocfg.speaker_pins[i];
2069 if (pin) /* connect to front */
2070 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN);
2074 static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in)
2076 struct sigmatel_spec *spec = codec->spec;
2079 if ((err = snd_hda_parse_pin_def_config(codec,
2081 spec->dmic_nids)) < 0)
2083 if (! spec->autocfg.line_outs)
2084 return 0; /* can't find valid pin config */
2086 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
2088 if (spec->multiout.num_dacs == 0)
2089 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
2092 err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg);
2097 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
2102 err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
2107 if (spec->num_dmics > 0)
2108 if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
2109 &spec->autocfg)) < 0)
2112 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2113 if (spec->multiout.max_channels > 2)
2114 spec->surr_switch = 1;
2116 if (spec->autocfg.dig_out_pin)
2117 spec->multiout.dig_out_nid = dig_out;
2118 if (spec->autocfg.dig_in_pin)
2119 spec->dig_in_nid = dig_in;
2121 if (spec->kctl_alloc)
2122 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2124 spec->input_mux = &spec->private_imux;
2125 spec->dinput_mux = &spec->private_dimux;
2130 /* add playback controls for HP output */
2131 static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
2132 struct auto_pin_cfg *cfg)
2134 struct sigmatel_spec *spec = codec->spec;
2135 hda_nid_t pin = cfg->hp_pins[0];
2136 unsigned int wid_caps;
2141 wid_caps = get_wcaps(codec, pin);
2142 if (wid_caps & AC_WCAP_UNSOL_CAP)
2143 spec->hp_detect = 1;
2148 /* add playback controls for LFE output */
2149 static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec,
2150 struct auto_pin_cfg *cfg)
2152 struct sigmatel_spec *spec = codec->spec;
2154 hda_nid_t lfe_pin = 0x0;
2158 * search speaker outs and line outs for a mono speaker pin
2159 * with an amp. If one is found, add LFE controls
2162 for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) {
2163 hda_nid_t pin = spec->autocfg.speaker_pins[i];
2164 unsigned long wcaps = get_wcaps(codec, pin);
2165 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
2166 if (wcaps == AC_WCAP_OUT_AMP)
2167 /* found a mono speaker with an amp, must be lfe */
2171 /* if speaker_outs is 0, then speakers may be in line_outs */
2172 if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) {
2173 for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) {
2174 hda_nid_t pin = spec->autocfg.line_out_pins[i];
2176 cfg = snd_hda_codec_read(codec, pin, 0,
2177 AC_VERB_GET_CONFIG_DEFAULT,
2179 if (get_defcfg_device(cfg) == AC_JACK_SPEAKER) {
2180 unsigned long wcaps = get_wcaps(codec, pin);
2181 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
2182 if (wcaps == AC_WCAP_OUT_AMP)
2183 /* found a mono speaker with an amp,
2191 err = create_controls(spec, "LFE", lfe_pin, 1);
2199 static int stac9200_parse_auto_config(struct hda_codec *codec)
2201 struct sigmatel_spec *spec = codec->spec;
2204 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
2207 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
2210 if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)
2213 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
2216 if (spec->autocfg.dig_out_pin)
2217 spec->multiout.dig_out_nid = 0x05;
2218 if (spec->autocfg.dig_in_pin)
2219 spec->dig_in_nid = 0x04;
2221 if (spec->kctl_alloc)
2222 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2224 spec->input_mux = &spec->private_imux;
2225 spec->dinput_mux = &spec->private_dimux;
2231 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
2232 * funky external mute control using GPIO pins.
2235 static void stac922x_gpio_mute(struct hda_codec *codec, int pin, int muted)
2237 unsigned int gpiostate, gpiomask, gpiodir;
2239 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
2240 AC_VERB_GET_GPIO_DATA, 0);
2243 gpiostate |= (1 << pin);
2245 gpiostate &= ~(1 << pin);
2247 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
2248 AC_VERB_GET_GPIO_MASK, 0);
2249 gpiomask |= (1 << pin);
2251 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
2252 AC_VERB_GET_GPIO_DIRECTION, 0);
2253 gpiodir |= (1 << pin);
2255 /* AppleHDA seems to do this -- WTF is this verb?? */
2256 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
2258 snd_hda_codec_write(codec, codec->afg, 0,
2259 AC_VERB_SET_GPIO_MASK, gpiomask);
2260 snd_hda_codec_write(codec, codec->afg, 0,
2261 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
2265 snd_hda_codec_write(codec, codec->afg, 0,
2266 AC_VERB_SET_GPIO_DATA, gpiostate);
2269 static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
2272 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)
2273 snd_hda_codec_write_cache(codec, nid, 0,
2274 AC_VERB_SET_UNSOLICITED_ENABLE,
2275 (AC_USRSP_EN | event));
2278 static int stac92xx_init(struct hda_codec *codec)
2280 struct sigmatel_spec *spec = codec->spec;
2281 struct auto_pin_cfg *cfg = &spec->autocfg;
2284 snd_hda_sequence_write(codec, spec->init);
2287 if (spec->hp_detect) {
2288 /* Enable unsolicited responses on the HP widget */
2289 for (i = 0; i < cfg->hp_outs; i++)
2290 enable_pin_detect(codec, cfg->hp_pins[i],
2292 /* force to enable the first line-out; the others are set up
2295 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
2297 stac92xx_auto_init_hp_out(codec);
2298 /* fake event to set up pins */
2299 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2301 stac92xx_auto_init_multi_out(codec);
2302 stac92xx_auto_init_hp_out(codec);
2304 for (i = 0; i < AUTO_PIN_LAST; i++) {
2305 hda_nid_t nid = cfg->input_pins[i];
2307 unsigned int pinctl = AC_PINCTL_IN_EN;
2308 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
2309 pinctl |= stac92xx_get_vref(codec, nid);
2310 stac92xx_auto_set_pinctl(codec, nid, pinctl);
2313 if (spec->num_dmics > 0)
2314 for (i = 0; i < spec->num_dmics; i++)
2315 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
2318 if (cfg->dig_out_pin)
2319 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
2321 if (cfg->dig_in_pin)
2322 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
2325 if (spec->gpio_mute) {
2326 stac922x_gpio_mute(codec, 0, 0);
2327 stac922x_gpio_mute(codec, 1, 0);
2333 static void stac92xx_free(struct hda_codec *codec)
2335 struct sigmatel_spec *spec = codec->spec;
2341 if (spec->kctl_alloc) {
2342 for (i = 0; i < spec->num_kctl_used; i++)
2343 kfree(spec->kctl_alloc[i].name);
2344 kfree(spec->kctl_alloc);
2347 if (spec->bios_pin_configs)
2348 kfree(spec->bios_pin_configs);
2353 static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
2356 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
2357 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
2359 if (pin_ctl & AC_PINCTL_IN_EN) {
2361 * we need to check the current set-up direction of
2362 * shared input pins since they can be switched via
2363 * "xxx as Output" mixer switch
2365 struct sigmatel_spec *spec = codec->spec;
2366 struct auto_pin_cfg *cfg = &spec->autocfg;
2367 if ((nid == cfg->input_pins[AUTO_PIN_LINE] &&
2368 spec->line_switch) ||
2369 (nid == cfg->input_pins[AUTO_PIN_MIC] &&
2374 /* if setting pin direction bits, clear the current
2375 direction bits first */
2376 if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
2377 pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
2379 snd_hda_codec_write_cache(codec, nid, 0,
2380 AC_VERB_SET_PIN_WIDGET_CONTROL,
2384 static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
2387 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
2388 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
2389 snd_hda_codec_write_cache(codec, nid, 0,
2390 AC_VERB_SET_PIN_WIDGET_CONTROL,
2394 static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
2398 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00)
2404 static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
2406 struct sigmatel_spec *spec = codec->spec;
2407 struct auto_pin_cfg *cfg = &spec->autocfg;
2411 for (i = 0; i < cfg->hp_outs; i++) {
2412 presence = get_pin_presence(codec, cfg->hp_pins[i]);
2418 /* disable lineouts, enable hp */
2419 for (i = 0; i < cfg->line_outs; i++)
2420 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
2422 for (i = 0; i < cfg->speaker_outs; i++)
2423 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
2426 /* enable lineouts, disable hp */
2427 for (i = 0; i < cfg->line_outs; i++)
2428 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
2430 for (i = 0; i < cfg->speaker_outs; i++)
2431 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
2436 static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
2438 switch (res >> 26) {
2440 stac92xx_hp_detect(codec, res);
2445 #ifdef SND_HDA_NEEDS_RESUME
2446 static int stac92xx_resume(struct hda_codec *codec)
2448 struct sigmatel_spec *spec = codec->spec;
2450 stac92xx_set_config_regs(codec);
2451 snd_hda_sequence_write(codec, spec->init);
2452 if (spec->gpio_mute) {
2453 stac922x_gpio_mute(codec, 0, 0);
2454 stac922x_gpio_mute(codec, 1, 0);
2456 snd_hda_codec_resume_amp(codec);
2457 snd_hda_codec_resume_cache(codec);
2458 /* invoke unsolicited event to reset the HP state */
2459 if (spec->hp_detect)
2460 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2465 static struct hda_codec_ops stac92xx_patch_ops = {
2466 .build_controls = stac92xx_build_controls,
2467 .build_pcms = stac92xx_build_pcms,
2468 .init = stac92xx_init,
2469 .free = stac92xx_free,
2470 .unsol_event = stac92xx_unsol_event,
2471 #ifdef SND_HDA_NEEDS_RESUME
2472 .resume = stac92xx_resume,
2476 static int patch_stac9200(struct hda_codec *codec)
2478 struct sigmatel_spec *spec;
2481 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2486 spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
2487 spec->pin_nids = stac9200_pin_nids;
2488 spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
2491 if (spec->board_config < 0) {
2492 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
2493 err = stac92xx_save_bios_config_regs(codec);
2495 stac92xx_free(codec);
2498 spec->pin_configs = spec->bios_pin_configs;
2500 spec->pin_configs = stac9200_brd_tbl[spec->board_config];
2501 stac92xx_set_config_regs(codec);
2504 spec->multiout.max_channels = 2;
2505 spec->multiout.num_dacs = 1;
2506 spec->multiout.dac_nids = stac9200_dac_nids;
2507 spec->adc_nids = stac9200_adc_nids;
2508 spec->mux_nids = stac9200_mux_nids;
2509 spec->num_muxes = 1;
2510 spec->num_dmics = 0;
2513 if (spec->board_config == STAC_9200_GATEWAY)
2514 spec->init = stac9200_eapd_init;
2516 spec->init = stac9200_core_init;
2517 spec->mixer = stac9200_mixer;
2519 err = stac9200_parse_auto_config(codec);
2521 stac92xx_free(codec);
2525 codec->patch_ops = stac92xx_patch_ops;
2530 static int patch_stac925x(struct hda_codec *codec)
2532 struct sigmatel_spec *spec;
2535 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2540 spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
2541 spec->pin_nids = stac925x_pin_nids;
2542 spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
2546 if (spec->board_config < 0) {
2547 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x,"
2548 "using BIOS defaults\n");
2549 err = stac92xx_save_bios_config_regs(codec);
2551 stac92xx_free(codec);
2554 spec->pin_configs = spec->bios_pin_configs;
2555 } else if (stac925x_brd_tbl[spec->board_config] != NULL){
2556 spec->pin_configs = stac925x_brd_tbl[spec->board_config];
2557 stac92xx_set_config_regs(codec);
2560 spec->multiout.max_channels = 2;
2561 spec->multiout.num_dacs = 1;
2562 spec->multiout.dac_nids = stac925x_dac_nids;
2563 spec->adc_nids = stac925x_adc_nids;
2564 spec->mux_nids = stac925x_mux_nids;
2565 spec->num_muxes = 1;
2567 switch (codec->vendor_id) {
2568 case 0x83847632: /* STAC9202 */
2569 case 0x83847633: /* STAC9202D */
2570 case 0x83847636: /* STAC9251 */
2571 case 0x83847637: /* STAC9251D */
2572 spec->num_dmics = 1;
2573 spec->dmic_nids = stac925x_dmic_nids;
2576 spec->num_dmics = 0;
2580 spec->init = stac925x_core_init;
2581 spec->mixer = stac925x_mixer;
2583 err = stac92xx_parse_auto_config(codec, 0x8, 0x7);
2585 if (spec->board_config < 0) {
2586 printk(KERN_WARNING "hda_codec: No auto-config is "
2587 "available, default to model=ref\n");
2588 spec->board_config = STAC_925x_REF;
2594 stac92xx_free(codec);
2598 codec->patch_ops = stac92xx_patch_ops;
2603 static int patch_stac922x(struct hda_codec *codec)
2605 struct sigmatel_spec *spec;
2608 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2613 spec->num_pins = ARRAY_SIZE(stac922x_pin_nids);
2614 spec->pin_nids = stac922x_pin_nids;
2615 spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
2618 if (spec->board_config == STAC_INTEL_MAC_V3) {
2619 spec->gpio_mute = 1;
2620 /* Intel Macs have all same PCI SSID, so we need to check
2621 * codec SSID to distinguish the exact models
2623 printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id);
2624 switch (codec->subsystem_id) {
2627 spec->board_config = STAC_INTEL_MAC_V1;
2631 spec->board_config = STAC_INTEL_MAC_V2;
2639 spec->board_config = STAC_INTEL_MAC_V3;
2643 spec->board_config = STAC_INTEL_MAC_V4;
2647 spec->board_config = STAC_INTEL_MAC_V5;
2653 if (spec->board_config < 0) {
2654 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, "
2655 "using BIOS defaults\n");
2656 err = stac92xx_save_bios_config_regs(codec);
2658 stac92xx_free(codec);
2661 spec->pin_configs = spec->bios_pin_configs;
2662 } else if (stac922x_brd_tbl[spec->board_config] != NULL) {
2663 spec->pin_configs = stac922x_brd_tbl[spec->board_config];
2664 stac92xx_set_config_regs(codec);
2667 spec->adc_nids = stac922x_adc_nids;
2668 spec->mux_nids = stac922x_mux_nids;
2669 spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
2670 spec->num_adcs = ARRAY_SIZE(stac922x_adc_nids);
2671 spec->num_dmics = 0;
2673 spec->init = stac922x_core_init;
2674 spec->mixer = stac922x_mixer;
2676 spec->multiout.dac_nids = spec->dac_nids;
2678 err = stac92xx_parse_auto_config(codec, 0x08, 0x09);
2680 if (spec->board_config < 0) {
2681 printk(KERN_WARNING "hda_codec: No auto-config is "
2682 "available, default to model=ref\n");
2683 spec->board_config = STAC_D945_REF;
2689 stac92xx_free(codec);
2693 codec->patch_ops = stac92xx_patch_ops;
2695 /* Fix Mux capture level; max to 2 */
2696 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
2697 (0 << AC_AMPCAP_OFFSET_SHIFT) |
2698 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2699 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2700 (0 << AC_AMPCAP_MUTE_SHIFT));
2705 static int patch_stac927x(struct hda_codec *codec)
2707 struct sigmatel_spec *spec;
2710 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2715 spec->num_pins = ARRAY_SIZE(stac927x_pin_nids);
2716 spec->pin_nids = stac927x_pin_nids;
2717 spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS,
2721 if (spec->board_config < 0) {
2722 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n");
2723 err = stac92xx_save_bios_config_regs(codec);
2725 stac92xx_free(codec);
2728 spec->pin_configs = spec->bios_pin_configs;
2729 } else if (stac927x_brd_tbl[spec->board_config] != NULL) {
2730 spec->pin_configs = stac927x_brd_tbl[spec->board_config];
2731 stac92xx_set_config_regs(codec);
2734 switch (spec->board_config) {
2736 spec->adc_nids = stac927x_adc_nids;
2737 spec->mux_nids = stac927x_mux_nids;
2738 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2739 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
2740 spec->num_dmics = 0;
2741 spec->init = d965_core_init;
2742 spec->mixer = stac927x_mixer;
2745 spec->adc_nids = stac927x_adc_nids;
2746 spec->mux_nids = stac927x_mux_nids;
2747 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2748 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
2749 spec->num_dmics = 0;
2750 spec->init = d965_core_init;
2751 spec->mixer = stac927x_mixer;
2754 spec->adc_nids = stac927x_adc_nids;
2755 spec->mux_nids = stac927x_mux_nids;
2756 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2757 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
2758 spec->num_dmics = 0;
2759 spec->init = stac927x_core_init;
2760 spec->mixer = stac927x_mixer;
2763 spec->multiout.dac_nids = spec->dac_nids;
2764 /* GPIO0 High = Enable EAPD */
2765 spec->gpio_mask = spec->gpio_data = 0x00000001;
2766 stac92xx_enable_gpio_mask(codec);
2768 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
2770 if (spec->board_config < 0) {
2771 printk(KERN_WARNING "hda_codec: No auto-config is "
2772 "available, default to model=ref\n");
2773 spec->board_config = STAC_D965_REF;
2779 stac92xx_free(codec);
2783 codec->patch_ops = stac92xx_patch_ops;
2788 static int patch_stac9205(struct hda_codec *codec)
2790 struct sigmatel_spec *spec;
2793 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2798 spec->num_pins = ARRAY_SIZE(stac9205_pin_nids);
2799 spec->pin_nids = stac9205_pin_nids;
2800 spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
2804 if (spec->board_config < 0) {
2805 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n");
2806 err = stac92xx_save_bios_config_regs(codec);
2808 stac92xx_free(codec);
2811 spec->pin_configs = spec->bios_pin_configs;
2813 spec->pin_configs = stac9205_brd_tbl[spec->board_config];
2814 stac92xx_set_config_regs(codec);
2817 spec->adc_nids = stac9205_adc_nids;
2818 spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids);
2819 spec->mux_nids = stac9205_mux_nids;
2820 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
2821 spec->dmic_nids = stac9205_dmic_nids;
2822 spec->num_dmics = ARRAY_SIZE(stac9205_dmic_nids);
2823 spec->dmux_nid = 0x1d;
2825 spec->init = stac9205_core_init;
2826 spec->mixer = stac9205_mixer;
2828 spec->multiout.dac_nids = spec->dac_nids;
2830 switch (spec->board_config){
2831 case STAC_9205_DELL_M43:
2832 /* Enable SPDIF in/out */
2833 stac92xx_set_config_reg(codec, 0x1f, 0x01441030);
2834 stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
2836 spec->gpio_mask = 0x00000007; /* GPIO0-2 */
2837 /* GPIO0 High = EAPD, GPIO1 Low = DRM,
2838 * GPIO2 High = Headphone Mute
2840 spec->gpio_data = 0x00000005;
2843 /* GPIO0 High = EAPD */
2844 spec->gpio_mask = spec->gpio_data = 0x00000001;
2848 stac92xx_enable_gpio_mask(codec);
2849 err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
2851 if (spec->board_config < 0) {
2852 printk(KERN_WARNING "hda_codec: No auto-config is "
2853 "available, default to model=ref\n");
2854 spec->board_config = STAC_9205_REF;
2860 stac92xx_free(codec);
2864 codec->patch_ops = stac92xx_patch_ops;
2873 /* static config for Sony VAIO FE550G and Sony VAIO AR */
2874 static hda_nid_t vaio_dacs[] = { 0x2 };
2875 #define VAIO_HP_DAC 0x5
2876 static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ };
2877 static hda_nid_t vaio_mux_nids[] = { 0x15 };
2879 static struct hda_input_mux vaio_mux = {
2882 /* { "HP", 0x0 }, */
2883 { "Mic Jack", 0x1 },
2884 { "Internal Mic", 0x2 },
2889 static struct hda_verb vaio_init[] = {
2890 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
2891 {0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT},
2892 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
2893 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
2894 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
2895 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
2896 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
2897 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
2898 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
2899 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
2900 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
2901 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
2905 static struct hda_verb vaio_ar_init[] = {
2906 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
2907 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
2908 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
2909 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
2910 /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */
2911 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
2912 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
2913 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
2914 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
2915 /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */
2916 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
2917 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
2918 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
2922 /* bind volumes of both NID 0x02 and 0x05 */
2923 static struct hda_bind_ctls vaio_bind_master_vol = {
2924 .ops = &snd_hda_bind_vol,
2926 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
2927 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
2932 /* bind volumes of both NID 0x02 and 0x05 */
2933 static struct hda_bind_ctls vaio_bind_master_sw = {
2934 .ops = &snd_hda_bind_sw,
2936 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
2937 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
2942 static struct snd_kcontrol_new vaio_mixer[] = {
2943 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
2944 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
2945 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
2946 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
2947 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
2949 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2950 .name = "Capture Source",
2952 .info = stac92xx_mux_enum_info,
2953 .get = stac92xx_mux_enum_get,
2954 .put = stac92xx_mux_enum_put,
2959 static struct snd_kcontrol_new vaio_ar_mixer[] = {
2960 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
2961 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
2962 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
2963 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
2964 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
2965 /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT),
2966 HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/
2968 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2969 .name = "Capture Source",
2971 .info = stac92xx_mux_enum_info,
2972 .get = stac92xx_mux_enum_get,
2973 .put = stac92xx_mux_enum_put,
2978 static struct hda_codec_ops stac9872_patch_ops = {
2979 .build_controls = stac92xx_build_controls,
2980 .build_pcms = stac92xx_build_pcms,
2981 .init = stac92xx_init,
2982 .free = stac92xx_free,
2983 #ifdef SND_HDA_NEEDS_RESUME
2984 .resume = stac92xx_resume,
2988 static int stac9872_vaio_init(struct hda_codec *codec)
2992 err = stac92xx_init(codec);
2995 if (codec->patch_ops.unsol_event)
2996 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
3000 static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
3002 if (get_pin_presence(codec, 0x0a)) {
3003 stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
3004 stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
3006 stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
3007 stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
3011 static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res)
3013 switch (res >> 26) {
3015 stac9872_vaio_hp_detect(codec, res);
3020 static struct hda_codec_ops stac9872_vaio_patch_ops = {
3021 .build_controls = stac92xx_build_controls,
3022 .build_pcms = stac92xx_build_pcms,
3023 .init = stac9872_vaio_init,
3024 .free = stac92xx_free,
3025 .unsol_event = stac9872_vaio_unsol_event,
3027 .resume = stac92xx_resume,
3031 enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */
3033 /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */
3035 /* Unknown. id=0x83847661 and subsys=0x104D1200. */
3037 /* AR Series. id=0x83847664 and subsys=104D1300 */
3042 static const char *stac9872_models[STAC_9872_MODELS] = {
3043 [CXD9872RD_VAIO] = "vaio",
3044 [CXD9872AKD_VAIO] = "vaio-ar",
3047 static struct snd_pci_quirk stac9872_cfg_tbl[] = {
3048 SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
3049 SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
3050 SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
3051 SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO),
3055 static int patch_stac9872(struct hda_codec *codec)
3057 struct sigmatel_spec *spec;
3060 board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
3063 if (board_config < 0)
3064 /* unknown config, let generic-parser do its job... */
3065 return snd_hda_parse_generic_codec(codec);
3067 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3072 switch (board_config) {
3073 case CXD9872RD_VAIO:
3074 case STAC9872AK_VAIO:
3075 case STAC9872K_VAIO:
3076 spec->mixer = vaio_mixer;
3077 spec->init = vaio_init;
3078 spec->multiout.max_channels = 2;
3079 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
3080 spec->multiout.dac_nids = vaio_dacs;
3081 spec->multiout.hp_nid = VAIO_HP_DAC;
3082 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
3083 spec->adc_nids = vaio_adcs;
3084 spec->input_mux = &vaio_mux;
3085 spec->mux_nids = vaio_mux_nids;
3086 codec->patch_ops = stac9872_vaio_patch_ops;
3089 case CXD9872AKD_VAIO:
3090 spec->mixer = vaio_ar_mixer;
3091 spec->init = vaio_ar_init;
3092 spec->multiout.max_channels = 2;
3093 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
3094 spec->multiout.dac_nids = vaio_dacs;
3095 spec->multiout.hp_nid = VAIO_HP_DAC;
3096 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
3097 spec->adc_nids = vaio_adcs;
3098 spec->input_mux = &vaio_mux;
3099 spec->mux_nids = vaio_mux_nids;
3100 codec->patch_ops = stac9872_patch_ops;
3111 struct hda_codec_preset snd_hda_preset_sigmatel[] = {
3112 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
3113 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
3114 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
3115 { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x },
3116 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
3117 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
3118 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
3119 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x },
3120 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x },
3121 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x },
3122 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x },
3123 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x },
3124 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x },
3125 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
3126 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
3127 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
3128 { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x },
3129 { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x },
3130 { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x },
3131 { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x },
3132 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x },
3133 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x },
3134 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x },
3135 { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x },
3136 { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x },
3137 { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x },
3138 { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
3139 { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
3140 { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
3141 /* The following does not take into account .id=0x83847661 when subsys =
3142 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
3143 * currently not fully supported.
3145 { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 },
3146 { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 },
3147 { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 },
3148 { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 },
3149 { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 },
3150 { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 },
3151 { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 },
3152 { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 },
3153 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
3154 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
3155 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },