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;
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);
364 if (kcontrol->private_value == ucontrol->value.integer.value[0])
367 kcontrol->private_value = ucontrol->value.integer.value[0];
369 snd_hda_codec_write_cache(codec, 0x24, 0,
370 AC_VERB_SET_VOLUME_KNOB_CONTROL,
371 kcontrol->private_value | 0x80);
376 static struct hda_verb stac9200_core_init[] = {
377 /* set dac0mux for dac converter */
378 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
382 static struct hda_verb stac925x_core_init[] = {
383 /* set dac0mux for dac converter */
384 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
388 static struct hda_verb stac922x_core_init[] = {
389 /* set master volume and direct control */
390 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
394 static struct hda_verb d965_core_init[] = {
395 /* set master volume and direct control */
396 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
397 /* unmute node 0x1b */
398 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
399 /* select node 0x03 as DAC */
400 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
404 static struct hda_verb stac927x_core_init[] = {
405 /* set master volume and direct control */
406 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
410 static struct hda_verb stac9205_core_init[] = {
411 /* set master volume and direct control */
412 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
416 #define STAC_INPUT_SOURCE \
418 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
419 .name = "Input Source", \
421 .info = stac92xx_mux_enum_info, \
422 .get = stac92xx_mux_enum_get, \
423 .put = stac92xx_mux_enum_put, \
426 #define STAC_ANALOG_LOOPBACK(verb_read,verb_write) \
428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
429 .name = "Analog Loopback", \
431 .info = stac92xx_aloopback_info, \
432 .get = stac92xx_aloopback_get, \
433 .put = stac92xx_aloopback_put, \
434 .private_value = verb_read | (verb_write << 16), \
437 #define STAC_VOLKNOB \
439 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
440 .name = "Master Playback Volume", \
442 .info = stac92xx_volknob_info, \
443 .get = stac92xx_volknob_get, \
444 .put = stac92xx_volknob_put, \
445 .private_value = 127, \
449 static struct snd_kcontrol_new stac9200_mixer[] = {
450 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
451 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
453 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
454 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
455 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT),
459 static struct snd_kcontrol_new stac925x_mixer[] = {
461 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
462 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT),
463 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT),
467 /* This needs to be generated dynamically based on sequence */
468 static struct snd_kcontrol_new stac922x_mixer[] = {
471 HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_INPUT),
472 HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_INPUT),
473 HDA_CODEC_VOLUME("Mux Capture Volume", 0x12, 0x0, HDA_OUTPUT),
477 /* This needs to be generated dynamically based on sequence */
478 static struct snd_kcontrol_new stac9227_mixer[] = {
481 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB),
482 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
483 HDA_CODEC_MUTE("Capture Switch", 0x1b, 0x0, HDA_OUTPUT),
487 static struct snd_kcontrol_new stac927x_mixer[] = {
490 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB),
491 HDA_CODEC_VOLUME("InMux Capture Volume", 0x15, 0x0, HDA_OUTPUT),
492 HDA_CODEC_VOLUME("InVol Capture Volume", 0x18, 0x0, HDA_INPUT),
493 HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1b, 0x0, HDA_OUTPUT),
497 static struct snd_kcontrol_new stac9205_mixer[] = {
499 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
500 .name = "Digital Input Source",
502 .info = stac92xx_dmux_enum_info,
503 .get = stac92xx_dmux_enum_get,
504 .put = stac92xx_dmux_enum_put,
507 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0),
509 HDA_CODEC_VOLUME("InMux Capture Volume", 0x19, 0x0, HDA_OUTPUT),
510 HDA_CODEC_VOLUME("InVol Capture Volume", 0x1b, 0x0, HDA_INPUT),
511 HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1d, 0x0, HDA_OUTPUT),
515 static int stac92xx_build_controls(struct hda_codec *codec)
517 struct sigmatel_spec *spec = codec->spec;
521 err = snd_hda_add_new_ctls(codec, spec->mixer);
525 for (i = 0; i < spec->num_mixers; i++) {
526 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
531 if (spec->multiout.dig_out_nid) {
532 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
536 if (spec->dig_in_nid) {
537 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
544 static unsigned int ref9200_pin_configs[8] = {
545 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
546 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
550 STAC 9200 pin configs for
555 static unsigned int dell9200_d21_pin_configs[8] = {
556 0x400001f0, 0x400001f1, 0x01a19021, 0x90100140,
557 0x01813122, 0x02214030, 0x01014010, 0x02a19020,
561 STAC 9200 pin configs for
565 static unsigned int dell9200_d22_pin_configs[8] = {
566 0x400001f0, 0x400001f1, 0x02a19021, 0x90100140,
567 0x400001f2, 0x0221401f, 0x01014010, 0x01813020,
571 STAC 9200 pin configs for
572 102801C4 (Dell Dimension E310)
579 static unsigned int dell9200_d23_pin_configs[8] = {
580 0x400001f0, 0x400001f1, 0x01a19021, 0x90100140,
581 0x400001f2, 0x0221401f, 0x01014010, 0x01813020,
586 STAC 9200-32 pin configs for
587 102801B5 (Dell Inspiron 630m)
588 102801D8 (Dell Inspiron 640m)
590 static unsigned int dell9200_m21_pin_configs[8] = {
591 0x40c003fa, 0x03441340, 0x03a11020, 0x401003fc,
592 0x403003fd, 0x0321121f, 0x0321121f, 0x408003fb,
596 STAC 9200-32 pin configs for
597 102801C2 (Dell Latitude D620)
599 102801CC (Dell Latitude D820)
603 static unsigned int dell9200_m22_pin_configs[8] = {
604 0x40c003fa, 0x0144131f, 0x03A11020, 0x401003fb,
605 0x40f000fc, 0x0321121f, 0x90170310, 0x90a70321,
609 STAC 9200-32 pin configs for
610 102801CE (Dell XPS M1710)
611 102801CF (Dell Precision M90)
613 static unsigned int dell9200_m23_pin_configs[8] = {
614 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310,
615 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc,
619 STAC 9200-32 pin configs for
622 102801CB (Dell Latitude 120L)
625 static unsigned int dell9200_m24_pin_configs[8] = {
626 0x40c003fa, 0x404003fb, 0x03a11020, 0x401003fd,
627 0x403003fe, 0x0321121f, 0x90170310, 0x408003fc,
631 STAC 9200-32 pin configs for
632 102801BD (Dell Inspiron E1505n)
636 static unsigned int dell9200_m25_pin_configs[8] = {
637 0x40c003fa, 0x01441340, 0x04a11020, 0x401003fc,
638 0x403003fd, 0x0421121f, 0x90170310, 0x408003fb,
642 STAC 9200-32 pin configs for
643 102801F5 (Dell Inspiron 1501)
646 static unsigned int dell9200_m26_pin_configs[8] = {
647 0x40c003fa, 0x404003fb, 0x04a11020, 0x401003fd,
648 0x403003fe, 0x0421121f, 0x90170310, 0x408003fc,
653 102801CD (Dell Inspiron E1705/9400)
655 static unsigned int dell9200_m27_pin_configs[8] = {
656 0x40c003fa, 0x01441340, 0x04a11020, 0x90170310,
657 0x40f003fc, 0x0421121f, 0x90170310, 0x408003fb,
661 static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
662 [STAC_REF] = ref9200_pin_configs,
663 [STAC_9200_DELL_D21] = dell9200_d21_pin_configs,
664 [STAC_9200_DELL_D22] = dell9200_d22_pin_configs,
665 [STAC_9200_DELL_D23] = dell9200_d23_pin_configs,
666 [STAC_9200_DELL_M21] = dell9200_m21_pin_configs,
667 [STAC_9200_DELL_M22] = dell9200_m22_pin_configs,
668 [STAC_9200_DELL_M23] = dell9200_m23_pin_configs,
669 [STAC_9200_DELL_M24] = dell9200_m24_pin_configs,
670 [STAC_9200_DELL_M25] = dell9200_m25_pin_configs,
671 [STAC_9200_DELL_M26] = dell9200_m26_pin_configs,
672 [STAC_9200_DELL_M27] = dell9200_m27_pin_configs,
675 static const char *stac9200_models[STAC_9200_MODELS] = {
677 [STAC_9200_DELL_D21] = "dell-d21",
678 [STAC_9200_DELL_D22] = "dell-d22",
679 [STAC_9200_DELL_D23] = "dell-d23",
680 [STAC_9200_DELL_M21] = "dell-m21",
681 [STAC_9200_DELL_M22] = "dell-m22",
682 [STAC_9200_DELL_M23] = "dell-m23",
683 [STAC_9200_DELL_M24] = "dell-m24",
684 [STAC_9200_DELL_M25] = "dell-m25",
685 [STAC_9200_DELL_M26] = "dell-m26",
686 [STAC_9200_DELL_M27] = "dell-m27",
689 static struct snd_pci_quirk stac9200_cfg_tbl[] = {
690 /* SigmaTel reference board */
691 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
692 "DFI LanParty", STAC_REF),
693 /* Dell laptops have BIOS problem */
694 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
695 "unknown Dell", STAC_9200_DELL_D21),
696 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
697 "Dell Inspiron 630m", STAC_9200_DELL_M21),
698 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
699 "Dell Inspiron E1505n", STAC_9200_DELL_M25),
700 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
701 "unknown Dell", STAC_9200_DELL_D22),
702 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
703 "unknown Dell", STAC_9200_DELL_D22),
704 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
705 "Dell Latitude D620", STAC_9200_DELL_M22),
706 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
707 "unknown Dell", STAC_9200_DELL_D23),
708 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
709 "unknown Dell", STAC_9200_DELL_D23),
710 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
711 "unknown Dell", STAC_9200_DELL_M22),
712 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
713 "unknown Dell", STAC_9200_DELL_M24),
714 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
715 "unknown Dell", STAC_9200_DELL_M24),
716 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
717 "Dell Latitude 120L", STAC_9200_DELL_M24),
718 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
719 "Dell Latitude D820", STAC_9200_DELL_M22),
720 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
721 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
722 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
723 "Dell XPS M1710", STAC_9200_DELL_M23),
724 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
725 "Dell Precision M90", STAC_9200_DELL_M23),
726 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
727 "unknown Dell", STAC_9200_DELL_M22),
728 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
729 "unknown Dell", STAC_9200_DELL_M22),
730 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
731 "unknown Dell", STAC_9200_DELL_M22),
732 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
733 "Dell Inspiron 640m", STAC_9200_DELL_M21),
734 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
735 "unknown Dell", STAC_9200_DELL_D23),
736 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
737 "unknown Dell", STAC_9200_DELL_D23),
738 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
739 "unknown Dell", STAC_9200_DELL_D21),
740 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
741 "unknown Dell", STAC_9200_DELL_D23),
742 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
743 "unknown Dell", STAC_9200_DELL_D21),
744 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
745 "unknown Dell", STAC_9200_DELL_M25),
746 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
747 "unknown Dell", STAC_9200_DELL_M25),
748 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
749 "Dell Inspiron 1501", STAC_9200_DELL_M26),
750 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
751 "unknown Dell", STAC_9200_DELL_M26),
753 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_REF),
758 static unsigned int ref925x_pin_configs[8] = {
759 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
760 0x90a70320, 0x02214210, 0x400003f1, 0x9033032e,
763 static unsigned int stac925x_MA6_pin_configs[8] = {
764 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
765 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e,
768 static unsigned int stac925x_PA6_pin_configs[8] = {
769 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
770 0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e,
773 static unsigned int stac925xM2_2_pin_configs[8] = {
774 0x40c003f3, 0x424503f2, 0x04180011, 0x02a19020,
775 0x50a103f0, 0x90100212, 0x400003f1, 0x9033032e,
778 static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
779 [STAC_REF] = ref925x_pin_configs,
780 [STAC_M2_2] = stac925xM2_2_pin_configs,
781 [STAC_MA6] = stac925x_MA6_pin_configs,
782 [STAC_PA6] = stac925x_PA6_pin_configs,
785 static const char *stac925x_models[STAC_925x_MODELS] = {
787 [STAC_M2_2] = "m2-2",
792 static struct snd_pci_quirk stac925x_cfg_tbl[] = {
793 /* SigmaTel reference board */
794 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
795 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
796 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF),
797 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF),
798 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6),
799 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_PA6),
800 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2),
804 static unsigned int ref922x_pin_configs[10] = {
805 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
806 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
807 0x40000100, 0x40000100,
811 STAC 922X pin configs for
818 static unsigned int dell_922x_d81_pin_configs[10] = {
819 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
820 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1,
821 0x01813122, 0x400001f2,
825 STAC 922X pin configs for
829 static unsigned int dell_922x_d82_pin_configs[10] = {
830 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
831 0x02a19020, 0x01117011, 0x01451140, 0x400001f0,
832 0x01813122, 0x400001f1,
836 STAC 922X pin configs for
839 static unsigned int dell_922x_m81_pin_configs[10] = {
840 0x0321101f, 0x01112024, 0x01111222, 0x91174220,
841 0x03a11050, 0x01116221, 0x90a70330, 0x01452340,
842 0x40C003f1, 0x405003f0,
846 STAC 9221 A1 pin configs for
847 102801D7 (Dell XPS M1210)
849 static unsigned int dell_922x_m82_pin_configs[10] = {
850 0x0221121f, 0x408103ff, 0x02111212, 0x90100310,
851 0x408003f1, 0x02111211, 0x03451340, 0x40c003f2,
852 0x508003f3, 0x405003f4,
855 static unsigned int d945gtp3_pin_configs[10] = {
856 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
857 0x40000100, 0x40000100, 0x40000100, 0x40000100,
858 0x02a19120, 0x40000100,
861 static unsigned int d945gtp5_pin_configs[10] = {
862 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
863 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
864 0x02a19320, 0x40000100,
867 static unsigned int intel_mac_v1_pin_configs[10] = {
868 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd,
869 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240,
870 0x400000fc, 0x400000fb,
873 static unsigned int intel_mac_v2_pin_configs[10] = {
874 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
875 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa,
876 0x400000fc, 0x400000fb,
879 static unsigned int intel_mac_v3_pin_configs[10] = {
880 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
881 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240,
882 0x400000fc, 0x400000fb,
885 static unsigned int intel_mac_v4_pin_configs[10] = {
886 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
887 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
888 0x400000fc, 0x400000fb,
891 static unsigned int intel_mac_v5_pin_configs[10] = {
892 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
893 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
894 0x400000fc, 0x400000fb,
898 static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
899 [STAC_D945_REF] = ref922x_pin_configs,
900 [STAC_D945GTP3] = d945gtp3_pin_configs,
901 [STAC_D945GTP5] = d945gtp5_pin_configs,
902 [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs,
903 [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs,
904 [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs,
905 [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs,
906 [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs,
907 /* for backward compatibility */
908 [STAC_MACMINI] = intel_mac_v3_pin_configs,
909 [STAC_MACBOOK] = intel_mac_v5_pin_configs,
910 [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs,
911 [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs,
912 [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs,
913 [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs,
914 [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs,
915 [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs,
916 [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs,
917 [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs,
920 static const char *stac922x_models[STAC_922X_MODELS] = {
921 [STAC_D945_REF] = "ref",
922 [STAC_D945GTP5] = "5stack",
923 [STAC_D945GTP3] = "3stack",
924 [STAC_INTEL_MAC_V1] = "intel-mac-v1",
925 [STAC_INTEL_MAC_V2] = "intel-mac-v2",
926 [STAC_INTEL_MAC_V3] = "intel-mac-v3",
927 [STAC_INTEL_MAC_V4] = "intel-mac-v4",
928 [STAC_INTEL_MAC_V5] = "intel-mac-v5",
929 /* for backward compatibility */
930 [STAC_MACMINI] = "macmini",
931 [STAC_MACBOOK] = "macbook",
932 [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1",
933 [STAC_MACBOOK_PRO_V2] = "macbook-pro",
934 [STAC_IMAC_INTEL] = "imac-intel",
935 [STAC_IMAC_INTEL_20] = "imac-intel-20",
936 [STAC_922X_DELL_D81] = "dell-d81",
937 [STAC_922X_DELL_D82] = "dell-d82",
938 [STAC_922X_DELL_M81] = "dell-m81",
939 [STAC_922X_DELL_M82] = "dell-m82",
942 static struct snd_pci_quirk stac922x_cfg_tbl[] = {
943 /* SigmaTel reference board */
944 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
945 "DFI LanParty", STAC_D945_REF),
946 /* Intel 945G based systems */
947 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
948 "Intel D945G", STAC_D945GTP3),
949 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
950 "Intel D945G", STAC_D945GTP3),
951 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
952 "Intel D945G", STAC_D945GTP3),
953 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
954 "Intel D945G", STAC_D945GTP3),
955 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
956 "Intel D945G", STAC_D945GTP3),
957 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
958 "Intel D945G", STAC_D945GTP3),
959 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
960 "Intel D945G", STAC_D945GTP3),
961 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
962 "Intel D945G", STAC_D945GTP3),
963 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
964 "Intel D945G", STAC_D945GTP3),
965 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
966 "Intel D945G", STAC_D945GTP3),
967 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
968 "Intel D945G", STAC_D945GTP3),
969 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
970 "Intel D945G", STAC_D945GTP3),
971 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
972 "Intel D945G", STAC_D945GTP3),
973 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
974 "Intel D945G", STAC_D945GTP3),
975 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
976 "Intel D945G", STAC_D945GTP3),
977 /* Intel D945G 5-stack systems */
978 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
979 "Intel D945G", STAC_D945GTP5),
980 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
981 "Intel D945G", STAC_D945GTP5),
982 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
983 "Intel D945G", STAC_D945GTP5),
984 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
985 "Intel D945G", STAC_D945GTP5),
986 /* Intel 945P based systems */
987 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
988 "Intel D945P", STAC_D945GTP3),
989 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
990 "Intel D945P", STAC_D945GTP3),
991 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
992 "Intel D945P", STAC_D945GTP3),
993 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
994 "Intel D945P", STAC_D945GTP3),
995 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
996 "Intel D945P", STAC_D945GTP3),
997 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
998 "Intel D945P", STAC_D945GTP5),
1000 /* Apple Mac Mini (early 2006) */
1001 SND_PCI_QUIRK(0x8384, 0x7680,
1002 "Mac Mini", STAC_INTEL_MAC_V3),
1004 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
1005 "unknown Dell", STAC_922X_DELL_D81),
1006 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
1007 "unknown Dell", STAC_922X_DELL_D81),
1008 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
1009 "unknown Dell", STAC_922X_DELL_D81),
1010 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
1011 "unknown Dell", STAC_922X_DELL_D82),
1012 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
1013 "unknown Dell", STAC_922X_DELL_M81),
1014 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
1015 "unknown Dell", STAC_922X_DELL_D82),
1016 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
1017 "unknown Dell", STAC_922X_DELL_D81),
1018 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
1019 "unknown Dell", STAC_922X_DELL_D81),
1020 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
1021 "Dell XPS M1210", STAC_922X_DELL_M82),
1025 static unsigned int ref927x_pin_configs[14] = {
1026 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1027 0x01a19040, 0x01011012, 0x01016011, 0x0101201f,
1028 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070,
1029 0x01c42190, 0x40000100,
1032 static unsigned int d965_3st_pin_configs[14] = {
1033 0x0221401f, 0x02a19120, 0x40000100, 0x01014011,
1034 0x01a19021, 0x01813024, 0x40000100, 0x40000100,
1035 0x40000100, 0x40000100, 0x40000100, 0x40000100,
1036 0x40000100, 0x40000100
1039 static unsigned int d965_5st_pin_configs[14] = {
1040 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1041 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
1042 0x40000100, 0x40000100, 0x40000100, 0x01442070,
1043 0x40000100, 0x40000100
1046 static unsigned int dell_3st_pin_configs[14] = {
1047 0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
1048 0x01111212, 0x01116211, 0x01813050, 0x01112214,
1049 0x403003fa, 0x40000100, 0x40000100, 0x404003fb,
1050 0x40c003fc, 0x40000100
1053 static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
1054 [STAC_D965_REF] = ref927x_pin_configs,
1055 [STAC_D965_3ST] = d965_3st_pin_configs,
1056 [STAC_D965_5ST] = d965_5st_pin_configs,
1057 [STAC_DELL_3ST] = dell_3st_pin_configs,
1060 static const char *stac927x_models[STAC_927X_MODELS] = {
1061 [STAC_D965_REF] = "ref",
1062 [STAC_D965_3ST] = "3stack",
1063 [STAC_D965_5ST] = "5stack",
1064 [STAC_DELL_3ST] = "dell-3stack",
1067 static struct snd_pci_quirk stac927x_cfg_tbl[] = {
1068 /* SigmaTel reference board */
1069 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1070 "DFI LanParty", STAC_D965_REF),
1071 /* Intel 946 based systems */
1072 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
1073 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
1074 /* 965 based 3 stack systems */
1075 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2116, "Intel D965", STAC_D965_3ST),
1076 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2115, "Intel D965", STAC_D965_3ST),
1077 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2114, "Intel D965", STAC_D965_3ST),
1078 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2113, "Intel D965", STAC_D965_3ST),
1079 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2112, "Intel D965", STAC_D965_3ST),
1080 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2111, "Intel D965", STAC_D965_3ST),
1081 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2110, "Intel D965", STAC_D965_3ST),
1082 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2009, "Intel D965", STAC_D965_3ST),
1083 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2008, "Intel D965", STAC_D965_3ST),
1084 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2007, "Intel D965", STAC_D965_3ST),
1085 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2006, "Intel D965", STAC_D965_3ST),
1086 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2005, "Intel D965", STAC_D965_3ST),
1087 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2004, "Intel D965", STAC_D965_3ST),
1088 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST),
1089 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST),
1090 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST),
1091 /* Dell 3 stack systems */
1092 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
1093 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
1094 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
1095 /* 965 based 5 stack systems */
1096 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST),
1097 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST),
1098 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST),
1099 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2304, "Intel D965", STAC_D965_5ST),
1100 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2305, "Intel D965", STAC_D965_5ST),
1101 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2501, "Intel D965", STAC_D965_5ST),
1102 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2502, "Intel D965", STAC_D965_5ST),
1103 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2503, "Intel D965", STAC_D965_5ST),
1104 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2504, "Intel D965", STAC_D965_5ST),
1108 static unsigned int ref9205_pin_configs[12] = {
1109 0x40000100, 0x40000100, 0x01016011, 0x01014010,
1110 0x01813122, 0x01a19021, 0x40000100, 0x40000100,
1111 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
1115 STAC 9205 pin configs for
1123 static unsigned int dell_9205_m42_pin_configs[12] = {
1124 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310,
1125 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9,
1126 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE,
1130 STAC 9205 pin configs for
1134 102801FF (Dell Precision M4300)
1139 static unsigned int dell_9205_m43_pin_configs[12] = {
1140 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310,
1141 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9,
1142 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8,
1145 static unsigned int dell_9205_m44_pin_configs[12] = {
1146 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310,
1147 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9,
1148 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe,
1151 static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
1152 [STAC_9205_REF] = ref9205_pin_configs,
1153 [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs,
1154 [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs,
1155 [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs,
1156 [STAC_9205_M43xx] = NULL,
1159 static const char *stac9205_models[STAC_9205_MODELS] = {
1160 [STAC_9205_REF] = "ref",
1161 [STAC_9205_DELL_M42] = "dell-m42",
1162 [STAC_9205_DELL_M43] = "dell-m43",
1163 [STAC_9205_DELL_M44] = "dell-m44",
1166 static struct snd_pci_quirk stac9205_cfg_tbl[] = {
1167 /* SigmaTel reference board */
1168 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1169 "DFI LanParty", STAC_9205_REF),
1170 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1171 "unknown Dell", STAC_9205_DELL_M42),
1172 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1173 "unknown Dell", STAC_9205_DELL_M42),
1174 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
1175 "Dell Precision", STAC_9205_M43xx),
1176 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
1177 "Dell Precision", STAC_9205_DELL_M43),
1178 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
1179 "Dell Precision", STAC_9205_DELL_M43),
1180 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1181 "unknown Dell", STAC_9205_DELL_M42),
1182 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1183 "unknown Dell", STAC_9205_DELL_M42),
1184 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
1185 "Dell Precision", STAC_9205_DELL_M43),
1186 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
1187 "Dell Precision M4300", STAC_9205_DELL_M43),
1188 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
1189 "Dell Precision", STAC_9205_DELL_M43),
1190 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1191 "Dell Inspiron", STAC_9205_DELL_M44),
1192 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1193 "Dell Inspiron", STAC_9205_DELL_M44),
1194 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1195 "Dell Inspiron", STAC_9205_DELL_M44),
1196 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1197 "Dell Inspiron", STAC_9205_DELL_M44),
1198 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
1199 "unknown Dell", STAC_9205_DELL_M42),
1200 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
1201 "Dell Inspiron", STAC_9205_DELL_M44),
1205 static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
1208 struct sigmatel_spec *spec = codec->spec;
1210 if (! spec->bios_pin_configs) {
1211 spec->bios_pin_configs = kcalloc(spec->num_pins,
1212 sizeof(*spec->bios_pin_configs), GFP_KERNEL);
1213 if (! spec->bios_pin_configs)
1217 for (i = 0; i < spec->num_pins; i++) {
1218 hda_nid_t nid = spec->pin_nids[i];
1219 unsigned int pin_cfg;
1221 pin_cfg = snd_hda_codec_read(codec, nid, 0,
1222 AC_VERB_GET_CONFIG_DEFAULT, 0x00);
1223 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n",
1225 spec->bios_pin_configs[i] = pin_cfg;
1231 static void stac92xx_set_config_reg(struct hda_codec *codec,
1232 hda_nid_t pin_nid, unsigned int pin_config)
1235 snd_hda_codec_write(codec, pin_nid, 0,
1236 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
1237 pin_config & 0x000000ff);
1238 snd_hda_codec_write(codec, pin_nid, 0,
1239 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
1240 (pin_config & 0x0000ff00) >> 8);
1241 snd_hda_codec_write(codec, pin_nid, 0,
1242 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
1243 (pin_config & 0x00ff0000) >> 16);
1244 snd_hda_codec_write(codec, pin_nid, 0,
1245 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
1247 i = snd_hda_codec_read(codec, pin_nid, 0,
1248 AC_VERB_GET_CONFIG_DEFAULT,
1250 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n",
1254 static void stac92xx_set_config_regs(struct hda_codec *codec)
1257 struct sigmatel_spec *spec = codec->spec;
1259 if (!spec->pin_configs)
1262 for (i = 0; i < spec->num_pins; i++)
1263 stac92xx_set_config_reg(codec, spec->pin_nids[i],
1264 spec->pin_configs[i]);
1267 static void stac92xx_enable_gpio_mask(struct hda_codec *codec)
1269 struct sigmatel_spec *spec = codec->spec;
1270 /* Configure GPIOx as output */
1271 snd_hda_codec_write_cache(codec, codec->afg, 0,
1272 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_mask);
1273 /* Configure GPIOx as CMOS */
1274 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7e7, 0x00000000);
1276 snd_hda_codec_write_cache(codec, codec->afg, 0,
1277 AC_VERB_SET_GPIO_DATA, spec->gpio_data);
1279 snd_hda_codec_write_cache(codec, codec->afg, 0,
1280 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
1284 * Analog playback callbacks
1286 static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
1287 struct hda_codec *codec,
1288 struct snd_pcm_substream *substream)
1290 struct sigmatel_spec *spec = codec->spec;
1291 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
1294 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1295 struct hda_codec *codec,
1296 unsigned int stream_tag,
1297 unsigned int format,
1298 struct snd_pcm_substream *substream)
1300 struct sigmatel_spec *spec = codec->spec;
1301 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream);
1304 static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1305 struct hda_codec *codec,
1306 struct snd_pcm_substream *substream)
1308 struct sigmatel_spec *spec = codec->spec;
1309 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1313 * Digital playback callbacks
1315 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1316 struct hda_codec *codec,
1317 struct snd_pcm_substream *substream)
1319 struct sigmatel_spec *spec = codec->spec;
1320 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1323 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1324 struct hda_codec *codec,
1325 struct snd_pcm_substream *substream)
1327 struct sigmatel_spec *spec = codec->spec;
1328 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1331 static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1332 struct hda_codec *codec,
1333 unsigned int stream_tag,
1334 unsigned int format,
1335 struct snd_pcm_substream *substream)
1337 struct sigmatel_spec *spec = codec->spec;
1338 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1339 stream_tag, format, substream);
1344 * Analog capture callbacks
1346 static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1347 struct hda_codec *codec,
1348 unsigned int stream_tag,
1349 unsigned int format,
1350 struct snd_pcm_substream *substream)
1352 struct sigmatel_spec *spec = codec->spec;
1354 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1355 stream_tag, 0, format);
1359 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1360 struct hda_codec *codec,
1361 struct snd_pcm_substream *substream)
1363 struct sigmatel_spec *spec = codec->spec;
1365 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
1369 static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
1373 /* NID is set in stac92xx_build_pcms */
1375 .open = stac92xx_dig_playback_pcm_open,
1376 .close = stac92xx_dig_playback_pcm_close,
1377 .prepare = stac92xx_dig_playback_pcm_prepare
1381 static struct hda_pcm_stream stac92xx_pcm_digital_capture = {
1385 /* NID is set in stac92xx_build_pcms */
1388 static struct hda_pcm_stream stac92xx_pcm_analog_playback = {
1392 .nid = 0x02, /* NID to query formats and rates */
1394 .open = stac92xx_playback_pcm_open,
1395 .prepare = stac92xx_playback_pcm_prepare,
1396 .cleanup = stac92xx_playback_pcm_cleanup
1400 static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
1404 .nid = 0x06, /* NID to query formats and rates */
1406 .open = stac92xx_playback_pcm_open,
1407 .prepare = stac92xx_playback_pcm_prepare,
1408 .cleanup = stac92xx_playback_pcm_cleanup
1412 static struct hda_pcm_stream stac92xx_pcm_analog_capture = {
1416 /* NID is set in stac92xx_build_pcms */
1418 .prepare = stac92xx_capture_pcm_prepare,
1419 .cleanup = stac92xx_capture_pcm_cleanup
1423 static int stac92xx_build_pcms(struct hda_codec *codec)
1425 struct sigmatel_spec *spec = codec->spec;
1426 struct hda_pcm *info = spec->pcm_rec;
1428 codec->num_pcms = 1;
1429 codec->pcm_info = info;
1431 info->name = "STAC92xx Analog";
1432 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
1433 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
1434 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1436 if (spec->alt_switch) {
1439 info->name = "STAC92xx Analog Alt";
1440 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback;
1443 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1446 info->name = "STAC92xx Digital";
1447 if (spec->multiout.dig_out_nid) {
1448 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
1449 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
1451 if (spec->dig_in_nid) {
1452 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture;
1453 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
1460 static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
1462 unsigned int pincap = snd_hda_param_read(codec, nid,
1464 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
1465 if (pincap & AC_PINCAP_VREF_100)
1466 return AC_PINCTL_VREF_100;
1467 if (pincap & AC_PINCAP_VREF_80)
1468 return AC_PINCTL_VREF_80;
1469 if (pincap & AC_PINCAP_VREF_50)
1470 return AC_PINCTL_VREF_50;
1471 if (pincap & AC_PINCAP_VREF_GRD)
1472 return AC_PINCTL_VREF_GRD;
1476 static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
1479 snd_hda_codec_write_cache(codec, nid, 0,
1480 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
1483 #define stac92xx_io_switch_info snd_ctl_boolean_mono_info
1485 static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1487 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1488 struct sigmatel_spec *spec = codec->spec;
1489 int io_idx = kcontrol-> private_value & 0xff;
1491 ucontrol->value.integer.value[0] = spec->io_switch[io_idx];
1495 static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1497 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1498 struct sigmatel_spec *spec = codec->spec;
1499 hda_nid_t nid = kcontrol->private_value >> 8;
1500 int io_idx = kcontrol-> private_value & 0xff;
1501 unsigned short val = ucontrol->value.integer.value[0];
1503 spec->io_switch[io_idx] = val;
1506 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
1508 unsigned int pinctl = AC_PINCTL_IN_EN;
1509 if (io_idx) /* set VREF for mic */
1510 pinctl |= stac92xx_get_vref(codec, nid);
1511 stac92xx_auto_set_pinctl(codec, nid, pinctl);
1516 #define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info
1518 static int stac92xx_clfe_switch_get(struct snd_kcontrol *kcontrol,
1519 struct snd_ctl_elem_value *ucontrol)
1521 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1522 struct sigmatel_spec *spec = codec->spec;
1524 ucontrol->value.integer.value[0] = spec->clfe_swap;
1528 static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
1529 struct snd_ctl_elem_value *ucontrol)
1531 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1532 struct sigmatel_spec *spec = codec->spec;
1533 hda_nid_t nid = kcontrol->private_value & 0xff;
1535 if (spec->clfe_swap == ucontrol->value.integer.value[0])
1538 spec->clfe_swap = ucontrol->value.integer.value[0];
1540 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1541 spec->clfe_swap ? 0x4 : 0x0);
1546 #define STAC_CODEC_IO_SWITCH(xname, xpval) \
1547 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1550 .info = stac92xx_io_switch_info, \
1551 .get = stac92xx_io_switch_get, \
1552 .put = stac92xx_io_switch_put, \
1553 .private_value = xpval, \
1556 #define STAC_CODEC_CLFE_SWITCH(xname, xpval) \
1557 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1560 .info = stac92xx_clfe_switch_info, \
1561 .get = stac92xx_clfe_switch_get, \
1562 .put = stac92xx_clfe_switch_put, \
1563 .private_value = xpval, \
1567 STAC_CTL_WIDGET_VOL,
1568 STAC_CTL_WIDGET_MUTE,
1569 STAC_CTL_WIDGET_IO_SWITCH,
1570 STAC_CTL_WIDGET_CLFE_SWITCH
1573 static struct snd_kcontrol_new stac92xx_control_templates[] = {
1574 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
1575 HDA_CODEC_MUTE(NULL, 0, 0, 0),
1576 STAC_CODEC_IO_SWITCH(NULL, 0),
1577 STAC_CODEC_CLFE_SWITCH(NULL, 0),
1580 /* add dynamic controls */
1581 static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val)
1583 struct snd_kcontrol_new *knew;
1585 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
1586 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
1588 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
1591 if (spec->kctl_alloc) {
1592 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
1593 kfree(spec->kctl_alloc);
1595 spec->kctl_alloc = knew;
1596 spec->num_kctl_alloc = num;
1599 knew = &spec->kctl_alloc[spec->num_kctl_used];
1600 *knew = stac92xx_control_templates[type];
1601 knew->name = kstrdup(name, GFP_KERNEL);
1604 knew->private_value = val;
1605 spec->num_kctl_used++;
1609 /* flag inputs as additional dynamic lineouts */
1610 static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
1612 struct sigmatel_spec *spec = codec->spec;
1613 unsigned int wcaps, wtype;
1614 int i, num_dacs = 0;
1616 /* use the wcaps cache to count all DACs available for line-outs */
1617 for (i = 0; i < codec->num_nodes; i++) {
1618 wcaps = codec->wcaps[i];
1619 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
1620 if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL))
1624 snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
1626 switch (cfg->line_outs) {
1628 /* add line-in as side */
1629 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
1630 cfg->line_out_pins[cfg->line_outs] =
1631 cfg->input_pins[AUTO_PIN_LINE];
1632 spec->line_switch = 1;
1637 /* add line-in as clfe and mic as side */
1638 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
1639 cfg->line_out_pins[cfg->line_outs] =
1640 cfg->input_pins[AUTO_PIN_LINE];
1641 spec->line_switch = 1;
1644 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
1645 cfg->line_out_pins[cfg->line_outs] =
1646 cfg->input_pins[AUTO_PIN_MIC];
1647 spec->mic_switch = 1;
1652 /* add line-in as surr and mic as clfe */
1653 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
1654 cfg->line_out_pins[cfg->line_outs] =
1655 cfg->input_pins[AUTO_PIN_LINE];
1656 spec->line_switch = 1;
1659 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
1660 cfg->line_out_pins[cfg->line_outs] =
1661 cfg->input_pins[AUTO_PIN_MIC];
1662 spec->mic_switch = 1;
1672 static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
1676 for (i = 0; i < spec->multiout.num_dacs; i++) {
1677 if (spec->multiout.dac_nids[i] == nid)
1685 * Fill in the dac_nids table from the parsed pin configuration
1686 * This function only works when every pin in line_out_pins[]
1687 * contains atleast one DAC in its connection list. Some 92xx
1688 * codecs are not connected directly to a DAC, such as the 9200
1689 * and 9202/925x. For those, dac_nids[] must be hard-coded.
1691 static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
1692 struct auto_pin_cfg *cfg)
1694 struct sigmatel_spec *spec = codec->spec;
1695 int i, j, conn_len = 0;
1696 hda_nid_t nid, conn[HDA_MAX_CONNECTIONS];
1697 unsigned int wcaps, wtype;
1699 for (i = 0; i < cfg->line_outs; i++) {
1700 nid = cfg->line_out_pins[i];
1701 conn_len = snd_hda_get_connections(codec, nid, conn,
1702 HDA_MAX_CONNECTIONS);
1703 for (j = 0; j < conn_len; j++) {
1704 wcaps = snd_hda_param_read(codec, conn[j],
1705 AC_PAR_AUDIO_WIDGET_CAP);
1706 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
1708 if (wtype != AC_WID_AUD_OUT ||
1709 (wcaps & AC_WCAP_DIGITAL))
1711 /* conn[j] is a DAC routed to this line-out */
1712 if (!is_in_dac_nids(spec, conn[j]))
1716 if (j == conn_len) {
1717 if (spec->multiout.num_dacs > 0) {
1718 /* we have already working output pins,
1719 * so let's drop the broken ones again
1721 cfg->line_outs = spec->multiout.num_dacs;
1724 /* error out, no available DAC found */
1726 "%s: No available DAC for pin 0x%x\n",
1731 spec->multiout.dac_nids[i] = conn[j];
1732 spec->multiout.num_dacs++;
1734 /* select this DAC in the pin's input mux */
1735 snd_hda_codec_write_cache(codec, nid, 0,
1736 AC_VERB_SET_CONNECT_SEL, j);
1741 snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
1742 spec->multiout.num_dacs,
1743 spec->multiout.dac_nids[0],
1744 spec->multiout.dac_nids[1],
1745 spec->multiout.dac_nids[2],
1746 spec->multiout.dac_nids[3],
1747 spec->multiout.dac_nids[4]);
1751 /* create volume control/switch for the given prefx type */
1752 static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_t nid, int chs)
1757 sprintf(name, "%s Playback Volume", pfx);
1758 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name,
1759 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1762 sprintf(name, "%s Playback Switch", pfx);
1763 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name,
1764 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1770 /* add playback controls from the parsed DAC table */
1771 static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
1772 const struct auto_pin_cfg *cfg)
1774 static const char *chname[4] = {
1775 "Front", "Surround", NULL /*CLFE*/, "Side"
1780 struct sigmatel_spec *spec = codec->spec;
1781 unsigned int wid_caps;
1784 for (i = 0; i < cfg->line_outs; i++) {
1785 if (!spec->multiout.dac_nids[i])
1788 nid = spec->multiout.dac_nids[i];
1792 err = create_controls(spec, "Center", nid, 1);
1795 err = create_controls(spec, "LFE", nid, 2);
1799 wid_caps = get_wcaps(codec, nid);
1801 if (wid_caps & AC_WCAP_LR_SWAP) {
1802 err = stac92xx_add_control(spec,
1803 STAC_CTL_WIDGET_CLFE_SWITCH,
1804 "Swap Center/LFE Playback Switch", nid);
1811 err = create_controls(spec, chname[i], nid, 3);
1817 if (spec->line_switch)
1818 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Line In as Output Switch", cfg->input_pins[AUTO_PIN_LINE] << 8)) < 0)
1821 if (spec->mic_switch)
1822 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Mic as Output Switch", (cfg->input_pins[AUTO_PIN_MIC] << 8) | 1)) < 0)
1828 static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
1830 if (is_in_dac_nids(spec, nid))
1832 if (spec->multiout.hp_nid == nid)
1837 static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
1839 if (!spec->multiout.hp_nid)
1840 spec->multiout.hp_nid = nid;
1841 else if (spec->multiout.num_dacs > 4) {
1842 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
1845 spec->multiout.dac_nids[spec->multiout.num_dacs] = nid;
1846 spec->multiout.num_dacs++;
1851 /* add playback controls for Speaker and HP outputs */
1852 static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
1853 struct auto_pin_cfg *cfg)
1855 struct sigmatel_spec *spec = codec->spec;
1857 int i, old_num_dacs, err;
1859 old_num_dacs = spec->multiout.num_dacs;
1860 for (i = 0; i < cfg->hp_outs; i++) {
1861 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]);
1862 if (wid_caps & AC_WCAP_UNSOL_CAP)
1863 spec->hp_detect = 1;
1864 nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
1865 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1866 if (check_in_dac_nids(spec, nid))
1870 add_spec_dacs(spec, nid);
1872 for (i = 0; i < cfg->speaker_outs; i++) {
1873 nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
1874 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1875 if (check_in_dac_nids(spec, nid))
1879 add_spec_dacs(spec, nid);
1881 for (i = 0; i < cfg->line_outs; i++) {
1882 nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0,
1883 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1884 if (check_in_dac_nids(spec, nid))
1888 add_spec_dacs(spec, nid);
1890 for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) {
1891 static const char *pfxs[] = {
1892 "Speaker", "External Speaker", "Speaker2",
1894 err = create_controls(spec, pfxs[i - old_num_dacs],
1895 spec->multiout.dac_nids[i], 3);
1899 if (spec->multiout.hp_nid) {
1901 if (old_num_dacs == spec->multiout.num_dacs)
1905 err = create_controls(spec, pfx, spec->multiout.hp_nid, 3);
1913 /* labels for dmic mux inputs */
1914 static const char *stac92xx_dmic_labels[5] = {
1915 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
1916 "Digital Mic 3", "Digital Mic 4"
1919 /* create playback/capture controls for input pins on dmic capable codecs */
1920 static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
1921 const struct auto_pin_cfg *cfg)
1923 struct sigmatel_spec *spec = codec->spec;
1924 struct hda_input_mux *dimux = &spec->private_dimux;
1925 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
1928 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0];
1929 dimux->items[dimux->num_items].index = 0;
1932 for (i = 0; i < spec->num_dmics; i++) {
1935 unsigned int def_conf;
1937 def_conf = snd_hda_codec_read(codec,
1940 AC_VERB_GET_CONFIG_DEFAULT,
1942 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
1945 num_cons = snd_hda_get_connections(codec,
1948 HDA_MAX_NUM_INPUTS);
1949 for (j = 0; j < num_cons; j++)
1950 if (con_lst[j] == spec->dmic_nids[i]) {
1956 dimux->items[dimux->num_items].label =
1957 stac92xx_dmic_labels[dimux->num_items];
1958 dimux->items[dimux->num_items].index = index;
1965 /* create playback/capture controls for input pins */
1966 static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
1968 struct sigmatel_spec *spec = codec->spec;
1969 struct hda_input_mux *imux = &spec->private_imux;
1970 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
1973 for (i = 0; i < AUTO_PIN_LAST; i++) {
1976 if (!cfg->input_pins[i])
1979 for (j = 0; j < spec->num_muxes; j++) {
1981 num_cons = snd_hda_get_connections(codec,
1984 HDA_MAX_NUM_INPUTS);
1985 for (k = 0; k < num_cons; k++)
1986 if (con_lst[k] == cfg->input_pins[i]) {
1993 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
1994 imux->items[imux->num_items].index = index;
1998 if (imux->num_items) {
2000 * Set the current input for the muxes.
2001 * The STAC9221 has two input muxes with identical source
2002 * NID lists. Hopefully this won't get confused.
2004 for (i = 0; i < spec->num_muxes; i++) {
2005 snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0,
2006 AC_VERB_SET_CONNECT_SEL,
2007 imux->items[0].index);
2014 static void stac92xx_auto_init_multi_out(struct hda_codec *codec)
2016 struct sigmatel_spec *spec = codec->spec;
2019 for (i = 0; i < spec->autocfg.line_outs; i++) {
2020 hda_nid_t nid = spec->autocfg.line_out_pins[i];
2021 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
2025 static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
2027 struct sigmatel_spec *spec = codec->spec;
2030 for (i = 0; i < spec->autocfg.hp_outs; i++) {
2032 pin = spec->autocfg.hp_pins[i];
2033 if (pin) /* connect to front */
2034 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
2036 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
2038 pin = spec->autocfg.speaker_pins[i];
2039 if (pin) /* connect to front */
2040 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN);
2044 static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in)
2046 struct sigmatel_spec *spec = codec->spec;
2049 if ((err = snd_hda_parse_pin_def_config(codec,
2051 spec->dmic_nids)) < 0)
2053 if (! spec->autocfg.line_outs)
2054 return 0; /* can't find valid pin config */
2056 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
2058 if (spec->multiout.num_dacs == 0)
2059 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
2062 err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg);
2067 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
2072 err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
2077 if (spec->num_dmics > 0)
2078 if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
2079 &spec->autocfg)) < 0)
2082 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2083 if (spec->multiout.max_channels > 2)
2084 spec->surr_switch = 1;
2086 if (spec->autocfg.dig_out_pin)
2087 spec->multiout.dig_out_nid = dig_out;
2088 if (spec->autocfg.dig_in_pin)
2089 spec->dig_in_nid = dig_in;
2091 if (spec->kctl_alloc)
2092 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2094 spec->input_mux = &spec->private_imux;
2095 spec->dinput_mux = &spec->private_dimux;
2100 /* add playback controls for HP output */
2101 static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
2102 struct auto_pin_cfg *cfg)
2104 struct sigmatel_spec *spec = codec->spec;
2105 hda_nid_t pin = cfg->hp_pins[0];
2106 unsigned int wid_caps;
2111 wid_caps = get_wcaps(codec, pin);
2112 if (wid_caps & AC_WCAP_UNSOL_CAP)
2113 spec->hp_detect = 1;
2118 /* add playback controls for LFE output */
2119 static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec,
2120 struct auto_pin_cfg *cfg)
2122 struct sigmatel_spec *spec = codec->spec;
2124 hda_nid_t lfe_pin = 0x0;
2128 * search speaker outs and line outs for a mono speaker pin
2129 * with an amp. If one is found, add LFE controls
2132 for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) {
2133 hda_nid_t pin = spec->autocfg.speaker_pins[i];
2134 unsigned long wcaps = get_wcaps(codec, pin);
2135 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
2136 if (wcaps == AC_WCAP_OUT_AMP)
2137 /* found a mono speaker with an amp, must be lfe */
2141 /* if speaker_outs is 0, then speakers may be in line_outs */
2142 if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) {
2143 for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) {
2144 hda_nid_t pin = spec->autocfg.line_out_pins[i];
2146 cfg = snd_hda_codec_read(codec, pin, 0,
2147 AC_VERB_GET_CONFIG_DEFAULT,
2149 if (get_defcfg_device(cfg) == AC_JACK_SPEAKER) {
2150 unsigned long wcaps = get_wcaps(codec, pin);
2151 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
2152 if (wcaps == AC_WCAP_OUT_AMP)
2153 /* found a mono speaker with an amp,
2161 err = create_controls(spec, "LFE", lfe_pin, 1);
2169 static int stac9200_parse_auto_config(struct hda_codec *codec)
2171 struct sigmatel_spec *spec = codec->spec;
2174 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
2177 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
2180 if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)
2183 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
2186 if (spec->autocfg.dig_out_pin)
2187 spec->multiout.dig_out_nid = 0x05;
2188 if (spec->autocfg.dig_in_pin)
2189 spec->dig_in_nid = 0x04;
2191 if (spec->kctl_alloc)
2192 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2194 spec->input_mux = &spec->private_imux;
2195 spec->dinput_mux = &spec->private_dimux;
2201 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
2202 * funky external mute control using GPIO pins.
2205 static void stac922x_gpio_mute(struct hda_codec *codec, int pin, int muted)
2207 unsigned int gpiostate, gpiomask, gpiodir;
2209 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
2210 AC_VERB_GET_GPIO_DATA, 0);
2213 gpiostate |= (1 << pin);
2215 gpiostate &= ~(1 << pin);
2217 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
2218 AC_VERB_GET_GPIO_MASK, 0);
2219 gpiomask |= (1 << pin);
2221 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
2222 AC_VERB_GET_GPIO_DIRECTION, 0);
2223 gpiodir |= (1 << pin);
2225 /* AppleHDA seems to do this -- WTF is this verb?? */
2226 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
2228 snd_hda_codec_write(codec, codec->afg, 0,
2229 AC_VERB_SET_GPIO_MASK, gpiomask);
2230 snd_hda_codec_write(codec, codec->afg, 0,
2231 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
2235 snd_hda_codec_write(codec, codec->afg, 0,
2236 AC_VERB_SET_GPIO_DATA, gpiostate);
2239 static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
2242 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)
2243 snd_hda_codec_write_cache(codec, nid, 0,
2244 AC_VERB_SET_UNSOLICITED_ENABLE,
2245 (AC_USRSP_EN | event));
2248 static int stac92xx_init(struct hda_codec *codec)
2250 struct sigmatel_spec *spec = codec->spec;
2251 struct auto_pin_cfg *cfg = &spec->autocfg;
2254 snd_hda_sequence_write(codec, spec->init);
2257 if (spec->hp_detect) {
2258 /* Enable unsolicited responses on the HP widget */
2259 for (i = 0; i < cfg->hp_outs; i++)
2260 enable_pin_detect(codec, cfg->hp_pins[i],
2262 /* force to enable the first line-out; the others are set up
2265 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
2267 stac92xx_auto_init_hp_out(codec);
2268 /* fake event to set up pins */
2269 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2271 stac92xx_auto_init_multi_out(codec);
2272 stac92xx_auto_init_hp_out(codec);
2274 for (i = 0; i < AUTO_PIN_LAST; i++) {
2275 hda_nid_t nid = cfg->input_pins[i];
2277 unsigned int pinctl = AC_PINCTL_IN_EN;
2278 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
2279 pinctl |= stac92xx_get_vref(codec, nid);
2280 stac92xx_auto_set_pinctl(codec, nid, pinctl);
2283 if (spec->num_dmics > 0)
2284 for (i = 0; i < spec->num_dmics; i++)
2285 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
2288 if (cfg->dig_out_pin)
2289 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
2291 if (cfg->dig_in_pin)
2292 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
2295 if (spec->gpio_mute) {
2296 stac922x_gpio_mute(codec, 0, 0);
2297 stac922x_gpio_mute(codec, 1, 0);
2303 static void stac92xx_free(struct hda_codec *codec)
2305 struct sigmatel_spec *spec = codec->spec;
2311 if (spec->kctl_alloc) {
2312 for (i = 0; i < spec->num_kctl_used; i++)
2313 kfree(spec->kctl_alloc[i].name);
2314 kfree(spec->kctl_alloc);
2317 if (spec->bios_pin_configs)
2318 kfree(spec->bios_pin_configs);
2323 static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
2326 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
2327 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
2329 if (pin_ctl & AC_PINCTL_IN_EN) {
2331 * we need to check the current set-up direction of
2332 * shared input pins since they can be switched via
2333 * "xxx as Output" mixer switch
2335 struct sigmatel_spec *spec = codec->spec;
2336 struct auto_pin_cfg *cfg = &spec->autocfg;
2337 if ((nid == cfg->input_pins[AUTO_PIN_LINE] &&
2338 spec->line_switch) ||
2339 (nid == cfg->input_pins[AUTO_PIN_MIC] &&
2344 /* if setting pin direction bits, clear the current
2345 direction bits first */
2346 if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
2347 pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
2349 snd_hda_codec_write_cache(codec, nid, 0,
2350 AC_VERB_SET_PIN_WIDGET_CONTROL,
2354 static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
2357 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
2358 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
2359 snd_hda_codec_write_cache(codec, nid, 0,
2360 AC_VERB_SET_PIN_WIDGET_CONTROL,
2364 static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
2368 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00)
2374 static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
2376 struct sigmatel_spec *spec = codec->spec;
2377 struct auto_pin_cfg *cfg = &spec->autocfg;
2381 for (i = 0; i < cfg->hp_outs; i++) {
2382 presence = get_pin_presence(codec, cfg->hp_pins[i]);
2388 /* disable lineouts, enable hp */
2389 for (i = 0; i < cfg->line_outs; i++)
2390 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
2392 for (i = 0; i < cfg->speaker_outs; i++)
2393 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
2396 /* enable lineouts, disable hp */
2397 for (i = 0; i < cfg->line_outs; i++)
2398 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
2400 for (i = 0; i < cfg->speaker_outs; i++)
2401 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
2406 static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
2408 switch (res >> 26) {
2410 stac92xx_hp_detect(codec, res);
2415 #ifdef SND_HDA_NEEDS_RESUME
2416 static int stac92xx_resume(struct hda_codec *codec)
2418 struct sigmatel_spec *spec = codec->spec;
2420 stac92xx_set_config_regs(codec);
2421 snd_hda_sequence_write(codec, spec->init);
2422 if (spec->gpio_mute) {
2423 stac922x_gpio_mute(codec, 0, 0);
2424 stac922x_gpio_mute(codec, 1, 0);
2426 snd_hda_codec_resume_amp(codec);
2427 snd_hda_codec_resume_cache(codec);
2428 /* invoke unsolicited event to reset the HP state */
2429 if (spec->hp_detect)
2430 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2435 static struct hda_codec_ops stac92xx_patch_ops = {
2436 .build_controls = stac92xx_build_controls,
2437 .build_pcms = stac92xx_build_pcms,
2438 .init = stac92xx_init,
2439 .free = stac92xx_free,
2440 .unsol_event = stac92xx_unsol_event,
2441 #ifdef SND_HDA_NEEDS_RESUME
2442 .resume = stac92xx_resume,
2446 static int patch_stac9200(struct hda_codec *codec)
2448 struct sigmatel_spec *spec;
2451 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2456 spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
2457 spec->pin_nids = stac9200_pin_nids;
2458 spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
2461 if (spec->board_config < 0) {
2462 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
2463 err = stac92xx_save_bios_config_regs(codec);
2465 stac92xx_free(codec);
2468 spec->pin_configs = spec->bios_pin_configs;
2470 spec->pin_configs = stac9200_brd_tbl[spec->board_config];
2471 stac92xx_set_config_regs(codec);
2474 spec->multiout.max_channels = 2;
2475 spec->multiout.num_dacs = 1;
2476 spec->multiout.dac_nids = stac9200_dac_nids;
2477 spec->adc_nids = stac9200_adc_nids;
2478 spec->mux_nids = stac9200_mux_nids;
2479 spec->num_muxes = 1;
2480 spec->num_dmics = 0;
2482 spec->init = stac9200_core_init;
2483 spec->mixer = stac9200_mixer;
2485 err = stac9200_parse_auto_config(codec);
2487 stac92xx_free(codec);
2491 codec->patch_ops = stac92xx_patch_ops;
2496 static int patch_stac925x(struct hda_codec *codec)
2498 struct sigmatel_spec *spec;
2501 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2506 spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
2507 spec->pin_nids = stac925x_pin_nids;
2508 spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
2512 if (spec->board_config < 0) {
2513 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x,"
2514 "using BIOS defaults\n");
2515 err = stac92xx_save_bios_config_regs(codec);
2517 stac92xx_free(codec);
2520 spec->pin_configs = spec->bios_pin_configs;
2521 } else if (stac925x_brd_tbl[spec->board_config] != NULL){
2522 spec->pin_configs = stac925x_brd_tbl[spec->board_config];
2523 stac92xx_set_config_regs(codec);
2526 spec->multiout.max_channels = 2;
2527 spec->multiout.num_dacs = 1;
2528 spec->multiout.dac_nids = stac925x_dac_nids;
2529 spec->adc_nids = stac925x_adc_nids;
2530 spec->mux_nids = stac925x_mux_nids;
2531 spec->num_muxes = 1;
2532 switch (codec->vendor_id) {
2533 case 0x83847632: /* STAC9202 */
2534 case 0x83847633: /* STAC9202D */
2535 case 0x83847636: /* STAC9251 */
2536 case 0x83847637: /* STAC9251D */
2537 spec->num_dmics = 1;
2538 spec->dmic_nids = stac925x_dmic_nids;
2541 spec->num_dmics = 0;
2545 spec->init = stac925x_core_init;
2546 spec->mixer = stac925x_mixer;
2548 err = stac92xx_parse_auto_config(codec, 0x8, 0x7);
2550 if (spec->board_config < 0) {
2551 printk(KERN_WARNING "hda_codec: No auto-config is "
2552 "available, default to model=ref\n");
2553 spec->board_config = STAC_925x_REF;
2559 stac92xx_free(codec);
2563 codec->patch_ops = stac92xx_patch_ops;
2568 static int patch_stac922x(struct hda_codec *codec)
2570 struct sigmatel_spec *spec;
2573 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2578 spec->num_pins = ARRAY_SIZE(stac922x_pin_nids);
2579 spec->pin_nids = stac922x_pin_nids;
2580 spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
2583 if (spec->board_config == STAC_INTEL_MAC_V3) {
2584 spec->gpio_mute = 1;
2585 /* Intel Macs have all same PCI SSID, so we need to check
2586 * codec SSID to distinguish the exact models
2588 printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id);
2589 switch (codec->subsystem_id) {
2592 spec->board_config = STAC_INTEL_MAC_V1;
2596 spec->board_config = STAC_INTEL_MAC_V2;
2604 spec->board_config = STAC_INTEL_MAC_V3;
2608 spec->board_config = STAC_INTEL_MAC_V4;
2612 spec->board_config = STAC_INTEL_MAC_V5;
2618 if (spec->board_config < 0) {
2619 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, "
2620 "using BIOS defaults\n");
2621 err = stac92xx_save_bios_config_regs(codec);
2623 stac92xx_free(codec);
2626 spec->pin_configs = spec->bios_pin_configs;
2627 } else if (stac922x_brd_tbl[spec->board_config] != NULL) {
2628 spec->pin_configs = stac922x_brd_tbl[spec->board_config];
2629 stac92xx_set_config_regs(codec);
2632 spec->adc_nids = stac922x_adc_nids;
2633 spec->mux_nids = stac922x_mux_nids;
2634 spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
2635 spec->num_dmics = 0;
2637 spec->init = stac922x_core_init;
2638 spec->mixer = stac922x_mixer;
2640 spec->multiout.dac_nids = spec->dac_nids;
2642 err = stac92xx_parse_auto_config(codec, 0x08, 0x09);
2644 if (spec->board_config < 0) {
2645 printk(KERN_WARNING "hda_codec: No auto-config is "
2646 "available, default to model=ref\n");
2647 spec->board_config = STAC_D945_REF;
2653 stac92xx_free(codec);
2657 codec->patch_ops = stac92xx_patch_ops;
2659 /* Fix Mux capture level; max to 2 */
2660 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
2661 (0 << AC_AMPCAP_OFFSET_SHIFT) |
2662 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2663 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2664 (0 << AC_AMPCAP_MUTE_SHIFT));
2669 static int patch_stac927x(struct hda_codec *codec)
2671 struct sigmatel_spec *spec;
2674 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2679 spec->num_pins = ARRAY_SIZE(stac927x_pin_nids);
2680 spec->pin_nids = stac927x_pin_nids;
2681 spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS,
2685 if (spec->board_config < 0) {
2686 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n");
2687 err = stac92xx_save_bios_config_regs(codec);
2689 stac92xx_free(codec);
2692 spec->pin_configs = spec->bios_pin_configs;
2693 } else if (stac927x_brd_tbl[spec->board_config] != NULL) {
2694 spec->pin_configs = stac927x_brd_tbl[spec->board_config];
2695 stac92xx_set_config_regs(codec);
2698 switch (spec->board_config) {
2700 spec->adc_nids = stac927x_adc_nids;
2701 spec->mux_nids = stac927x_mux_nids;
2702 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2703 spec->num_dmics = 0;
2704 spec->init = d965_core_init;
2705 spec->mixer = stac9227_mixer;
2708 spec->adc_nids = stac927x_adc_nids;
2709 spec->mux_nids = stac927x_mux_nids;
2710 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2711 spec->num_dmics = 0;
2712 spec->init = d965_core_init;
2713 spec->mixer = stac9227_mixer;
2716 spec->adc_nids = stac927x_adc_nids;
2717 spec->mux_nids = stac927x_mux_nids;
2718 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2719 spec->num_dmics = 0;
2720 spec->init = stac927x_core_init;
2721 spec->mixer = stac927x_mixer;
2724 spec->multiout.dac_nids = spec->dac_nids;
2725 /* GPIO0 High = Enable EAPD */
2726 spec->gpio_mask = spec->gpio_data = 0x00000001;
2727 stac92xx_enable_gpio_mask(codec);
2729 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
2731 if (spec->board_config < 0) {
2732 printk(KERN_WARNING "hda_codec: No auto-config is "
2733 "available, default to model=ref\n");
2734 spec->board_config = STAC_D965_REF;
2740 stac92xx_free(codec);
2744 codec->patch_ops = stac92xx_patch_ops;
2749 static int patch_stac9205(struct hda_codec *codec)
2751 struct sigmatel_spec *spec;
2754 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2759 spec->num_pins = ARRAY_SIZE(stac9205_pin_nids);
2760 spec->pin_nids = stac9205_pin_nids;
2761 spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
2765 if (spec->board_config < 0) {
2766 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n");
2767 err = stac92xx_save_bios_config_regs(codec);
2769 stac92xx_free(codec);
2772 spec->pin_configs = spec->bios_pin_configs;
2774 spec->pin_configs = stac9205_brd_tbl[spec->board_config];
2775 stac92xx_set_config_regs(codec);
2778 spec->adc_nids = stac9205_adc_nids;
2779 spec->mux_nids = stac9205_mux_nids;
2780 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
2781 spec->dmic_nids = stac9205_dmic_nids;
2782 spec->num_dmics = ARRAY_SIZE(stac9205_dmic_nids);
2783 spec->dmux_nid = 0x1d;
2785 spec->init = stac9205_core_init;
2786 spec->mixer = stac9205_mixer;
2788 spec->multiout.dac_nids = spec->dac_nids;
2790 switch (spec->board_config){
2791 case STAC_9205_M43xx:
2792 case STAC_9205_DELL_M43:
2793 /* Enable SPDIF in/out */
2794 stac92xx_set_config_reg(codec, 0x1f, 0x01441030);
2795 stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
2797 spec->gpio_mask = 0x00000007; /* GPIO0-2 */
2798 /* GPIO0 High = EAPD, GPIO1 Low = DRM,
2799 * GPIO2 High = Headphone Mute
2801 spec->gpio_data = 0x00000005;
2804 /* GPIO0 High = EAPD */
2805 spec->gpio_mask = spec->gpio_data = 0x00000001;
2809 stac92xx_enable_gpio_mask(codec);
2810 err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
2812 if (spec->board_config < 0) {
2813 printk(KERN_WARNING "hda_codec: No auto-config is "
2814 "available, default to model=ref\n");
2815 spec->board_config = STAC_9205_REF;
2821 stac92xx_free(codec);
2825 codec->patch_ops = stac92xx_patch_ops;
2834 /* static config for Sony VAIO FE550G and Sony VAIO AR */
2835 static hda_nid_t vaio_dacs[] = { 0x2 };
2836 #define VAIO_HP_DAC 0x5
2837 static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ };
2838 static hda_nid_t vaio_mux_nids[] = { 0x15 };
2840 static struct hda_input_mux vaio_mux = {
2843 /* { "HP", 0x0 }, */
2844 { "Mic Jack", 0x1 },
2845 { "Internal Mic", 0x2 },
2850 static struct hda_verb vaio_init[] = {
2851 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
2852 {0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT},
2853 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
2854 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
2855 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
2856 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
2857 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
2858 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
2859 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
2860 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
2861 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
2862 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
2866 static struct hda_verb vaio_ar_init[] = {
2867 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
2868 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
2869 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
2870 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
2871 /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */
2872 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
2873 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
2874 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
2875 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
2876 /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */
2877 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
2878 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
2879 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
2883 /* bind volumes of both NID 0x02 and 0x05 */
2884 static struct hda_bind_ctls vaio_bind_master_vol = {
2885 .ops = &snd_hda_bind_vol,
2887 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
2888 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
2893 /* bind volumes of both NID 0x02 and 0x05 */
2894 static struct hda_bind_ctls vaio_bind_master_sw = {
2895 .ops = &snd_hda_bind_sw,
2897 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
2898 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
2903 static struct snd_kcontrol_new vaio_mixer[] = {
2904 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
2905 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
2906 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
2907 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
2908 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
2910 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2911 .name = "Capture Source",
2913 .info = stac92xx_mux_enum_info,
2914 .get = stac92xx_mux_enum_get,
2915 .put = stac92xx_mux_enum_put,
2920 static struct snd_kcontrol_new vaio_ar_mixer[] = {
2921 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
2922 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
2923 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
2924 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
2925 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
2926 /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT),
2927 HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/
2929 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2930 .name = "Capture Source",
2932 .info = stac92xx_mux_enum_info,
2933 .get = stac92xx_mux_enum_get,
2934 .put = stac92xx_mux_enum_put,
2939 static struct hda_codec_ops stac9872_patch_ops = {
2940 .build_controls = stac92xx_build_controls,
2941 .build_pcms = stac92xx_build_pcms,
2942 .init = stac92xx_init,
2943 .free = stac92xx_free,
2944 #ifdef SND_HDA_NEEDS_RESUME
2945 .resume = stac92xx_resume,
2949 static int stac9872_vaio_init(struct hda_codec *codec)
2953 err = stac92xx_init(codec);
2956 if (codec->patch_ops.unsol_event)
2957 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2961 static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
2963 if (get_pin_presence(codec, 0x0a)) {
2964 stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
2965 stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
2967 stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
2968 stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
2972 static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res)
2974 switch (res >> 26) {
2976 stac9872_vaio_hp_detect(codec, res);
2981 static struct hda_codec_ops stac9872_vaio_patch_ops = {
2982 .build_controls = stac92xx_build_controls,
2983 .build_pcms = stac92xx_build_pcms,
2984 .init = stac9872_vaio_init,
2985 .free = stac92xx_free,
2986 .unsol_event = stac9872_vaio_unsol_event,
2988 .resume = stac92xx_resume,
2992 enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */
2994 /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */
2996 /* Unknown. id=0x83847661 and subsys=0x104D1200. */
2998 /* AR Series. id=0x83847664 and subsys=104D1300 */
3003 static const char *stac9872_models[STAC_9872_MODELS] = {
3004 [CXD9872RD_VAIO] = "vaio",
3005 [CXD9872AKD_VAIO] = "vaio-ar",
3008 static struct snd_pci_quirk stac9872_cfg_tbl[] = {
3009 SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
3010 SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
3011 SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
3012 SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO),
3016 static int patch_stac9872(struct hda_codec *codec)
3018 struct sigmatel_spec *spec;
3021 board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
3024 if (board_config < 0)
3025 /* unknown config, let generic-parser do its job... */
3026 return snd_hda_parse_generic_codec(codec);
3028 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3033 switch (board_config) {
3034 case CXD9872RD_VAIO:
3035 case STAC9872AK_VAIO:
3036 case STAC9872K_VAIO:
3037 spec->mixer = vaio_mixer;
3038 spec->init = vaio_init;
3039 spec->multiout.max_channels = 2;
3040 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
3041 spec->multiout.dac_nids = vaio_dacs;
3042 spec->multiout.hp_nid = VAIO_HP_DAC;
3043 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
3044 spec->adc_nids = vaio_adcs;
3045 spec->input_mux = &vaio_mux;
3046 spec->mux_nids = vaio_mux_nids;
3047 codec->patch_ops = stac9872_vaio_patch_ops;
3050 case CXD9872AKD_VAIO:
3051 spec->mixer = vaio_ar_mixer;
3052 spec->init = vaio_ar_init;
3053 spec->multiout.max_channels = 2;
3054 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
3055 spec->multiout.dac_nids = vaio_dacs;
3056 spec->multiout.hp_nid = VAIO_HP_DAC;
3057 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
3058 spec->adc_nids = vaio_adcs;
3059 spec->input_mux = &vaio_mux;
3060 spec->mux_nids = vaio_mux_nids;
3061 codec->patch_ops = stac9872_patch_ops;
3072 struct hda_codec_preset snd_hda_preset_sigmatel[] = {
3073 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
3074 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
3075 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
3076 { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x },
3077 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
3078 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
3079 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
3080 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x },
3081 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x },
3082 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x },
3083 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x },
3084 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x },
3085 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x },
3086 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
3087 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
3088 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
3089 { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x },
3090 { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x },
3091 { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x },
3092 { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x },
3093 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x },
3094 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x },
3095 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x },
3096 { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x },
3097 { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x },
3098 { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x },
3099 { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
3100 { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
3101 { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
3102 /* The following does not take into account .id=0x83847661 when subsys =
3103 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
3104 * currently not fully supported.
3106 { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 },
3107 { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 },
3108 { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 },
3109 { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 },
3110 { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 },
3111 { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 },
3112 { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 },
3113 { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 },
3114 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
3115 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
3116 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },