add port definition for mcf UART driver
[linux-2.6/next.git] / sound / pci / hda / patch_sigmatel.c
blobf9b2c435a1303ec767193b6d7dcb7197dd60497d
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;
114 unsigned int no_vol_knob :1;
116 unsigned int gpio_mask, gpio_data;
118 /* playback */
119 struct hda_multi_out multiout;
120 hda_nid_t dac_nids[5];
122 /* capture */
123 hda_nid_t *adc_nids;
124 unsigned int num_adcs;
125 hda_nid_t *mux_nids;
126 unsigned int num_muxes;
127 hda_nid_t *dmic_nids;
128 unsigned int num_dmics;
129 hda_nid_t dmux_nid;
130 hda_nid_t dig_in_nid;
132 /* pin widgets */
133 hda_nid_t *pin_nids;
134 unsigned int num_pins;
135 unsigned int *pin_configs;
136 unsigned int *bios_pin_configs;
138 /* codec specific stuff */
139 struct hda_verb *init;
140 struct snd_kcontrol_new *mixer;
142 /* capture source */
143 struct hda_input_mux *dinput_mux;
144 unsigned int cur_dmux;
145 struct hda_input_mux *input_mux;
146 unsigned int cur_mux[3];
148 /* i/o switches */
149 unsigned int io_switch[2];
150 unsigned int clfe_swap;
151 unsigned int aloopback;
153 struct hda_pcm pcm_rec[2]; /* PCM information */
155 /* dynamic controls and input_mux */
156 struct auto_pin_cfg autocfg;
157 unsigned int num_kctl_alloc, num_kctl_used;
158 struct snd_kcontrol_new *kctl_alloc;
159 struct hda_input_mux private_dimux;
160 struct hda_input_mux private_imux;
163 static hda_nid_t stac9200_adc_nids[1] = {
164 0x03,
167 static hda_nid_t stac9200_mux_nids[1] = {
168 0x0c,
171 static hda_nid_t stac9200_dac_nids[1] = {
172 0x02,
175 static hda_nid_t stac925x_adc_nids[1] = {
176 0x03,
179 static hda_nid_t stac925x_mux_nids[1] = {
180 0x0f,
183 static hda_nid_t stac925x_dac_nids[1] = {
184 0x02,
187 #define STAC925X_NUM_DMICS 1
188 static hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = {
189 0x15, 0
192 static hda_nid_t stac922x_adc_nids[2] = {
193 0x06, 0x07,
196 static hda_nid_t stac922x_mux_nids[2] = {
197 0x12, 0x13,
200 static hda_nid_t stac927x_adc_nids[3] = {
201 0x07, 0x08, 0x09
204 static hda_nid_t stac927x_mux_nids[3] = {
205 0x15, 0x16, 0x17
208 static hda_nid_t stac9205_adc_nids[2] = {
209 0x12, 0x13
212 static hda_nid_t stac9205_mux_nids[2] = {
213 0x19, 0x1a
216 #define STAC9205_NUM_DMICS 2
217 static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
218 0x17, 0x18, 0
221 static hda_nid_t stac9200_pin_nids[8] = {
222 0x08, 0x09, 0x0d, 0x0e,
223 0x0f, 0x10, 0x11, 0x12,
226 static hda_nid_t stac925x_pin_nids[8] = {
227 0x07, 0x08, 0x0a, 0x0b,
228 0x0c, 0x0d, 0x10, 0x11,
231 static hda_nid_t stac922x_pin_nids[10] = {
232 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
233 0x0f, 0x10, 0x11, 0x15, 0x1b,
236 static hda_nid_t stac927x_pin_nids[14] = {
237 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
238 0x0f, 0x10, 0x11, 0x12, 0x13,
239 0x14, 0x21, 0x22, 0x23,
242 static hda_nid_t stac9205_pin_nids[12] = {
243 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
244 0x0f, 0x14, 0x16, 0x17, 0x18,
245 0x21, 0x22,
248 static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
249 struct snd_ctl_elem_info *uinfo)
251 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
252 struct sigmatel_spec *spec = codec->spec;
253 return snd_hda_input_mux_info(spec->dinput_mux, uinfo);
256 static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol,
257 struct snd_ctl_elem_value *ucontrol)
259 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
260 struct sigmatel_spec *spec = codec->spec;
262 ucontrol->value.enumerated.item[0] = spec->cur_dmux;
263 return 0;
266 static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
267 struct snd_ctl_elem_value *ucontrol)
269 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
270 struct sigmatel_spec *spec = codec->spec;
272 return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol,
273 spec->dmux_nid, &spec->cur_dmux);
276 static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
278 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
279 struct sigmatel_spec *spec = codec->spec;
280 return snd_hda_input_mux_info(spec->input_mux, uinfo);
283 static int stac92xx_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
285 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
286 struct sigmatel_spec *spec = codec->spec;
287 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
289 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
290 return 0;
293 static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
295 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
296 struct sigmatel_spec *spec = codec->spec;
297 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
299 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
300 spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]);
303 #define stac92xx_aloopback_info snd_ctl_boolean_mono_info
305 static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol,
306 struct snd_ctl_elem_value *ucontrol)
308 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
309 struct sigmatel_spec *spec = codec->spec;
311 ucontrol->value.integer.value[0] = spec->aloopback;
312 return 0;
315 static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol,
316 struct snd_ctl_elem_value *ucontrol)
318 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
319 struct sigmatel_spec *spec = codec->spec;
320 unsigned int dac_mode;
322 if (spec->aloopback == ucontrol->value.integer.value[0])
323 return 0;
325 spec->aloopback = ucontrol->value.integer.value[0];
328 dac_mode = snd_hda_codec_read(codec, codec->afg, 0,
329 kcontrol->private_value & 0xFFFF, 0x0);
331 if (spec->aloopback) {
332 snd_hda_power_up(codec);
333 dac_mode |= 0x40;
334 } else {
335 snd_hda_power_down(codec);
336 dac_mode &= ~0x40;
339 snd_hda_codec_write_cache(codec, codec->afg, 0,
340 kcontrol->private_value >> 16, dac_mode);
342 return 1;
345 static int stac92xx_volknob_info(struct snd_kcontrol *kcontrol,
346 struct snd_ctl_elem_info *uinfo)
348 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
349 uinfo->count = 1;
350 uinfo->value.integer.min = 0;
351 uinfo->value.integer.max = 127;
352 return 0;
355 static int stac92xx_volknob_get(struct snd_kcontrol *kcontrol,
356 struct snd_ctl_elem_value *ucontrol)
358 ucontrol->value.integer.value[0] = kcontrol->private_value & 0xff;
359 return 0;
362 static int stac92xx_volknob_put(struct snd_kcontrol *kcontrol,
363 struct snd_ctl_elem_value *ucontrol)
365 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
366 unsigned int val = kcontrol->private_value & 0xff;
368 if (val == ucontrol->value.integer.value[0])
369 return 0;
371 val = ucontrol->value.integer.value[0];
372 kcontrol->private_value &= ~0xff;
373 kcontrol->private_value |= val;
375 snd_hda_codec_write_cache(codec, kcontrol->private_value >> 16, 0,
376 AC_VERB_SET_VOLUME_KNOB_CONTROL, val | 0x80);
377 return 1;
381 static struct hda_verb stac9200_core_init[] = {
382 /* set dac0mux for dac converter */
383 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
387 static struct hda_verb stac9200_eapd_init[] = {
388 /* set dac0mux for dac converter */
389 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
390 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
394 static struct hda_verb stac925x_core_init[] = {
395 /* set dac0mux for dac converter */
396 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
400 static struct hda_verb stac922x_core_init[] = {
401 /* set master volume and direct control */
402 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
406 static struct hda_verb d965_core_init[] = {
407 /* set master volume and direct control */
408 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
409 /* unmute node 0x1b */
410 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
411 /* select node 0x03 as DAC */
412 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
416 static struct hda_verb stac927x_core_init[] = {
417 /* set master volume and direct control */
418 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
422 static struct hda_verb stac9205_core_init[] = {
423 /* set master volume and direct control */
424 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
428 #define STAC_INPUT_SOURCE(cnt) \
430 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
431 .name = "Input Source", \
432 .count = cnt, \
433 .info = stac92xx_mux_enum_info, \
434 .get = stac92xx_mux_enum_get, \
435 .put = stac92xx_mux_enum_put, \
438 #define STAC_ANALOG_LOOPBACK(verb_read,verb_write) \
440 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
441 .name = "Analog Loopback", \
442 .count = 1, \
443 .info = stac92xx_aloopback_info, \
444 .get = stac92xx_aloopback_get, \
445 .put = stac92xx_aloopback_put, \
446 .private_value = verb_read | (verb_write << 16), \
449 #define STAC_VOLKNOB(knob_nid) \
451 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
452 .name = "Master Playback Volume", \
453 .count = 1, \
454 .info = stac92xx_volknob_info, \
455 .get = stac92xx_volknob_get, \
456 .put = stac92xx_volknob_put, \
457 .private_value = 127 | (knob_nid << 16), \
461 static struct snd_kcontrol_new stac9200_mixer[] = {
462 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
463 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
464 STAC_INPUT_SOURCE(1),
465 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
466 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
467 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT),
468 { } /* end */
471 static struct snd_kcontrol_new stac925x_mixer[] = {
472 STAC_INPUT_SOURCE(1),
473 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
474 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT),
475 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT),
476 { } /* end */
479 static struct snd_kcontrol_new stac9205_mixer[] = {
481 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
482 .name = "Digital Input Source",
483 .count = 1,
484 .info = stac92xx_dmux_enum_info,
485 .get = stac92xx_dmux_enum_get,
486 .put = stac92xx_dmux_enum_put,
488 STAC_INPUT_SOURCE(2),
489 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0),
490 STAC_VOLKNOB(0x24),
492 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT),
493 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT),
494 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x19, 0x0, HDA_OUTPUT),
496 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT),
497 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT),
498 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x1A, 0x0, HDA_OUTPUT),
500 { } /* end */
503 /* This needs to be generated dynamically based on sequence */
504 static struct snd_kcontrol_new stac922x_mixer[] = {
505 STAC_INPUT_SOURCE(2),
506 STAC_VOLKNOB(0x16),
507 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT),
508 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT),
509 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x12, 0x0, HDA_OUTPUT),
511 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT),
512 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT),
513 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x13, 0x0, HDA_OUTPUT),
514 { } /* end */
518 static struct snd_kcontrol_new stac927x_mixer[] = {
519 STAC_INPUT_SOURCE(3),
520 STAC_VOLKNOB(0x24),
521 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB),
523 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT),
524 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT),
525 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x15, 0x0, HDA_OUTPUT),
527 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT),
528 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT),
529 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x16, 0x0, HDA_OUTPUT),
531 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT),
532 HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT),
533 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x2, 0x17, 0x0, HDA_OUTPUT),
534 { } /* end */
537 static int stac92xx_build_controls(struct hda_codec *codec)
539 struct sigmatel_spec *spec = codec->spec;
540 int err;
541 int i;
543 err = snd_hda_add_new_ctls(codec, spec->mixer);
544 if (err < 0)
545 return err;
547 for (i = 0; i < spec->num_mixers; i++) {
548 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
549 if (err < 0)
550 return err;
553 if (spec->multiout.dig_out_nid) {
554 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
555 if (err < 0)
556 return err;
558 if (spec->dig_in_nid) {
559 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
560 if (err < 0)
561 return err;
563 return 0;
566 static unsigned int ref9200_pin_configs[8] = {
567 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
568 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
572 STAC 9200 pin configs for
573 102801A8
574 102801DE
575 102801E8
577 static unsigned int dell9200_d21_pin_configs[8] = {
578 0x400001f0, 0x400001f1, 0x02214030, 0x01014010,
579 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
583 STAC 9200 pin configs for
584 102801C0
585 102801C1
587 static unsigned int dell9200_d22_pin_configs[8] = {
588 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
589 0x01813020, 0x02a19021, 0x90100140, 0x400001f2,
593 STAC 9200 pin configs for
594 102801C4 (Dell Dimension E310)
595 102801C5
596 102801C7
597 102801D9
598 102801DA
599 102801E3
601 static unsigned int dell9200_d23_pin_configs[8] = {
602 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
603 0x01813020, 0x01a19021, 0x90100140, 0x400001f2,
608 STAC 9200-32 pin configs for
609 102801B5 (Dell Inspiron 630m)
610 102801D8 (Dell Inspiron 640m)
612 static unsigned int dell9200_m21_pin_configs[8] = {
613 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310,
614 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd,
618 STAC 9200-32 pin configs for
619 102801C2 (Dell Latitude D620)
620 102801C8
621 102801CC (Dell Latitude D820)
622 102801D4
623 102801D6
625 static unsigned int dell9200_m22_pin_configs[8] = {
626 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310,
627 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc,
631 STAC 9200-32 pin configs for
632 102801CE (Dell XPS M1710)
633 102801CF (Dell Precision M90)
635 static unsigned int dell9200_m23_pin_configs[8] = {
636 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310,
637 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc,
641 STAC 9200-32 pin configs for
642 102801C9
643 102801CA
644 102801CB (Dell Latitude 120L)
645 102801D3
647 static unsigned int dell9200_m24_pin_configs[8] = {
648 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310,
649 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe,
653 STAC 9200-32 pin configs for
654 102801BD (Dell Inspiron E1505n)
655 102801EE
656 102801EF
658 static unsigned int dell9200_m25_pin_configs[8] = {
659 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
660 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd,
664 STAC 9200-32 pin configs for
665 102801F5 (Dell Inspiron 1501)
666 102801F6
668 static unsigned int dell9200_m26_pin_configs[8] = {
669 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310,
670 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe,
674 STAC 9200-32
675 102801CD (Dell Inspiron E1705/9400)
677 static unsigned int dell9200_m27_pin_configs[8] = {
678 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
679 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc,
683 static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
684 [STAC_REF] = ref9200_pin_configs,
685 [STAC_9200_DELL_D21] = dell9200_d21_pin_configs,
686 [STAC_9200_DELL_D22] = dell9200_d22_pin_configs,
687 [STAC_9200_DELL_D23] = dell9200_d23_pin_configs,
688 [STAC_9200_DELL_M21] = dell9200_m21_pin_configs,
689 [STAC_9200_DELL_M22] = dell9200_m22_pin_configs,
690 [STAC_9200_DELL_M23] = dell9200_m23_pin_configs,
691 [STAC_9200_DELL_M24] = dell9200_m24_pin_configs,
692 [STAC_9200_DELL_M25] = dell9200_m25_pin_configs,
693 [STAC_9200_DELL_M26] = dell9200_m26_pin_configs,
694 [STAC_9200_DELL_M27] = dell9200_m27_pin_configs,
697 static const char *stac9200_models[STAC_9200_MODELS] = {
698 [STAC_REF] = "ref",
699 [STAC_9200_DELL_D21] = "dell-d21",
700 [STAC_9200_DELL_D22] = "dell-d22",
701 [STAC_9200_DELL_D23] = "dell-d23",
702 [STAC_9200_DELL_M21] = "dell-m21",
703 [STAC_9200_DELL_M22] = "dell-m22",
704 [STAC_9200_DELL_M23] = "dell-m23",
705 [STAC_9200_DELL_M24] = "dell-m24",
706 [STAC_9200_DELL_M25] = "dell-m25",
707 [STAC_9200_DELL_M26] = "dell-m26",
708 [STAC_9200_DELL_M27] = "dell-m27",
709 [STAC_9200_GATEWAY] = "gateway",
712 static struct snd_pci_quirk stac9200_cfg_tbl[] = {
713 /* SigmaTel reference board */
714 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
715 "DFI LanParty", STAC_REF),
716 /* Dell laptops have BIOS problem */
717 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
718 "unknown Dell", STAC_9200_DELL_D21),
719 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
720 "Dell Inspiron 630m", STAC_9200_DELL_M21),
721 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
722 "Dell Inspiron E1505n", STAC_9200_DELL_M25),
723 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
724 "unknown Dell", STAC_9200_DELL_D22),
725 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
726 "unknown Dell", STAC_9200_DELL_D22),
727 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
728 "Dell Latitude D620", STAC_9200_DELL_M22),
729 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
730 "unknown Dell", STAC_9200_DELL_D23),
731 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
732 "unknown Dell", STAC_9200_DELL_D23),
733 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
734 "unknown Dell", STAC_9200_DELL_M22),
735 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
736 "unknown Dell", STAC_9200_DELL_M24),
737 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
738 "unknown Dell", STAC_9200_DELL_M24),
739 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
740 "Dell Latitude 120L", STAC_9200_DELL_M24),
741 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
742 "Dell Latitude D820", STAC_9200_DELL_M22),
743 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
744 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
745 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
746 "Dell XPS M1710", STAC_9200_DELL_M23),
747 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
748 "Dell Precision M90", STAC_9200_DELL_M23),
749 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
750 "unknown Dell", STAC_9200_DELL_M22),
751 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
752 "unknown Dell", STAC_9200_DELL_M22),
753 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
754 "unknown Dell", STAC_9200_DELL_M22),
755 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
756 "Dell Inspiron 640m", STAC_9200_DELL_M21),
757 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
758 "unknown Dell", STAC_9200_DELL_D23),
759 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
760 "unknown Dell", STAC_9200_DELL_D23),
761 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
762 "unknown Dell", STAC_9200_DELL_D21),
763 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
764 "unknown Dell", STAC_9200_DELL_D23),
765 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
766 "unknown Dell", STAC_9200_DELL_D21),
767 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
768 "unknown Dell", STAC_9200_DELL_M25),
769 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
770 "unknown Dell", STAC_9200_DELL_M25),
771 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
772 "Dell Inspiron 1501", STAC_9200_DELL_M26),
773 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
774 "unknown Dell", STAC_9200_DELL_M26),
775 /* Panasonic */
776 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_REF),
777 /* Gateway machines needs EAPD to be set on resume */
778 SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY),
779 SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*",
780 STAC_9200_GATEWAY),
781 SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707",
782 STAC_9200_GATEWAY),
783 {} /* terminator */
786 static unsigned int ref925x_pin_configs[8] = {
787 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
788 0x90a70320, 0x02214210, 0x400003f1, 0x9033032e,
791 static unsigned int stac925x_MA6_pin_configs[8] = {
792 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
793 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e,
796 static unsigned int stac925x_PA6_pin_configs[8] = {
797 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
798 0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e,
801 static unsigned int stac925xM2_2_pin_configs[8] = {
802 0x40c003f3, 0x424503f2, 0x04180011, 0x02a19020,
803 0x50a103f0, 0x90100212, 0x400003f1, 0x9033032e,
806 static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
807 [STAC_REF] = ref925x_pin_configs,
808 [STAC_M2_2] = stac925xM2_2_pin_configs,
809 [STAC_MA6] = stac925x_MA6_pin_configs,
810 [STAC_PA6] = stac925x_PA6_pin_configs,
813 static const char *stac925x_models[STAC_925x_MODELS] = {
814 [STAC_REF] = "ref",
815 [STAC_M2_2] = "m2-2",
816 [STAC_MA6] = "m6",
817 [STAC_PA6] = "pa6",
820 static struct snd_pci_quirk stac925x_cfg_tbl[] = {
821 /* SigmaTel reference board */
822 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
823 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
824 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF),
825 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF),
826 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6),
827 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_PA6),
828 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2),
829 {} /* terminator */
832 static unsigned int ref922x_pin_configs[10] = {
833 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
834 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
835 0x40000100, 0x40000100,
839 STAC 922X pin configs for
840 102801A7
841 102801AB
842 102801A9
843 102801D1
844 102801D2
846 static unsigned int dell_922x_d81_pin_configs[10] = {
847 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
848 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1,
849 0x01813122, 0x400001f2,
853 STAC 922X pin configs for
854 102801AC
855 102801D0
857 static unsigned int dell_922x_d82_pin_configs[10] = {
858 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
859 0x02a19020, 0x01117011, 0x01451140, 0x400001f0,
860 0x01813122, 0x400001f1,
864 STAC 922X pin configs for
865 102801BF
867 static unsigned int dell_922x_m81_pin_configs[10] = {
868 0x0321101f, 0x01112024, 0x01111222, 0x91174220,
869 0x03a11050, 0x01116221, 0x90a70330, 0x01452340,
870 0x40C003f1, 0x405003f0,
874 STAC 9221 A1 pin configs for
875 102801D7 (Dell XPS M1210)
877 static unsigned int dell_922x_m82_pin_configs[10] = {
878 0x0221121f, 0x408103ff, 0x02111212, 0x90100310,
879 0x408003f1, 0x02111211, 0x03451340, 0x40c003f2,
880 0x508003f3, 0x405003f4,
883 static unsigned int d945gtp3_pin_configs[10] = {
884 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
885 0x40000100, 0x40000100, 0x40000100, 0x40000100,
886 0x02a19120, 0x40000100,
889 static unsigned int d945gtp5_pin_configs[10] = {
890 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
891 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
892 0x02a19320, 0x40000100,
895 static unsigned int intel_mac_v1_pin_configs[10] = {
896 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd,
897 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240,
898 0x400000fc, 0x400000fb,
901 static unsigned int intel_mac_v2_pin_configs[10] = {
902 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
903 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa,
904 0x400000fc, 0x400000fb,
907 static unsigned int intel_mac_v3_pin_configs[10] = {
908 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
909 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240,
910 0x400000fc, 0x400000fb,
913 static unsigned int intel_mac_v4_pin_configs[10] = {
914 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
915 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
916 0x400000fc, 0x400000fb,
919 static unsigned int intel_mac_v5_pin_configs[10] = {
920 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
921 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
922 0x400000fc, 0x400000fb,
926 static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
927 [STAC_D945_REF] = ref922x_pin_configs,
928 [STAC_D945GTP3] = d945gtp3_pin_configs,
929 [STAC_D945GTP5] = d945gtp5_pin_configs,
930 [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs,
931 [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs,
932 [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs,
933 [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs,
934 [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs,
935 /* for backward compatibility */
936 [STAC_MACMINI] = intel_mac_v3_pin_configs,
937 [STAC_MACBOOK] = intel_mac_v5_pin_configs,
938 [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs,
939 [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs,
940 [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs,
941 [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs,
942 [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs,
943 [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs,
944 [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs,
945 [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs,
948 static const char *stac922x_models[STAC_922X_MODELS] = {
949 [STAC_D945_REF] = "ref",
950 [STAC_D945GTP5] = "5stack",
951 [STAC_D945GTP3] = "3stack",
952 [STAC_INTEL_MAC_V1] = "intel-mac-v1",
953 [STAC_INTEL_MAC_V2] = "intel-mac-v2",
954 [STAC_INTEL_MAC_V3] = "intel-mac-v3",
955 [STAC_INTEL_MAC_V4] = "intel-mac-v4",
956 [STAC_INTEL_MAC_V5] = "intel-mac-v5",
957 /* for backward compatibility */
958 [STAC_MACMINI] = "macmini",
959 [STAC_MACBOOK] = "macbook",
960 [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1",
961 [STAC_MACBOOK_PRO_V2] = "macbook-pro",
962 [STAC_IMAC_INTEL] = "imac-intel",
963 [STAC_IMAC_INTEL_20] = "imac-intel-20",
964 [STAC_922X_DELL_D81] = "dell-d81",
965 [STAC_922X_DELL_D82] = "dell-d82",
966 [STAC_922X_DELL_M81] = "dell-m81",
967 [STAC_922X_DELL_M82] = "dell-m82",
970 static struct snd_pci_quirk stac922x_cfg_tbl[] = {
971 /* SigmaTel reference board */
972 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
973 "DFI LanParty", STAC_D945_REF),
974 /* Intel 945G based systems */
975 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
976 "Intel D945G", STAC_D945GTP3),
977 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
978 "Intel D945G", STAC_D945GTP3),
979 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
980 "Intel D945G", STAC_D945GTP3),
981 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
982 "Intel D945G", STAC_D945GTP3),
983 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
984 "Intel D945G", STAC_D945GTP3),
985 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
986 "Intel D945G", STAC_D945GTP3),
987 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
988 "Intel D945G", STAC_D945GTP3),
989 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
990 "Intel D945G", STAC_D945GTP3),
991 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
992 "Intel D945G", STAC_D945GTP3),
993 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
994 "Intel D945G", STAC_D945GTP3),
995 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
996 "Intel D945G", STAC_D945GTP3),
997 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
998 "Intel D945G", STAC_D945GTP3),
999 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
1000 "Intel D945G", STAC_D945GTP3),
1001 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
1002 "Intel D945G", STAC_D945GTP3),
1003 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
1004 "Intel D945G", STAC_D945GTP3),
1005 /* Intel D945G 5-stack systems */
1006 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
1007 "Intel D945G", STAC_D945GTP5),
1008 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
1009 "Intel D945G", STAC_D945GTP5),
1010 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
1011 "Intel D945G", STAC_D945GTP5),
1012 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
1013 "Intel D945G", STAC_D945GTP5),
1014 /* Intel 945P based systems */
1015 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
1016 "Intel D945P", STAC_D945GTP3),
1017 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
1018 "Intel D945P", STAC_D945GTP3),
1019 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
1020 "Intel D945P", STAC_D945GTP3),
1021 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
1022 "Intel D945P", STAC_D945GTP3),
1023 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
1024 "Intel D945P", STAC_D945GTP3),
1025 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
1026 "Intel D945P", STAC_D945GTP5),
1027 /* other systems */
1028 /* Apple Mac Mini (early 2006) */
1029 SND_PCI_QUIRK(0x8384, 0x7680,
1030 "Mac Mini", STAC_INTEL_MAC_V3),
1031 /* Dell systems */
1032 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
1033 "unknown Dell", STAC_922X_DELL_D81),
1034 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
1035 "unknown Dell", STAC_922X_DELL_D81),
1036 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
1037 "unknown Dell", STAC_922X_DELL_D81),
1038 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
1039 "unknown Dell", STAC_922X_DELL_D82),
1040 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
1041 "unknown Dell", STAC_922X_DELL_M81),
1042 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
1043 "unknown Dell", STAC_922X_DELL_D82),
1044 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
1045 "unknown Dell", STAC_922X_DELL_D81),
1046 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
1047 "unknown Dell", STAC_922X_DELL_D81),
1048 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
1049 "Dell XPS M1210", STAC_922X_DELL_M82),
1050 {} /* terminator */
1053 static unsigned int ref927x_pin_configs[14] = {
1054 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1055 0x01a19040, 0x01011012, 0x01016011, 0x0101201f,
1056 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070,
1057 0x01c42190, 0x40000100,
1060 static unsigned int d965_3st_pin_configs[14] = {
1061 0x0221401f, 0x02a19120, 0x40000100, 0x01014011,
1062 0x01a19021, 0x01813024, 0x40000100, 0x40000100,
1063 0x40000100, 0x40000100, 0x40000100, 0x40000100,
1064 0x40000100, 0x40000100
1067 static unsigned int d965_5st_pin_configs[14] = {
1068 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1069 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
1070 0x40000100, 0x40000100, 0x40000100, 0x01442070,
1071 0x40000100, 0x40000100
1074 static unsigned int dell_3st_pin_configs[14] = {
1075 0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
1076 0x01111212, 0x01116211, 0x01813050, 0x01112214,
1077 0x403003fa, 0x40000100, 0x40000100, 0x404003fb,
1078 0x40c003fc, 0x40000100
1081 static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
1082 [STAC_D965_REF] = ref927x_pin_configs,
1083 [STAC_D965_3ST] = d965_3st_pin_configs,
1084 [STAC_D965_5ST] = d965_5st_pin_configs,
1085 [STAC_DELL_3ST] = dell_3st_pin_configs,
1088 static const char *stac927x_models[STAC_927X_MODELS] = {
1089 [STAC_D965_REF] = "ref",
1090 [STAC_D965_3ST] = "3stack",
1091 [STAC_D965_5ST] = "5stack",
1092 [STAC_DELL_3ST] = "dell-3stack",
1095 static struct snd_pci_quirk stac927x_cfg_tbl[] = {
1096 /* SigmaTel reference board */
1097 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1098 "DFI LanParty", STAC_D965_REF),
1099 /* Intel 946 based systems */
1100 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
1101 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
1102 /* 965 based 3 stack systems */
1103 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2116, "Intel D965", STAC_D965_3ST),
1104 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2115, "Intel D965", STAC_D965_3ST),
1105 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2114, "Intel D965", STAC_D965_3ST),
1106 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2113, "Intel D965", STAC_D965_3ST),
1107 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2112, "Intel D965", STAC_D965_3ST),
1108 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2111, "Intel D965", STAC_D965_3ST),
1109 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2110, "Intel D965", STAC_D965_3ST),
1110 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2009, "Intel D965", STAC_D965_3ST),
1111 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2008, "Intel D965", STAC_D965_3ST),
1112 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2007, "Intel D965", STAC_D965_3ST),
1113 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2006, "Intel D965", STAC_D965_3ST),
1114 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2005, "Intel D965", STAC_D965_3ST),
1115 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2004, "Intel D965", STAC_D965_3ST),
1116 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST),
1117 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST),
1118 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST),
1119 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_D965_3ST),
1120 /* Dell 3 stack systems */
1121 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
1122 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
1123 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
1124 /* 965 based 5 stack systems */
1125 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_D965_5ST),
1126 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST),
1127 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST),
1128 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST),
1129 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2304, "Intel D965", STAC_D965_5ST),
1130 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2305, "Intel D965", STAC_D965_5ST),
1131 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2501, "Intel D965", STAC_D965_5ST),
1132 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2502, "Intel D965", STAC_D965_5ST),
1133 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2503, "Intel D965", STAC_D965_5ST),
1134 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2504, "Intel D965", STAC_D965_5ST),
1135 {} /* terminator */
1138 static unsigned int ref9205_pin_configs[12] = {
1139 0x40000100, 0x40000100, 0x01016011, 0x01014010,
1140 0x01813122, 0x01a19021, 0x40000100, 0x40000100,
1141 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
1145 STAC 9205 pin configs for
1146 102801F1
1147 102801F2
1148 102801FC
1149 102801FD
1150 10280204
1151 1028021F
1153 static unsigned int dell_9205_m42_pin_configs[12] = {
1154 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310,
1155 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9,
1156 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE,
1160 STAC 9205 pin configs for
1161 102801F9
1162 102801FA
1163 102801FE
1164 102801FF (Dell Precision M4300)
1165 10280206
1166 10280200
1167 10280201
1169 static unsigned int dell_9205_m43_pin_configs[12] = {
1170 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310,
1171 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9,
1172 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8,
1175 static unsigned int dell_9205_m44_pin_configs[12] = {
1176 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310,
1177 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9,
1178 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe,
1181 static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
1182 [STAC_9205_REF] = ref9205_pin_configs,
1183 [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs,
1184 [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs,
1185 [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs,
1188 static const char *stac9205_models[STAC_9205_MODELS] = {
1189 [STAC_9205_REF] = "ref",
1190 [STAC_9205_DELL_M42] = "dell-m42",
1191 [STAC_9205_DELL_M43] = "dell-m43",
1192 [STAC_9205_DELL_M44] = "dell-m44",
1195 static struct snd_pci_quirk stac9205_cfg_tbl[] = {
1196 /* SigmaTel reference board */
1197 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1198 "DFI LanParty", STAC_9205_REF),
1199 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1200 "unknown Dell", STAC_9205_DELL_M42),
1201 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1202 "unknown Dell", STAC_9205_DELL_M42),
1203 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
1204 "Dell Precision", STAC_9205_DELL_M43),
1205 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
1206 "Dell Precision", STAC_9205_DELL_M43),
1207 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
1208 "Dell Precision", STAC_9205_DELL_M43),
1209 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
1210 "Dell Precision", STAC_9205_DELL_M43),
1211 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
1212 "Dell Precision", STAC_9205_DELL_M43),
1213 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1214 "unknown Dell", STAC_9205_DELL_M42),
1215 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1216 "unknown Dell", STAC_9205_DELL_M42),
1217 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
1218 "Dell Precision", STAC_9205_DELL_M43),
1219 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
1220 "Dell Precision M4300", STAC_9205_DELL_M43),
1221 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
1222 "Dell Precision", STAC_9205_DELL_M43),
1223 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1224 "Dell Inspiron", STAC_9205_DELL_M44),
1225 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1226 "Dell Inspiron", STAC_9205_DELL_M44),
1227 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1228 "Dell Inspiron", STAC_9205_DELL_M44),
1229 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1230 "Dell Inspiron", STAC_9205_DELL_M44),
1231 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
1232 "unknown Dell", STAC_9205_DELL_M42),
1233 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
1234 "Dell Inspiron", STAC_9205_DELL_M44),
1235 {} /* terminator */
1238 static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
1240 int i;
1241 struct sigmatel_spec *spec = codec->spec;
1243 if (! spec->bios_pin_configs) {
1244 spec->bios_pin_configs = kcalloc(spec->num_pins,
1245 sizeof(*spec->bios_pin_configs), GFP_KERNEL);
1246 if (! spec->bios_pin_configs)
1247 return -ENOMEM;
1250 for (i = 0; i < spec->num_pins; i++) {
1251 hda_nid_t nid = spec->pin_nids[i];
1252 unsigned int pin_cfg;
1254 pin_cfg = snd_hda_codec_read(codec, nid, 0,
1255 AC_VERB_GET_CONFIG_DEFAULT, 0x00);
1256 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n",
1257 nid, pin_cfg);
1258 spec->bios_pin_configs[i] = pin_cfg;
1261 return 0;
1264 static void stac92xx_set_config_reg(struct hda_codec *codec,
1265 hda_nid_t pin_nid, unsigned int pin_config)
1267 int i;
1268 snd_hda_codec_write(codec, pin_nid, 0,
1269 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
1270 pin_config & 0x000000ff);
1271 snd_hda_codec_write(codec, pin_nid, 0,
1272 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
1273 (pin_config & 0x0000ff00) >> 8);
1274 snd_hda_codec_write(codec, pin_nid, 0,
1275 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
1276 (pin_config & 0x00ff0000) >> 16);
1277 snd_hda_codec_write(codec, pin_nid, 0,
1278 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
1279 pin_config >> 24);
1280 i = snd_hda_codec_read(codec, pin_nid, 0,
1281 AC_VERB_GET_CONFIG_DEFAULT,
1282 0x00);
1283 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n",
1284 pin_nid, i);
1287 static void stac92xx_set_config_regs(struct hda_codec *codec)
1289 int i;
1290 struct sigmatel_spec *spec = codec->spec;
1292 if (!spec->pin_configs)
1293 return;
1295 for (i = 0; i < spec->num_pins; i++)
1296 stac92xx_set_config_reg(codec, spec->pin_nids[i],
1297 spec->pin_configs[i]);
1300 static void stac92xx_enable_gpio_mask(struct hda_codec *codec)
1302 struct sigmatel_spec *spec = codec->spec;
1303 /* Configure GPIOx as output */
1304 snd_hda_codec_write_cache(codec, codec->afg, 0,
1305 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_mask);
1306 /* Configure GPIOx as CMOS */
1307 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7e7, 0x00000000);
1308 /* Assert GPIOx */
1309 snd_hda_codec_write_cache(codec, codec->afg, 0,
1310 AC_VERB_SET_GPIO_DATA, spec->gpio_data);
1311 /* Enable GPIOx */
1312 snd_hda_codec_write_cache(codec, codec->afg, 0,
1313 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
1317 * Analog playback callbacks
1319 static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
1320 struct hda_codec *codec,
1321 struct snd_pcm_substream *substream)
1323 struct sigmatel_spec *spec = codec->spec;
1324 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
1327 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1328 struct hda_codec *codec,
1329 unsigned int stream_tag,
1330 unsigned int format,
1331 struct snd_pcm_substream *substream)
1333 struct sigmatel_spec *spec = codec->spec;
1334 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream);
1337 static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1338 struct hda_codec *codec,
1339 struct snd_pcm_substream *substream)
1341 struct sigmatel_spec *spec = codec->spec;
1342 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1346 * Digital playback callbacks
1348 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1349 struct hda_codec *codec,
1350 struct snd_pcm_substream *substream)
1352 struct sigmatel_spec *spec = codec->spec;
1353 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1356 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1357 struct hda_codec *codec,
1358 struct snd_pcm_substream *substream)
1360 struct sigmatel_spec *spec = codec->spec;
1361 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1364 static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1365 struct hda_codec *codec,
1366 unsigned int stream_tag,
1367 unsigned int format,
1368 struct snd_pcm_substream *substream)
1370 struct sigmatel_spec *spec = codec->spec;
1371 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1372 stream_tag, format, substream);
1377 * Analog capture callbacks
1379 static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1380 struct hda_codec *codec,
1381 unsigned int stream_tag,
1382 unsigned int format,
1383 struct snd_pcm_substream *substream)
1385 struct sigmatel_spec *spec = codec->spec;
1387 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1388 stream_tag, 0, format);
1389 return 0;
1392 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1393 struct hda_codec *codec,
1394 struct snd_pcm_substream *substream)
1396 struct sigmatel_spec *spec = codec->spec;
1398 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
1399 return 0;
1402 static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
1403 .substreams = 1,
1404 .channels_min = 2,
1405 .channels_max = 2,
1406 /* NID is set in stac92xx_build_pcms */
1407 .ops = {
1408 .open = stac92xx_dig_playback_pcm_open,
1409 .close = stac92xx_dig_playback_pcm_close,
1410 .prepare = stac92xx_dig_playback_pcm_prepare
1414 static struct hda_pcm_stream stac92xx_pcm_digital_capture = {
1415 .substreams = 1,
1416 .channels_min = 2,
1417 .channels_max = 2,
1418 /* NID is set in stac92xx_build_pcms */
1421 static struct hda_pcm_stream stac92xx_pcm_analog_playback = {
1422 .substreams = 1,
1423 .channels_min = 2,
1424 .channels_max = 8,
1425 .nid = 0x02, /* NID to query formats and rates */
1426 .ops = {
1427 .open = stac92xx_playback_pcm_open,
1428 .prepare = stac92xx_playback_pcm_prepare,
1429 .cleanup = stac92xx_playback_pcm_cleanup
1433 static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
1434 .substreams = 1,
1435 .channels_min = 2,
1436 .channels_max = 2,
1437 .nid = 0x06, /* NID to query formats and rates */
1438 .ops = {
1439 .open = stac92xx_playback_pcm_open,
1440 .prepare = stac92xx_playback_pcm_prepare,
1441 .cleanup = stac92xx_playback_pcm_cleanup
1445 static struct hda_pcm_stream stac92xx_pcm_analog_capture = {
1446 .channels_min = 2,
1447 .channels_max = 2,
1448 /* NID + .substreams is set in stac92xx_build_pcms */
1449 .ops = {
1450 .prepare = stac92xx_capture_pcm_prepare,
1451 .cleanup = stac92xx_capture_pcm_cleanup
1455 static int stac92xx_build_pcms(struct hda_codec *codec)
1457 struct sigmatel_spec *spec = codec->spec;
1458 struct hda_pcm *info = spec->pcm_rec;
1460 codec->num_pcms = 1;
1461 codec->pcm_info = info;
1463 info->name = "STAC92xx Analog";
1464 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
1465 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
1466 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1467 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs;
1469 if (spec->alt_switch) {
1470 codec->num_pcms++;
1471 info++;
1472 info->name = "STAC92xx Analog Alt";
1473 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback;
1476 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1477 codec->num_pcms++;
1478 info++;
1479 info->name = "STAC92xx Digital";
1480 if (spec->multiout.dig_out_nid) {
1481 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
1482 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
1484 if (spec->dig_in_nid) {
1485 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture;
1486 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
1490 return 0;
1493 static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
1495 unsigned int pincap = snd_hda_param_read(codec, nid,
1496 AC_PAR_PIN_CAP);
1497 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
1498 if (pincap & AC_PINCAP_VREF_100)
1499 return AC_PINCTL_VREF_100;
1500 if (pincap & AC_PINCAP_VREF_80)
1501 return AC_PINCTL_VREF_80;
1502 if (pincap & AC_PINCAP_VREF_50)
1503 return AC_PINCTL_VREF_50;
1504 if (pincap & AC_PINCAP_VREF_GRD)
1505 return AC_PINCTL_VREF_GRD;
1506 return 0;
1509 static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
1512 snd_hda_codec_write_cache(codec, nid, 0,
1513 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
1516 #define stac92xx_io_switch_info snd_ctl_boolean_mono_info
1518 static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1520 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1521 struct sigmatel_spec *spec = codec->spec;
1522 int io_idx = kcontrol-> private_value & 0xff;
1524 ucontrol->value.integer.value[0] = spec->io_switch[io_idx];
1525 return 0;
1528 static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1530 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1531 struct sigmatel_spec *spec = codec->spec;
1532 hda_nid_t nid = kcontrol->private_value >> 8;
1533 int io_idx = kcontrol-> private_value & 0xff;
1534 unsigned short val = ucontrol->value.integer.value[0];
1536 spec->io_switch[io_idx] = val;
1538 if (val)
1539 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
1540 else {
1541 unsigned int pinctl = AC_PINCTL_IN_EN;
1542 if (io_idx) /* set VREF for mic */
1543 pinctl |= stac92xx_get_vref(codec, nid);
1544 stac92xx_auto_set_pinctl(codec, nid, pinctl);
1546 return 1;
1549 #define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info
1551 static int stac92xx_clfe_switch_get(struct snd_kcontrol *kcontrol,
1552 struct snd_ctl_elem_value *ucontrol)
1554 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1555 struct sigmatel_spec *spec = codec->spec;
1557 ucontrol->value.integer.value[0] = spec->clfe_swap;
1558 return 0;
1561 static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
1562 struct snd_ctl_elem_value *ucontrol)
1564 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1565 struct sigmatel_spec *spec = codec->spec;
1566 hda_nid_t nid = kcontrol->private_value & 0xff;
1568 if (spec->clfe_swap == ucontrol->value.integer.value[0])
1569 return 0;
1571 spec->clfe_swap = ucontrol->value.integer.value[0];
1573 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1574 spec->clfe_swap ? 0x4 : 0x0);
1576 return 1;
1579 #define STAC_CODEC_IO_SWITCH(xname, xpval) \
1580 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1581 .name = xname, \
1582 .index = 0, \
1583 .info = stac92xx_io_switch_info, \
1584 .get = stac92xx_io_switch_get, \
1585 .put = stac92xx_io_switch_put, \
1586 .private_value = xpval, \
1589 #define STAC_CODEC_CLFE_SWITCH(xname, xpval) \
1590 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1591 .name = xname, \
1592 .index = 0, \
1593 .info = stac92xx_clfe_switch_info, \
1594 .get = stac92xx_clfe_switch_get, \
1595 .put = stac92xx_clfe_switch_put, \
1596 .private_value = xpval, \
1599 enum {
1600 STAC_CTL_WIDGET_VOL,
1601 STAC_CTL_WIDGET_MUTE,
1602 STAC_CTL_WIDGET_IO_SWITCH,
1603 STAC_CTL_WIDGET_CLFE_SWITCH
1606 static struct snd_kcontrol_new stac92xx_control_templates[] = {
1607 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
1608 HDA_CODEC_MUTE(NULL, 0, 0, 0),
1609 STAC_CODEC_IO_SWITCH(NULL, 0),
1610 STAC_CODEC_CLFE_SWITCH(NULL, 0),
1613 /* add dynamic controls */
1614 static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val)
1616 struct snd_kcontrol_new *knew;
1618 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
1619 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
1621 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
1622 if (! knew)
1623 return -ENOMEM;
1624 if (spec->kctl_alloc) {
1625 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
1626 kfree(spec->kctl_alloc);
1628 spec->kctl_alloc = knew;
1629 spec->num_kctl_alloc = num;
1632 knew = &spec->kctl_alloc[spec->num_kctl_used];
1633 *knew = stac92xx_control_templates[type];
1634 knew->name = kstrdup(name, GFP_KERNEL);
1635 if (! knew->name)
1636 return -ENOMEM;
1637 knew->private_value = val;
1638 spec->num_kctl_used++;
1639 return 0;
1642 /* flag inputs as additional dynamic lineouts */
1643 static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
1645 struct sigmatel_spec *spec = codec->spec;
1646 unsigned int wcaps, wtype;
1647 int i, num_dacs = 0;
1649 /* use the wcaps cache to count all DACs available for line-outs */
1650 for (i = 0; i < codec->num_nodes; i++) {
1651 wcaps = codec->wcaps[i];
1652 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
1653 if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL))
1654 num_dacs++;
1657 snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
1659 switch (cfg->line_outs) {
1660 case 3:
1661 /* add line-in as side */
1662 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
1663 cfg->line_out_pins[cfg->line_outs] =
1664 cfg->input_pins[AUTO_PIN_LINE];
1665 spec->line_switch = 1;
1666 cfg->line_outs++;
1668 break;
1669 case 2:
1670 /* add line-in as clfe and mic as side */
1671 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
1672 cfg->line_out_pins[cfg->line_outs] =
1673 cfg->input_pins[AUTO_PIN_LINE];
1674 spec->line_switch = 1;
1675 cfg->line_outs++;
1677 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
1678 cfg->line_out_pins[cfg->line_outs] =
1679 cfg->input_pins[AUTO_PIN_MIC];
1680 spec->mic_switch = 1;
1681 cfg->line_outs++;
1683 break;
1684 case 1:
1685 /* add line-in as surr and mic as clfe */
1686 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
1687 cfg->line_out_pins[cfg->line_outs] =
1688 cfg->input_pins[AUTO_PIN_LINE];
1689 spec->line_switch = 1;
1690 cfg->line_outs++;
1692 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
1693 cfg->line_out_pins[cfg->line_outs] =
1694 cfg->input_pins[AUTO_PIN_MIC];
1695 spec->mic_switch = 1;
1696 cfg->line_outs++;
1698 break;
1701 return 0;
1705 static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
1707 int i;
1709 for (i = 0; i < spec->multiout.num_dacs; i++) {
1710 if (spec->multiout.dac_nids[i] == nid)
1711 return 1;
1714 return 0;
1718 * Fill in the dac_nids table from the parsed pin configuration
1719 * This function only works when every pin in line_out_pins[]
1720 * contains atleast one DAC in its connection list. Some 92xx
1721 * codecs are not connected directly to a DAC, such as the 9200
1722 * and 9202/925x. For those, dac_nids[] must be hard-coded.
1724 static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
1725 struct auto_pin_cfg *cfg)
1727 struct sigmatel_spec *spec = codec->spec;
1728 int i, j, conn_len = 0;
1729 hda_nid_t nid, conn[HDA_MAX_CONNECTIONS];
1730 unsigned int wcaps, wtype;
1732 for (i = 0; i < cfg->line_outs; i++) {
1733 nid = cfg->line_out_pins[i];
1734 conn_len = snd_hda_get_connections(codec, nid, conn,
1735 HDA_MAX_CONNECTIONS);
1736 for (j = 0; j < conn_len; j++) {
1737 wcaps = snd_hda_param_read(codec, conn[j],
1738 AC_PAR_AUDIO_WIDGET_CAP);
1739 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
1741 if (wtype != AC_WID_AUD_OUT ||
1742 (wcaps & AC_WCAP_DIGITAL))
1743 continue;
1744 /* conn[j] is a DAC routed to this line-out */
1745 if (!is_in_dac_nids(spec, conn[j]))
1746 break;
1749 if (j == conn_len) {
1750 if (spec->multiout.num_dacs > 0) {
1751 /* we have already working output pins,
1752 * so let's drop the broken ones again
1754 cfg->line_outs = spec->multiout.num_dacs;
1755 break;
1757 /* error out, no available DAC found */
1758 snd_printk(KERN_ERR
1759 "%s: No available DAC for pin 0x%x\n",
1760 __func__, nid);
1761 return -ENODEV;
1764 spec->multiout.dac_nids[i] = conn[j];
1765 spec->multiout.num_dacs++;
1766 if (conn_len > 1) {
1767 /* select this DAC in the pin's input mux */
1768 snd_hda_codec_write_cache(codec, nid, 0,
1769 AC_VERB_SET_CONNECT_SEL, j);
1774 snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
1775 spec->multiout.num_dacs,
1776 spec->multiout.dac_nids[0],
1777 spec->multiout.dac_nids[1],
1778 spec->multiout.dac_nids[2],
1779 spec->multiout.dac_nids[3],
1780 spec->multiout.dac_nids[4]);
1781 return 0;
1784 /* create volume control/switch for the given prefx type */
1785 static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_t nid, int chs)
1787 char name[32];
1788 int err;
1790 sprintf(name, "%s Playback Volume", pfx);
1791 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name,
1792 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1793 if (err < 0)
1794 return err;
1795 sprintf(name, "%s Playback Switch", pfx);
1796 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name,
1797 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1798 if (err < 0)
1799 return err;
1800 return 0;
1803 /* add playback controls from the parsed DAC table */
1804 static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
1805 const struct auto_pin_cfg *cfg)
1807 static const char *chname[4] = {
1808 "Front", "Surround", NULL /*CLFE*/, "Side"
1810 hda_nid_t nid;
1811 int i, err;
1813 struct sigmatel_spec *spec = codec->spec;
1814 unsigned int wid_caps;
1817 for (i = 0; i < cfg->line_outs; i++) {
1818 if (!spec->multiout.dac_nids[i])
1819 continue;
1821 nid = spec->multiout.dac_nids[i];
1823 if (i == 2) {
1824 /* Center/LFE */
1825 err = create_controls(spec, "Center", nid, 1);
1826 if (err < 0)
1827 return err;
1828 err = create_controls(spec, "LFE", nid, 2);
1829 if (err < 0)
1830 return err;
1832 wid_caps = get_wcaps(codec, nid);
1834 if (wid_caps & AC_WCAP_LR_SWAP) {
1835 err = stac92xx_add_control(spec,
1836 STAC_CTL_WIDGET_CLFE_SWITCH,
1837 "Swap Center/LFE Playback Switch", nid);
1839 if (err < 0)
1840 return err;
1843 } else {
1844 err = create_controls(spec, chname[i], nid, 3);
1845 if (err < 0)
1846 return err;
1850 if (spec->line_switch)
1851 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Line In as Output Switch", cfg->input_pins[AUTO_PIN_LINE] << 8)) < 0)
1852 return err;
1854 if (spec->mic_switch)
1855 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Mic as Output Switch", (cfg->input_pins[AUTO_PIN_MIC] << 8) | 1)) < 0)
1856 return err;
1858 return 0;
1861 static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
1863 if (is_in_dac_nids(spec, nid))
1864 return 1;
1865 if (spec->multiout.hp_nid == nid)
1866 return 1;
1867 return 0;
1870 static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
1872 if (!spec->multiout.hp_nid)
1873 spec->multiout.hp_nid = nid;
1874 else if (spec->multiout.num_dacs > 4) {
1875 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
1876 return 1;
1877 } else {
1878 spec->multiout.dac_nids[spec->multiout.num_dacs] = nid;
1879 spec->multiout.num_dacs++;
1881 return 0;
1884 /* add playback controls for Speaker and HP outputs */
1885 static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
1886 struct auto_pin_cfg *cfg)
1888 struct sigmatel_spec *spec = codec->spec;
1889 hda_nid_t nid;
1890 int i, old_num_dacs, err;
1892 old_num_dacs = spec->multiout.num_dacs;
1893 for (i = 0; i < cfg->hp_outs; i++) {
1894 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]);
1895 if (wid_caps & AC_WCAP_UNSOL_CAP)
1896 spec->hp_detect = 1;
1897 nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
1898 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1899 if (check_in_dac_nids(spec, nid))
1900 nid = 0;
1901 if (! nid)
1902 continue;
1903 add_spec_dacs(spec, nid);
1905 for (i = 0; i < cfg->speaker_outs; i++) {
1906 nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
1907 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1908 if (check_in_dac_nids(spec, nid))
1909 nid = 0;
1910 if (! nid)
1911 continue;
1912 add_spec_dacs(spec, nid);
1914 for (i = 0; i < cfg->line_outs; i++) {
1915 nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0,
1916 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1917 if (check_in_dac_nids(spec, nid))
1918 nid = 0;
1919 if (! nid)
1920 continue;
1921 add_spec_dacs(spec, nid);
1923 for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) {
1924 static const char *pfxs[] = {
1925 "Speaker", "External Speaker", "Speaker2",
1927 err = create_controls(spec, pfxs[i - old_num_dacs],
1928 spec->multiout.dac_nids[i], 3);
1929 if (err < 0)
1930 return err;
1932 if (spec->multiout.hp_nid) {
1933 const char *pfx;
1934 if (old_num_dacs == spec->multiout.num_dacs &&
1935 spec->no_vol_knob)
1936 pfx = "Master";
1937 else
1938 pfx = "Headphone";
1939 err = create_controls(spec, pfx, spec->multiout.hp_nid, 3);
1940 if (err < 0)
1941 return err;
1944 return 0;
1947 /* labels for dmic mux inputs */
1948 static const char *stac92xx_dmic_labels[5] = {
1949 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
1950 "Digital Mic 3", "Digital Mic 4"
1953 /* create playback/capture controls for input pins on dmic capable codecs */
1954 static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
1955 const struct auto_pin_cfg *cfg)
1957 struct sigmatel_spec *spec = codec->spec;
1958 struct hda_input_mux *dimux = &spec->private_dimux;
1959 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
1960 int i, j;
1962 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0];
1963 dimux->items[dimux->num_items].index = 0;
1964 dimux->num_items++;
1966 for (i = 0; i < spec->num_dmics; i++) {
1967 int index;
1968 int num_cons;
1969 unsigned int def_conf;
1971 def_conf = snd_hda_codec_read(codec,
1972 spec->dmic_nids[i],
1974 AC_VERB_GET_CONFIG_DEFAULT,
1976 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
1977 continue;
1979 num_cons = snd_hda_get_connections(codec,
1980 spec->dmux_nid,
1981 con_lst,
1982 HDA_MAX_NUM_INPUTS);
1983 for (j = 0; j < num_cons; j++)
1984 if (con_lst[j] == spec->dmic_nids[i]) {
1985 index = j;
1986 goto found;
1988 continue;
1989 found:
1990 dimux->items[dimux->num_items].label =
1991 stac92xx_dmic_labels[dimux->num_items];
1992 dimux->items[dimux->num_items].index = index;
1993 dimux->num_items++;
1996 return 0;
1999 /* create playback/capture controls for input pins */
2000 static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
2002 struct sigmatel_spec *spec = codec->spec;
2003 struct hda_input_mux *imux = &spec->private_imux;
2004 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
2005 int i, j, k;
2007 for (i = 0; i < AUTO_PIN_LAST; i++) {
2008 int index;
2010 if (!cfg->input_pins[i])
2011 continue;
2012 index = -1;
2013 for (j = 0; j < spec->num_muxes; j++) {
2014 int num_cons;
2015 num_cons = snd_hda_get_connections(codec,
2016 spec->mux_nids[j],
2017 con_lst,
2018 HDA_MAX_NUM_INPUTS);
2019 for (k = 0; k < num_cons; k++)
2020 if (con_lst[k] == cfg->input_pins[i]) {
2021 index = k;
2022 goto found;
2025 continue;
2026 found:
2027 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2028 imux->items[imux->num_items].index = index;
2029 imux->num_items++;
2032 if (imux->num_items) {
2034 * Set the current input for the muxes.
2035 * The STAC9221 has two input muxes with identical source
2036 * NID lists. Hopefully this won't get confused.
2038 for (i = 0; i < spec->num_muxes; i++) {
2039 snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0,
2040 AC_VERB_SET_CONNECT_SEL,
2041 imux->items[0].index);
2045 return 0;
2048 static void stac92xx_auto_init_multi_out(struct hda_codec *codec)
2050 struct sigmatel_spec *spec = codec->spec;
2051 int i;
2053 for (i = 0; i < spec->autocfg.line_outs; i++) {
2054 hda_nid_t nid = spec->autocfg.line_out_pins[i];
2055 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
2059 static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
2061 struct sigmatel_spec *spec = codec->spec;
2062 int i;
2064 for (i = 0; i < spec->autocfg.hp_outs; i++) {
2065 hda_nid_t pin;
2066 pin = spec->autocfg.hp_pins[i];
2067 if (pin) /* connect to front */
2068 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
2070 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
2071 hda_nid_t pin;
2072 pin = spec->autocfg.speaker_pins[i];
2073 if (pin) /* connect to front */
2074 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN);
2078 static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in)
2080 struct sigmatel_spec *spec = codec->spec;
2081 int err;
2083 if ((err = snd_hda_parse_pin_def_config(codec,
2084 &spec->autocfg,
2085 spec->dmic_nids)) < 0)
2086 return err;
2087 if (! spec->autocfg.line_outs)
2088 return 0; /* can't find valid pin config */
2090 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
2091 return err;
2092 if (spec->multiout.num_dacs == 0)
2093 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
2094 return err;
2096 err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg);
2098 if (err < 0)
2099 return err;
2101 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
2103 if (err < 0)
2104 return err;
2106 err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
2108 if (err < 0)
2109 return err;
2111 if (spec->num_dmics > 0)
2112 if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
2113 &spec->autocfg)) < 0)
2114 return err;
2116 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2117 if (spec->multiout.max_channels > 2)
2118 spec->surr_switch = 1;
2120 if (spec->autocfg.dig_out_pin)
2121 spec->multiout.dig_out_nid = dig_out;
2122 if (spec->autocfg.dig_in_pin)
2123 spec->dig_in_nid = dig_in;
2125 if (spec->kctl_alloc)
2126 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2128 spec->input_mux = &spec->private_imux;
2129 spec->dinput_mux = &spec->private_dimux;
2131 return 1;
2134 /* add playback controls for HP output */
2135 static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
2136 struct auto_pin_cfg *cfg)
2138 struct sigmatel_spec *spec = codec->spec;
2139 hda_nid_t pin = cfg->hp_pins[0];
2140 unsigned int wid_caps;
2142 if (! pin)
2143 return 0;
2145 wid_caps = get_wcaps(codec, pin);
2146 if (wid_caps & AC_WCAP_UNSOL_CAP)
2147 spec->hp_detect = 1;
2149 return 0;
2152 /* add playback controls for LFE output */
2153 static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec,
2154 struct auto_pin_cfg *cfg)
2156 struct sigmatel_spec *spec = codec->spec;
2157 int err;
2158 hda_nid_t lfe_pin = 0x0;
2159 int i;
2162 * search speaker outs and line outs for a mono speaker pin
2163 * with an amp. If one is found, add LFE controls
2164 * for it.
2166 for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) {
2167 hda_nid_t pin = spec->autocfg.speaker_pins[i];
2168 unsigned long wcaps = get_wcaps(codec, pin);
2169 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
2170 if (wcaps == AC_WCAP_OUT_AMP)
2171 /* found a mono speaker with an amp, must be lfe */
2172 lfe_pin = pin;
2175 /* if speaker_outs is 0, then speakers may be in line_outs */
2176 if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) {
2177 for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) {
2178 hda_nid_t pin = spec->autocfg.line_out_pins[i];
2179 unsigned long cfg;
2180 cfg = snd_hda_codec_read(codec, pin, 0,
2181 AC_VERB_GET_CONFIG_DEFAULT,
2182 0x00);
2183 if (get_defcfg_device(cfg) == AC_JACK_SPEAKER) {
2184 unsigned long wcaps = get_wcaps(codec, pin);
2185 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
2186 if (wcaps == AC_WCAP_OUT_AMP)
2187 /* found a mono speaker with an amp,
2188 must be lfe */
2189 lfe_pin = pin;
2194 if (lfe_pin) {
2195 err = create_controls(spec, "LFE", lfe_pin, 1);
2196 if (err < 0)
2197 return err;
2200 return 0;
2203 static int stac9200_parse_auto_config(struct hda_codec *codec)
2205 struct sigmatel_spec *spec = codec->spec;
2206 int err;
2208 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
2209 return err;
2211 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
2212 return err;
2214 if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)
2215 return err;
2217 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
2218 return err;
2220 if (spec->autocfg.dig_out_pin)
2221 spec->multiout.dig_out_nid = 0x05;
2222 if (spec->autocfg.dig_in_pin)
2223 spec->dig_in_nid = 0x04;
2225 if (spec->kctl_alloc)
2226 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2228 spec->input_mux = &spec->private_imux;
2229 spec->dinput_mux = &spec->private_dimux;
2231 return 1;
2235 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
2236 * funky external mute control using GPIO pins.
2239 static void stac922x_gpio_mute(struct hda_codec *codec, int pin, int muted)
2241 unsigned int gpiostate, gpiomask, gpiodir;
2243 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
2244 AC_VERB_GET_GPIO_DATA, 0);
2246 if (!muted)
2247 gpiostate |= (1 << pin);
2248 else
2249 gpiostate &= ~(1 << pin);
2251 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
2252 AC_VERB_GET_GPIO_MASK, 0);
2253 gpiomask |= (1 << pin);
2255 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
2256 AC_VERB_GET_GPIO_DIRECTION, 0);
2257 gpiodir |= (1 << pin);
2259 /* AppleHDA seems to do this -- WTF is this verb?? */
2260 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
2262 snd_hda_codec_write(codec, codec->afg, 0,
2263 AC_VERB_SET_GPIO_MASK, gpiomask);
2264 snd_hda_codec_write(codec, codec->afg, 0,
2265 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
2267 msleep(1);
2269 snd_hda_codec_write(codec, codec->afg, 0,
2270 AC_VERB_SET_GPIO_DATA, gpiostate);
2273 static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
2274 unsigned int event)
2276 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)
2277 snd_hda_codec_write_cache(codec, nid, 0,
2278 AC_VERB_SET_UNSOLICITED_ENABLE,
2279 (AC_USRSP_EN | event));
2282 static int stac92xx_init(struct hda_codec *codec)
2284 struct sigmatel_spec *spec = codec->spec;
2285 struct auto_pin_cfg *cfg = &spec->autocfg;
2286 int i;
2288 snd_hda_sequence_write(codec, spec->init);
2290 /* set up pins */
2291 if (spec->hp_detect) {
2292 /* Enable unsolicited responses on the HP widget */
2293 for (i = 0; i < cfg->hp_outs; i++)
2294 enable_pin_detect(codec, cfg->hp_pins[i],
2295 STAC_HP_EVENT);
2296 /* force to enable the first line-out; the others are set up
2297 * in unsol_event
2299 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
2300 AC_PINCTL_OUT_EN);
2301 stac92xx_auto_init_hp_out(codec);
2302 /* fake event to set up pins */
2303 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2304 } else {
2305 stac92xx_auto_init_multi_out(codec);
2306 stac92xx_auto_init_hp_out(codec);
2308 for (i = 0; i < AUTO_PIN_LAST; i++) {
2309 hda_nid_t nid = cfg->input_pins[i];
2310 if (nid) {
2311 unsigned int pinctl = AC_PINCTL_IN_EN;
2312 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
2313 pinctl |= stac92xx_get_vref(codec, nid);
2314 stac92xx_auto_set_pinctl(codec, nid, pinctl);
2317 if (spec->num_dmics > 0)
2318 for (i = 0; i < spec->num_dmics; i++)
2319 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
2320 AC_PINCTL_IN_EN);
2322 if (cfg->dig_out_pin)
2323 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
2324 AC_PINCTL_OUT_EN);
2325 if (cfg->dig_in_pin)
2326 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
2327 AC_PINCTL_IN_EN);
2329 if (spec->gpio_mute) {
2330 stac922x_gpio_mute(codec, 0, 0);
2331 stac922x_gpio_mute(codec, 1, 0);
2334 return 0;
2337 static void stac92xx_free(struct hda_codec *codec)
2339 struct sigmatel_spec *spec = codec->spec;
2340 int i;
2342 if (! spec)
2343 return;
2345 if (spec->kctl_alloc) {
2346 for (i = 0; i < spec->num_kctl_used; i++)
2347 kfree(spec->kctl_alloc[i].name);
2348 kfree(spec->kctl_alloc);
2351 if (spec->bios_pin_configs)
2352 kfree(spec->bios_pin_configs);
2354 kfree(spec);
2357 static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
2358 unsigned int flag)
2360 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
2361 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
2363 if (pin_ctl & AC_PINCTL_IN_EN) {
2365 * we need to check the current set-up direction of
2366 * shared input pins since they can be switched via
2367 * "xxx as Output" mixer switch
2369 struct sigmatel_spec *spec = codec->spec;
2370 struct auto_pin_cfg *cfg = &spec->autocfg;
2371 if ((nid == cfg->input_pins[AUTO_PIN_LINE] &&
2372 spec->line_switch) ||
2373 (nid == cfg->input_pins[AUTO_PIN_MIC] &&
2374 spec->mic_switch))
2375 return;
2378 /* if setting pin direction bits, clear the current
2379 direction bits first */
2380 if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
2381 pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
2383 snd_hda_codec_write_cache(codec, nid, 0,
2384 AC_VERB_SET_PIN_WIDGET_CONTROL,
2385 pin_ctl | flag);
2388 static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
2389 unsigned int flag)
2391 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
2392 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
2393 snd_hda_codec_write_cache(codec, nid, 0,
2394 AC_VERB_SET_PIN_WIDGET_CONTROL,
2395 pin_ctl & ~flag);
2398 static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
2400 if (!nid)
2401 return 0;
2402 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00)
2403 & (1 << 31))
2404 return 1;
2405 return 0;
2408 static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
2410 struct sigmatel_spec *spec = codec->spec;
2411 struct auto_pin_cfg *cfg = &spec->autocfg;
2412 int i, presence;
2414 presence = 0;
2415 for (i = 0; i < cfg->hp_outs; i++) {
2416 presence = get_pin_presence(codec, cfg->hp_pins[i]);
2417 if (presence)
2418 break;
2421 if (presence) {
2422 /* disable lineouts, enable hp */
2423 for (i = 0; i < cfg->line_outs; i++)
2424 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
2425 AC_PINCTL_OUT_EN);
2426 for (i = 0; i < cfg->speaker_outs; i++)
2427 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
2428 AC_PINCTL_OUT_EN);
2429 } else {
2430 /* enable lineouts, disable hp */
2431 for (i = 0; i < cfg->line_outs; i++)
2432 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
2433 AC_PINCTL_OUT_EN);
2434 for (i = 0; i < cfg->speaker_outs; i++)
2435 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
2436 AC_PINCTL_OUT_EN);
2440 static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
2442 switch (res >> 26) {
2443 case STAC_HP_EVENT:
2444 stac92xx_hp_detect(codec, res);
2445 break;
2449 #ifdef SND_HDA_NEEDS_RESUME
2450 static int stac92xx_resume(struct hda_codec *codec)
2452 struct sigmatel_spec *spec = codec->spec;
2454 stac92xx_set_config_regs(codec);
2455 snd_hda_sequence_write(codec, spec->init);
2456 if (spec->gpio_mute) {
2457 stac922x_gpio_mute(codec, 0, 0);
2458 stac922x_gpio_mute(codec, 1, 0);
2460 snd_hda_codec_resume_amp(codec);
2461 snd_hda_codec_resume_cache(codec);
2462 /* invoke unsolicited event to reset the HP state */
2463 if (spec->hp_detect)
2464 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2465 return 0;
2467 #endif
2469 static struct hda_codec_ops stac92xx_patch_ops = {
2470 .build_controls = stac92xx_build_controls,
2471 .build_pcms = stac92xx_build_pcms,
2472 .init = stac92xx_init,
2473 .free = stac92xx_free,
2474 .unsol_event = stac92xx_unsol_event,
2475 #ifdef SND_HDA_NEEDS_RESUME
2476 .resume = stac92xx_resume,
2477 #endif
2480 static int patch_stac9200(struct hda_codec *codec)
2482 struct sigmatel_spec *spec;
2483 int err;
2485 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2486 if (spec == NULL)
2487 return -ENOMEM;
2489 codec->spec = spec;
2490 spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
2491 spec->pin_nids = stac9200_pin_nids;
2492 spec->no_vol_knob = 1;
2493 spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
2494 stac9200_models,
2495 stac9200_cfg_tbl);
2496 if (spec->board_config < 0) {
2497 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
2498 err = stac92xx_save_bios_config_regs(codec);
2499 if (err < 0) {
2500 stac92xx_free(codec);
2501 return err;
2503 spec->pin_configs = spec->bios_pin_configs;
2504 } else {
2505 spec->pin_configs = stac9200_brd_tbl[spec->board_config];
2506 stac92xx_set_config_regs(codec);
2509 spec->multiout.max_channels = 2;
2510 spec->multiout.num_dacs = 1;
2511 spec->multiout.dac_nids = stac9200_dac_nids;
2512 spec->adc_nids = stac9200_adc_nids;
2513 spec->mux_nids = stac9200_mux_nids;
2514 spec->num_muxes = 1;
2515 spec->num_dmics = 0;
2516 spec->num_adcs = 1;
2518 if (spec->board_config == STAC_9200_GATEWAY)
2519 spec->init = stac9200_eapd_init;
2520 else
2521 spec->init = stac9200_core_init;
2522 spec->mixer = stac9200_mixer;
2524 err = stac9200_parse_auto_config(codec);
2525 if (err < 0) {
2526 stac92xx_free(codec);
2527 return err;
2530 codec->patch_ops = stac92xx_patch_ops;
2532 return 0;
2535 static int patch_stac925x(struct hda_codec *codec)
2537 struct sigmatel_spec *spec;
2538 int err;
2540 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2541 if (spec == NULL)
2542 return -ENOMEM;
2544 codec->spec = spec;
2545 spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
2546 spec->pin_nids = stac925x_pin_nids;
2547 spec->no_vol_knob = 1;
2548 spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
2549 stac925x_models,
2550 stac925x_cfg_tbl);
2551 again:
2552 if (spec->board_config < 0) {
2553 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x,"
2554 "using BIOS defaults\n");
2555 err = stac92xx_save_bios_config_regs(codec);
2556 if (err < 0) {
2557 stac92xx_free(codec);
2558 return err;
2560 spec->pin_configs = spec->bios_pin_configs;
2561 } else if (stac925x_brd_tbl[spec->board_config] != NULL){
2562 spec->pin_configs = stac925x_brd_tbl[spec->board_config];
2563 stac92xx_set_config_regs(codec);
2566 spec->multiout.max_channels = 2;
2567 spec->multiout.num_dacs = 1;
2568 spec->multiout.dac_nids = stac925x_dac_nids;
2569 spec->adc_nids = stac925x_adc_nids;
2570 spec->mux_nids = stac925x_mux_nids;
2571 spec->num_muxes = 1;
2572 spec->num_adcs = 1;
2573 switch (codec->vendor_id) {
2574 case 0x83847632: /* STAC9202 */
2575 case 0x83847633: /* STAC9202D */
2576 case 0x83847636: /* STAC9251 */
2577 case 0x83847637: /* STAC9251D */
2578 spec->num_dmics = STAC925X_NUM_DMICS;
2579 spec->dmic_nids = stac925x_dmic_nids;
2580 break;
2581 default:
2582 spec->num_dmics = 0;
2583 break;
2586 spec->init = stac925x_core_init;
2587 spec->mixer = stac925x_mixer;
2589 err = stac92xx_parse_auto_config(codec, 0x8, 0x7);
2590 if (!err) {
2591 if (spec->board_config < 0) {
2592 printk(KERN_WARNING "hda_codec: No auto-config is "
2593 "available, default to model=ref\n");
2594 spec->board_config = STAC_925x_REF;
2595 goto again;
2597 err = -EINVAL;
2599 if (err < 0) {
2600 stac92xx_free(codec);
2601 return err;
2604 codec->patch_ops = stac92xx_patch_ops;
2606 return 0;
2609 static int patch_stac922x(struct hda_codec *codec)
2611 struct sigmatel_spec *spec;
2612 int err;
2614 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2615 if (spec == NULL)
2616 return -ENOMEM;
2618 codec->spec = spec;
2619 spec->num_pins = ARRAY_SIZE(stac922x_pin_nids);
2620 spec->pin_nids = stac922x_pin_nids;
2621 spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
2622 stac922x_models,
2623 stac922x_cfg_tbl);
2624 if (spec->board_config == STAC_INTEL_MAC_V3) {
2625 spec->gpio_mute = 1;
2626 /* Intel Macs have all same PCI SSID, so we need to check
2627 * codec SSID to distinguish the exact models
2629 printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id);
2630 switch (codec->subsystem_id) {
2632 case 0x106b0800:
2633 spec->board_config = STAC_INTEL_MAC_V1;
2634 break;
2635 case 0x106b0600:
2636 case 0x106b0700:
2637 spec->board_config = STAC_INTEL_MAC_V2;
2638 break;
2639 case 0x106b0e00:
2640 case 0x106b0f00:
2641 case 0x106b1600:
2642 case 0x106b1700:
2643 case 0x106b0200:
2644 case 0x106b1e00:
2645 spec->board_config = STAC_INTEL_MAC_V3;
2646 break;
2647 case 0x106b1a00:
2648 case 0x00000100:
2649 spec->board_config = STAC_INTEL_MAC_V4;
2650 break;
2651 case 0x106b0a00:
2652 case 0x106b2200:
2653 spec->board_config = STAC_INTEL_MAC_V5;
2654 break;
2658 again:
2659 if (spec->board_config < 0) {
2660 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, "
2661 "using BIOS defaults\n");
2662 err = stac92xx_save_bios_config_regs(codec);
2663 if (err < 0) {
2664 stac92xx_free(codec);
2665 return err;
2667 spec->pin_configs = spec->bios_pin_configs;
2668 } else if (stac922x_brd_tbl[spec->board_config] != NULL) {
2669 spec->pin_configs = stac922x_brd_tbl[spec->board_config];
2670 stac92xx_set_config_regs(codec);
2673 spec->adc_nids = stac922x_adc_nids;
2674 spec->mux_nids = stac922x_mux_nids;
2675 spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
2676 spec->num_adcs = ARRAY_SIZE(stac922x_adc_nids);
2677 spec->num_dmics = 0;
2679 spec->init = stac922x_core_init;
2680 spec->mixer = stac922x_mixer;
2682 spec->multiout.dac_nids = spec->dac_nids;
2684 err = stac92xx_parse_auto_config(codec, 0x08, 0x09);
2685 if (!err) {
2686 if (spec->board_config < 0) {
2687 printk(KERN_WARNING "hda_codec: No auto-config is "
2688 "available, default to model=ref\n");
2689 spec->board_config = STAC_D945_REF;
2690 goto again;
2692 err = -EINVAL;
2694 if (err < 0) {
2695 stac92xx_free(codec);
2696 return err;
2699 codec->patch_ops = stac92xx_patch_ops;
2701 /* Fix Mux capture level; max to 2 */
2702 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
2703 (0 << AC_AMPCAP_OFFSET_SHIFT) |
2704 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2705 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2706 (0 << AC_AMPCAP_MUTE_SHIFT));
2708 return 0;
2711 static int patch_stac927x(struct hda_codec *codec)
2713 struct sigmatel_spec *spec;
2714 int err;
2716 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2717 if (spec == NULL)
2718 return -ENOMEM;
2720 codec->spec = spec;
2721 spec->num_pins = ARRAY_SIZE(stac927x_pin_nids);
2722 spec->pin_nids = stac927x_pin_nids;
2723 spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS,
2724 stac927x_models,
2725 stac927x_cfg_tbl);
2726 again:
2727 if (spec->board_config < 0) {
2728 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n");
2729 err = stac92xx_save_bios_config_regs(codec);
2730 if (err < 0) {
2731 stac92xx_free(codec);
2732 return err;
2734 spec->pin_configs = spec->bios_pin_configs;
2735 } else if (stac927x_brd_tbl[spec->board_config] != NULL) {
2736 spec->pin_configs = stac927x_brd_tbl[spec->board_config];
2737 stac92xx_set_config_regs(codec);
2740 switch (spec->board_config) {
2741 case STAC_D965_3ST:
2742 spec->adc_nids = stac927x_adc_nids;
2743 spec->mux_nids = stac927x_mux_nids;
2744 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2745 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
2746 spec->num_dmics = 0;
2747 spec->init = d965_core_init;
2748 spec->mixer = stac927x_mixer;
2749 break;
2750 case STAC_D965_5ST:
2751 spec->adc_nids = stac927x_adc_nids;
2752 spec->mux_nids = stac927x_mux_nids;
2753 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2754 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
2755 spec->num_dmics = 0;
2756 spec->init = d965_core_init;
2757 spec->mixer = stac927x_mixer;
2758 break;
2759 default:
2760 spec->adc_nids = stac927x_adc_nids;
2761 spec->mux_nids = stac927x_mux_nids;
2762 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
2763 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
2764 spec->num_dmics = 0;
2765 spec->init = stac927x_core_init;
2766 spec->mixer = stac927x_mixer;
2769 spec->multiout.dac_nids = spec->dac_nids;
2770 /* GPIO0 High = Enable EAPD */
2771 spec->gpio_mask = spec->gpio_data = 0x00000001;
2772 stac92xx_enable_gpio_mask(codec);
2774 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
2775 if (!err) {
2776 if (spec->board_config < 0) {
2777 printk(KERN_WARNING "hda_codec: No auto-config is "
2778 "available, default to model=ref\n");
2779 spec->board_config = STAC_D965_REF;
2780 goto again;
2782 err = -EINVAL;
2784 if (err < 0) {
2785 stac92xx_free(codec);
2786 return err;
2789 codec->patch_ops = stac92xx_patch_ops;
2791 return 0;
2794 static int patch_stac9205(struct hda_codec *codec)
2796 struct sigmatel_spec *spec;
2797 int err;
2799 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2800 if (spec == NULL)
2801 return -ENOMEM;
2803 codec->spec = spec;
2804 spec->num_pins = ARRAY_SIZE(stac9205_pin_nids);
2805 spec->pin_nids = stac9205_pin_nids;
2806 spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
2807 stac9205_models,
2808 stac9205_cfg_tbl);
2809 again:
2810 if (spec->board_config < 0) {
2811 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n");
2812 err = stac92xx_save_bios_config_regs(codec);
2813 if (err < 0) {
2814 stac92xx_free(codec);
2815 return err;
2817 spec->pin_configs = spec->bios_pin_configs;
2818 } else {
2819 spec->pin_configs = stac9205_brd_tbl[spec->board_config];
2820 stac92xx_set_config_regs(codec);
2823 spec->adc_nids = stac9205_adc_nids;
2824 spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids);
2825 spec->mux_nids = stac9205_mux_nids;
2826 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
2827 spec->dmic_nids = stac9205_dmic_nids;
2828 spec->num_dmics = STAC9205_NUM_DMICS;
2829 spec->dmux_nid = 0x1d;
2831 spec->init = stac9205_core_init;
2832 spec->mixer = stac9205_mixer;
2834 spec->multiout.dac_nids = spec->dac_nids;
2836 switch (spec->board_config){
2837 case STAC_9205_DELL_M43:
2838 /* Enable SPDIF in/out */
2839 stac92xx_set_config_reg(codec, 0x1f, 0x01441030);
2840 stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
2842 spec->gpio_mask = 0x00000007; /* GPIO0-2 */
2843 /* GPIO0 High = EAPD, GPIO1 Low = DRM,
2844 * GPIO2 High = Headphone Mute
2846 spec->gpio_data = 0x00000005;
2847 break;
2848 default:
2849 /* GPIO0 High = EAPD */
2850 spec->gpio_mask = spec->gpio_data = 0x00000001;
2851 break;
2854 stac92xx_enable_gpio_mask(codec);
2855 err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
2856 if (!err) {
2857 if (spec->board_config < 0) {
2858 printk(KERN_WARNING "hda_codec: No auto-config is "
2859 "available, default to model=ref\n");
2860 spec->board_config = STAC_9205_REF;
2861 goto again;
2863 err = -EINVAL;
2865 if (err < 0) {
2866 stac92xx_free(codec);
2867 return err;
2870 codec->patch_ops = stac92xx_patch_ops;
2872 return 0;
2876 * STAC9872 hack
2879 /* static config for Sony VAIO FE550G and Sony VAIO AR */
2880 static hda_nid_t vaio_dacs[] = { 0x2 };
2881 #define VAIO_HP_DAC 0x5
2882 static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ };
2883 static hda_nid_t vaio_mux_nids[] = { 0x15 };
2885 static struct hda_input_mux vaio_mux = {
2886 .num_items = 3,
2887 .items = {
2888 /* { "HP", 0x0 }, */
2889 { "Mic Jack", 0x1 },
2890 { "Internal Mic", 0x2 },
2891 { "PCM", 0x3 },
2895 static struct hda_verb vaio_init[] = {
2896 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
2897 {0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT},
2898 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
2899 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
2900 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
2901 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
2902 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
2903 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
2904 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
2905 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
2906 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
2907 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
2911 static struct hda_verb vaio_ar_init[] = {
2912 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
2913 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
2914 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
2915 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
2916 /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */
2917 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
2918 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
2919 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
2920 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
2921 /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */
2922 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
2923 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
2924 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
2928 /* bind volumes of both NID 0x02 and 0x05 */
2929 static struct hda_bind_ctls vaio_bind_master_vol = {
2930 .ops = &snd_hda_bind_vol,
2931 .values = {
2932 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
2933 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
2938 /* bind volumes of both NID 0x02 and 0x05 */
2939 static struct hda_bind_ctls vaio_bind_master_sw = {
2940 .ops = &snd_hda_bind_sw,
2941 .values = {
2942 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
2943 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
2948 static struct snd_kcontrol_new vaio_mixer[] = {
2949 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
2950 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
2951 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
2952 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
2953 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
2955 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2956 .name = "Capture Source",
2957 .count = 1,
2958 .info = stac92xx_mux_enum_info,
2959 .get = stac92xx_mux_enum_get,
2960 .put = stac92xx_mux_enum_put,
2965 static struct snd_kcontrol_new vaio_ar_mixer[] = {
2966 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
2967 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
2968 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
2969 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
2970 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
2971 /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT),
2972 HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/
2974 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2975 .name = "Capture Source",
2976 .count = 1,
2977 .info = stac92xx_mux_enum_info,
2978 .get = stac92xx_mux_enum_get,
2979 .put = stac92xx_mux_enum_put,
2984 static struct hda_codec_ops stac9872_patch_ops = {
2985 .build_controls = stac92xx_build_controls,
2986 .build_pcms = stac92xx_build_pcms,
2987 .init = stac92xx_init,
2988 .free = stac92xx_free,
2989 #ifdef SND_HDA_NEEDS_RESUME
2990 .resume = stac92xx_resume,
2991 #endif
2994 static int stac9872_vaio_init(struct hda_codec *codec)
2996 int err;
2998 err = stac92xx_init(codec);
2999 if (err < 0)
3000 return err;
3001 if (codec->patch_ops.unsol_event)
3002 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
3003 return 0;
3006 static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
3008 if (get_pin_presence(codec, 0x0a)) {
3009 stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
3010 stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
3011 } else {
3012 stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
3013 stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
3017 static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res)
3019 switch (res >> 26) {
3020 case STAC_HP_EVENT:
3021 stac9872_vaio_hp_detect(codec, res);
3022 break;
3026 static struct hda_codec_ops stac9872_vaio_patch_ops = {
3027 .build_controls = stac92xx_build_controls,
3028 .build_pcms = stac92xx_build_pcms,
3029 .init = stac9872_vaio_init,
3030 .free = stac92xx_free,
3031 .unsol_event = stac9872_vaio_unsol_event,
3032 #ifdef CONFIG_PM
3033 .resume = stac92xx_resume,
3034 #endif
3037 enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */
3038 CXD9872RD_VAIO,
3039 /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */
3040 STAC9872AK_VAIO,
3041 /* Unknown. id=0x83847661 and subsys=0x104D1200. */
3042 STAC9872K_VAIO,
3043 /* AR Series. id=0x83847664 and subsys=104D1300 */
3044 CXD9872AKD_VAIO,
3045 STAC_9872_MODELS,
3048 static const char *stac9872_models[STAC_9872_MODELS] = {
3049 [CXD9872RD_VAIO] = "vaio",
3050 [CXD9872AKD_VAIO] = "vaio-ar",
3053 static struct snd_pci_quirk stac9872_cfg_tbl[] = {
3054 SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
3055 SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
3056 SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
3057 SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO),
3061 static int patch_stac9872(struct hda_codec *codec)
3063 struct sigmatel_spec *spec;
3064 int board_config;
3066 board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
3067 stac9872_models,
3068 stac9872_cfg_tbl);
3069 if (board_config < 0)
3070 /* unknown config, let generic-parser do its job... */
3071 return snd_hda_parse_generic_codec(codec);
3073 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3074 if (spec == NULL)
3075 return -ENOMEM;
3077 codec->spec = spec;
3078 switch (board_config) {
3079 case CXD9872RD_VAIO:
3080 case STAC9872AK_VAIO:
3081 case STAC9872K_VAIO:
3082 spec->mixer = vaio_mixer;
3083 spec->init = vaio_init;
3084 spec->multiout.max_channels = 2;
3085 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
3086 spec->multiout.dac_nids = vaio_dacs;
3087 spec->multiout.hp_nid = VAIO_HP_DAC;
3088 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
3089 spec->adc_nids = vaio_adcs;
3090 spec->input_mux = &vaio_mux;
3091 spec->mux_nids = vaio_mux_nids;
3092 codec->patch_ops = stac9872_vaio_patch_ops;
3093 break;
3095 case CXD9872AKD_VAIO:
3096 spec->mixer = vaio_ar_mixer;
3097 spec->init = vaio_ar_init;
3098 spec->multiout.max_channels = 2;
3099 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
3100 spec->multiout.dac_nids = vaio_dacs;
3101 spec->multiout.hp_nid = VAIO_HP_DAC;
3102 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
3103 spec->adc_nids = vaio_adcs;
3104 spec->input_mux = &vaio_mux;
3105 spec->mux_nids = vaio_mux_nids;
3106 codec->patch_ops = stac9872_patch_ops;
3107 break;
3110 return 0;
3115 * patch entries
3117 struct hda_codec_preset snd_hda_preset_sigmatel[] = {
3118 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
3119 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
3120 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
3121 { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x },
3122 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
3123 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
3124 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
3125 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x },
3126 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x },
3127 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x },
3128 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x },
3129 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x },
3130 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x },
3131 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
3132 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
3133 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
3134 { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x },
3135 { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x },
3136 { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x },
3137 { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x },
3138 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x },
3139 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x },
3140 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x },
3141 { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x },
3142 { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x },
3143 { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x },
3144 { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
3145 { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
3146 { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
3147 /* The following does not take into account .id=0x83847661 when subsys =
3148 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
3149 * currently not fully supported.
3151 { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 },
3152 { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 },
3153 { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 },
3154 { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 },
3155 { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 },
3156 { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 },
3157 { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 },
3158 { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 },
3159 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
3160 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
3161 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
3162 {} /* terminator */