[ALSA] hda-codec - Re-add quirk support for Dell XPS 1330 and Inspiron 1420
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / sound / pci / hda / patch_sigmatel.c
blob9fae4f1296bb3d0d9afc6fce8c947979d2eec370
1 /*
2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for SigmaTel STAC92xx
6 * Copyright (c) 2005 Embedded Alley Solutions, Inc.
7 * Matt Porter <mporter@embeddedalley.com>
9 * Based on patch_cmedia.c and patch_realtek.c
10 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
12 * This driver is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This driver is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <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
40 enum {
41 STAC_REF,
42 STAC_9200_DELL_D21,
43 STAC_9200_DELL_D22,
44 STAC_9200_DELL_D23,
45 STAC_9200_DELL_M21,
46 STAC_9200_DELL_M22,
47 STAC_9200_DELL_M23,
48 STAC_9200_DELL_M24,
49 STAC_9200_DELL_M25,
50 STAC_9200_DELL_M26,
51 STAC_9200_DELL_M27,
52 STAC_9200_GATEWAY,
53 STAC_9200_MODELS
56 enum {
57 STAC_9205_REF,
58 STAC_9205_DELL_M42,
59 STAC_9205_DELL_M43,
60 STAC_9205_DELL_M44,
61 STAC_9205_MODELS
64 enum {
65 STAC_925x_REF,
66 STAC_M2_2,
67 STAC_MA6,
68 STAC_PA6,
69 STAC_925x_MODELS
72 enum {
73 STAC_D945_REF,
74 STAC_D945GTP3,
75 STAC_D945GTP5,
76 STAC_INTEL_MAC_V1,
77 STAC_INTEL_MAC_V2,
78 STAC_INTEL_MAC_V3,
79 STAC_INTEL_MAC_V4,
80 STAC_INTEL_MAC_V5,
81 /* for backward compatibility */
82 STAC_MACMINI,
83 STAC_MACBOOK,
84 STAC_MACBOOK_PRO_V1,
85 STAC_MACBOOK_PRO_V2,
86 STAC_IMAC_INTEL,
87 STAC_IMAC_INTEL_20,
88 STAC_922X_DELL_D81,
89 STAC_922X_DELL_D82,
90 STAC_922X_DELL_M81,
91 STAC_922X_DELL_M82,
92 STAC_922X_MODELS
95 enum {
96 STAC_D965_REF,
97 STAC_D965_3ST,
98 STAC_D965_5ST,
99 STAC_DELL_3ST,
100 STAC_927X_MODELS
103 struct sigmatel_spec {
104 struct snd_kcontrol_new *mixers[4];
105 unsigned int num_mixers;
107 int board_config;
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;
117 /* playback */
118 struct hda_multi_out multiout;
119 hda_nid_t dac_nids[5];
121 /* capture */
122 hda_nid_t *adc_nids;
123 unsigned int num_adcs;
124 hda_nid_t *mux_nids;
125 unsigned int num_muxes;
126 hda_nid_t *dmic_nids;
127 unsigned int num_dmics;
128 hda_nid_t dmux_nid;
129 hda_nid_t dig_in_nid;
131 /* pin widgets */
132 hda_nid_t *pin_nids;
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;
141 /* capture source */
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];
147 /* i/o switches */
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] = {
163 0x03,
166 static hda_nid_t stac9200_mux_nids[1] = {
167 0x0c,
170 static hda_nid_t stac9200_dac_nids[1] = {
171 0x02,
174 static hda_nid_t stac925x_adc_nids[1] = {
175 0x03,
178 static hda_nid_t stac925x_mux_nids[1] = {
179 0x0f,
182 static hda_nid_t stac925x_dac_nids[1] = {
183 0x02,
186 static hda_nid_t stac925x_dmic_nids[1] = {
187 0x15,
190 static hda_nid_t stac922x_adc_nids[2] = {
191 0x06, 0x07,
194 static hda_nid_t stac922x_mux_nids[2] = {
195 0x12, 0x13,
198 static hda_nid_t stac927x_adc_nids[3] = {
199 0x07, 0x08, 0x09
202 static hda_nid_t stac927x_mux_nids[3] = {
203 0x15, 0x16, 0x17
206 static hda_nid_t stac9205_adc_nids[2] = {
207 0x12, 0x13
210 static hda_nid_t stac9205_mux_nids[2] = {
211 0x19, 0x1a
214 static hda_nid_t stac9205_dmic_nids[2] = {
215 0x17, 0x18,
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,
242 0x21, 0x22,
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;
260 return 0;
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];
287 return 0;
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;
309 return 0;
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])
320 return 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);
330 dac_mode |= 0x40;
331 } else {
332 snd_hda_power_down(codec);
333 dac_mode &= ~0x40;
336 snd_hda_codec_write_cache(codec, codec->afg, 0,
337 kcontrol->private_value >> 16, dac_mode);
339 return 1;
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;
346 uinfo->count = 1;
347 uinfo->value.integer.min = 0;
348 uinfo->value.integer.max = 127;
349 return 0;
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;
356 return 0;
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])
365 return 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);
372 return 1;
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 stac9200_eapd_init[] = {
383 /* set dac0mux for dac converter */
384 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
385 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
389 static struct hda_verb stac925x_core_init[] = {
390 /* set dac0mux for dac converter */
391 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
395 static struct hda_verb stac922x_core_init[] = {
396 /* set master volume and direct control */
397 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
401 static struct hda_verb d965_core_init[] = {
402 /* set master volume and direct control */
403 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
404 /* unmute node 0x1b */
405 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
406 /* select node 0x03 as DAC */
407 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
411 static struct hda_verb stac927x_core_init[] = {
412 /* set master volume and direct control */
413 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
417 static struct hda_verb stac9205_core_init[] = {
418 /* set master volume and direct control */
419 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
423 #define STAC_INPUT_SOURCE(cnt) \
425 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
426 .name = "Input Source", \
427 .count = cnt, \
428 .info = stac92xx_mux_enum_info, \
429 .get = stac92xx_mux_enum_get, \
430 .put = stac92xx_mux_enum_put, \
433 #define STAC_ANALOG_LOOPBACK(verb_read,verb_write) \
435 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
436 .name = "Analog Loopback", \
437 .count = 1, \
438 .info = stac92xx_aloopback_info, \
439 .get = stac92xx_aloopback_get, \
440 .put = stac92xx_aloopback_put, \
441 .private_value = verb_read | (verb_write << 16), \
444 #define STAC_VOLKNOB \
446 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
447 .name = "Master Playback Volume", \
448 .count = 1, \
449 .info = stac92xx_volknob_info, \
450 .get = stac92xx_volknob_get, \
451 .put = stac92xx_volknob_put, \
452 .private_value = 127, \
456 static struct snd_kcontrol_new stac9200_mixer[] = {
457 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
458 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
459 STAC_INPUT_SOURCE(1),
460 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
461 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
462 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT),
463 { } /* end */
466 static struct snd_kcontrol_new stac925x_mixer[] = {
467 STAC_INPUT_SOURCE(1),
468 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
469 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT),
470 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT),
471 { } /* end */
474 static struct snd_kcontrol_new stac9205_mixer[] = {
476 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
477 .name = "Digital Input Source",
478 .count = 1,
479 .info = stac92xx_dmux_enum_info,
480 .get = stac92xx_dmux_enum_get,
481 .put = stac92xx_dmux_enum_put,
483 STAC_INPUT_SOURCE(2),
484 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0),
485 STAC_VOLKNOB,
487 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT),
488 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT),
489 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x19, 0x0, HDA_OUTPUT),
491 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT),
492 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT),
493 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x1A, 0x0, HDA_OUTPUT),
495 { } /* end */
498 /* This needs to be generated dynamically based on sequence */
499 static struct snd_kcontrol_new stac922x_mixer[] = {
500 STAC_INPUT_SOURCE(2),
501 STAC_VOLKNOB,
502 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT),
503 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT),
504 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x12, 0x0, HDA_OUTPUT),
506 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT),
507 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT),
508 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x13, 0x0, HDA_OUTPUT),
509 { } /* end */
513 static struct snd_kcontrol_new stac927x_mixer[] = {
514 STAC_INPUT_SOURCE(3),
515 STAC_VOLKNOB,
516 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB),
518 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT),
519 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT),
520 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x15, 0x0, HDA_OUTPUT),
522 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT),
523 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT),
524 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x16, 0x0, HDA_OUTPUT),
526 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT),
527 HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT),
528 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x2, 0x17, 0x0, HDA_OUTPUT),
529 { } /* end */
532 static int stac92xx_build_controls(struct hda_codec *codec)
534 struct sigmatel_spec *spec = codec->spec;
535 int err;
536 int i;
538 err = snd_hda_add_new_ctls(codec, spec->mixer);
539 if (err < 0)
540 return err;
542 for (i = 0; i < spec->num_mixers; i++) {
543 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
544 if (err < 0)
545 return err;
548 if (spec->multiout.dig_out_nid) {
549 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
550 if (err < 0)
551 return err;
553 if (spec->dig_in_nid) {
554 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
555 if (err < 0)
556 return err;
558 return 0;
561 static unsigned int ref9200_pin_configs[8] = {
562 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
563 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
567 STAC 9200 pin configs for
568 102801A8
569 102801DE
570 102801E8
572 static unsigned int dell9200_d21_pin_configs[8] = {
573 0x400001f0, 0x400001f1, 0x02214030, 0x01014010,
574 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
578 STAC 9200 pin configs for
579 102801C0
580 102801C1
582 static unsigned int dell9200_d22_pin_configs[8] = {
583 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
584 0x01813020, 0x02a19021, 0x90100140, 0x400001f2,
588 STAC 9200 pin configs for
589 102801C4 (Dell Dimension E310)
590 102801C5
591 102801C7
592 102801D9
593 102801DA
594 102801E3
596 static unsigned int dell9200_d23_pin_configs[8] = {
597 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
598 0x01813020, 0x01a19021, 0x90100140, 0x400001f2,
603 STAC 9200-32 pin configs for
604 102801B5 (Dell Inspiron 630m)
605 102801D8 (Dell Inspiron 640m)
607 static unsigned int dell9200_m21_pin_configs[8] = {
608 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310,
609 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd,
613 STAC 9200-32 pin configs for
614 102801C2 (Dell Latitude D620)
615 102801C8
616 102801CC (Dell Latitude D820)
617 102801D4
618 102801D6
620 static unsigned int dell9200_m22_pin_configs[8] = {
621 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310,
622 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc,
626 STAC 9200-32 pin configs for
627 102801CE (Dell XPS M1710)
628 102801CF (Dell Precision M90)
630 static unsigned int dell9200_m23_pin_configs[8] = {
631 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310,
632 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc,
636 STAC 9200-32 pin configs for
637 102801C9
638 102801CA
639 102801CB (Dell Latitude 120L)
640 102801D3
642 static unsigned int dell9200_m24_pin_configs[8] = {
643 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310,
644 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe,
648 STAC 9200-32 pin configs for
649 102801BD (Dell Inspiron E1505n)
650 102801EE
651 102801EF
653 static unsigned int dell9200_m25_pin_configs[8] = {
654 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
655 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd,
659 STAC 9200-32 pin configs for
660 102801F5 (Dell Inspiron 1501)
661 102801F6
663 static unsigned int dell9200_m26_pin_configs[8] = {
664 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310,
665 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe,
669 STAC 9200-32
670 102801CD (Dell Inspiron E1705/9400)
672 static unsigned int dell9200_m27_pin_configs[8] = {
673 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
674 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc,
678 static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
679 [STAC_REF] = ref9200_pin_configs,
680 [STAC_9200_DELL_D21] = dell9200_d21_pin_configs,
681 [STAC_9200_DELL_D22] = dell9200_d22_pin_configs,
682 [STAC_9200_DELL_D23] = dell9200_d23_pin_configs,
683 [STAC_9200_DELL_M21] = dell9200_m21_pin_configs,
684 [STAC_9200_DELL_M22] = dell9200_m22_pin_configs,
685 [STAC_9200_DELL_M23] = dell9200_m23_pin_configs,
686 [STAC_9200_DELL_M24] = dell9200_m24_pin_configs,
687 [STAC_9200_DELL_M25] = dell9200_m25_pin_configs,
688 [STAC_9200_DELL_M26] = dell9200_m26_pin_configs,
689 [STAC_9200_DELL_M27] = dell9200_m27_pin_configs,
692 static const char *stac9200_models[STAC_9200_MODELS] = {
693 [STAC_REF] = "ref",
694 [STAC_9200_DELL_D21] = "dell-d21",
695 [STAC_9200_DELL_D22] = "dell-d22",
696 [STAC_9200_DELL_D23] = "dell-d23",
697 [STAC_9200_DELL_M21] = "dell-m21",
698 [STAC_9200_DELL_M22] = "dell-m22",
699 [STAC_9200_DELL_M23] = "dell-m23",
700 [STAC_9200_DELL_M24] = "dell-m24",
701 [STAC_9200_DELL_M25] = "dell-m25",
702 [STAC_9200_DELL_M26] = "dell-m26",
703 [STAC_9200_DELL_M27] = "dell-m27",
704 [STAC_9200_GATEWAY] = "gateway",
707 static struct snd_pci_quirk stac9200_cfg_tbl[] = {
708 /* SigmaTel reference board */
709 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
710 "DFI LanParty", STAC_REF),
711 /* Dell laptops have BIOS problem */
712 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
713 "unknown Dell", STAC_9200_DELL_D21),
714 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
715 "Dell Inspiron 630m", STAC_9200_DELL_M21),
716 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
717 "Dell Inspiron E1505n", STAC_9200_DELL_M25),
718 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
719 "unknown Dell", STAC_9200_DELL_D22),
720 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
721 "unknown Dell", STAC_9200_DELL_D22),
722 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
723 "Dell Latitude D620", STAC_9200_DELL_M22),
724 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
725 "unknown Dell", STAC_9200_DELL_D23),
726 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
727 "unknown Dell", STAC_9200_DELL_D23),
728 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
729 "unknown Dell", STAC_9200_DELL_M22),
730 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
731 "unknown Dell", STAC_9200_DELL_M24),
732 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
733 "unknown Dell", STAC_9200_DELL_M24),
734 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
735 "Dell Latitude 120L", STAC_9200_DELL_M24),
736 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
737 "Dell Latitude D820", STAC_9200_DELL_M22),
738 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
739 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
740 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
741 "Dell XPS M1710", STAC_9200_DELL_M23),
742 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
743 "Dell Precision M90", STAC_9200_DELL_M23),
744 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
745 "unknown Dell", STAC_9200_DELL_M22),
746 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
747 "unknown Dell", STAC_9200_DELL_M22),
748 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
749 "unknown Dell", STAC_9200_DELL_M22),
750 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
751 "Dell Inspiron 640m", STAC_9200_DELL_M21),
752 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
753 "unknown Dell", STAC_9200_DELL_D23),
754 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
755 "unknown Dell", STAC_9200_DELL_D23),
756 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
757 "unknown Dell", STAC_9200_DELL_D21),
758 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
759 "unknown Dell", STAC_9200_DELL_D23),
760 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
761 "unknown Dell", STAC_9200_DELL_D21),
762 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
763 "unknown Dell", STAC_9200_DELL_M25),
764 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
765 "unknown Dell", STAC_9200_DELL_M25),
766 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
767 "Dell Inspiron 1501", STAC_9200_DELL_M26),
768 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
769 "unknown Dell", STAC_9200_DELL_M26),
770 /* Panasonic */
771 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_REF),
772 /* Gateway machines needs EAPD to be set on resume */
773 SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY),
774 SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*",
775 STAC_9200_GATEWAY),
776 SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707",
777 STAC_9200_GATEWAY),
778 {} /* terminator */
781 static unsigned int ref925x_pin_configs[8] = {
782 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
783 0x90a70320, 0x02214210, 0x400003f1, 0x9033032e,
786 static unsigned int stac925x_MA6_pin_configs[8] = {
787 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
788 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e,
791 static unsigned int stac925x_PA6_pin_configs[8] = {
792 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
793 0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e,
796 static unsigned int stac925xM2_2_pin_configs[8] = {
797 0x40c003f3, 0x424503f2, 0x04180011, 0x02a19020,
798 0x50a103f0, 0x90100212, 0x400003f1, 0x9033032e,
801 static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
802 [STAC_REF] = ref925x_pin_configs,
803 [STAC_M2_2] = stac925xM2_2_pin_configs,
804 [STAC_MA6] = stac925x_MA6_pin_configs,
805 [STAC_PA6] = stac925x_PA6_pin_configs,
808 static const char *stac925x_models[STAC_925x_MODELS] = {
809 [STAC_REF] = "ref",
810 [STAC_M2_2] = "m2-2",
811 [STAC_MA6] = "m6",
812 [STAC_PA6] = "pa6",
815 static struct snd_pci_quirk stac925x_cfg_tbl[] = {
816 /* SigmaTel reference board */
817 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
818 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
819 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF),
820 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF),
821 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6),
822 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_PA6),
823 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2),
824 {} /* terminator */
827 static unsigned int ref922x_pin_configs[10] = {
828 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
829 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
830 0x40000100, 0x40000100,
834 STAC 922X pin configs for
835 102801A7
836 102801AB
837 102801A9
838 102801D1
839 102801D2
841 static unsigned int dell_922x_d81_pin_configs[10] = {
842 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
843 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1,
844 0x01813122, 0x400001f2,
848 STAC 922X pin configs for
849 102801AC
850 102801D0
852 static unsigned int dell_922x_d82_pin_configs[10] = {
853 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
854 0x02a19020, 0x01117011, 0x01451140, 0x400001f0,
855 0x01813122, 0x400001f1,
859 STAC 922X pin configs for
860 102801BF
862 static unsigned int dell_922x_m81_pin_configs[10] = {
863 0x0321101f, 0x01112024, 0x01111222, 0x91174220,
864 0x03a11050, 0x01116221, 0x90a70330, 0x01452340,
865 0x40C003f1, 0x405003f0,
869 STAC 9221 A1 pin configs for
870 102801D7 (Dell XPS M1210)
872 static unsigned int dell_922x_m82_pin_configs[10] = {
873 0x0221121f, 0x408103ff, 0x02111212, 0x90100310,
874 0x408003f1, 0x02111211, 0x03451340, 0x40c003f2,
875 0x508003f3, 0x405003f4,
878 static unsigned int d945gtp3_pin_configs[10] = {
879 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
880 0x40000100, 0x40000100, 0x40000100, 0x40000100,
881 0x02a19120, 0x40000100,
884 static unsigned int d945gtp5_pin_configs[10] = {
885 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
886 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
887 0x02a19320, 0x40000100,
890 static unsigned int intel_mac_v1_pin_configs[10] = {
891 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd,
892 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240,
893 0x400000fc, 0x400000fb,
896 static unsigned int intel_mac_v2_pin_configs[10] = {
897 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
898 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa,
899 0x400000fc, 0x400000fb,
902 static unsigned int intel_mac_v3_pin_configs[10] = {
903 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
904 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240,
905 0x400000fc, 0x400000fb,
908 static unsigned int intel_mac_v4_pin_configs[10] = {
909 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
910 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
911 0x400000fc, 0x400000fb,
914 static unsigned int intel_mac_v5_pin_configs[10] = {
915 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
916 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
917 0x400000fc, 0x400000fb,
921 static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
922 [STAC_D945_REF] = ref922x_pin_configs,
923 [STAC_D945GTP3] = d945gtp3_pin_configs,
924 [STAC_D945GTP5] = d945gtp5_pin_configs,
925 [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs,
926 [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs,
927 [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs,
928 [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs,
929 [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs,
930 /* for backward compatibility */
931 [STAC_MACMINI] = intel_mac_v3_pin_configs,
932 [STAC_MACBOOK] = intel_mac_v5_pin_configs,
933 [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs,
934 [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs,
935 [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs,
936 [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs,
937 [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs,
938 [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs,
939 [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs,
940 [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs,
943 static const char *stac922x_models[STAC_922X_MODELS] = {
944 [STAC_D945_REF] = "ref",
945 [STAC_D945GTP5] = "5stack",
946 [STAC_D945GTP3] = "3stack",
947 [STAC_INTEL_MAC_V1] = "intel-mac-v1",
948 [STAC_INTEL_MAC_V2] = "intel-mac-v2",
949 [STAC_INTEL_MAC_V3] = "intel-mac-v3",
950 [STAC_INTEL_MAC_V4] = "intel-mac-v4",
951 [STAC_INTEL_MAC_V5] = "intel-mac-v5",
952 /* for backward compatibility */
953 [STAC_MACMINI] = "macmini",
954 [STAC_MACBOOK] = "macbook",
955 [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1",
956 [STAC_MACBOOK_PRO_V2] = "macbook-pro",
957 [STAC_IMAC_INTEL] = "imac-intel",
958 [STAC_IMAC_INTEL_20] = "imac-intel-20",
959 [STAC_922X_DELL_D81] = "dell-d81",
960 [STAC_922X_DELL_D82] = "dell-d82",
961 [STAC_922X_DELL_M81] = "dell-m81",
962 [STAC_922X_DELL_M82] = "dell-m82",
965 static struct snd_pci_quirk stac922x_cfg_tbl[] = {
966 /* SigmaTel reference board */
967 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
968 "DFI LanParty", STAC_D945_REF),
969 /* Intel 945G based systems */
970 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
971 "Intel D945G", STAC_D945GTP3),
972 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
973 "Intel D945G", STAC_D945GTP3),
974 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
975 "Intel D945G", STAC_D945GTP3),
976 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
977 "Intel D945G", STAC_D945GTP3),
978 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
979 "Intel D945G", STAC_D945GTP3),
980 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
981 "Intel D945G", STAC_D945GTP3),
982 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
983 "Intel D945G", STAC_D945GTP3),
984 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
985 "Intel D945G", STAC_D945GTP3),
986 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
987 "Intel D945G", STAC_D945GTP3),
988 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
989 "Intel D945G", STAC_D945GTP3),
990 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
991 "Intel D945G", STAC_D945GTP3),
992 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
993 "Intel D945G", STAC_D945GTP3),
994 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
995 "Intel D945G", STAC_D945GTP3),
996 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
997 "Intel D945G", STAC_D945GTP3),
998 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
999 "Intel D945G", STAC_D945GTP3),
1000 /* Intel D945G 5-stack systems */
1001 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
1002 "Intel D945G", STAC_D945GTP5),
1003 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
1004 "Intel D945G", STAC_D945GTP5),
1005 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
1006 "Intel D945G", STAC_D945GTP5),
1007 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
1008 "Intel D945G", STAC_D945GTP5),
1009 /* Intel 945P based systems */
1010 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
1011 "Intel D945P", STAC_D945GTP3),
1012 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
1013 "Intel D945P", STAC_D945GTP3),
1014 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
1015 "Intel D945P", STAC_D945GTP3),
1016 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
1017 "Intel D945P", STAC_D945GTP3),
1018 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
1019 "Intel D945P", STAC_D945GTP3),
1020 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
1021 "Intel D945P", STAC_D945GTP5),
1022 /* other systems */
1023 /* Apple Mac Mini (early 2006) */
1024 SND_PCI_QUIRK(0x8384, 0x7680,
1025 "Mac Mini", STAC_INTEL_MAC_V3),
1026 /* Dell systems */
1027 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
1028 "unknown Dell", STAC_922X_DELL_D81),
1029 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
1030 "unknown Dell", STAC_922X_DELL_D81),
1031 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
1032 "unknown Dell", STAC_922X_DELL_D81),
1033 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
1034 "unknown Dell", STAC_922X_DELL_D82),
1035 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
1036 "unknown Dell", STAC_922X_DELL_M81),
1037 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
1038 "unknown Dell", STAC_922X_DELL_D82),
1039 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
1040 "unknown Dell", STAC_922X_DELL_D81),
1041 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
1042 "unknown Dell", STAC_922X_DELL_D81),
1043 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
1044 "Dell XPS M1210", STAC_922X_DELL_M82),
1045 {} /* terminator */
1048 static unsigned int ref927x_pin_configs[14] = {
1049 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1050 0x01a19040, 0x01011012, 0x01016011, 0x0101201f,
1051 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070,
1052 0x01c42190, 0x40000100,
1055 static unsigned int d965_3st_pin_configs[14] = {
1056 0x0221401f, 0x02a19120, 0x40000100, 0x01014011,
1057 0x01a19021, 0x01813024, 0x40000100, 0x40000100,
1058 0x40000100, 0x40000100, 0x40000100, 0x40000100,
1059 0x40000100, 0x40000100
1062 static unsigned int d965_5st_pin_configs[14] = {
1063 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1064 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
1065 0x40000100, 0x40000100, 0x40000100, 0x01442070,
1066 0x40000100, 0x40000100
1069 static unsigned int dell_3st_pin_configs[14] = {
1070 0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
1071 0x01111212, 0x01116211, 0x01813050, 0x01112214,
1072 0x403003fa, 0x40000100, 0x40000100, 0x404003fb,
1073 0x40c003fc, 0x40000100
1076 static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
1077 [STAC_D965_REF] = ref927x_pin_configs,
1078 [STAC_D965_3ST] = d965_3st_pin_configs,
1079 [STAC_D965_5ST] = d965_5st_pin_configs,
1080 [STAC_DELL_3ST] = dell_3st_pin_configs,
1083 static const char *stac927x_models[STAC_927X_MODELS] = {
1084 [STAC_D965_REF] = "ref",
1085 [STAC_D965_3ST] = "3stack",
1086 [STAC_D965_5ST] = "5stack",
1087 [STAC_DELL_3ST] = "dell-3stack",
1090 static struct snd_pci_quirk stac927x_cfg_tbl[] = {
1091 /* SigmaTel reference board */
1092 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1093 "DFI LanParty", STAC_D965_REF),
1094 /* Intel 946 based systems */
1095 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
1096 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
1097 /* 965 based 3 stack systems */
1098 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2116, "Intel D965", STAC_D965_3ST),
1099 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2115, "Intel D965", STAC_D965_3ST),
1100 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2114, "Intel D965", STAC_D965_3ST),
1101 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2113, "Intel D965", STAC_D965_3ST),
1102 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2112, "Intel D965", STAC_D965_3ST),
1103 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2111, "Intel D965", STAC_D965_3ST),
1104 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2110, "Intel D965", STAC_D965_3ST),
1105 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2009, "Intel D965", STAC_D965_3ST),
1106 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2008, "Intel D965", STAC_D965_3ST),
1107 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2007, "Intel D965", STAC_D965_3ST),
1108 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2006, "Intel D965", STAC_D965_3ST),
1109 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2005, "Intel D965", STAC_D965_3ST),
1110 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2004, "Intel D965", STAC_D965_3ST),
1111 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST),
1112 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST),
1113 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST),
1114 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_D965_3ST),
1115 /* Dell 3 stack systems */
1116 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
1117 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
1118 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
1119 /* 965 based 5 stack systems */
1120 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_D965_5ST),
1121 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST),
1122 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST),
1123 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST),
1124 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2304, "Intel D965", STAC_D965_5ST),
1125 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2305, "Intel D965", STAC_D965_5ST),
1126 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2501, "Intel D965", STAC_D965_5ST),
1127 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2502, "Intel D965", STAC_D965_5ST),
1128 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2503, "Intel D965", STAC_D965_5ST),
1129 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2504, "Intel D965", STAC_D965_5ST),
1130 {} /* terminator */
1133 static unsigned int ref9205_pin_configs[12] = {
1134 0x40000100, 0x40000100, 0x01016011, 0x01014010,
1135 0x01813122, 0x01a19021, 0x40000100, 0x40000100,
1136 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
1140 STAC 9205 pin configs for
1141 102801F1
1142 102801F2
1143 102801FC
1144 102801FD
1145 10280204
1146 1028021F
1148 static unsigned int dell_9205_m42_pin_configs[12] = {
1149 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310,
1150 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9,
1151 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE,
1155 STAC 9205 pin configs for
1156 102801F9
1157 102801FA
1158 102801FE
1159 102801FF (Dell Precision M4300)
1160 10280206
1161 10280200
1162 10280201
1164 static unsigned int dell_9205_m43_pin_configs[12] = {
1165 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310,
1166 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9,
1167 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8,
1170 static unsigned int dell_9205_m44_pin_configs[12] = {
1171 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310,
1172 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9,
1173 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe,
1176 static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
1177 [STAC_9205_REF] = ref9205_pin_configs,
1178 [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs,
1179 [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs,
1180 [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs,
1183 static const char *stac9205_models[STAC_9205_MODELS] = {
1184 [STAC_9205_REF] = "ref",
1185 [STAC_9205_DELL_M42] = "dell-m42",
1186 [STAC_9205_DELL_M43] = "dell-m43",
1187 [STAC_9205_DELL_M44] = "dell-m44",
1190 static struct snd_pci_quirk stac9205_cfg_tbl[] = {
1191 /* SigmaTel reference board */
1192 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1193 "DFI LanParty", STAC_9205_REF),
1194 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1195 "unknown Dell", STAC_9205_DELL_M42),
1196 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1197 "unknown Dell", STAC_9205_DELL_M42),
1198 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
1199 "Dell Precision", STAC_9205_DELL_M43),
1200 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
1201 "Dell Precision", STAC_9205_DELL_M43),
1202 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
1203 "Dell Precision", STAC_9205_DELL_M43),
1204 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
1205 "Dell Precision", STAC_9205_DELL_M43),
1206 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
1207 "Dell Precision", STAC_9205_DELL_M43),
1208 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1209 "unknown Dell", STAC_9205_DELL_M42),
1210 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1211 "unknown Dell", STAC_9205_DELL_M42),
1212 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
1213 "Dell Precision", STAC_9205_DELL_M43),
1214 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
1215 "Dell Precision M4300", STAC_9205_DELL_M43),
1216 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
1217 "Dell Precision", STAC_9205_DELL_M43),
1218 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1219 "Dell Inspiron", STAC_9205_DELL_M44),
1220 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1221 "Dell Inspiron", STAC_9205_DELL_M44),
1222 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1223 "Dell Inspiron", STAC_9205_DELL_M44),
1224 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1225 "Dell Inspiron", STAC_9205_DELL_M44),
1226 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
1227 "unknown Dell", STAC_9205_DELL_M42),
1228 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
1229 "Dell Inspiron", STAC_9205_DELL_M44),
1230 {} /* terminator */
1233 static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
1235 int i;
1236 struct sigmatel_spec *spec = codec->spec;
1238 if (! spec->bios_pin_configs) {
1239 spec->bios_pin_configs = kcalloc(spec->num_pins,
1240 sizeof(*spec->bios_pin_configs), GFP_KERNEL);
1241 if (! spec->bios_pin_configs)
1242 return -ENOMEM;
1245 for (i = 0; i < spec->num_pins; i++) {
1246 hda_nid_t nid = spec->pin_nids[i];
1247 unsigned int pin_cfg;
1249 pin_cfg = snd_hda_codec_read(codec, nid, 0,
1250 AC_VERB_GET_CONFIG_DEFAULT, 0x00);
1251 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n",
1252 nid, pin_cfg);
1253 spec->bios_pin_configs[i] = pin_cfg;
1256 return 0;
1259 static void stac92xx_set_config_reg(struct hda_codec *codec,
1260 hda_nid_t pin_nid, unsigned int pin_config)
1262 int i;
1263 snd_hda_codec_write(codec, pin_nid, 0,
1264 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
1265 pin_config & 0x000000ff);
1266 snd_hda_codec_write(codec, pin_nid, 0,
1267 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
1268 (pin_config & 0x0000ff00) >> 8);
1269 snd_hda_codec_write(codec, pin_nid, 0,
1270 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
1271 (pin_config & 0x00ff0000) >> 16);
1272 snd_hda_codec_write(codec, pin_nid, 0,
1273 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
1274 pin_config >> 24);
1275 i = snd_hda_codec_read(codec, pin_nid, 0,
1276 AC_VERB_GET_CONFIG_DEFAULT,
1277 0x00);
1278 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n",
1279 pin_nid, i);
1282 static void stac92xx_set_config_regs(struct hda_codec *codec)
1284 int i;
1285 struct sigmatel_spec *spec = codec->spec;
1287 if (!spec->pin_configs)
1288 return;
1290 for (i = 0; i < spec->num_pins; i++)
1291 stac92xx_set_config_reg(codec, spec->pin_nids[i],
1292 spec->pin_configs[i]);
1295 static void stac92xx_enable_gpio_mask(struct hda_codec *codec)
1297 struct sigmatel_spec *spec = codec->spec;
1298 /* Configure GPIOx as output */
1299 snd_hda_codec_write_cache(codec, codec->afg, 0,
1300 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_mask);
1301 /* Configure GPIOx as CMOS */
1302 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7e7, 0x00000000);
1303 /* Assert GPIOx */
1304 snd_hda_codec_write_cache(codec, codec->afg, 0,
1305 AC_VERB_SET_GPIO_DATA, spec->gpio_data);
1306 /* Enable GPIOx */
1307 snd_hda_codec_write_cache(codec, codec->afg, 0,
1308 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
1312 * Analog playback callbacks
1314 static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
1315 struct hda_codec *codec,
1316 struct snd_pcm_substream *substream)
1318 struct sigmatel_spec *spec = codec->spec;
1319 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
1322 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1323 struct hda_codec *codec,
1324 unsigned int stream_tag,
1325 unsigned int format,
1326 struct snd_pcm_substream *substream)
1328 struct sigmatel_spec *spec = codec->spec;
1329 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream);
1332 static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1333 struct hda_codec *codec,
1334 struct snd_pcm_substream *substream)
1336 struct sigmatel_spec *spec = codec->spec;
1337 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1341 * Digital playback callbacks
1343 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1344 struct hda_codec *codec,
1345 struct snd_pcm_substream *substream)
1347 struct sigmatel_spec *spec = codec->spec;
1348 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1351 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1352 struct hda_codec *codec,
1353 struct snd_pcm_substream *substream)
1355 struct sigmatel_spec *spec = codec->spec;
1356 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1359 static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1360 struct hda_codec *codec,
1361 unsigned int stream_tag,
1362 unsigned int format,
1363 struct snd_pcm_substream *substream)
1365 struct sigmatel_spec *spec = codec->spec;
1366 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1367 stream_tag, format, substream);
1372 * Analog capture callbacks
1374 static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1375 struct hda_codec *codec,
1376 unsigned int stream_tag,
1377 unsigned int format,
1378 struct snd_pcm_substream *substream)
1380 struct sigmatel_spec *spec = codec->spec;
1382 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1383 stream_tag, 0, format);
1384 return 0;
1387 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1388 struct hda_codec *codec,
1389 struct snd_pcm_substream *substream)
1391 struct sigmatel_spec *spec = codec->spec;
1393 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
1394 return 0;
1397 static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
1398 .substreams = 1,
1399 .channels_min = 2,
1400 .channels_max = 2,
1401 /* NID is set in stac92xx_build_pcms */
1402 .ops = {
1403 .open = stac92xx_dig_playback_pcm_open,
1404 .close = stac92xx_dig_playback_pcm_close,
1405 .prepare = stac92xx_dig_playback_pcm_prepare
1409 static struct hda_pcm_stream stac92xx_pcm_digital_capture = {
1410 .substreams = 1,
1411 .channels_min = 2,
1412 .channels_max = 2,
1413 /* NID is set in stac92xx_build_pcms */
1416 static struct hda_pcm_stream stac92xx_pcm_analog_playback = {
1417 .substreams = 1,
1418 .channels_min = 2,
1419 .channels_max = 8,
1420 .nid = 0x02, /* NID to query formats and rates */
1421 .ops = {
1422 .open = stac92xx_playback_pcm_open,
1423 .prepare = stac92xx_playback_pcm_prepare,
1424 .cleanup = stac92xx_playback_pcm_cleanup
1428 static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
1429 .substreams = 1,
1430 .channels_min = 2,
1431 .channels_max = 2,
1432 .nid = 0x06, /* NID to query formats and rates */
1433 .ops = {
1434 .open = stac92xx_playback_pcm_open,
1435 .prepare = stac92xx_playback_pcm_prepare,
1436 .cleanup = stac92xx_playback_pcm_cleanup
1440 static struct hda_pcm_stream stac92xx_pcm_analog_capture = {
1441 .channels_min = 2,
1442 .channels_max = 2,
1443 /* NID + .substreams is set in stac92xx_build_pcms */
1444 .ops = {
1445 .prepare = stac92xx_capture_pcm_prepare,
1446 .cleanup = stac92xx_capture_pcm_cleanup
1450 static int stac92xx_build_pcms(struct hda_codec *codec)
1452 struct sigmatel_spec *spec = codec->spec;
1453 struct hda_pcm *info = spec->pcm_rec;
1455 codec->num_pcms = 1;
1456 codec->pcm_info = info;
1458 info->name = "STAC92xx Analog";
1459 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
1460 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
1461 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1462 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs;
1464 if (spec->alt_switch) {
1465 codec->num_pcms++;
1466 info++;
1467 info->name = "STAC92xx Analog Alt";
1468 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback;
1471 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1472 codec->num_pcms++;
1473 info++;
1474 info->name = "STAC92xx Digital";
1475 if (spec->multiout.dig_out_nid) {
1476 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
1477 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
1479 if (spec->dig_in_nid) {
1480 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture;
1481 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
1485 return 0;
1488 static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
1490 unsigned int pincap = snd_hda_param_read(codec, nid,
1491 AC_PAR_PIN_CAP);
1492 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
1493 if (pincap & AC_PINCAP_VREF_100)
1494 return AC_PINCTL_VREF_100;
1495 if (pincap & AC_PINCAP_VREF_80)
1496 return AC_PINCTL_VREF_80;
1497 if (pincap & AC_PINCAP_VREF_50)
1498 return AC_PINCTL_VREF_50;
1499 if (pincap & AC_PINCAP_VREF_GRD)
1500 return AC_PINCTL_VREF_GRD;
1501 return 0;
1504 static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
1507 snd_hda_codec_write_cache(codec, nid, 0,
1508 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
1511 #define stac92xx_io_switch_info snd_ctl_boolean_mono_info
1513 static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1515 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1516 struct sigmatel_spec *spec = codec->spec;
1517 int io_idx = kcontrol-> private_value & 0xff;
1519 ucontrol->value.integer.value[0] = spec->io_switch[io_idx];
1520 return 0;
1523 static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1525 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1526 struct sigmatel_spec *spec = codec->spec;
1527 hda_nid_t nid = kcontrol->private_value >> 8;
1528 int io_idx = kcontrol-> private_value & 0xff;
1529 unsigned short val = ucontrol->value.integer.value[0];
1531 spec->io_switch[io_idx] = val;
1533 if (val)
1534 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
1535 else {
1536 unsigned int pinctl = AC_PINCTL_IN_EN;
1537 if (io_idx) /* set VREF for mic */
1538 pinctl |= stac92xx_get_vref(codec, nid);
1539 stac92xx_auto_set_pinctl(codec, nid, pinctl);
1541 return 1;
1544 #define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info
1546 static int stac92xx_clfe_switch_get(struct snd_kcontrol *kcontrol,
1547 struct snd_ctl_elem_value *ucontrol)
1549 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1550 struct sigmatel_spec *spec = codec->spec;
1552 ucontrol->value.integer.value[0] = spec->clfe_swap;
1553 return 0;
1556 static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
1557 struct snd_ctl_elem_value *ucontrol)
1559 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1560 struct sigmatel_spec *spec = codec->spec;
1561 hda_nid_t nid = kcontrol->private_value & 0xff;
1563 if (spec->clfe_swap == ucontrol->value.integer.value[0])
1564 return 0;
1566 spec->clfe_swap = ucontrol->value.integer.value[0];
1568 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1569 spec->clfe_swap ? 0x4 : 0x0);
1571 return 1;
1574 #define STAC_CODEC_IO_SWITCH(xname, xpval) \
1575 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1576 .name = xname, \
1577 .index = 0, \
1578 .info = stac92xx_io_switch_info, \
1579 .get = stac92xx_io_switch_get, \
1580 .put = stac92xx_io_switch_put, \
1581 .private_value = xpval, \
1584 #define STAC_CODEC_CLFE_SWITCH(xname, xpval) \
1585 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1586 .name = xname, \
1587 .index = 0, \
1588 .info = stac92xx_clfe_switch_info, \
1589 .get = stac92xx_clfe_switch_get, \
1590 .put = stac92xx_clfe_switch_put, \
1591 .private_value = xpval, \
1594 enum {
1595 STAC_CTL_WIDGET_VOL,
1596 STAC_CTL_WIDGET_MUTE,
1597 STAC_CTL_WIDGET_IO_SWITCH,
1598 STAC_CTL_WIDGET_CLFE_SWITCH
1601 static struct snd_kcontrol_new stac92xx_control_templates[] = {
1602 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
1603 HDA_CODEC_MUTE(NULL, 0, 0, 0),
1604 STAC_CODEC_IO_SWITCH(NULL, 0),
1605 STAC_CODEC_CLFE_SWITCH(NULL, 0),
1608 /* add dynamic controls */
1609 static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val)
1611 struct snd_kcontrol_new *knew;
1613 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
1614 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
1616 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
1617 if (! knew)
1618 return -ENOMEM;
1619 if (spec->kctl_alloc) {
1620 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
1621 kfree(spec->kctl_alloc);
1623 spec->kctl_alloc = knew;
1624 spec->num_kctl_alloc = num;
1627 knew = &spec->kctl_alloc[spec->num_kctl_used];
1628 *knew = stac92xx_control_templates[type];
1629 knew->name = kstrdup(name, GFP_KERNEL);
1630 if (! knew->name)
1631 return -ENOMEM;
1632 knew->private_value = val;
1633 spec->num_kctl_used++;
1634 return 0;
1637 /* flag inputs as additional dynamic lineouts */
1638 static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
1640 struct sigmatel_spec *spec = codec->spec;
1641 unsigned int wcaps, wtype;
1642 int i, num_dacs = 0;
1644 /* use the wcaps cache to count all DACs available for line-outs */
1645 for (i = 0; i < codec->num_nodes; i++) {
1646 wcaps = codec->wcaps[i];
1647 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
1648 if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL))
1649 num_dacs++;
1652 snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
1654 switch (cfg->line_outs) {
1655 case 3:
1656 /* add line-in as side */
1657 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
1658 cfg->line_out_pins[cfg->line_outs] =
1659 cfg->input_pins[AUTO_PIN_LINE];
1660 spec->line_switch = 1;
1661 cfg->line_outs++;
1663 break;
1664 case 2:
1665 /* add line-in as clfe and mic as side */
1666 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
1667 cfg->line_out_pins[cfg->line_outs] =
1668 cfg->input_pins[AUTO_PIN_LINE];
1669 spec->line_switch = 1;
1670 cfg->line_outs++;
1672 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
1673 cfg->line_out_pins[cfg->line_outs] =
1674 cfg->input_pins[AUTO_PIN_MIC];
1675 spec->mic_switch = 1;
1676 cfg->line_outs++;
1678 break;
1679 case 1:
1680 /* add line-in as surr and mic as clfe */
1681 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
1682 cfg->line_out_pins[cfg->line_outs] =
1683 cfg->input_pins[AUTO_PIN_LINE];
1684 spec->line_switch = 1;
1685 cfg->line_outs++;
1687 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
1688 cfg->line_out_pins[cfg->line_outs] =
1689 cfg->input_pins[AUTO_PIN_MIC];
1690 spec->mic_switch = 1;
1691 cfg->line_outs++;
1693 break;
1696 return 0;
1700 static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
1702 int i;
1704 for (i = 0; i < spec->multiout.num_dacs; i++) {
1705 if (spec->multiout.dac_nids[i] == nid)
1706 return 1;
1709 return 0;
1713 * Fill in the dac_nids table from the parsed pin configuration
1714 * This function only works when every pin in line_out_pins[]
1715 * contains atleast one DAC in its connection list. Some 92xx
1716 * codecs are not connected directly to a DAC, such as the 9200
1717 * and 9202/925x. For those, dac_nids[] must be hard-coded.
1719 static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
1720 struct auto_pin_cfg *cfg)
1722 struct sigmatel_spec *spec = codec->spec;
1723 int i, j, conn_len = 0;
1724 hda_nid_t nid, conn[HDA_MAX_CONNECTIONS];
1725 unsigned int wcaps, wtype;
1727 for (i = 0; i < cfg->line_outs; i++) {
1728 nid = cfg->line_out_pins[i];
1729 conn_len = snd_hda_get_connections(codec, nid, conn,
1730 HDA_MAX_CONNECTIONS);
1731 for (j = 0; j < conn_len; j++) {
1732 wcaps = snd_hda_param_read(codec, conn[j],
1733 AC_PAR_AUDIO_WIDGET_CAP);
1734 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
1736 if (wtype != AC_WID_AUD_OUT ||
1737 (wcaps & AC_WCAP_DIGITAL))
1738 continue;
1739 /* conn[j] is a DAC routed to this line-out */
1740 if (!is_in_dac_nids(spec, conn[j]))
1741 break;
1744 if (j == conn_len) {
1745 if (spec->multiout.num_dacs > 0) {
1746 /* we have already working output pins,
1747 * so let's drop the broken ones again
1749 cfg->line_outs = spec->multiout.num_dacs;
1750 break;
1752 /* error out, no available DAC found */
1753 snd_printk(KERN_ERR
1754 "%s: No available DAC for pin 0x%x\n",
1755 __func__, nid);
1756 return -ENODEV;
1759 spec->multiout.dac_nids[i] = conn[j];
1760 spec->multiout.num_dacs++;
1761 if (conn_len > 1) {
1762 /* select this DAC in the pin's input mux */
1763 snd_hda_codec_write_cache(codec, nid, 0,
1764 AC_VERB_SET_CONNECT_SEL, j);
1769 snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
1770 spec->multiout.num_dacs,
1771 spec->multiout.dac_nids[0],
1772 spec->multiout.dac_nids[1],
1773 spec->multiout.dac_nids[2],
1774 spec->multiout.dac_nids[3],
1775 spec->multiout.dac_nids[4]);
1776 return 0;
1779 /* create volume control/switch for the given prefx type */
1780 static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_t nid, int chs)
1782 char name[32];
1783 int err;
1785 sprintf(name, "%s Playback Volume", pfx);
1786 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name,
1787 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1788 if (err < 0)
1789 return err;
1790 sprintf(name, "%s Playback Switch", pfx);
1791 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name,
1792 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1793 if (err < 0)
1794 return err;
1795 return 0;
1798 /* add playback controls from the parsed DAC table */
1799 static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
1800 const struct auto_pin_cfg *cfg)
1802 static const char *chname[4] = {
1803 "Front", "Surround", NULL /*CLFE*/, "Side"
1805 hda_nid_t nid;
1806 int i, err;
1808 struct sigmatel_spec *spec = codec->spec;
1809 unsigned int wid_caps;
1812 for (i = 0; i < cfg->line_outs; i++) {
1813 if (!spec->multiout.dac_nids[i])
1814 continue;
1816 nid = spec->multiout.dac_nids[i];
1818 if (i == 2) {
1819 /* Center/LFE */
1820 err = create_controls(spec, "Center", nid, 1);
1821 if (err < 0)
1822 return err;
1823 err = create_controls(spec, "LFE", nid, 2);
1824 if (err < 0)
1825 return err;
1827 wid_caps = get_wcaps(codec, nid);
1829 if (wid_caps & AC_WCAP_LR_SWAP) {
1830 err = stac92xx_add_control(spec,
1831 STAC_CTL_WIDGET_CLFE_SWITCH,
1832 "Swap Center/LFE Playback Switch", nid);
1834 if (err < 0)
1835 return err;
1838 } else {
1839 err = create_controls(spec, chname[i], nid, 3);
1840 if (err < 0)
1841 return err;
1845 if (spec->line_switch)
1846 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Line In as Output Switch", cfg->input_pins[AUTO_PIN_LINE] << 8)) < 0)
1847 return err;
1849 if (spec->mic_switch)
1850 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Mic as Output Switch", (cfg->input_pins[AUTO_PIN_MIC] << 8) | 1)) < 0)
1851 return err;
1853 return 0;
1856 static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
1858 if (is_in_dac_nids(spec, nid))
1859 return 1;
1860 if (spec->multiout.hp_nid == nid)
1861 return 1;
1862 return 0;
1865 static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
1867 if (!spec->multiout.hp_nid)
1868 spec->multiout.hp_nid = nid;
1869 else if (spec->multiout.num_dacs > 4) {
1870 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
1871 return 1;
1872 } else {
1873 spec->multiout.dac_nids[spec->multiout.num_dacs] = nid;
1874 spec->multiout.num_dacs++;
1876 return 0;
1879 /* add playback controls for Speaker and HP outputs */
1880 static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
1881 struct auto_pin_cfg *cfg)
1883 struct sigmatel_spec *spec = codec->spec;
1884 hda_nid_t nid;
1885 int i, old_num_dacs, err;
1887 old_num_dacs = spec->multiout.num_dacs;
1888 for (i = 0; i < cfg->hp_outs; i++) {
1889 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]);
1890 if (wid_caps & AC_WCAP_UNSOL_CAP)
1891 spec->hp_detect = 1;
1892 nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
1893 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1894 if (check_in_dac_nids(spec, nid))
1895 nid = 0;
1896 if (! nid)
1897 continue;
1898 add_spec_dacs(spec, nid);
1900 for (i = 0; i < cfg->speaker_outs; i++) {
1901 nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
1902 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1903 if (check_in_dac_nids(spec, nid))
1904 nid = 0;
1905 if (! nid)
1906 continue;
1907 add_spec_dacs(spec, nid);
1909 for (i = 0; i < cfg->line_outs; i++) {
1910 nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0,
1911 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1912 if (check_in_dac_nids(spec, nid))
1913 nid = 0;
1914 if (! nid)
1915 continue;
1916 add_spec_dacs(spec, nid);
1918 for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) {
1919 static const char *pfxs[] = {
1920 "Speaker", "External Speaker", "Speaker2",
1922 err = create_controls(spec, pfxs[i - old_num_dacs],
1923 spec->multiout.dac_nids[i], 3);
1924 if (err < 0)
1925 return err;
1927 if (spec->multiout.hp_nid) {
1928 const char *pfx;
1929 if (old_num_dacs == spec->multiout.num_dacs)
1930 pfx = "Master";
1931 else
1932 pfx = "Headphone";
1933 err = create_controls(spec, pfx, spec->multiout.hp_nid, 3);
1934 if (err < 0)
1935 return err;
1938 return 0;
1941 /* labels for dmic mux inputs */
1942 static const char *stac92xx_dmic_labels[5] = {
1943 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
1944 "Digital Mic 3", "Digital Mic 4"
1947 /* create playback/capture controls for input pins on dmic capable codecs */
1948 static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
1949 const struct auto_pin_cfg *cfg)
1951 struct sigmatel_spec *spec = codec->spec;
1952 struct hda_input_mux *dimux = &spec->private_dimux;
1953 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
1954 int i, j;
1956 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0];
1957 dimux->items[dimux->num_items].index = 0;
1958 dimux->num_items++;
1960 for (i = 0; i < spec->num_dmics; i++) {
1961 int index;
1962 int num_cons;
1963 unsigned int def_conf;
1965 def_conf = snd_hda_codec_read(codec,
1966 spec->dmic_nids[i],
1968 AC_VERB_GET_CONFIG_DEFAULT,
1970 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
1971 continue;
1973 num_cons = snd_hda_get_connections(codec,
1974 spec->dmux_nid,
1975 con_lst,
1976 HDA_MAX_NUM_INPUTS);
1977 for (j = 0; j < num_cons; j++)
1978 if (con_lst[j] == spec->dmic_nids[i]) {
1979 index = j;
1980 goto found;
1982 continue;
1983 found:
1984 dimux->items[dimux->num_items].label =
1985 stac92xx_dmic_labels[dimux->num_items];
1986 dimux->items[dimux->num_items].index = index;
1987 dimux->num_items++;
1990 return 0;
1993 /* create playback/capture controls for input pins */
1994 static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
1996 struct sigmatel_spec *spec = codec->spec;
1997 struct hda_input_mux *imux = &spec->private_imux;
1998 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
1999 int i, j, k;
2001 for (i = 0; i < AUTO_PIN_LAST; i++) {
2002 int index;
2004 if (!cfg->input_pins[i])
2005 continue;
2006 index = -1;
2007 for (j = 0; j < spec->num_muxes; j++) {
2008 int num_cons;
2009 num_cons = snd_hda_get_connections(codec,
2010 spec->mux_nids[j],
2011 con_lst,
2012 HDA_MAX_NUM_INPUTS);
2013 for (k = 0; k < num_cons; k++)
2014 if (con_lst[k] == cfg->input_pins[i]) {
2015 index = k;
2016 goto found;
2019 continue;
2020 found:
2021 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2022 imux->items[imux->num_items].index = index;
2023 imux->num_items++;
2026 if (imux->num_items) {
2028 * Set the current input for the muxes.
2029 * The STAC9221 has two input muxes with identical source
2030 * NID lists. Hopefully this won't get confused.
2032 for (i = 0; i < spec->num_muxes; i++) {
2033 snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0,
2034 AC_VERB_SET_CONNECT_SEL,
2035 imux->items[0].index);
2039 return 0;
2042 static void stac92xx_auto_init_multi_out(struct hda_codec *codec)
2044 struct sigmatel_spec *spec = codec->spec;
2045 int i;
2047 for (i = 0; i < spec->autocfg.line_outs; i++) {
2048 hda_nid_t nid = spec->autocfg.line_out_pins[i];
2049 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
2053 static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
2055 struct sigmatel_spec *spec = codec->spec;
2056 int i;
2058 for (i = 0; i < spec->autocfg.hp_outs; i++) {
2059 hda_nid_t pin;
2060 pin = spec->autocfg.hp_pins[i];
2061 if (pin) /* connect to front */
2062 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
2064 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
2065 hda_nid_t pin;
2066 pin = spec->autocfg.speaker_pins[i];
2067 if (pin) /* connect to front */
2068 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN);
2072 static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in)
2074 struct sigmatel_spec *spec = codec->spec;
2075 int err;
2077 if ((err = snd_hda_parse_pin_def_config(codec,
2078 &spec->autocfg,
2079 spec->dmic_nids)) < 0)
2080 return err;
2081 if (! spec->autocfg.line_outs)
2082 return 0; /* can't find valid pin config */
2084 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
2085 return err;
2086 if (spec->multiout.num_dacs == 0)
2087 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
2088 return err;
2090 err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg);
2092 if (err < 0)
2093 return err;
2095 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
2097 if (err < 0)
2098 return err;
2100 err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
2102 if (err < 0)
2103 return err;
2105 if (spec->num_dmics > 0)
2106 if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
2107 &spec->autocfg)) < 0)
2108 return err;
2110 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2111 if (spec->multiout.max_channels > 2)
2112 spec->surr_switch = 1;
2114 if (spec->autocfg.dig_out_pin)
2115 spec->multiout.dig_out_nid = dig_out;
2116 if (spec->autocfg.dig_in_pin)
2117 spec->dig_in_nid = dig_in;
2119 if (spec->kctl_alloc)
2120 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2122 spec->input_mux = &spec->private_imux;
2123 spec->dinput_mux = &spec->private_dimux;
2125 return 1;
2128 /* add playback controls for HP output */
2129 static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
2130 struct auto_pin_cfg *cfg)
2132 struct sigmatel_spec *spec = codec->spec;
2133 hda_nid_t pin = cfg->hp_pins[0];
2134 unsigned int wid_caps;
2136 if (! pin)
2137 return 0;
2139 wid_caps = get_wcaps(codec, pin);
2140 if (wid_caps & AC_WCAP_UNSOL_CAP)
2141 spec->hp_detect = 1;
2143 return 0;
2146 /* add playback controls for LFE output */
2147 static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec,
2148 struct auto_pin_cfg *cfg)
2150 struct sigmatel_spec *spec = codec->spec;
2151 int err;
2152 hda_nid_t lfe_pin = 0x0;
2153 int i;
2156 * search speaker outs and line outs for a mono speaker pin
2157 * with an amp. If one is found, add LFE controls
2158 * for it.
2160 for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) {
2161 hda_nid_t pin = spec->autocfg.speaker_pins[i];
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, must be lfe */
2166 lfe_pin = pin;
2169 /* if speaker_outs is 0, then speakers may be in line_outs */
2170 if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) {
2171 for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) {
2172 hda_nid_t pin = spec->autocfg.line_out_pins[i];
2173 unsigned long cfg;
2174 cfg = snd_hda_codec_read(codec, pin, 0,
2175 AC_VERB_GET_CONFIG_DEFAULT,
2176 0x00);
2177 if (get_defcfg_device(cfg) == AC_JACK_SPEAKER) {
2178 unsigned long wcaps = get_wcaps(codec, pin);
2179 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
2180 if (wcaps == AC_WCAP_OUT_AMP)
2181 /* found a mono speaker with an amp,
2182 must be lfe */
2183 lfe_pin = pin;
2188 if (lfe_pin) {
2189 err = create_controls(spec, "LFE", lfe_pin, 1);
2190 if (err < 0)
2191 return err;
2194 return 0;
2197 static int stac9200_parse_auto_config(struct hda_codec *codec)
2199 struct sigmatel_spec *spec = codec->spec;
2200 int err;
2202 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
2203 return err;
2205 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
2206 return err;
2208 if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)
2209 return err;
2211 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
2212 return err;
2214 if (spec->autocfg.dig_out_pin)
2215 spec->multiout.dig_out_nid = 0x05;
2216 if (spec->autocfg.dig_in_pin)
2217 spec->dig_in_nid = 0x04;
2219 if (spec->kctl_alloc)
2220 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2222 spec->input_mux = &spec->private_imux;
2223 spec->dinput_mux = &spec->private_dimux;
2225 return 1;
2229 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
2230 * funky external mute control using GPIO pins.
2233 static void stac922x_gpio_mute(struct hda_codec *codec, int pin, int muted)
2235 unsigned int gpiostate, gpiomask, gpiodir;
2237 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
2238 AC_VERB_GET_GPIO_DATA, 0);
2240 if (!muted)
2241 gpiostate |= (1 << pin);
2242 else
2243 gpiostate &= ~(1 << pin);
2245 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
2246 AC_VERB_GET_GPIO_MASK, 0);
2247 gpiomask |= (1 << pin);
2249 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
2250 AC_VERB_GET_GPIO_DIRECTION, 0);
2251 gpiodir |= (1 << pin);
2253 /* AppleHDA seems to do this -- WTF is this verb?? */
2254 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
2256 snd_hda_codec_write(codec, codec->afg, 0,
2257 AC_VERB_SET_GPIO_MASK, gpiomask);
2258 snd_hda_codec_write(codec, codec->afg, 0,
2259 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
2261 msleep(1);
2263 snd_hda_codec_write(codec, codec->afg, 0,
2264 AC_VERB_SET_GPIO_DATA, gpiostate);
2267 static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
2268 unsigned int event)
2270 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)
2271 snd_hda_codec_write_cache(codec, nid, 0,
2272 AC_VERB_SET_UNSOLICITED_ENABLE,
2273 (AC_USRSP_EN | event));
2276 static int stac92xx_init(struct hda_codec *codec)
2278 struct sigmatel_spec *spec = codec->spec;
2279 struct auto_pin_cfg *cfg = &spec->autocfg;
2280 int i;
2282 snd_hda_sequence_write(codec, spec->init);
2284 /* set up pins */
2285 if (spec->hp_detect) {
2286 /* Enable unsolicited responses on the HP widget */
2287 for (i = 0; i < cfg->hp_outs; i++)
2288 enable_pin_detect(codec, cfg->hp_pins[i],
2289 STAC_HP_EVENT);
2290 /* force to enable the first line-out; the others are set up
2291 * in unsol_event
2293 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
2294 AC_PINCTL_OUT_EN);
2295 stac92xx_auto_init_hp_out(codec);
2296 /* fake event to set up pins */
2297 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2298 } else {
2299 stac92xx_auto_init_multi_out(codec);
2300 stac92xx_auto_init_hp_out(codec);
2302 for (i = 0; i < AUTO_PIN_LAST; i++) {
2303 hda_nid_t nid = cfg->input_pins[i];
2304 if (nid) {
2305 unsigned int pinctl = AC_PINCTL_IN_EN;
2306 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
2307 pinctl |= stac92xx_get_vref(codec, nid);
2308 stac92xx_auto_set_pinctl(codec, nid, pinctl);
2311 if (spec->num_dmics > 0)
2312 for (i = 0; i < spec->num_dmics; i++)
2313 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
2314 AC_PINCTL_IN_EN);
2316 if (cfg->dig_out_pin)
2317 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
2318 AC_PINCTL_OUT_EN);
2319 if (cfg->dig_in_pin)
2320 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
2321 AC_PINCTL_IN_EN);
2323 if (spec->gpio_mute) {
2324 stac922x_gpio_mute(codec, 0, 0);
2325 stac922x_gpio_mute(codec, 1, 0);
2328 return 0;
2331 static void stac92xx_free(struct hda_codec *codec)
2333 struct sigmatel_spec *spec = codec->spec;
2334 int i;
2336 if (! spec)
2337 return;
2339 if (spec->kctl_alloc) {
2340 for (i = 0; i < spec->num_kctl_used; i++)
2341 kfree(spec->kctl_alloc[i].name);
2342 kfree(spec->kctl_alloc);
2345 if (spec->bios_pin_configs)
2346 kfree(spec->bios_pin_configs);
2348 kfree(spec);
2351 static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
2352 unsigned int flag)
2354 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
2355 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
2357 if (pin_ctl & AC_PINCTL_IN_EN) {
2359 * we need to check the current set-up direction of
2360 * shared input pins since they can be switched via
2361 * "xxx as Output" mixer switch
2363 struct sigmatel_spec *spec = codec->spec;
2364 struct auto_pin_cfg *cfg = &spec->autocfg;
2365 if ((nid == cfg->input_pins[AUTO_PIN_LINE] &&
2366 spec->line_switch) ||
2367 (nid == cfg->input_pins[AUTO_PIN_MIC] &&
2368 spec->mic_switch))
2369 return;
2372 /* if setting pin direction bits, clear the current
2373 direction bits first */
2374 if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
2375 pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
2377 snd_hda_codec_write_cache(codec, nid, 0,
2378 AC_VERB_SET_PIN_WIDGET_CONTROL,
2379 pin_ctl | flag);
2382 static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
2383 unsigned int flag)
2385 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
2386 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
2387 snd_hda_codec_write_cache(codec, nid, 0,
2388 AC_VERB_SET_PIN_WIDGET_CONTROL,
2389 pin_ctl & ~flag);
2392 static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
2394 if (!nid)
2395 return 0;
2396 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00)
2397 & (1 << 31))
2398 return 1;
2399 return 0;
2402 static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
2404 struct sigmatel_spec *spec = codec->spec;
2405 struct auto_pin_cfg *cfg = &spec->autocfg;
2406 int i, presence;
2408 presence = 0;
2409 for (i = 0; i < cfg->hp_outs; i++) {
2410 presence = get_pin_presence(codec, cfg->hp_pins[i]);
2411 if (presence)
2412 break;
2415 if (presence) {
2416 /* disable lineouts, enable hp */
2417 for (i = 0; i < cfg->line_outs; i++)
2418 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
2419 AC_PINCTL_OUT_EN);
2420 for (i = 0; i < cfg->speaker_outs; i++)
2421 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
2422 AC_PINCTL_OUT_EN);
2423 } else {
2424 /* enable lineouts, disable hp */
2425 for (i = 0; i < cfg->line_outs; i++)
2426 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
2427 AC_PINCTL_OUT_EN);
2428 for (i = 0; i < cfg->speaker_outs; i++)
2429 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
2430 AC_PINCTL_OUT_EN);
2434 static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
2436 switch (res >> 26) {
2437 case STAC_HP_EVENT:
2438 stac92xx_hp_detect(codec, res);
2439 break;
2443 #ifdef SND_HDA_NEEDS_RESUME
2444 static int stac92xx_resume(struct hda_codec *codec)
2446 struct sigmatel_spec *spec = codec->spec;
2448 stac92xx_set_config_regs(codec);
2449 snd_hda_sequence_write(codec, spec->init);
2450 if (spec->gpio_mute) {
2451 stac922x_gpio_mute(codec, 0, 0);
2452 stac922x_gpio_mute(codec, 1, 0);
2454 snd_hda_codec_resume_amp(codec);
2455 snd_hda_codec_resume_cache(codec);
2456 /* invoke unsolicited event to reset the HP state */
2457 if (spec->hp_detect)
2458 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2459 return 0;
2461 #endif
2463 static struct hda_codec_ops stac92xx_patch_ops = {
2464 .build_controls = stac92xx_build_controls,
2465 .build_pcms = stac92xx_build_pcms,
2466 .init = stac92xx_init,
2467 .free = stac92xx_free,
2468 .unsol_event = stac92xx_unsol_event,
2469 #ifdef SND_HDA_NEEDS_RESUME
2470 .resume = stac92xx_resume,
2471 #endif
2474 static int patch_stac9200(struct hda_codec *codec)
2476 struct sigmatel_spec *spec;
2477 int err;
2479 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2480 if (spec == NULL)
2481 return -ENOMEM;
2483 codec->spec = spec;
2484 spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
2485 spec->pin_nids = stac9200_pin_nids;
2486 spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
2487 stac9200_models,
2488 stac9200_cfg_tbl);
2489 if (spec->board_config < 0) {
2490 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
2491 err = stac92xx_save_bios_config_regs(codec);
2492 if (err < 0) {
2493 stac92xx_free(codec);
2494 return err;
2496 spec->pin_configs = spec->bios_pin_configs;
2497 } else {
2498 spec->pin_configs = stac9200_brd_tbl[spec->board_config];
2499 stac92xx_set_config_regs(codec);
2502 spec->multiout.max_channels = 2;
2503 spec->multiout.num_dacs = 1;
2504 spec->multiout.dac_nids = stac9200_dac_nids;
2505 spec->adc_nids = stac9200_adc_nids;
2506 spec->mux_nids = stac9200_mux_nids;
2507 spec->num_muxes = 1;
2508 spec->num_dmics = 0;
2509 spec->num_adcs = 1;
2511 if (spec->board_config == STAC_9200_GATEWAY)
2512 spec->init = stac9200_eapd_init;
2513 else
2514 spec->init = stac9200_core_init;
2515 spec->mixer = stac9200_mixer;
2517 err = stac9200_parse_auto_config(codec);
2518 if (err < 0) {
2519 stac92xx_free(codec);
2520 return err;
2523 codec->patch_ops = stac92xx_patch_ops;
2525 return 0;
2528 static int patch_stac925x(struct hda_codec *codec)
2530 struct sigmatel_spec *spec;
2531 int err;
2533 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2534 if (spec == NULL)
2535 return -ENOMEM;
2537 codec->spec = spec;
2538 spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
2539 spec->pin_nids = stac925x_pin_nids;
2540 spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
2541 stac925x_models,
2542 stac925x_cfg_tbl);
2543 again:
2544 if (spec->board_config < 0) {
2545 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x,"
2546 "using BIOS defaults\n");
2547 err = stac92xx_save_bios_config_regs(codec);
2548 if (err < 0) {
2549 stac92xx_free(codec);
2550 return err;
2552 spec->pin_configs = spec->bios_pin_configs;
2553 } else if (stac925x_brd_tbl[spec->board_config] != NULL){
2554 spec->pin_configs = stac925x_brd_tbl[spec->board_config];
2555 stac92xx_set_config_regs(codec);
2558 spec->multiout.max_channels = 2;
2559 spec->multiout.num_dacs = 1;
2560 spec->multiout.dac_nids = stac925x_dac_nids;
2561 spec->adc_nids = stac925x_adc_nids;
2562 spec->mux_nids = stac925x_mux_nids;
2563 spec->num_muxes = 1;
2564 spec->num_adcs = 1;
2565 switch (codec->vendor_id) {
2566 case 0x83847632: /* STAC9202 */
2567 case 0x83847633: /* STAC9202D */
2568 case 0x83847636: /* STAC9251 */
2569 case 0x83847637: /* STAC9251D */
2570 spec->num_dmics = 1;
2571 spec->dmic_nids = stac925x_dmic_nids;
2572 break;
2573 default:
2574 spec->num_dmics = 0;
2575 break;
2578 spec->init = stac925x_core_init;
2579 spec->mixer = stac925x_mixer;
2581 err = stac92xx_parse_auto_config(codec, 0x8, 0x7);
2582 if (!err) {
2583 if (spec->board_config < 0) {
2584 printk(KERN_WARNING "hda_codec: No auto-config is "
2585 "available, default to model=ref\n");
2586 spec->board_config = STAC_925x_REF;
2587 goto again;
2589 err = -EINVAL;
2591 if (err < 0) {
2592 stac92xx_free(codec);
2593 return err;
2596 codec->patch_ops = stac92xx_patch_ops;
2598 return 0;
2601 static int patch_stac922x(struct hda_codec *codec)
2603 struct sigmatel_spec *spec;
2604 int err;
2606 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2607 if (spec == NULL)
2608 return -ENOMEM;
2610 codec->spec = spec;
2611 spec->num_pins = ARRAY_SIZE(stac922x_pin_nids);
2612 spec->pin_nids = stac922x_pin_nids;
2613 spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
2614 stac922x_models,
2615 stac922x_cfg_tbl);
2616 if (spec->board_config == STAC_INTEL_MAC_V3) {
2617 spec->gpio_mute = 1;
2618 /* Intel Macs have all same PCI SSID, so we need to check
2619 * codec SSID to distinguish the exact models
2621 printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id);
2622 switch (codec->subsystem_id) {
2624 case 0x106b0800:
2625 spec->board_config = STAC_INTEL_MAC_V1;
2626 break;
2627 case 0x106b0600:
2628 case 0x106b0700:
2629 spec->board_config = STAC_INTEL_MAC_V2;
2630 break;
2631 case 0x106b0e00:
2632 case 0x106b0f00:
2633 case 0x106b1600:
2634 case 0x106b1700:
2635 case 0x106b0200:
2636 case 0x106b1e00:
2637 spec->board_config = STAC_INTEL_MAC_V3;
2638 break;
2639 case 0x106b1a00:
2640 case 0x00000100:
2641 spec->board_config = STAC_INTEL_MAC_V4;
2642 break;
2643 case 0x106b0a00:
2644 case 0x106b2200:
2645 spec->board_config = STAC_INTEL_MAC_V5;
2646 break;
2650 again:
2651 if (spec->board_config < 0) {
2652 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, "
2653 "using BIOS defaults\n");
2654 err = stac92xx_save_bios_config_regs(codec);
2655 if (err < 0) {
2656 stac92xx_free(codec);
2657 return err;
2659 spec->pin_configs = spec->bios_pin_configs;
2660 } else if (stac922x_brd_tbl[spec->board_config] != NULL) {
2661 spec->pin_configs = stac922x_brd_tbl[spec->board_config];
2662 stac92xx_set_config_regs(codec);
2665 spec->adc_nids = stac922x_adc_nids;
2666 spec->mux_nids = stac922x_mux_nids;
2667 spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
2668 spec->num_adcs = ARRAY_SIZE(stac922x_adc_nids);
2669 spec->num_dmics = 0;
2671 spec->init = stac922x_core_init;
2672 spec->mixer = stac922x_mixer;
2674 spec->multiout.dac_nids = spec->dac_nids;
2676 err = stac92xx_parse_auto_config(codec, 0x08, 0x09);
2677 if (!err) {
2678 if (spec->board_config < 0) {
2679 printk(KERN_WARNING "hda_codec: No auto-config is "
2680 "available, default to model=ref\n");
2681 spec->board_config = STAC_D945_REF;
2682 goto again;
2684 err = -EINVAL;
2686 if (err < 0) {
2687 stac92xx_free(codec);
2688 return err;
2691 codec->patch_ops = stac92xx_patch_ops;
2693 /* Fix Mux capture level; max to 2 */
2694 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
2695 (0 << AC_AMPCAP_OFFSET_SHIFT) |
2696 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2697 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2698 (0 << AC_AMPCAP_MUTE_SHIFT));
2700 return 0;
2703 static int patch_stac927x(struct hda_codec *codec)
2705 struct sigmatel_spec *spec;
2706 int err;
2708 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2709 if (spec == NULL)
2710 return -ENOMEM;
2712 codec->spec = spec;
2713 spec->num_pins = ARRAY_SIZE(stac927x_pin_nids);
2714 spec->pin_nids = stac927x_pin_nids;
2715 spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS,
2716 stac927x_models,
2717 stac927x_cfg_tbl);
2718 again:
2719 if (spec->board_config < 0) {
2720 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n");
2721 err = stac92xx_save_bios_config_regs(codec);
2722 if (err < 0) {
2723 stac92xx_free(codec);
2724 return err;
2726 spec->pin_configs = spec->bios_pin_configs;
2727 } else if (stac927x_brd_tbl[spec->board_config] != NULL) {
2728 spec->pin_configs = stac927x_brd_tbl[spec->board_config];
2729 stac92xx_set_config_regs(codec);
2732 switch (spec->board_config) {
2733 case STAC_D965_3ST:
2734 spec->adc_nids = stac927x_adc_nids;
2735 spec->mux_nids = stac927x_mux_nids;
2736 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2737 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
2738 spec->num_dmics = 0;
2739 spec->init = d965_core_init;
2740 spec->mixer = stac927x_mixer;
2741 break;
2742 case STAC_D965_5ST:
2743 spec->adc_nids = stac927x_adc_nids;
2744 spec->mux_nids = stac927x_mux_nids;
2745 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2746 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
2747 spec->num_dmics = 0;
2748 spec->init = d965_core_init;
2749 spec->mixer = stac927x_mixer;
2750 break;
2751 default:
2752 spec->adc_nids = stac927x_adc_nids;
2753 spec->mux_nids = stac927x_mux_nids;
2754 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2755 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
2756 spec->num_dmics = 0;
2757 spec->init = stac927x_core_init;
2758 spec->mixer = stac927x_mixer;
2761 spec->multiout.dac_nids = spec->dac_nids;
2762 /* GPIO0 High = Enable EAPD */
2763 spec->gpio_mask = spec->gpio_data = 0x00000001;
2764 stac92xx_enable_gpio_mask(codec);
2766 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
2767 if (!err) {
2768 if (spec->board_config < 0) {
2769 printk(KERN_WARNING "hda_codec: No auto-config is "
2770 "available, default to model=ref\n");
2771 spec->board_config = STAC_D965_REF;
2772 goto again;
2774 err = -EINVAL;
2776 if (err < 0) {
2777 stac92xx_free(codec);
2778 return err;
2781 codec->patch_ops = stac92xx_patch_ops;
2783 return 0;
2786 static int patch_stac9205(struct hda_codec *codec)
2788 struct sigmatel_spec *spec;
2789 int err;
2791 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2792 if (spec == NULL)
2793 return -ENOMEM;
2795 codec->spec = spec;
2796 spec->num_pins = ARRAY_SIZE(stac9205_pin_nids);
2797 spec->pin_nids = stac9205_pin_nids;
2798 spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
2799 stac9205_models,
2800 stac9205_cfg_tbl);
2801 again:
2802 if (spec->board_config < 0) {
2803 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n");
2804 err = stac92xx_save_bios_config_regs(codec);
2805 if (err < 0) {
2806 stac92xx_free(codec);
2807 return err;
2809 spec->pin_configs = spec->bios_pin_configs;
2810 } else {
2811 spec->pin_configs = stac9205_brd_tbl[spec->board_config];
2812 stac92xx_set_config_regs(codec);
2815 spec->adc_nids = stac9205_adc_nids;
2816 spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids);
2817 spec->mux_nids = stac9205_mux_nids;
2818 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
2819 spec->dmic_nids = stac9205_dmic_nids;
2820 spec->num_dmics = ARRAY_SIZE(stac9205_dmic_nids);
2821 spec->dmux_nid = 0x1d;
2823 spec->init = stac9205_core_init;
2824 spec->mixer = stac9205_mixer;
2826 spec->multiout.dac_nids = spec->dac_nids;
2828 switch (spec->board_config){
2829 case STAC_9205_DELL_M43:
2830 /* Enable SPDIF in/out */
2831 stac92xx_set_config_reg(codec, 0x1f, 0x01441030);
2832 stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
2834 spec->gpio_mask = 0x00000007; /* GPIO0-2 */
2835 /* GPIO0 High = EAPD, GPIO1 Low = DRM,
2836 * GPIO2 High = Headphone Mute
2838 spec->gpio_data = 0x00000005;
2839 break;
2840 default:
2841 /* GPIO0 High = EAPD */
2842 spec->gpio_mask = spec->gpio_data = 0x00000001;
2843 break;
2846 stac92xx_enable_gpio_mask(codec);
2847 err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
2848 if (!err) {
2849 if (spec->board_config < 0) {
2850 printk(KERN_WARNING "hda_codec: No auto-config is "
2851 "available, default to model=ref\n");
2852 spec->board_config = STAC_9205_REF;
2853 goto again;
2855 err = -EINVAL;
2857 if (err < 0) {
2858 stac92xx_free(codec);
2859 return err;
2862 codec->patch_ops = stac92xx_patch_ops;
2864 return 0;
2868 * STAC9872 hack
2871 /* static config for Sony VAIO FE550G and Sony VAIO AR */
2872 static hda_nid_t vaio_dacs[] = { 0x2 };
2873 #define VAIO_HP_DAC 0x5
2874 static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ };
2875 static hda_nid_t vaio_mux_nids[] = { 0x15 };
2877 static struct hda_input_mux vaio_mux = {
2878 .num_items = 2,
2879 .items = {
2880 /* { "HP", 0x0 }, */
2881 { "Mic Jack", 0x1 },
2882 { "Internal Mic", 0x2 },
2883 { "PCM", 0x3 },
2887 static struct hda_verb vaio_init[] = {
2888 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
2889 {0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT},
2890 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
2891 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
2892 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
2893 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
2894 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
2895 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
2896 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
2897 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
2898 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
2899 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
2903 static struct hda_verb vaio_ar_init[] = {
2904 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
2905 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
2906 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
2907 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
2908 /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */
2909 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
2910 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
2911 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
2912 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
2913 /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */
2914 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
2915 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
2916 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
2920 /* bind volumes of both NID 0x02 and 0x05 */
2921 static struct hda_bind_ctls vaio_bind_master_vol = {
2922 .ops = &snd_hda_bind_vol,
2923 .values = {
2924 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
2925 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
2930 /* bind volumes of both NID 0x02 and 0x05 */
2931 static struct hda_bind_ctls vaio_bind_master_sw = {
2932 .ops = &snd_hda_bind_sw,
2933 .values = {
2934 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
2935 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
2940 static struct snd_kcontrol_new vaio_mixer[] = {
2941 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
2942 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
2943 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
2944 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
2945 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
2947 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2948 .name = "Capture Source",
2949 .count = 1,
2950 .info = stac92xx_mux_enum_info,
2951 .get = stac92xx_mux_enum_get,
2952 .put = stac92xx_mux_enum_put,
2957 static struct snd_kcontrol_new vaio_ar_mixer[] = {
2958 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
2959 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
2960 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
2961 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
2962 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
2963 /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT),
2964 HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/
2966 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2967 .name = "Capture Source",
2968 .count = 1,
2969 .info = stac92xx_mux_enum_info,
2970 .get = stac92xx_mux_enum_get,
2971 .put = stac92xx_mux_enum_put,
2976 static struct hda_codec_ops stac9872_patch_ops = {
2977 .build_controls = stac92xx_build_controls,
2978 .build_pcms = stac92xx_build_pcms,
2979 .init = stac92xx_init,
2980 .free = stac92xx_free,
2981 #ifdef SND_HDA_NEEDS_RESUME
2982 .resume = stac92xx_resume,
2983 #endif
2986 static int stac9872_vaio_init(struct hda_codec *codec)
2988 int err;
2990 err = stac92xx_init(codec);
2991 if (err < 0)
2992 return err;
2993 if (codec->patch_ops.unsol_event)
2994 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2995 return 0;
2998 static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
3000 if (get_pin_presence(codec, 0x0a)) {
3001 stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
3002 stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
3003 } else {
3004 stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
3005 stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
3009 static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res)
3011 switch (res >> 26) {
3012 case STAC_HP_EVENT:
3013 stac9872_vaio_hp_detect(codec, res);
3014 break;
3018 static struct hda_codec_ops stac9872_vaio_patch_ops = {
3019 .build_controls = stac92xx_build_controls,
3020 .build_pcms = stac92xx_build_pcms,
3021 .init = stac9872_vaio_init,
3022 .free = stac92xx_free,
3023 .unsol_event = stac9872_vaio_unsol_event,
3024 #ifdef CONFIG_PM
3025 .resume = stac92xx_resume,
3026 #endif
3029 enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */
3030 CXD9872RD_VAIO,
3031 /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */
3032 STAC9872AK_VAIO,
3033 /* Unknown. id=0x83847661 and subsys=0x104D1200. */
3034 STAC9872K_VAIO,
3035 /* AR Series. id=0x83847664 and subsys=104D1300 */
3036 CXD9872AKD_VAIO,
3037 STAC_9872_MODELS,
3040 static const char *stac9872_models[STAC_9872_MODELS] = {
3041 [CXD9872RD_VAIO] = "vaio",
3042 [CXD9872AKD_VAIO] = "vaio-ar",
3045 static struct snd_pci_quirk stac9872_cfg_tbl[] = {
3046 SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
3047 SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
3048 SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
3049 SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO),
3053 static int patch_stac9872(struct hda_codec *codec)
3055 struct sigmatel_spec *spec;
3056 int board_config;
3058 board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
3059 stac9872_models,
3060 stac9872_cfg_tbl);
3061 if (board_config < 0)
3062 /* unknown config, let generic-parser do its job... */
3063 return snd_hda_parse_generic_codec(codec);
3065 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3066 if (spec == NULL)
3067 return -ENOMEM;
3069 codec->spec = spec;
3070 switch (board_config) {
3071 case CXD9872RD_VAIO:
3072 case STAC9872AK_VAIO:
3073 case STAC9872K_VAIO:
3074 spec->mixer = vaio_mixer;
3075 spec->init = vaio_init;
3076 spec->multiout.max_channels = 2;
3077 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
3078 spec->multiout.dac_nids = vaio_dacs;
3079 spec->multiout.hp_nid = VAIO_HP_DAC;
3080 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
3081 spec->adc_nids = vaio_adcs;
3082 spec->input_mux = &vaio_mux;
3083 spec->mux_nids = vaio_mux_nids;
3084 codec->patch_ops = stac9872_vaio_patch_ops;
3085 break;
3087 case CXD9872AKD_VAIO:
3088 spec->mixer = vaio_ar_mixer;
3089 spec->init = vaio_ar_init;
3090 spec->multiout.max_channels = 2;
3091 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
3092 spec->multiout.dac_nids = vaio_dacs;
3093 spec->multiout.hp_nid = VAIO_HP_DAC;
3094 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
3095 spec->adc_nids = vaio_adcs;
3096 spec->input_mux = &vaio_mux;
3097 spec->mux_nids = vaio_mux_nids;
3098 codec->patch_ops = stac9872_patch_ops;
3099 break;
3102 return 0;
3107 * patch entries
3109 struct hda_codec_preset snd_hda_preset_sigmatel[] = {
3110 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
3111 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
3112 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
3113 { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x },
3114 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
3115 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
3116 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
3117 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x },
3118 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x },
3119 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x },
3120 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x },
3121 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x },
3122 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x },
3123 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
3124 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
3125 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
3126 { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x },
3127 { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x },
3128 { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x },
3129 { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x },
3130 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x },
3131 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x },
3132 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x },
3133 { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x },
3134 { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x },
3135 { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x },
3136 { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
3137 { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
3138 { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
3139 /* The following does not take into account .id=0x83847661 when subsys =
3140 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
3141 * currently not fully supported.
3143 { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 },
3144 { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 },
3145 { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 },
3146 { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 },
3147 { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 },
3148 { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 },
3149 { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 },
3150 { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 },
3151 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
3152 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
3153 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
3154 {} /* terminator */