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
80 /* for backward compatibility */
102 struct sigmatel_spec {
103 struct snd_kcontrol_new *mixers[4];
104 unsigned int num_mixers;
107 unsigned int surr_switch: 1;
108 unsigned int line_switch: 1;
109 unsigned int mic_switch: 1;
110 unsigned int alt_switch: 1;
111 unsigned int hp_detect: 1;
112 unsigned int gpio_mute: 1;
114 unsigned int gpio_mask, gpio_data;
117 struct hda_multi_out multiout;
118 hda_nid_t dac_nids[5];
122 unsigned int num_adcs;
124 unsigned int num_muxes;
125 hda_nid_t *dmic_nids;
126 unsigned int num_dmics;
128 hda_nid_t dig_in_nid;
132 unsigned int num_pins;
133 unsigned int *pin_configs;
134 unsigned int *bios_pin_configs;
136 /* codec specific stuff */
137 struct hda_verb *init;
138 struct snd_kcontrol_new *mixer;
141 struct hda_input_mux *dinput_mux;
142 unsigned int cur_dmux;
143 struct hda_input_mux *input_mux;
144 unsigned int cur_mux[3];
147 unsigned int io_switch[2];
148 unsigned int clfe_swap;
149 unsigned int aloopback;
151 struct hda_pcm pcm_rec[2]; /* PCM information */
153 /* dynamic controls and input_mux */
154 struct auto_pin_cfg autocfg;
155 unsigned int num_kctl_alloc, num_kctl_used;
156 struct snd_kcontrol_new *kctl_alloc;
157 struct hda_input_mux private_dimux;
158 struct hda_input_mux private_imux;
161 static hda_nid_t stac9200_adc_nids[1] = {
165 static hda_nid_t stac9200_mux_nids[1] = {
169 static hda_nid_t stac9200_dac_nids[1] = {
173 static hda_nid_t stac925x_adc_nids[1] = {
177 static hda_nid_t stac925x_mux_nids[1] = {
181 static hda_nid_t stac925x_dac_nids[1] = {
185 static hda_nid_t stac925x_dmic_nids[1] = {
189 static hda_nid_t stac922x_adc_nids[2] = {
193 static hda_nid_t stac922x_mux_nids[2] = {
197 static hda_nid_t stac927x_adc_nids[3] = {
201 static hda_nid_t stac927x_mux_nids[3] = {
205 static hda_nid_t stac9205_adc_nids[2] = {
209 static hda_nid_t stac9205_mux_nids[2] = {
213 static hda_nid_t stac9205_dmic_nids[2] = {
217 static hda_nid_t stac9200_pin_nids[8] = {
218 0x08, 0x09, 0x0d, 0x0e,
219 0x0f, 0x10, 0x11, 0x12,
222 static hda_nid_t stac925x_pin_nids[8] = {
223 0x07, 0x08, 0x0a, 0x0b,
224 0x0c, 0x0d, 0x10, 0x11,
227 static hda_nid_t stac922x_pin_nids[10] = {
228 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
229 0x0f, 0x10, 0x11, 0x15, 0x1b,
232 static hda_nid_t stac927x_pin_nids[14] = {
233 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
234 0x0f, 0x10, 0x11, 0x12, 0x13,
235 0x14, 0x21, 0x22, 0x23,
238 static hda_nid_t stac9205_pin_nids[12] = {
239 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
240 0x0f, 0x14, 0x16, 0x17, 0x18,
244 static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
245 struct snd_ctl_elem_info *uinfo)
247 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
248 struct sigmatel_spec *spec = codec->spec;
249 return snd_hda_input_mux_info(spec->dinput_mux, uinfo);
252 static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol,
253 struct snd_ctl_elem_value *ucontrol)
255 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
256 struct sigmatel_spec *spec = codec->spec;
258 ucontrol->value.enumerated.item[0] = spec->cur_dmux;
262 static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
263 struct snd_ctl_elem_value *ucontrol)
265 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
266 struct sigmatel_spec *spec = codec->spec;
268 return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol,
269 spec->dmux_nid, &spec->cur_dmux);
272 static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
274 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
275 struct sigmatel_spec *spec = codec->spec;
276 return snd_hda_input_mux_info(spec->input_mux, uinfo);
279 static int stac92xx_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
281 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
282 struct sigmatel_spec *spec = codec->spec;
283 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
285 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
289 static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
291 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
292 struct sigmatel_spec *spec = codec->spec;
293 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
295 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
296 spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]);
299 #define stac92xx_aloopback_info snd_ctl_boolean_mono_info
301 static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol,
302 struct snd_ctl_elem_value *ucontrol)
304 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
305 struct sigmatel_spec *spec = codec->spec;
307 ucontrol->value.integer.value[0] = spec->aloopback;
311 static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol,
312 struct snd_ctl_elem_value *ucontrol)
314 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
315 struct sigmatel_spec *spec = codec->spec;
316 unsigned int dac_mode;
318 if (spec->aloopback == ucontrol->value.integer.value[0])
321 spec->aloopback = ucontrol->value.integer.value[0];
324 dac_mode = snd_hda_codec_read(codec, codec->afg, 0,
325 kcontrol->private_value & 0xFFFF, 0x0);
327 if (spec->aloopback) {
328 snd_hda_power_up(codec);
331 snd_hda_power_down(codec);
335 snd_hda_codec_write_cache(codec, codec->afg, 0,
336 kcontrol->private_value >> 16, dac_mode);
341 static int stac92xx_volknob_info(struct snd_kcontrol *kcontrol,
342 struct snd_ctl_elem_info *uinfo)
344 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
346 uinfo->value.integer.min = 0;
347 uinfo->value.integer.max = 127;
351 static int stac92xx_volknob_get(struct snd_kcontrol *kcontrol,
352 struct snd_ctl_elem_value *ucontrol)
354 ucontrol->value.integer.value[0] = kcontrol->private_value;
358 static int stac92xx_volknob_put(struct snd_kcontrol *kcontrol,
359 struct snd_ctl_elem_value *ucontrol)
361 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
363 if (kcontrol->private_value == ucontrol->value.integer.value[0])
366 kcontrol->private_value = ucontrol->value.integer.value[0];
368 snd_hda_codec_write_cache(codec, 0x24, 0,
369 AC_VERB_SET_VOLUME_KNOB_CONTROL,
370 kcontrol->private_value | 0x80);
375 static struct hda_verb stac9200_core_init[] = {
376 /* set dac0mux for dac converter */
377 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
381 static struct hda_verb stac925x_core_init[] = {
382 /* set dac0mux for dac converter */
383 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
387 static struct hda_verb stac922x_core_init[] = {
388 /* set master volume and direct control */
389 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
393 static struct hda_verb d965_core_init[] = {
394 /* set master volume and direct control */
395 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
396 /* unmute node 0x1b */
397 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
398 /* select node 0x03 as DAC */
399 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
403 static struct hda_verb stac927x_core_init[] = {
404 /* set master volume and direct control */
405 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
409 static struct hda_verb stac9205_core_init[] = {
410 /* set master volume and direct control */
411 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
415 #define STAC_INPUT_SOURCE(cnt) \
417 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
418 .name = "Input Source", \
420 .info = stac92xx_mux_enum_info, \
421 .get = stac92xx_mux_enum_get, \
422 .put = stac92xx_mux_enum_put, \
425 #define STAC_ANALOG_LOOPBACK(verb_read,verb_write) \
427 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
428 .name = "Analog Loopback", \
430 .info = stac92xx_aloopback_info, \
431 .get = stac92xx_aloopback_get, \
432 .put = stac92xx_aloopback_put, \
433 .private_value = verb_read | (verb_write << 16), \
436 #define STAC_VOLKNOB \
438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
439 .name = "Master Playback Volume", \
441 .info = stac92xx_volknob_info, \
442 .get = stac92xx_volknob_get, \
443 .put = stac92xx_volknob_put, \
444 .private_value = 127, \
448 static struct snd_kcontrol_new stac9200_mixer[] = {
449 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
450 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
451 STAC_INPUT_SOURCE(1),
452 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
453 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
454 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT),
458 static struct snd_kcontrol_new stac925x_mixer[] = {
459 STAC_INPUT_SOURCE(1),
460 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
461 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT),
462 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT),
466 static struct snd_kcontrol_new stac9205_mixer[] = {
468 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
469 .name = "Digital Input Source",
471 .info = stac92xx_dmux_enum_info,
472 .get = stac92xx_dmux_enum_get,
473 .put = stac92xx_dmux_enum_put,
475 STAC_INPUT_SOURCE(2),
476 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0),
479 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT),
480 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT),
481 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x19, 0x0, HDA_OUTPUT),
483 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT),
484 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT),
485 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x1A, 0x0, HDA_OUTPUT),
490 /* This needs to be generated dynamically based on sequence */
491 static struct snd_kcontrol_new stac922x_mixer[] = {
492 STAC_INPUT_SOURCE(2),
494 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT),
495 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT),
496 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x12, 0x0, HDA_OUTPUT),
498 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT),
499 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT),
500 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x13, 0x0, HDA_OUTPUT),
505 static struct snd_kcontrol_new stac927x_mixer[] = {
506 STAC_INPUT_SOURCE(3),
508 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB),
510 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT),
511 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT),
512 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x15, 0x0, HDA_OUTPUT),
514 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT),
515 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT),
516 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x16, 0x0, HDA_OUTPUT),
518 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT),
519 HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT),
520 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x2, 0x17, 0x0, HDA_OUTPUT),
524 static int stac92xx_build_controls(struct hda_codec *codec)
526 struct sigmatel_spec *spec = codec->spec;
530 err = snd_hda_add_new_ctls(codec, spec->mixer);
534 for (i = 0; i < spec->num_mixers; i++) {
535 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
540 if (spec->multiout.dig_out_nid) {
541 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
545 if (spec->dig_in_nid) {
546 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
553 static unsigned int ref9200_pin_configs[8] = {
554 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
555 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
559 STAC 9200 pin configs for
564 static unsigned int dell9200_d21_pin_configs[8] = {
565 0x400001f0, 0x400001f1, 0x02214030, 0x01014010,
566 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
570 STAC 9200 pin configs for
574 static unsigned int dell9200_d22_pin_configs[8] = {
575 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
576 0x01813020, 0x02a19021, 0x90100140, 0x400001f2,
580 STAC 9200 pin configs for
581 102801C4 (Dell Dimension E310)
588 static unsigned int dell9200_d23_pin_configs[8] = {
589 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
590 0x01813020, 0x01a19021, 0x90100140, 0x400001f2,
595 STAC 9200-32 pin configs for
596 102801B5 (Dell Inspiron 630m)
597 102801D8 (Dell Inspiron 640m)
599 static unsigned int dell9200_m21_pin_configs[8] = {
600 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310,
601 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd,
605 STAC 9200-32 pin configs for
606 102801C2 (Dell Latitude D620)
608 102801CC (Dell Latitude D820)
612 static unsigned int dell9200_m22_pin_configs[8] = {
613 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310,
614 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc,
618 STAC 9200-32 pin configs for
619 102801CE (Dell XPS M1710)
620 102801CF (Dell Precision M90)
622 static unsigned int dell9200_m23_pin_configs[8] = {
623 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310,
624 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc,
628 STAC 9200-32 pin configs for
631 102801CB (Dell Latitude 120L)
634 static unsigned int dell9200_m24_pin_configs[8] = {
635 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310,
636 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe,
640 STAC 9200-32 pin configs for
641 102801BD (Dell Inspiron E1505n)
645 static unsigned int dell9200_m25_pin_configs[8] = {
646 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
647 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd,
651 STAC 9200-32 pin configs for
652 102801F5 (Dell Inspiron 1501)
655 static unsigned int dell9200_m26_pin_configs[8] = {
656 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310,
657 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe,
662 102801CD (Dell Inspiron E1705/9400)
664 static unsigned int dell9200_m27_pin_configs[8] = {
665 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
666 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc,
670 static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
671 [STAC_REF] = ref9200_pin_configs,
672 [STAC_9200_DELL_D21] = dell9200_d21_pin_configs,
673 [STAC_9200_DELL_D22] = dell9200_d22_pin_configs,
674 [STAC_9200_DELL_D23] = dell9200_d23_pin_configs,
675 [STAC_9200_DELL_M21] = dell9200_m21_pin_configs,
676 [STAC_9200_DELL_M22] = dell9200_m22_pin_configs,
677 [STAC_9200_DELL_M23] = dell9200_m23_pin_configs,
678 [STAC_9200_DELL_M24] = dell9200_m24_pin_configs,
679 [STAC_9200_DELL_M25] = dell9200_m25_pin_configs,
680 [STAC_9200_DELL_M26] = dell9200_m26_pin_configs,
681 [STAC_9200_DELL_M27] = dell9200_m27_pin_configs,
684 static const char *stac9200_models[STAC_9200_MODELS] = {
686 [STAC_9200_DELL_D21] = "dell-d21",
687 [STAC_9200_DELL_D22] = "dell-d22",
688 [STAC_9200_DELL_D23] = "dell-d23",
689 [STAC_9200_DELL_M21] = "dell-m21",
690 [STAC_9200_DELL_M22] = "dell-m22",
691 [STAC_9200_DELL_M23] = "dell-m23",
692 [STAC_9200_DELL_M24] = "dell-m24",
693 [STAC_9200_DELL_M25] = "dell-m25",
694 [STAC_9200_DELL_M26] = "dell-m26",
695 [STAC_9200_DELL_M27] = "dell-m27",
698 static struct snd_pci_quirk stac9200_cfg_tbl[] = {
699 /* SigmaTel reference board */
700 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
701 "DFI LanParty", STAC_REF),
702 /* Dell laptops have BIOS problem */
703 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
704 "unknown Dell", STAC_9200_DELL_D21),
705 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
706 "Dell Inspiron 630m", STAC_9200_DELL_M21),
707 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
708 "Dell Inspiron E1505n", STAC_9200_DELL_M25),
709 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
710 "unknown Dell", STAC_9200_DELL_D22),
711 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
712 "unknown Dell", STAC_9200_DELL_D22),
713 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
714 "Dell Latitude D620", STAC_9200_DELL_M22),
715 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
716 "unknown Dell", STAC_9200_DELL_D23),
717 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
718 "unknown Dell", STAC_9200_DELL_D23),
719 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
720 "unknown Dell", STAC_9200_DELL_M22),
721 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
722 "unknown Dell", STAC_9200_DELL_M24),
723 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
724 "unknown Dell", STAC_9200_DELL_M24),
725 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
726 "Dell Latitude 120L", STAC_9200_DELL_M24),
727 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
728 "Dell Latitude D820", STAC_9200_DELL_M22),
729 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
730 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
731 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
732 "Dell XPS M1710", STAC_9200_DELL_M23),
733 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
734 "Dell Precision M90", STAC_9200_DELL_M23),
735 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
736 "unknown Dell", STAC_9200_DELL_M22),
737 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
738 "unknown Dell", STAC_9200_DELL_M22),
739 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
740 "unknown Dell", STAC_9200_DELL_M22),
741 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
742 "Dell Inspiron 640m", STAC_9200_DELL_M21),
743 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
744 "unknown Dell", STAC_9200_DELL_D23),
745 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
746 "unknown Dell", STAC_9200_DELL_D23),
747 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
748 "unknown Dell", STAC_9200_DELL_D21),
749 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
750 "unknown Dell", STAC_9200_DELL_D23),
751 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
752 "unknown Dell", STAC_9200_DELL_D21),
753 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
754 "unknown Dell", STAC_9200_DELL_M25),
755 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
756 "unknown Dell", STAC_9200_DELL_M25),
757 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
758 "Dell Inspiron 1501", STAC_9200_DELL_M26),
759 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
760 "unknown Dell", STAC_9200_DELL_M26),
762 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_REF),
767 static unsigned int ref925x_pin_configs[8] = {
768 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
769 0x90a70320, 0x02214210, 0x400003f1, 0x9033032e,
772 static unsigned int stac925x_MA6_pin_configs[8] = {
773 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
774 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e,
777 static unsigned int stac925x_PA6_pin_configs[8] = {
778 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
779 0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e,
782 static unsigned int stac925xM2_2_pin_configs[8] = {
783 0x40c003f3, 0x424503f2, 0x04180011, 0x02a19020,
784 0x50a103f0, 0x90100212, 0x400003f1, 0x9033032e,
787 static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
788 [STAC_REF] = ref925x_pin_configs,
789 [STAC_M2_2] = stac925xM2_2_pin_configs,
790 [STAC_MA6] = stac925x_MA6_pin_configs,
791 [STAC_PA6] = stac925x_PA6_pin_configs,
794 static const char *stac925x_models[STAC_925x_MODELS] = {
796 [STAC_M2_2] = "m2-2",
801 static struct snd_pci_quirk stac925x_cfg_tbl[] = {
802 /* SigmaTel reference board */
803 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
804 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
805 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF),
806 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF),
807 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6),
808 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_PA6),
809 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2),
813 static unsigned int ref922x_pin_configs[10] = {
814 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
815 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
816 0x40000100, 0x40000100,
820 STAC 922X pin configs for
827 static unsigned int dell_922x_d81_pin_configs[10] = {
828 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
829 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1,
830 0x01813122, 0x400001f2,
834 STAC 922X pin configs for
838 static unsigned int dell_922x_d82_pin_configs[10] = {
839 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
840 0x02a19020, 0x01117011, 0x01451140, 0x400001f0,
841 0x01813122, 0x400001f1,
845 STAC 922X pin configs for
848 static unsigned int dell_922x_m81_pin_configs[10] = {
849 0x0321101f, 0x01112024, 0x01111222, 0x91174220,
850 0x03a11050, 0x01116221, 0x90a70330, 0x01452340,
851 0x40C003f1, 0x405003f0,
855 STAC 9221 A1 pin configs for
856 102801D7 (Dell XPS M1210)
858 static unsigned int dell_922x_m82_pin_configs[10] = {
859 0x0221121f, 0x408103ff, 0x02111212, 0x90100310,
860 0x408003f1, 0x02111211, 0x03451340, 0x40c003f2,
861 0x508003f3, 0x405003f4,
864 static unsigned int d945gtp3_pin_configs[10] = {
865 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
866 0x40000100, 0x40000100, 0x40000100, 0x40000100,
867 0x02a19120, 0x40000100,
870 static unsigned int d945gtp5_pin_configs[10] = {
871 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
872 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
873 0x02a19320, 0x40000100,
876 static unsigned int intel_mac_v1_pin_configs[10] = {
877 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd,
878 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240,
879 0x400000fc, 0x400000fb,
882 static unsigned int intel_mac_v2_pin_configs[10] = {
883 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
884 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa,
885 0x400000fc, 0x400000fb,
888 static unsigned int intel_mac_v3_pin_configs[10] = {
889 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
890 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240,
891 0x400000fc, 0x400000fb,
894 static unsigned int intel_mac_v4_pin_configs[10] = {
895 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
896 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
897 0x400000fc, 0x400000fb,
900 static unsigned int intel_mac_v5_pin_configs[10] = {
901 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
902 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
903 0x400000fc, 0x400000fb,
907 static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
908 [STAC_D945_REF] = ref922x_pin_configs,
909 [STAC_D945GTP3] = d945gtp3_pin_configs,
910 [STAC_D945GTP5] = d945gtp5_pin_configs,
911 [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs,
912 [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs,
913 [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs,
914 [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs,
915 [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs,
916 /* for backward compatibility */
917 [STAC_MACMINI] = intel_mac_v3_pin_configs,
918 [STAC_MACBOOK] = intel_mac_v5_pin_configs,
919 [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs,
920 [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs,
921 [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs,
922 [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs,
923 [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs,
924 [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs,
925 [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs,
926 [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs,
929 static const char *stac922x_models[STAC_922X_MODELS] = {
930 [STAC_D945_REF] = "ref",
931 [STAC_D945GTP5] = "5stack",
932 [STAC_D945GTP3] = "3stack",
933 [STAC_INTEL_MAC_V1] = "intel-mac-v1",
934 [STAC_INTEL_MAC_V2] = "intel-mac-v2",
935 [STAC_INTEL_MAC_V3] = "intel-mac-v3",
936 [STAC_INTEL_MAC_V4] = "intel-mac-v4",
937 [STAC_INTEL_MAC_V5] = "intel-mac-v5",
938 /* for backward compatibility */
939 [STAC_MACMINI] = "macmini",
940 [STAC_MACBOOK] = "macbook",
941 [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1",
942 [STAC_MACBOOK_PRO_V2] = "macbook-pro",
943 [STAC_IMAC_INTEL] = "imac-intel",
944 [STAC_IMAC_INTEL_20] = "imac-intel-20",
945 [STAC_922X_DELL_D81] = "dell-d81",
946 [STAC_922X_DELL_D82] = "dell-d82",
947 [STAC_922X_DELL_M81] = "dell-m81",
948 [STAC_922X_DELL_M82] = "dell-m82",
951 static struct snd_pci_quirk stac922x_cfg_tbl[] = {
952 /* SigmaTel reference board */
953 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
954 "DFI LanParty", STAC_D945_REF),
955 /* Intel 945G based systems */
956 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
957 "Intel D945G", STAC_D945GTP3),
958 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
959 "Intel D945G", STAC_D945GTP3),
960 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
961 "Intel D945G", STAC_D945GTP3),
962 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
963 "Intel D945G", STAC_D945GTP3),
964 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
965 "Intel D945G", STAC_D945GTP3),
966 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
967 "Intel D945G", STAC_D945GTP3),
968 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
969 "Intel D945G", STAC_D945GTP3),
970 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
971 "Intel D945G", STAC_D945GTP3),
972 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
973 "Intel D945G", STAC_D945GTP3),
974 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
975 "Intel D945G", STAC_D945GTP3),
976 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
977 "Intel D945G", STAC_D945GTP3),
978 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
979 "Intel D945G", STAC_D945GTP3),
980 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
981 "Intel D945G", STAC_D945GTP3),
982 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
983 "Intel D945G", STAC_D945GTP3),
984 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
985 "Intel D945G", STAC_D945GTP3),
986 /* Intel D945G 5-stack systems */
987 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
988 "Intel D945G", STAC_D945GTP5),
989 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
990 "Intel D945G", STAC_D945GTP5),
991 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
992 "Intel D945G", STAC_D945GTP5),
993 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
994 "Intel D945G", STAC_D945GTP5),
995 /* Intel 945P based systems */
996 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
997 "Intel D945P", STAC_D945GTP3),
998 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
999 "Intel D945P", STAC_D945GTP3),
1000 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
1001 "Intel D945P", STAC_D945GTP3),
1002 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
1003 "Intel D945P", STAC_D945GTP3),
1004 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
1005 "Intel D945P", STAC_D945GTP3),
1006 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
1007 "Intel D945P", STAC_D945GTP5),
1009 /* Apple Mac Mini (early 2006) */
1010 SND_PCI_QUIRK(0x8384, 0x7680,
1011 "Mac Mini", STAC_INTEL_MAC_V3),
1013 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
1014 "unknown Dell", STAC_922X_DELL_D81),
1015 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
1016 "unknown Dell", STAC_922X_DELL_D81),
1017 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
1018 "unknown Dell", STAC_922X_DELL_D81),
1019 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
1020 "unknown Dell", STAC_922X_DELL_D82),
1021 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
1022 "unknown Dell", STAC_922X_DELL_M81),
1023 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
1024 "unknown Dell", STAC_922X_DELL_D82),
1025 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
1026 "unknown Dell", STAC_922X_DELL_D81),
1027 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
1028 "unknown Dell", STAC_922X_DELL_D81),
1029 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
1030 "Dell XPS M1210", STAC_922X_DELL_M82),
1034 static unsigned int ref927x_pin_configs[14] = {
1035 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1036 0x01a19040, 0x01011012, 0x01016011, 0x0101201f,
1037 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070,
1038 0x01c42190, 0x40000100,
1041 static unsigned int d965_3st_pin_configs[14] = {
1042 0x0221401f, 0x02a19120, 0x40000100, 0x01014011,
1043 0x01a19021, 0x01813024, 0x40000100, 0x40000100,
1044 0x40000100, 0x40000100, 0x40000100, 0x40000100,
1045 0x40000100, 0x40000100
1048 static unsigned int d965_5st_pin_configs[14] = {
1049 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1050 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
1051 0x40000100, 0x40000100, 0x40000100, 0x01442070,
1052 0x40000100, 0x40000100
1055 static unsigned int dell_3st_pin_configs[14] = {
1056 0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
1057 0x01111212, 0x01116211, 0x01813050, 0x01112214,
1058 0x403003fa, 0x40000100, 0x40000100, 0x404003fb,
1059 0x40c003fc, 0x40000100
1062 static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
1063 [STAC_D965_REF] = ref927x_pin_configs,
1064 [STAC_D965_3ST] = d965_3st_pin_configs,
1065 [STAC_D965_5ST] = d965_5st_pin_configs,
1066 [STAC_DELL_3ST] = dell_3st_pin_configs,
1069 static const char *stac927x_models[STAC_927X_MODELS] = {
1070 [STAC_D965_REF] = "ref",
1071 [STAC_D965_3ST] = "3stack",
1072 [STAC_D965_5ST] = "5stack",
1073 [STAC_DELL_3ST] = "dell-3stack",
1076 static struct snd_pci_quirk stac927x_cfg_tbl[] = {
1077 /* SigmaTel reference board */
1078 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1079 "DFI LanParty", STAC_D965_REF),
1080 /* Intel 946 based systems */
1081 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
1082 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
1083 /* 965 based 3 stack systems */
1084 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2116, "Intel D965", STAC_D965_3ST),
1085 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2115, "Intel D965", STAC_D965_3ST),
1086 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2114, "Intel D965", STAC_D965_3ST),
1087 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2113, "Intel D965", STAC_D965_3ST),
1088 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2112, "Intel D965", STAC_D965_3ST),
1089 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2111, "Intel D965", STAC_D965_3ST),
1090 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2110, "Intel D965", STAC_D965_3ST),
1091 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2009, "Intel D965", STAC_D965_3ST),
1092 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2008, "Intel D965", STAC_D965_3ST),
1093 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2007, "Intel D965", STAC_D965_3ST),
1094 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2006, "Intel D965", STAC_D965_3ST),
1095 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2005, "Intel D965", STAC_D965_3ST),
1096 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2004, "Intel D965", STAC_D965_3ST),
1097 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST),
1098 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST),
1099 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST),
1100 /* Dell 3 stack systems */
1101 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
1102 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
1103 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
1104 /* 965 based 5 stack systems */
1105 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST),
1106 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST),
1107 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST),
1108 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2304, "Intel D965", STAC_D965_5ST),
1109 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2305, "Intel D965", STAC_D965_5ST),
1110 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2501, "Intel D965", STAC_D965_5ST),
1111 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2502, "Intel D965", STAC_D965_5ST),
1112 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2503, "Intel D965", STAC_D965_5ST),
1113 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2504, "Intel D965", STAC_D965_5ST),
1117 static unsigned int ref9205_pin_configs[12] = {
1118 0x40000100, 0x40000100, 0x01016011, 0x01014010,
1119 0x01813122, 0x01a19021, 0x40000100, 0x40000100,
1120 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
1124 STAC 9205 pin configs for
1132 static unsigned int dell_9205_m42_pin_configs[12] = {
1133 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310,
1134 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9,
1135 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE,
1139 STAC 9205 pin configs for
1143 102801FF (Dell Precision M4300)
1148 static unsigned int dell_9205_m43_pin_configs[12] = {
1149 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310,
1150 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9,
1151 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8,
1154 static unsigned int dell_9205_m44_pin_configs[12] = {
1155 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310,
1156 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9,
1157 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe,
1160 static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
1161 [STAC_9205_REF] = ref9205_pin_configs,
1162 [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs,
1163 [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs,
1164 [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs,
1167 static const char *stac9205_models[STAC_9205_MODELS] = {
1168 [STAC_9205_REF] = "ref",
1169 [STAC_9205_DELL_M42] = "dell-m42",
1170 [STAC_9205_DELL_M43] = "dell-m43",
1171 [STAC_9205_DELL_M44] = "dell-m44",
1174 static struct snd_pci_quirk stac9205_cfg_tbl[] = {
1175 /* SigmaTel reference board */
1176 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1177 "DFI LanParty", STAC_9205_REF),
1178 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1179 "unknown Dell", STAC_9205_DELL_M42),
1180 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1181 "unknown Dell", STAC_9205_DELL_M42),
1182 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
1183 "Dell Precision", STAC_9205_DELL_M43),
1184 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
1185 "Dell Precision", STAC_9205_DELL_M43),
1186 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
1187 "Dell Precision", STAC_9205_DELL_M43),
1188 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
1189 "Dell Precision", STAC_9205_DELL_M43),
1190 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
1191 "Dell Precision", STAC_9205_DELL_M43),
1192 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1193 "unknown Dell", STAC_9205_DELL_M42),
1194 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1195 "unknown Dell", STAC_9205_DELL_M42),
1196 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
1197 "Dell Precision", STAC_9205_DELL_M43),
1198 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
1199 "Dell Precision M4300", STAC_9205_DELL_M43),
1200 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
1201 "Dell Precision", STAC_9205_DELL_M43),
1202 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1203 "Dell Inspiron", STAC_9205_DELL_M44),
1204 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1205 "Dell Inspiron", STAC_9205_DELL_M44),
1206 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1207 "Dell Inspiron", STAC_9205_DELL_M44),
1208 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1209 "Dell Inspiron", STAC_9205_DELL_M44),
1210 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
1211 "unknown Dell", STAC_9205_DELL_M42),
1212 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
1213 "Dell Inspiron", STAC_9205_DELL_M44),
1217 static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
1220 struct sigmatel_spec *spec = codec->spec;
1222 if (! spec->bios_pin_configs) {
1223 spec->bios_pin_configs = kcalloc(spec->num_pins,
1224 sizeof(*spec->bios_pin_configs), GFP_KERNEL);
1225 if (! spec->bios_pin_configs)
1229 for (i = 0; i < spec->num_pins; i++) {
1230 hda_nid_t nid = spec->pin_nids[i];
1231 unsigned int pin_cfg;
1233 pin_cfg = snd_hda_codec_read(codec, nid, 0,
1234 AC_VERB_GET_CONFIG_DEFAULT, 0x00);
1235 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n",
1237 spec->bios_pin_configs[i] = pin_cfg;
1243 static void stac92xx_set_config_reg(struct hda_codec *codec,
1244 hda_nid_t pin_nid, unsigned int pin_config)
1247 snd_hda_codec_write(codec, pin_nid, 0,
1248 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
1249 pin_config & 0x000000ff);
1250 snd_hda_codec_write(codec, pin_nid, 0,
1251 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
1252 (pin_config & 0x0000ff00) >> 8);
1253 snd_hda_codec_write(codec, pin_nid, 0,
1254 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
1255 (pin_config & 0x00ff0000) >> 16);
1256 snd_hda_codec_write(codec, pin_nid, 0,
1257 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
1259 i = snd_hda_codec_read(codec, pin_nid, 0,
1260 AC_VERB_GET_CONFIG_DEFAULT,
1262 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n",
1266 static void stac92xx_set_config_regs(struct hda_codec *codec)
1269 struct sigmatel_spec *spec = codec->spec;
1271 if (!spec->pin_configs)
1274 for (i = 0; i < spec->num_pins; i++)
1275 stac92xx_set_config_reg(codec, spec->pin_nids[i],
1276 spec->pin_configs[i]);
1279 static void stac92xx_enable_gpio_mask(struct hda_codec *codec)
1281 struct sigmatel_spec *spec = codec->spec;
1282 /* Configure GPIOx as output */
1283 snd_hda_codec_write_cache(codec, codec->afg, 0,
1284 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_mask);
1285 /* Configure GPIOx as CMOS */
1286 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7e7, 0x00000000);
1288 snd_hda_codec_write_cache(codec, codec->afg, 0,
1289 AC_VERB_SET_GPIO_DATA, spec->gpio_data);
1291 snd_hda_codec_write_cache(codec, codec->afg, 0,
1292 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
1296 * Analog playback callbacks
1298 static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
1299 struct hda_codec *codec,
1300 struct snd_pcm_substream *substream)
1302 struct sigmatel_spec *spec = codec->spec;
1303 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
1306 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1307 struct hda_codec *codec,
1308 unsigned int stream_tag,
1309 unsigned int format,
1310 struct snd_pcm_substream *substream)
1312 struct sigmatel_spec *spec = codec->spec;
1313 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream);
1316 static int stac92xx_playback_pcm_cleanup(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_cleanup(codec, &spec->multiout);
1325 * Digital playback callbacks
1327 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1328 struct hda_codec *codec,
1329 struct snd_pcm_substream *substream)
1331 struct sigmatel_spec *spec = codec->spec;
1332 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1335 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1336 struct hda_codec *codec,
1337 struct snd_pcm_substream *substream)
1339 struct sigmatel_spec *spec = codec->spec;
1340 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1343 static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1344 struct hda_codec *codec,
1345 unsigned int stream_tag,
1346 unsigned int format,
1347 struct snd_pcm_substream *substream)
1349 struct sigmatel_spec *spec = codec->spec;
1350 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1351 stream_tag, format, substream);
1356 * Analog capture callbacks
1358 static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1359 struct hda_codec *codec,
1360 unsigned int stream_tag,
1361 unsigned int format,
1362 struct snd_pcm_substream *substream)
1364 struct sigmatel_spec *spec = codec->spec;
1366 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1367 stream_tag, 0, format);
1371 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1372 struct hda_codec *codec,
1373 struct snd_pcm_substream *substream)
1375 struct sigmatel_spec *spec = codec->spec;
1377 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
1381 static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
1385 /* NID is set in stac92xx_build_pcms */
1387 .open = stac92xx_dig_playback_pcm_open,
1388 .close = stac92xx_dig_playback_pcm_close,
1389 .prepare = stac92xx_dig_playback_pcm_prepare
1393 static struct hda_pcm_stream stac92xx_pcm_digital_capture = {
1397 /* NID is set in stac92xx_build_pcms */
1400 static struct hda_pcm_stream stac92xx_pcm_analog_playback = {
1404 .nid = 0x02, /* 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_alt_playback = {
1416 .nid = 0x06, /* NID to query formats and rates */
1418 .open = stac92xx_playback_pcm_open,
1419 .prepare = stac92xx_playback_pcm_prepare,
1420 .cleanup = stac92xx_playback_pcm_cleanup
1424 static struct hda_pcm_stream stac92xx_pcm_analog_capture = {
1427 /* NID + .substreams is set in stac92xx_build_pcms */
1429 .prepare = stac92xx_capture_pcm_prepare,
1430 .cleanup = stac92xx_capture_pcm_cleanup
1434 static int stac92xx_build_pcms(struct hda_codec *codec)
1436 struct sigmatel_spec *spec = codec->spec;
1437 struct hda_pcm *info = spec->pcm_rec;
1439 codec->num_pcms = 1;
1440 codec->pcm_info = info;
1442 info->name = "STAC92xx Analog";
1443 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
1444 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
1445 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1446 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs;
1448 if (spec->alt_switch) {
1451 info->name = "STAC92xx Analog Alt";
1452 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback;
1455 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1458 info->name = "STAC92xx Digital";
1459 if (spec->multiout.dig_out_nid) {
1460 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
1461 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
1463 if (spec->dig_in_nid) {
1464 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture;
1465 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
1472 static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
1474 unsigned int pincap = snd_hda_param_read(codec, nid,
1476 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
1477 if (pincap & AC_PINCAP_VREF_100)
1478 return AC_PINCTL_VREF_100;
1479 if (pincap & AC_PINCAP_VREF_80)
1480 return AC_PINCTL_VREF_80;
1481 if (pincap & AC_PINCAP_VREF_50)
1482 return AC_PINCTL_VREF_50;
1483 if (pincap & AC_PINCAP_VREF_GRD)
1484 return AC_PINCTL_VREF_GRD;
1488 static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
1491 snd_hda_codec_write_cache(codec, nid, 0,
1492 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
1495 #define stac92xx_io_switch_info snd_ctl_boolean_mono_info
1497 static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1499 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1500 struct sigmatel_spec *spec = codec->spec;
1501 int io_idx = kcontrol-> private_value & 0xff;
1503 ucontrol->value.integer.value[0] = spec->io_switch[io_idx];
1507 static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1509 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1510 struct sigmatel_spec *spec = codec->spec;
1511 hda_nid_t nid = kcontrol->private_value >> 8;
1512 int io_idx = kcontrol-> private_value & 0xff;
1513 unsigned short val = ucontrol->value.integer.value[0];
1515 spec->io_switch[io_idx] = val;
1518 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
1520 unsigned int pinctl = AC_PINCTL_IN_EN;
1521 if (io_idx) /* set VREF for mic */
1522 pinctl |= stac92xx_get_vref(codec, nid);
1523 stac92xx_auto_set_pinctl(codec, nid, pinctl);
1528 #define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info
1530 static int stac92xx_clfe_switch_get(struct snd_kcontrol *kcontrol,
1531 struct snd_ctl_elem_value *ucontrol)
1533 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1534 struct sigmatel_spec *spec = codec->spec;
1536 ucontrol->value.integer.value[0] = spec->clfe_swap;
1540 static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
1541 struct snd_ctl_elem_value *ucontrol)
1543 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1544 struct sigmatel_spec *spec = codec->spec;
1545 hda_nid_t nid = kcontrol->private_value & 0xff;
1547 if (spec->clfe_swap == ucontrol->value.integer.value[0])
1550 spec->clfe_swap = ucontrol->value.integer.value[0];
1552 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1553 spec->clfe_swap ? 0x4 : 0x0);
1558 #define STAC_CODEC_IO_SWITCH(xname, xpval) \
1559 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1562 .info = stac92xx_io_switch_info, \
1563 .get = stac92xx_io_switch_get, \
1564 .put = stac92xx_io_switch_put, \
1565 .private_value = xpval, \
1568 #define STAC_CODEC_CLFE_SWITCH(xname, xpval) \
1569 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1572 .info = stac92xx_clfe_switch_info, \
1573 .get = stac92xx_clfe_switch_get, \
1574 .put = stac92xx_clfe_switch_put, \
1575 .private_value = xpval, \
1579 STAC_CTL_WIDGET_VOL,
1580 STAC_CTL_WIDGET_MUTE,
1581 STAC_CTL_WIDGET_IO_SWITCH,
1582 STAC_CTL_WIDGET_CLFE_SWITCH
1585 static struct snd_kcontrol_new stac92xx_control_templates[] = {
1586 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
1587 HDA_CODEC_MUTE(NULL, 0, 0, 0),
1588 STAC_CODEC_IO_SWITCH(NULL, 0),
1589 STAC_CODEC_CLFE_SWITCH(NULL, 0),
1592 /* add dynamic controls */
1593 static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val)
1595 struct snd_kcontrol_new *knew;
1597 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
1598 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
1600 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
1603 if (spec->kctl_alloc) {
1604 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
1605 kfree(spec->kctl_alloc);
1607 spec->kctl_alloc = knew;
1608 spec->num_kctl_alloc = num;
1611 knew = &spec->kctl_alloc[spec->num_kctl_used];
1612 *knew = stac92xx_control_templates[type];
1613 knew->name = kstrdup(name, GFP_KERNEL);
1616 knew->private_value = val;
1617 spec->num_kctl_used++;
1621 /* flag inputs as additional dynamic lineouts */
1622 static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
1624 struct sigmatel_spec *spec = codec->spec;
1625 unsigned int wcaps, wtype;
1626 int i, num_dacs = 0;
1628 /* use the wcaps cache to count all DACs available for line-outs */
1629 for (i = 0; i < codec->num_nodes; i++) {
1630 wcaps = codec->wcaps[i];
1631 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
1632 if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL))
1636 snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
1638 switch (cfg->line_outs) {
1640 /* add line-in as side */
1641 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
1642 cfg->line_out_pins[cfg->line_outs] =
1643 cfg->input_pins[AUTO_PIN_LINE];
1644 spec->line_switch = 1;
1649 /* add line-in as clfe and mic as side */
1650 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
1651 cfg->line_out_pins[cfg->line_outs] =
1652 cfg->input_pins[AUTO_PIN_LINE];
1653 spec->line_switch = 1;
1656 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
1657 cfg->line_out_pins[cfg->line_outs] =
1658 cfg->input_pins[AUTO_PIN_MIC];
1659 spec->mic_switch = 1;
1664 /* add line-in as surr and mic as clfe */
1665 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
1666 cfg->line_out_pins[cfg->line_outs] =
1667 cfg->input_pins[AUTO_PIN_LINE];
1668 spec->line_switch = 1;
1671 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
1672 cfg->line_out_pins[cfg->line_outs] =
1673 cfg->input_pins[AUTO_PIN_MIC];
1674 spec->mic_switch = 1;
1684 static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
1688 for (i = 0; i < spec->multiout.num_dacs; i++) {
1689 if (spec->multiout.dac_nids[i] == nid)
1697 * Fill in the dac_nids table from the parsed pin configuration
1698 * This function only works when every pin in line_out_pins[]
1699 * contains atleast one DAC in its connection list. Some 92xx
1700 * codecs are not connected directly to a DAC, such as the 9200
1701 * and 9202/925x. For those, dac_nids[] must be hard-coded.
1703 static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
1704 struct auto_pin_cfg *cfg)
1706 struct sigmatel_spec *spec = codec->spec;
1707 int i, j, conn_len = 0;
1708 hda_nid_t nid, conn[HDA_MAX_CONNECTIONS];
1709 unsigned int wcaps, wtype;
1711 for (i = 0; i < cfg->line_outs; i++) {
1712 nid = cfg->line_out_pins[i];
1713 conn_len = snd_hda_get_connections(codec, nid, conn,
1714 HDA_MAX_CONNECTIONS);
1715 for (j = 0; j < conn_len; j++) {
1716 wcaps = snd_hda_param_read(codec, conn[j],
1717 AC_PAR_AUDIO_WIDGET_CAP);
1718 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
1720 if (wtype != AC_WID_AUD_OUT ||
1721 (wcaps & AC_WCAP_DIGITAL))
1723 /* conn[j] is a DAC routed to this line-out */
1724 if (!is_in_dac_nids(spec, conn[j]))
1728 if (j == conn_len) {
1729 if (spec->multiout.num_dacs > 0) {
1730 /* we have already working output pins,
1731 * so let's drop the broken ones again
1733 cfg->line_outs = spec->multiout.num_dacs;
1736 /* error out, no available DAC found */
1738 "%s: No available DAC for pin 0x%x\n",
1743 spec->multiout.dac_nids[i] = conn[j];
1744 spec->multiout.num_dacs++;
1746 /* select this DAC in the pin's input mux */
1747 snd_hda_codec_write_cache(codec, nid, 0,
1748 AC_VERB_SET_CONNECT_SEL, j);
1753 snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
1754 spec->multiout.num_dacs,
1755 spec->multiout.dac_nids[0],
1756 spec->multiout.dac_nids[1],
1757 spec->multiout.dac_nids[2],
1758 spec->multiout.dac_nids[3],
1759 spec->multiout.dac_nids[4]);
1763 /* create volume control/switch for the given prefx type */
1764 static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_t nid, int chs)
1769 sprintf(name, "%s Playback Volume", pfx);
1770 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name,
1771 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1774 sprintf(name, "%s Playback Switch", pfx);
1775 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name,
1776 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1782 /* add playback controls from the parsed DAC table */
1783 static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
1784 const struct auto_pin_cfg *cfg)
1786 static const char *chname[4] = {
1787 "Front", "Surround", NULL /*CLFE*/, "Side"
1792 struct sigmatel_spec *spec = codec->spec;
1793 unsigned int wid_caps;
1796 for (i = 0; i < cfg->line_outs; i++) {
1797 if (!spec->multiout.dac_nids[i])
1800 nid = spec->multiout.dac_nids[i];
1804 err = create_controls(spec, "Center", nid, 1);
1807 err = create_controls(spec, "LFE", nid, 2);
1811 wid_caps = get_wcaps(codec, nid);
1813 if (wid_caps & AC_WCAP_LR_SWAP) {
1814 err = stac92xx_add_control(spec,
1815 STAC_CTL_WIDGET_CLFE_SWITCH,
1816 "Swap Center/LFE Playback Switch", nid);
1823 err = create_controls(spec, chname[i], nid, 3);
1829 if (spec->line_switch)
1830 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Line In as Output Switch", cfg->input_pins[AUTO_PIN_LINE] << 8)) < 0)
1833 if (spec->mic_switch)
1834 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Mic as Output Switch", (cfg->input_pins[AUTO_PIN_MIC] << 8) | 1)) < 0)
1840 static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
1842 if (is_in_dac_nids(spec, nid))
1844 if (spec->multiout.hp_nid == nid)
1849 static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
1851 if (!spec->multiout.hp_nid)
1852 spec->multiout.hp_nid = nid;
1853 else if (spec->multiout.num_dacs > 4) {
1854 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
1857 spec->multiout.dac_nids[spec->multiout.num_dacs] = nid;
1858 spec->multiout.num_dacs++;
1863 /* add playback controls for Speaker and HP outputs */
1864 static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
1865 struct auto_pin_cfg *cfg)
1867 struct sigmatel_spec *spec = codec->spec;
1869 int i, old_num_dacs, err;
1871 old_num_dacs = spec->multiout.num_dacs;
1872 for (i = 0; i < cfg->hp_outs; i++) {
1873 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]);
1874 if (wid_caps & AC_WCAP_UNSOL_CAP)
1875 spec->hp_detect = 1;
1876 nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
1877 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1878 if (check_in_dac_nids(spec, nid))
1882 add_spec_dacs(spec, nid);
1884 for (i = 0; i < cfg->speaker_outs; i++) {
1885 nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
1886 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1887 if (check_in_dac_nids(spec, nid))
1891 add_spec_dacs(spec, nid);
1893 for (i = 0; i < cfg->line_outs; i++) {
1894 nid = snd_hda_codec_read(codec, cfg->line_out_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 = old_num_dacs; i < spec->multiout.num_dacs; i++) {
1903 static const char *pfxs[] = {
1904 "Speaker", "External Speaker", "Speaker2",
1906 err = create_controls(spec, pfxs[i - old_num_dacs],
1907 spec->multiout.dac_nids[i], 3);
1911 if (spec->multiout.hp_nid) {
1913 if (old_num_dacs == spec->multiout.num_dacs)
1917 err = create_controls(spec, pfx, spec->multiout.hp_nid, 3);
1925 /* labels for dmic mux inputs */
1926 static const char *stac92xx_dmic_labels[5] = {
1927 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
1928 "Digital Mic 3", "Digital Mic 4"
1931 /* create playback/capture controls for input pins on dmic capable codecs */
1932 static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
1933 const struct auto_pin_cfg *cfg)
1935 struct sigmatel_spec *spec = codec->spec;
1936 struct hda_input_mux *dimux = &spec->private_dimux;
1937 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
1940 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0];
1941 dimux->items[dimux->num_items].index = 0;
1944 for (i = 0; i < spec->num_dmics; i++) {
1947 unsigned int def_conf;
1949 def_conf = snd_hda_codec_read(codec,
1952 AC_VERB_GET_CONFIG_DEFAULT,
1954 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
1957 num_cons = snd_hda_get_connections(codec,
1960 HDA_MAX_NUM_INPUTS);
1961 for (j = 0; j < num_cons; j++)
1962 if (con_lst[j] == spec->dmic_nids[i]) {
1968 dimux->items[dimux->num_items].label =
1969 stac92xx_dmic_labels[dimux->num_items];
1970 dimux->items[dimux->num_items].index = index;
1977 /* create playback/capture controls for input pins */
1978 static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
1980 struct sigmatel_spec *spec = codec->spec;
1981 struct hda_input_mux *imux = &spec->private_imux;
1982 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
1985 for (i = 0; i < AUTO_PIN_LAST; i++) {
1988 if (!cfg->input_pins[i])
1991 for (j = 0; j < spec->num_muxes; j++) {
1993 num_cons = snd_hda_get_connections(codec,
1996 HDA_MAX_NUM_INPUTS);
1997 for (k = 0; k < num_cons; k++)
1998 if (con_lst[k] == cfg->input_pins[i]) {
2005 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2006 imux->items[imux->num_items].index = index;
2010 if (imux->num_items) {
2012 * Set the current input for the muxes.
2013 * The STAC9221 has two input muxes with identical source
2014 * NID lists. Hopefully this won't get confused.
2016 for (i = 0; i < spec->num_muxes; i++) {
2017 snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0,
2018 AC_VERB_SET_CONNECT_SEL,
2019 imux->items[0].index);
2026 static void stac92xx_auto_init_multi_out(struct hda_codec *codec)
2028 struct sigmatel_spec *spec = codec->spec;
2031 for (i = 0; i < spec->autocfg.line_outs; i++) {
2032 hda_nid_t nid = spec->autocfg.line_out_pins[i];
2033 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
2037 static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
2039 struct sigmatel_spec *spec = codec->spec;
2042 for (i = 0; i < spec->autocfg.hp_outs; i++) {
2044 pin = spec->autocfg.hp_pins[i];
2045 if (pin) /* connect to front */
2046 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
2048 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
2050 pin = spec->autocfg.speaker_pins[i];
2051 if (pin) /* connect to front */
2052 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN);
2056 static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in)
2058 struct sigmatel_spec *spec = codec->spec;
2061 if ((err = snd_hda_parse_pin_def_config(codec,
2063 spec->dmic_nids)) < 0)
2065 if (! spec->autocfg.line_outs)
2066 return 0; /* can't find valid pin config */
2068 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
2070 if (spec->multiout.num_dacs == 0)
2071 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
2074 err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg);
2079 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
2084 err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
2089 if (spec->num_dmics > 0)
2090 if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
2091 &spec->autocfg)) < 0)
2094 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2095 if (spec->multiout.max_channels > 2)
2096 spec->surr_switch = 1;
2098 if (spec->autocfg.dig_out_pin)
2099 spec->multiout.dig_out_nid = dig_out;
2100 if (spec->autocfg.dig_in_pin)
2101 spec->dig_in_nid = dig_in;
2103 if (spec->kctl_alloc)
2104 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2106 spec->input_mux = &spec->private_imux;
2107 spec->dinput_mux = &spec->private_dimux;
2112 /* add playback controls for HP output */
2113 static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
2114 struct auto_pin_cfg *cfg)
2116 struct sigmatel_spec *spec = codec->spec;
2117 hda_nid_t pin = cfg->hp_pins[0];
2118 unsigned int wid_caps;
2123 wid_caps = get_wcaps(codec, pin);
2124 if (wid_caps & AC_WCAP_UNSOL_CAP)
2125 spec->hp_detect = 1;
2130 /* add playback controls for LFE output */
2131 static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec,
2132 struct auto_pin_cfg *cfg)
2134 struct sigmatel_spec *spec = codec->spec;
2136 hda_nid_t lfe_pin = 0x0;
2140 * search speaker outs and line outs for a mono speaker pin
2141 * with an amp. If one is found, add LFE controls
2144 for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) {
2145 hda_nid_t pin = spec->autocfg.speaker_pins[i];
2146 unsigned long wcaps = get_wcaps(codec, pin);
2147 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
2148 if (wcaps == AC_WCAP_OUT_AMP)
2149 /* found a mono speaker with an amp, must be lfe */
2153 /* if speaker_outs is 0, then speakers may be in line_outs */
2154 if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) {
2155 for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) {
2156 hda_nid_t pin = spec->autocfg.line_out_pins[i];
2158 cfg = snd_hda_codec_read(codec, pin, 0,
2159 AC_VERB_GET_CONFIG_DEFAULT,
2161 if (get_defcfg_device(cfg) == AC_JACK_SPEAKER) {
2162 unsigned long wcaps = get_wcaps(codec, pin);
2163 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
2164 if (wcaps == AC_WCAP_OUT_AMP)
2165 /* found a mono speaker with an amp,
2173 err = create_controls(spec, "LFE", lfe_pin, 1);
2181 static int stac9200_parse_auto_config(struct hda_codec *codec)
2183 struct sigmatel_spec *spec = codec->spec;
2186 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
2189 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
2192 if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)
2195 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
2198 if (spec->autocfg.dig_out_pin)
2199 spec->multiout.dig_out_nid = 0x05;
2200 if (spec->autocfg.dig_in_pin)
2201 spec->dig_in_nid = 0x04;
2203 if (spec->kctl_alloc)
2204 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2206 spec->input_mux = &spec->private_imux;
2207 spec->dinput_mux = &spec->private_dimux;
2213 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
2214 * funky external mute control using GPIO pins.
2217 static void stac922x_gpio_mute(struct hda_codec *codec, int pin, int muted)
2219 unsigned int gpiostate, gpiomask, gpiodir;
2221 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
2222 AC_VERB_GET_GPIO_DATA, 0);
2225 gpiostate |= (1 << pin);
2227 gpiostate &= ~(1 << pin);
2229 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
2230 AC_VERB_GET_GPIO_MASK, 0);
2231 gpiomask |= (1 << pin);
2233 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
2234 AC_VERB_GET_GPIO_DIRECTION, 0);
2235 gpiodir |= (1 << pin);
2237 /* AppleHDA seems to do this -- WTF is this verb?? */
2238 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
2240 snd_hda_codec_write(codec, codec->afg, 0,
2241 AC_VERB_SET_GPIO_MASK, gpiomask);
2242 snd_hda_codec_write(codec, codec->afg, 0,
2243 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
2247 snd_hda_codec_write(codec, codec->afg, 0,
2248 AC_VERB_SET_GPIO_DATA, gpiostate);
2251 static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
2254 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)
2255 snd_hda_codec_write_cache(codec, nid, 0,
2256 AC_VERB_SET_UNSOLICITED_ENABLE,
2257 (AC_USRSP_EN | event));
2260 static int stac92xx_init(struct hda_codec *codec)
2262 struct sigmatel_spec *spec = codec->spec;
2263 struct auto_pin_cfg *cfg = &spec->autocfg;
2266 snd_hda_sequence_write(codec, spec->init);
2269 if (spec->hp_detect) {
2270 /* Enable unsolicited responses on the HP widget */
2271 for (i = 0; i < cfg->hp_outs; i++)
2272 enable_pin_detect(codec, cfg->hp_pins[i],
2274 /* force to enable the first line-out; the others are set up
2277 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
2279 stac92xx_auto_init_hp_out(codec);
2280 /* fake event to set up pins */
2281 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2283 stac92xx_auto_init_multi_out(codec);
2284 stac92xx_auto_init_hp_out(codec);
2286 for (i = 0; i < AUTO_PIN_LAST; i++) {
2287 hda_nid_t nid = cfg->input_pins[i];
2289 unsigned int pinctl = AC_PINCTL_IN_EN;
2290 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
2291 pinctl |= stac92xx_get_vref(codec, nid);
2292 stac92xx_auto_set_pinctl(codec, nid, pinctl);
2295 if (spec->num_dmics > 0)
2296 for (i = 0; i < spec->num_dmics; i++)
2297 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
2300 if (cfg->dig_out_pin)
2301 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
2303 if (cfg->dig_in_pin)
2304 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
2307 if (spec->gpio_mute) {
2308 stac922x_gpio_mute(codec, 0, 0);
2309 stac922x_gpio_mute(codec, 1, 0);
2315 static void stac92xx_free(struct hda_codec *codec)
2317 struct sigmatel_spec *spec = codec->spec;
2323 if (spec->kctl_alloc) {
2324 for (i = 0; i < spec->num_kctl_used; i++)
2325 kfree(spec->kctl_alloc[i].name);
2326 kfree(spec->kctl_alloc);
2329 if (spec->bios_pin_configs)
2330 kfree(spec->bios_pin_configs);
2335 static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
2338 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
2339 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
2341 if (pin_ctl & AC_PINCTL_IN_EN) {
2343 * we need to check the current set-up direction of
2344 * shared input pins since they can be switched via
2345 * "xxx as Output" mixer switch
2347 struct sigmatel_spec *spec = codec->spec;
2348 struct auto_pin_cfg *cfg = &spec->autocfg;
2349 if ((nid == cfg->input_pins[AUTO_PIN_LINE] &&
2350 spec->line_switch) ||
2351 (nid == cfg->input_pins[AUTO_PIN_MIC] &&
2356 /* if setting pin direction bits, clear the current
2357 direction bits first */
2358 if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
2359 pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
2361 snd_hda_codec_write_cache(codec, nid, 0,
2362 AC_VERB_SET_PIN_WIDGET_CONTROL,
2366 static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
2369 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
2370 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
2371 snd_hda_codec_write_cache(codec, nid, 0,
2372 AC_VERB_SET_PIN_WIDGET_CONTROL,
2376 static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
2380 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00)
2386 static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
2388 struct sigmatel_spec *spec = codec->spec;
2389 struct auto_pin_cfg *cfg = &spec->autocfg;
2393 for (i = 0; i < cfg->hp_outs; i++) {
2394 presence = get_pin_presence(codec, cfg->hp_pins[i]);
2400 /* disable lineouts, enable hp */
2401 for (i = 0; i < cfg->line_outs; i++)
2402 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
2404 for (i = 0; i < cfg->speaker_outs; i++)
2405 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
2408 /* enable lineouts, disable hp */
2409 for (i = 0; i < cfg->line_outs; i++)
2410 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
2412 for (i = 0; i < cfg->speaker_outs; i++)
2413 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
2418 static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
2420 switch (res >> 26) {
2422 stac92xx_hp_detect(codec, res);
2427 #ifdef SND_HDA_NEEDS_RESUME
2428 static int stac92xx_resume(struct hda_codec *codec)
2430 struct sigmatel_spec *spec = codec->spec;
2432 stac92xx_set_config_regs(codec);
2433 snd_hda_sequence_write(codec, spec->init);
2434 if (spec->gpio_mute) {
2435 stac922x_gpio_mute(codec, 0, 0);
2436 stac922x_gpio_mute(codec, 1, 0);
2438 snd_hda_codec_resume_amp(codec);
2439 snd_hda_codec_resume_cache(codec);
2440 /* invoke unsolicited event to reset the HP state */
2441 if (spec->hp_detect)
2442 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2447 static struct hda_codec_ops stac92xx_patch_ops = {
2448 .build_controls = stac92xx_build_controls,
2449 .build_pcms = stac92xx_build_pcms,
2450 .init = stac92xx_init,
2451 .free = stac92xx_free,
2452 .unsol_event = stac92xx_unsol_event,
2453 #ifdef SND_HDA_NEEDS_RESUME
2454 .resume = stac92xx_resume,
2458 static int patch_stac9200(struct hda_codec *codec)
2460 struct sigmatel_spec *spec;
2463 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2468 spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
2469 spec->pin_nids = stac9200_pin_nids;
2470 spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
2473 if (spec->board_config < 0) {
2474 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
2475 err = stac92xx_save_bios_config_regs(codec);
2477 stac92xx_free(codec);
2480 spec->pin_configs = spec->bios_pin_configs;
2482 spec->pin_configs = stac9200_brd_tbl[spec->board_config];
2483 stac92xx_set_config_regs(codec);
2486 spec->multiout.max_channels = 2;
2487 spec->multiout.num_dacs = 1;
2488 spec->multiout.dac_nids = stac9200_dac_nids;
2489 spec->adc_nids = stac9200_adc_nids;
2490 spec->mux_nids = stac9200_mux_nids;
2491 spec->num_muxes = 1;
2492 spec->num_dmics = 0;
2495 spec->init = stac9200_core_init;
2496 spec->mixer = stac9200_mixer;
2498 err = stac9200_parse_auto_config(codec);
2500 stac92xx_free(codec);
2504 codec->patch_ops = stac92xx_patch_ops;
2509 static int patch_stac925x(struct hda_codec *codec)
2511 struct sigmatel_spec *spec;
2514 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2519 spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
2520 spec->pin_nids = stac925x_pin_nids;
2521 spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
2525 if (spec->board_config < 0) {
2526 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x,"
2527 "using BIOS defaults\n");
2528 err = stac92xx_save_bios_config_regs(codec);
2530 stac92xx_free(codec);
2533 spec->pin_configs = spec->bios_pin_configs;
2534 } else if (stac925x_brd_tbl[spec->board_config] != NULL){
2535 spec->pin_configs = stac925x_brd_tbl[spec->board_config];
2536 stac92xx_set_config_regs(codec);
2539 spec->multiout.max_channels = 2;
2540 spec->multiout.num_dacs = 1;
2541 spec->multiout.dac_nids = stac925x_dac_nids;
2542 spec->adc_nids = stac925x_adc_nids;
2543 spec->mux_nids = stac925x_mux_nids;
2544 spec->num_muxes = 1;
2546 switch (codec->vendor_id) {
2547 case 0x83847632: /* STAC9202 */
2548 case 0x83847633: /* STAC9202D */
2549 case 0x83847636: /* STAC9251 */
2550 case 0x83847637: /* STAC9251D */
2551 spec->num_dmics = 1;
2552 spec->dmic_nids = stac925x_dmic_nids;
2555 spec->num_dmics = 0;
2559 spec->init = stac925x_core_init;
2560 spec->mixer = stac925x_mixer;
2562 err = stac92xx_parse_auto_config(codec, 0x8, 0x7);
2564 if (spec->board_config < 0) {
2565 printk(KERN_WARNING "hda_codec: No auto-config is "
2566 "available, default to model=ref\n");
2567 spec->board_config = STAC_925x_REF;
2573 stac92xx_free(codec);
2577 codec->patch_ops = stac92xx_patch_ops;
2582 static int patch_stac922x(struct hda_codec *codec)
2584 struct sigmatel_spec *spec;
2587 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2592 spec->num_pins = ARRAY_SIZE(stac922x_pin_nids);
2593 spec->pin_nids = stac922x_pin_nids;
2594 spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
2597 if (spec->board_config == STAC_INTEL_MAC_V3) {
2598 spec->gpio_mute = 1;
2599 /* Intel Macs have all same PCI SSID, so we need to check
2600 * codec SSID to distinguish the exact models
2602 printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id);
2603 switch (codec->subsystem_id) {
2606 spec->board_config = STAC_INTEL_MAC_V1;
2610 spec->board_config = STAC_INTEL_MAC_V2;
2618 spec->board_config = STAC_INTEL_MAC_V3;
2622 spec->board_config = STAC_INTEL_MAC_V4;
2626 spec->board_config = STAC_INTEL_MAC_V5;
2632 if (spec->board_config < 0) {
2633 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, "
2634 "using BIOS defaults\n");
2635 err = stac92xx_save_bios_config_regs(codec);
2637 stac92xx_free(codec);
2640 spec->pin_configs = spec->bios_pin_configs;
2641 } else if (stac922x_brd_tbl[spec->board_config] != NULL) {
2642 spec->pin_configs = stac922x_brd_tbl[spec->board_config];
2643 stac92xx_set_config_regs(codec);
2646 spec->adc_nids = stac922x_adc_nids;
2647 spec->mux_nids = stac922x_mux_nids;
2648 spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
2649 spec->num_adcs = ARRAY_SIZE(stac922x_adc_nids);
2650 spec->num_dmics = 0;
2652 spec->init = stac922x_core_init;
2653 spec->mixer = stac922x_mixer;
2655 spec->multiout.dac_nids = spec->dac_nids;
2657 err = stac92xx_parse_auto_config(codec, 0x08, 0x09);
2659 if (spec->board_config < 0) {
2660 printk(KERN_WARNING "hda_codec: No auto-config is "
2661 "available, default to model=ref\n");
2662 spec->board_config = STAC_D945_REF;
2668 stac92xx_free(codec);
2672 codec->patch_ops = stac92xx_patch_ops;
2674 /* Fix Mux capture level; max to 2 */
2675 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
2676 (0 << AC_AMPCAP_OFFSET_SHIFT) |
2677 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2678 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2679 (0 << AC_AMPCAP_MUTE_SHIFT));
2684 static int patch_stac927x(struct hda_codec *codec)
2686 struct sigmatel_spec *spec;
2689 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2694 spec->num_pins = ARRAY_SIZE(stac927x_pin_nids);
2695 spec->pin_nids = stac927x_pin_nids;
2696 spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS,
2700 if (spec->board_config < 0) {
2701 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n");
2702 err = stac92xx_save_bios_config_regs(codec);
2704 stac92xx_free(codec);
2707 spec->pin_configs = spec->bios_pin_configs;
2708 } else if (stac927x_brd_tbl[spec->board_config] != NULL) {
2709 spec->pin_configs = stac927x_brd_tbl[spec->board_config];
2710 stac92xx_set_config_regs(codec);
2713 switch (spec->board_config) {
2715 spec->adc_nids = stac927x_adc_nids;
2716 spec->mux_nids = stac927x_mux_nids;
2717 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2718 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
2719 spec->num_dmics = 0;
2720 spec->init = d965_core_init;
2721 spec->mixer = stac927x_mixer;
2724 spec->adc_nids = stac927x_adc_nids;
2725 spec->mux_nids = stac927x_mux_nids;
2726 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2727 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
2728 spec->num_dmics = 0;
2729 spec->init = d965_core_init;
2730 spec->mixer = stac927x_mixer;
2733 spec->adc_nids = stac927x_adc_nids;
2734 spec->mux_nids = stac927x_mux_nids;
2735 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2736 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
2737 spec->num_dmics = 0;
2738 spec->init = stac927x_core_init;
2739 spec->mixer = stac927x_mixer;
2742 spec->multiout.dac_nids = spec->dac_nids;
2743 /* GPIO0 High = Enable EAPD */
2744 spec->gpio_mask = spec->gpio_data = 0x00000001;
2745 stac92xx_enable_gpio_mask(codec);
2747 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
2749 if (spec->board_config < 0) {
2750 printk(KERN_WARNING "hda_codec: No auto-config is "
2751 "available, default to model=ref\n");
2752 spec->board_config = STAC_D965_REF;
2758 stac92xx_free(codec);
2762 codec->patch_ops = stac92xx_patch_ops;
2767 static int patch_stac9205(struct hda_codec *codec)
2769 struct sigmatel_spec *spec;
2772 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2777 spec->num_pins = ARRAY_SIZE(stac9205_pin_nids);
2778 spec->pin_nids = stac9205_pin_nids;
2779 spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
2783 if (spec->board_config < 0) {
2784 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n");
2785 err = stac92xx_save_bios_config_regs(codec);
2787 stac92xx_free(codec);
2790 spec->pin_configs = spec->bios_pin_configs;
2792 spec->pin_configs = stac9205_brd_tbl[spec->board_config];
2793 stac92xx_set_config_regs(codec);
2796 spec->adc_nids = stac9205_adc_nids;
2797 spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids);
2798 spec->mux_nids = stac9205_mux_nids;
2799 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
2800 spec->dmic_nids = stac9205_dmic_nids;
2801 spec->num_dmics = ARRAY_SIZE(stac9205_dmic_nids);
2802 spec->dmux_nid = 0x1d;
2804 spec->init = stac9205_core_init;
2805 spec->mixer = stac9205_mixer;
2807 spec->multiout.dac_nids = spec->dac_nids;
2809 switch (spec->board_config){
2810 case STAC_9205_DELL_M43:
2811 /* Enable SPDIF in/out */
2812 stac92xx_set_config_reg(codec, 0x1f, 0x01441030);
2813 stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
2815 spec->gpio_mask = 0x00000007; /* GPIO0-2 */
2816 /* GPIO0 High = EAPD, GPIO1 Low = DRM,
2817 * GPIO2 High = Headphone Mute
2819 spec->gpio_data = 0x00000005;
2822 /* GPIO0 High = EAPD */
2823 spec->gpio_mask = spec->gpio_data = 0x00000001;
2827 stac92xx_enable_gpio_mask(codec);
2828 err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
2830 if (spec->board_config < 0) {
2831 printk(KERN_WARNING "hda_codec: No auto-config is "
2832 "available, default to model=ref\n");
2833 spec->board_config = STAC_9205_REF;
2839 stac92xx_free(codec);
2843 codec->patch_ops = stac92xx_patch_ops;
2852 /* static config for Sony VAIO FE550G and Sony VAIO AR */
2853 static hda_nid_t vaio_dacs[] = { 0x2 };
2854 #define VAIO_HP_DAC 0x5
2855 static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ };
2856 static hda_nid_t vaio_mux_nids[] = { 0x15 };
2858 static struct hda_input_mux vaio_mux = {
2861 /* { "HP", 0x0 }, */
2862 { "Mic Jack", 0x1 },
2863 { "Internal Mic", 0x2 },
2868 static struct hda_verb vaio_init[] = {
2869 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
2870 {0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT},
2871 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
2872 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
2873 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
2874 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
2875 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
2876 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
2877 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
2878 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
2879 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
2880 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
2884 static struct hda_verb vaio_ar_init[] = {
2885 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
2886 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
2887 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
2888 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
2889 /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */
2890 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
2891 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
2892 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
2893 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
2894 /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */
2895 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
2896 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
2897 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
2901 /* bind volumes of both NID 0x02 and 0x05 */
2902 static struct hda_bind_ctls vaio_bind_master_vol = {
2903 .ops = &snd_hda_bind_vol,
2905 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
2906 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
2911 /* bind volumes of both NID 0x02 and 0x05 */
2912 static struct hda_bind_ctls vaio_bind_master_sw = {
2913 .ops = &snd_hda_bind_sw,
2915 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
2916 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
2921 static struct snd_kcontrol_new vaio_mixer[] = {
2922 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
2923 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
2924 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
2925 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
2926 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
2928 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2929 .name = "Capture Source",
2931 .info = stac92xx_mux_enum_info,
2932 .get = stac92xx_mux_enum_get,
2933 .put = stac92xx_mux_enum_put,
2938 static struct snd_kcontrol_new vaio_ar_mixer[] = {
2939 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
2940 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
2941 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
2942 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
2943 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
2944 /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT),
2945 HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/
2947 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2948 .name = "Capture Source",
2950 .info = stac92xx_mux_enum_info,
2951 .get = stac92xx_mux_enum_get,
2952 .put = stac92xx_mux_enum_put,
2957 static struct hda_codec_ops stac9872_patch_ops = {
2958 .build_controls = stac92xx_build_controls,
2959 .build_pcms = stac92xx_build_pcms,
2960 .init = stac92xx_init,
2961 .free = stac92xx_free,
2962 #ifdef SND_HDA_NEEDS_RESUME
2963 .resume = stac92xx_resume,
2967 static int stac9872_vaio_init(struct hda_codec *codec)
2971 err = stac92xx_init(codec);
2974 if (codec->patch_ops.unsol_event)
2975 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2979 static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
2981 if (get_pin_presence(codec, 0x0a)) {
2982 stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
2983 stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
2985 stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
2986 stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
2990 static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res)
2992 switch (res >> 26) {
2994 stac9872_vaio_hp_detect(codec, res);
2999 static struct hda_codec_ops stac9872_vaio_patch_ops = {
3000 .build_controls = stac92xx_build_controls,
3001 .build_pcms = stac92xx_build_pcms,
3002 .init = stac9872_vaio_init,
3003 .free = stac92xx_free,
3004 .unsol_event = stac9872_vaio_unsol_event,
3006 .resume = stac92xx_resume,
3010 enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */
3012 /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */
3014 /* Unknown. id=0x83847661 and subsys=0x104D1200. */
3016 /* AR Series. id=0x83847664 and subsys=104D1300 */
3021 static const char *stac9872_models[STAC_9872_MODELS] = {
3022 [CXD9872RD_VAIO] = "vaio",
3023 [CXD9872AKD_VAIO] = "vaio-ar",
3026 static struct snd_pci_quirk stac9872_cfg_tbl[] = {
3027 SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
3028 SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
3029 SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
3030 SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO),
3034 static int patch_stac9872(struct hda_codec *codec)
3036 struct sigmatel_spec *spec;
3039 board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
3042 if (board_config < 0)
3043 /* unknown config, let generic-parser do its job... */
3044 return snd_hda_parse_generic_codec(codec);
3046 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3051 switch (board_config) {
3052 case CXD9872RD_VAIO:
3053 case STAC9872AK_VAIO:
3054 case STAC9872K_VAIO:
3055 spec->mixer = vaio_mixer;
3056 spec->init = vaio_init;
3057 spec->multiout.max_channels = 2;
3058 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
3059 spec->multiout.dac_nids = vaio_dacs;
3060 spec->multiout.hp_nid = VAIO_HP_DAC;
3061 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
3062 spec->adc_nids = vaio_adcs;
3063 spec->input_mux = &vaio_mux;
3064 spec->mux_nids = vaio_mux_nids;
3065 codec->patch_ops = stac9872_vaio_patch_ops;
3068 case CXD9872AKD_VAIO:
3069 spec->mixer = vaio_ar_mixer;
3070 spec->init = vaio_ar_init;
3071 spec->multiout.max_channels = 2;
3072 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
3073 spec->multiout.dac_nids = vaio_dacs;
3074 spec->multiout.hp_nid = VAIO_HP_DAC;
3075 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
3076 spec->adc_nids = vaio_adcs;
3077 spec->input_mux = &vaio_mux;
3078 spec->mux_nids = vaio_mux_nids;
3079 codec->patch_ops = stac9872_patch_ops;
3090 struct hda_codec_preset snd_hda_preset_sigmatel[] = {
3091 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
3092 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
3093 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
3094 { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x },
3095 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
3096 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
3097 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
3098 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x },
3099 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x },
3100 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x },
3101 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x },
3102 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x },
3103 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x },
3104 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
3105 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
3106 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
3107 { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x },
3108 { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x },
3109 { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x },
3110 { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x },
3111 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x },
3112 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x },
3113 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x },
3114 { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x },
3115 { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x },
3116 { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x },
3117 { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
3118 { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
3119 { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
3120 /* The following does not take into account .id=0x83847661 when subsys =
3121 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
3122 * currently not fully supported.
3124 { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 },
3125 { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 },
3126 { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 },
3127 { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 },
3128 { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 },
3129 { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 },
3130 { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 },
3131 { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 },
3132 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
3133 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
3134 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },