[ALSA] hda: 92HD71BXX Mono Mute Support
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / sound / pci / hda / patch_sigmatel.c
blobc4a85d23a8a5ad81ca81ce55eb4f53186ee0528f
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 <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/slab.h>
30 #include <linux/pci.h>
31 #include <sound/core.h>
32 #include <sound/asoundef.h>
33 #include "hda_codec.h"
34 #include "hda_local.h"
36 #define NUM_CONTROL_ALLOC 32
37 #define STAC_HP_EVENT 0x37
39 enum {
40 STAC_REF,
41 STAC_9200_DELL_D21,
42 STAC_9200_DELL_D22,
43 STAC_9200_DELL_D23,
44 STAC_9200_DELL_M21,
45 STAC_9200_DELL_M22,
46 STAC_9200_DELL_M23,
47 STAC_9200_DELL_M24,
48 STAC_9200_DELL_M25,
49 STAC_9200_DELL_M26,
50 STAC_9200_DELL_M27,
51 STAC_9200_GATEWAY,
52 STAC_9200_MODELS
55 enum {
56 STAC_9205_REF,
57 STAC_9205_DELL_M42,
58 STAC_9205_DELL_M43,
59 STAC_9205_DELL_M44,
60 STAC_9205_MODELS
63 enum {
64 STAC_92HD73XX_REF,
65 STAC_92HD73XX_MODELS
68 enum {
69 STAC_92HD71BXX_REF,
70 STAC_92HD71BXX_MODELS
73 enum {
74 STAC_925x_REF,
75 STAC_M2_2,
76 STAC_MA6,
77 STAC_PA6,
78 STAC_925x_MODELS
81 enum {
82 STAC_D945_REF,
83 STAC_D945GTP3,
84 STAC_D945GTP5,
85 STAC_INTEL_MAC_V1,
86 STAC_INTEL_MAC_V2,
87 STAC_INTEL_MAC_V3,
88 STAC_INTEL_MAC_V4,
89 STAC_INTEL_MAC_V5,
90 /* for backward compatibility */
91 STAC_MACMINI,
92 STAC_MACBOOK,
93 STAC_MACBOOK_PRO_V1,
94 STAC_MACBOOK_PRO_V2,
95 STAC_IMAC_INTEL,
96 STAC_IMAC_INTEL_20,
97 STAC_922X_DELL_D81,
98 STAC_922X_DELL_D82,
99 STAC_922X_DELL_M81,
100 STAC_922X_DELL_M82,
101 STAC_922X_MODELS
104 enum {
105 STAC_D965_REF,
106 STAC_D965_3ST,
107 STAC_D965_5ST,
108 STAC_DELL_3ST,
109 STAC_DELL_BIOS,
110 STAC_927X_MODELS
113 struct sigmatel_spec {
114 struct snd_kcontrol_new *mixers[4];
115 unsigned int num_mixers;
117 int board_config;
118 unsigned int surr_switch: 1;
119 unsigned int line_switch: 1;
120 unsigned int mic_switch: 1;
121 unsigned int alt_switch: 1;
122 unsigned int hp_detect: 1;
123 unsigned int gpio_mute: 1;
125 unsigned int gpio_mask, gpio_data;
126 unsigned char aloopback_mask;
127 unsigned char aloopback_shift;
129 /* playback */
130 struct hda_multi_out multiout;
131 hda_nid_t dac_nids[5];
133 /* capture */
134 hda_nid_t *adc_nids;
135 unsigned int num_adcs;
136 hda_nid_t *mux_nids;
137 unsigned int num_muxes;
138 hda_nid_t *dmic_nids;
139 unsigned int num_dmics;
140 hda_nid_t *dmux_nids;
141 unsigned int num_dmuxes;
142 hda_nid_t dig_in_nid;
144 /* pin widgets */
145 hda_nid_t *pin_nids;
146 unsigned int num_pins;
147 unsigned int *pin_configs;
148 unsigned int *bios_pin_configs;
150 /* codec specific stuff */
151 struct hda_verb *init;
152 struct snd_kcontrol_new *mixer;
154 /* capture source */
155 struct hda_input_mux *dinput_mux;
156 unsigned int cur_dmux[2];
157 struct hda_input_mux *input_mux;
158 unsigned int cur_mux[3];
160 /* i/o switches */
161 unsigned int io_switch[2];
162 unsigned int clfe_swap;
163 unsigned int aloopback;
165 struct hda_pcm pcm_rec[2]; /* PCM information */
167 /* dynamic controls and input_mux */
168 struct auto_pin_cfg autocfg;
169 unsigned int num_kctl_alloc, num_kctl_used;
170 struct snd_kcontrol_new *kctl_alloc;
171 struct hda_input_mux private_dimux;
172 struct hda_input_mux private_imux;
175 static hda_nid_t stac9200_adc_nids[1] = {
176 0x03,
179 static hda_nid_t stac9200_mux_nids[1] = {
180 0x0c,
183 static hda_nid_t stac9200_dac_nids[1] = {
184 0x02,
187 static hda_nid_t stac92hd73xx_adc_nids[2] = {
188 0x1a, 0x1b
191 #define STAC92HD73XX_NUM_DMICS 2
192 static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
193 0x13, 0x14, 0
196 #define STAC92HD73_DAC_COUNT 5
197 static hda_nid_t stac92hd73xx_dac_nids[STAC92HD73_DAC_COUNT] = {
198 0x15, 0x16, 0x17, 0x18, 0x19,
201 static hda_nid_t stac92hd73xx_mux_nids[4] = {
202 0x28, 0x29, 0x2a, 0x2b,
205 static hda_nid_t stac92hd73xx_dmux_nids[2] = {
206 0x20, 0x21,
209 static hda_nid_t stac92hd71bxx_adc_nids[2] = {
210 0x12, 0x13,
213 static hda_nid_t stac92hd71bxx_mux_nids[2] = {
214 0x1a, 0x1b
217 static hda_nid_t stac92hd71bxx_dmux_nids[1] = {
218 0x1c,
221 static hda_nid_t stac92hd71bxx_dac_nids[2] = {
222 0x10, /*0x11, */
225 #define STAC92HD71BXX_NUM_DMICS 2
226 static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
227 0x18, 0x19, 0
230 static hda_nid_t stac925x_adc_nids[1] = {
231 0x03,
234 static hda_nid_t stac925x_mux_nids[1] = {
235 0x0f,
238 static hda_nid_t stac925x_dac_nids[1] = {
239 0x02,
242 #define STAC925X_NUM_DMICS 1
243 static hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = {
244 0x15, 0
247 static hda_nid_t stac925x_dmux_nids[1] = {
248 0x14,
251 static hda_nid_t stac922x_adc_nids[2] = {
252 0x06, 0x07,
255 static hda_nid_t stac922x_mux_nids[2] = {
256 0x12, 0x13,
259 static hda_nid_t stac927x_adc_nids[3] = {
260 0x07, 0x08, 0x09
263 static hda_nid_t stac927x_mux_nids[3] = {
264 0x15, 0x16, 0x17
267 static hda_nid_t stac927x_dmux_nids[1] = {
268 0x1b,
271 #define STAC927X_NUM_DMICS 2
272 static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = {
273 0x13, 0x14, 0
276 static hda_nid_t stac9205_adc_nids[2] = {
277 0x12, 0x13
280 static hda_nid_t stac9205_mux_nids[2] = {
281 0x19, 0x1a
284 static hda_nid_t stac9205_dmux_nids[1] = {
285 0x1d,
288 #define STAC9205_NUM_DMICS 2
289 static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
290 0x17, 0x18, 0
293 static hda_nid_t stac9200_pin_nids[8] = {
294 0x08, 0x09, 0x0d, 0x0e,
295 0x0f, 0x10, 0x11, 0x12,
298 static hda_nid_t stac925x_pin_nids[8] = {
299 0x07, 0x08, 0x0a, 0x0b,
300 0x0c, 0x0d, 0x10, 0x11,
303 static hda_nid_t stac922x_pin_nids[10] = {
304 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
305 0x0f, 0x10, 0x11, 0x15, 0x1b,
308 static hda_nid_t stac92hd73xx_pin_nids[12] = {
309 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
310 0x0f, 0x10, 0x11, 0x12, 0x13,
311 0x14, 0x22
314 static hda_nid_t stac92hd71bxx_pin_nids[10] = {
315 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
316 0x0f, 0x14, 0x18, 0x19, 0x1e,
319 static hda_nid_t stac927x_pin_nids[14] = {
320 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
321 0x0f, 0x10, 0x11, 0x12, 0x13,
322 0x14, 0x21, 0x22, 0x23,
325 static hda_nid_t stac9205_pin_nids[12] = {
326 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
327 0x0f, 0x14, 0x16, 0x17, 0x18,
328 0x21, 0x22,
331 static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
332 struct snd_ctl_elem_info *uinfo)
334 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
335 struct sigmatel_spec *spec = codec->spec;
336 return snd_hda_input_mux_info(spec->dinput_mux, uinfo);
339 static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol,
340 struct snd_ctl_elem_value *ucontrol)
342 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
343 struct sigmatel_spec *spec = codec->spec;
344 unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
346 ucontrol->value.enumerated.item[0] = spec->cur_dmux[dmux_idx];
347 return 0;
350 static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
351 struct snd_ctl_elem_value *ucontrol)
353 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
354 struct sigmatel_spec *spec = codec->spec;
355 unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
357 return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol,
358 spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]);
361 static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
363 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
364 struct sigmatel_spec *spec = codec->spec;
365 return snd_hda_input_mux_info(spec->input_mux, uinfo);
368 static int stac92xx_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
370 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
371 struct sigmatel_spec *spec = codec->spec;
372 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
374 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
375 return 0;
378 static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
380 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
381 struct sigmatel_spec *spec = codec->spec;
382 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
384 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
385 spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]);
388 #define stac92xx_aloopback_info snd_ctl_boolean_mono_info
390 static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol,
391 struct snd_ctl_elem_value *ucontrol)
393 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
394 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
395 struct sigmatel_spec *spec = codec->spec;
397 ucontrol->value.integer.value[0] = !!(spec->aloopback &
398 (spec->aloopback_mask << idx));
399 return 0;
402 static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol,
403 struct snd_ctl_elem_value *ucontrol)
405 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
406 struct sigmatel_spec *spec = codec->spec;
407 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
408 unsigned int dac_mode;
409 unsigned int val, idx_val;
411 idx_val = spec->aloopback_mask << idx;
412 if (ucontrol->value.integer.value[0])
413 val = spec->aloopback | idx_val;
414 else
415 val = spec->aloopback & ~idx_val;
416 if (spec->aloopback == val)
417 return 0;
419 spec->aloopback = val;
421 /* Only return the bits defined by the shift value of the
422 * first two bytes of the mask
424 dac_mode = snd_hda_codec_read(codec, codec->afg, 0,
425 kcontrol->private_value & 0xFFFF, 0x0);
426 dac_mode >>= spec->aloopback_shift;
428 if (spec->aloopback & idx_val) {
429 snd_hda_power_up(codec);
430 dac_mode |= idx_val;
431 } else {
432 snd_hda_power_down(codec);
433 dac_mode &= ~idx_val;
436 snd_hda_codec_write_cache(codec, codec->afg, 0,
437 kcontrol->private_value >> 16, dac_mode);
439 return 1;
442 static struct hda_verb stac9200_core_init[] = {
443 /* set dac0mux for dac converter */
444 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
448 static struct hda_verb stac9200_eapd_init[] = {
449 /* set dac0mux for dac converter */
450 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
451 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
455 static struct hda_verb stac92hd73xx_6ch_core_init[] = {
456 /* set master volume and direct control */
457 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
458 /* setup audio connections */
459 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
460 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
461 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
462 /* setup adcs to point to mixer */
463 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
464 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
465 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
466 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
467 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
468 /* setup import muxs */
469 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
470 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
471 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
472 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00},
476 static struct hda_verb stac92hd73xx_8ch_core_init[] = {
477 /* set master volume and direct control */
478 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
479 /* setup audio connections */
480 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
481 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
482 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
483 /* connect hp ports to dac3 */
484 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x03},
485 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x03},
486 /* setup adcs to point to mixer */
487 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
488 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
489 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
490 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
491 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
492 /* setup import muxs */
493 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
494 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
495 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
496 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x03},
500 static struct hda_verb stac92hd73xx_10ch_core_init[] = {
501 /* set master volume and direct control */
502 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
503 /* setup audio connections */
504 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
505 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01 },
506 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02 },
507 /* dac3 is connected to import3 mux */
508 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f},
509 /* connect hp ports to dac4 */
510 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x04},
511 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x04},
512 /* setup adcs to point to mixer */
513 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
514 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
515 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
516 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
517 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
518 /* setup import muxs */
519 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
520 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
521 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
522 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x03},
526 static struct hda_verb stac92hd71bxx_core_init[] = {
527 /* set master volume and direct control */
528 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
529 /* connect headphone jack to dac1 */
530 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
531 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */
532 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */
533 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
534 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
535 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
538 static struct hda_verb stac92hd71bxx_analog_core_init[] = {
539 /* set master volume and direct control */
540 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
541 /* connect headphone jack to dac1 */
542 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
543 /* connect ports 0d and 0f to audio mixer */
544 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x2},
545 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2},
546 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
547 /* unmute dac0 input in audio mixer */
548 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
549 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */
550 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
551 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
552 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
556 static struct hda_verb stac925x_core_init[] = {
557 /* set dac0mux for dac converter */
558 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
562 static struct hda_verb stac922x_core_init[] = {
563 /* set master volume and direct control */
564 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
568 static struct hda_verb d965_core_init[] = {
569 /* set master volume and direct control */
570 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
571 /* unmute node 0x1b */
572 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
573 /* select node 0x03 as DAC */
574 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
578 static struct hda_verb stac927x_core_init[] = {
579 /* set master volume and direct control */
580 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
584 static struct hda_verb stac9205_core_init[] = {
585 /* set master volume and direct control */
586 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
590 #define STAC_INPUT_SOURCE(cnt) \
592 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
593 .name = "Input Source", \
594 .count = cnt, \
595 .info = stac92xx_mux_enum_info, \
596 .get = stac92xx_mux_enum_get, \
597 .put = stac92xx_mux_enum_put, \
600 #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \
602 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
603 .name = "Analog Loopback", \
604 .count = cnt, \
605 .info = stac92xx_aloopback_info, \
606 .get = stac92xx_aloopback_get, \
607 .put = stac92xx_aloopback_put, \
608 .private_value = verb_read | (verb_write << 16), \
611 static struct snd_kcontrol_new stac9200_mixer[] = {
612 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
613 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
614 STAC_INPUT_SOURCE(1),
615 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
616 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
617 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT),
618 { } /* end */
621 static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = {
622 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3),
624 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
625 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
627 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
628 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
630 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
631 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
633 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
634 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
636 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
637 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
639 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
640 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
642 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
643 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
644 { } /* end */
647 static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = {
648 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4),
650 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
651 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
653 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
654 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
656 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
657 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
659 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
660 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
662 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
663 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
665 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
666 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
668 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
669 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
670 { } /* end */
673 static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = {
674 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5),
676 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
677 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
679 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
680 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
682 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
683 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
685 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
686 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
688 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
689 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
691 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
692 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
694 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
695 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
696 { } /* end */
699 static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = {
700 STAC_INPUT_SOURCE(2),
702 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
703 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
704 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x0, 0x1a, 0x0, HDA_OUTPUT),
706 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT),
707 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
708 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT),
710 HDA_CODEC_MUTE("Analog Loopback 1", 0x17, 0x3, HDA_INPUT),
711 HDA_CODEC_MUTE("Analog Loopback 2", 0x17, 0x4, HDA_INPUT),
713 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x14, 0x1, 0, HDA_INPUT),
714 { } /* end */
717 static struct snd_kcontrol_new stac92hd71bxx_mixer[] = {
718 STAC_INPUT_SOURCE(2),
719 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2),
721 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
722 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
723 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x0, 0x1a, 0x0, HDA_OUTPUT),
725 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT),
726 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
727 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT),
729 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x14, 0x1, 0, HDA_INPUT),
730 { } /* end */
733 static struct snd_kcontrol_new stac925x_mixer[] = {
734 STAC_INPUT_SOURCE(1),
735 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
736 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT),
737 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT),
738 { } /* end */
741 static struct snd_kcontrol_new stac9205_mixer[] = {
742 STAC_INPUT_SOURCE(2),
743 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1),
745 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT),
746 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT),
747 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x19, 0x0, HDA_OUTPUT),
749 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT),
750 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT),
751 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x1A, 0x0, HDA_OUTPUT),
753 { } /* end */
756 /* This needs to be generated dynamically based on sequence */
757 static struct snd_kcontrol_new stac922x_mixer[] = {
758 STAC_INPUT_SOURCE(2),
759 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT),
760 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT),
761 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x12, 0x0, HDA_OUTPUT),
763 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT),
764 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT),
765 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x13, 0x0, HDA_OUTPUT),
766 { } /* end */
770 static struct snd_kcontrol_new stac927x_mixer[] = {
771 STAC_INPUT_SOURCE(3),
772 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1),
774 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT),
775 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT),
776 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x15, 0x0, HDA_OUTPUT),
778 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT),
779 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT),
780 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x16, 0x0, HDA_OUTPUT),
782 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT),
783 HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT),
784 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x2, 0x17, 0x0, HDA_OUTPUT),
785 { } /* end */
788 static struct snd_kcontrol_new stac_dmux_mixer = {
789 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
790 .name = "Digital Input Source",
791 /* count set later */
792 .info = stac92xx_dmux_enum_info,
793 .get = stac92xx_dmux_enum_get,
794 .put = stac92xx_dmux_enum_put,
797 static int stac92xx_build_controls(struct hda_codec *codec)
799 struct sigmatel_spec *spec = codec->spec;
800 int err;
801 int i;
803 err = snd_hda_add_new_ctls(codec, spec->mixer);
804 if (err < 0)
805 return err;
807 for (i = 0; i < spec->num_mixers; i++) {
808 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
809 if (err < 0)
810 return err;
812 if (spec->num_dmuxes > 0) {
813 stac_dmux_mixer.count = spec->num_dmuxes;
814 err = snd_ctl_add(codec->bus->card,
815 snd_ctl_new1(&stac_dmux_mixer, codec));
816 if (err < 0)
817 return err;
820 if (spec->multiout.dig_out_nid) {
821 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
822 if (err < 0)
823 return err;
825 if (spec->dig_in_nid) {
826 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
827 if (err < 0)
828 return err;
830 return 0;
833 static unsigned int ref9200_pin_configs[8] = {
834 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
835 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
839 STAC 9200 pin configs for
840 102801A8
841 102801DE
842 102801E8
844 static unsigned int dell9200_d21_pin_configs[8] = {
845 0x400001f0, 0x400001f1, 0x02214030, 0x01014010,
846 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
850 STAC 9200 pin configs for
851 102801C0
852 102801C1
854 static unsigned int dell9200_d22_pin_configs[8] = {
855 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
856 0x01813020, 0x02a19021, 0x90100140, 0x400001f2,
860 STAC 9200 pin configs for
861 102801C4 (Dell Dimension E310)
862 102801C5
863 102801C7
864 102801D9
865 102801DA
866 102801E3
868 static unsigned int dell9200_d23_pin_configs[8] = {
869 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
870 0x01813020, 0x01a19021, 0x90100140, 0x400001f2,
875 STAC 9200-32 pin configs for
876 102801B5 (Dell Inspiron 630m)
877 102801D8 (Dell Inspiron 640m)
879 static unsigned int dell9200_m21_pin_configs[8] = {
880 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310,
881 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd,
885 STAC 9200-32 pin configs for
886 102801C2 (Dell Latitude D620)
887 102801C8
888 102801CC (Dell Latitude D820)
889 102801D4
890 102801D6
892 static unsigned int dell9200_m22_pin_configs[8] = {
893 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310,
894 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc,
898 STAC 9200-32 pin configs for
899 102801CE (Dell XPS M1710)
900 102801CF (Dell Precision M90)
902 static unsigned int dell9200_m23_pin_configs[8] = {
903 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310,
904 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc,
908 STAC 9200-32 pin configs for
909 102801C9
910 102801CA
911 102801CB (Dell Latitude 120L)
912 102801D3
914 static unsigned int dell9200_m24_pin_configs[8] = {
915 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310,
916 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe,
920 STAC 9200-32 pin configs for
921 102801BD (Dell Inspiron E1505n)
922 102801EE
923 102801EF
925 static unsigned int dell9200_m25_pin_configs[8] = {
926 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
927 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd,
931 STAC 9200-32 pin configs for
932 102801F5 (Dell Inspiron 1501)
933 102801F6
935 static unsigned int dell9200_m26_pin_configs[8] = {
936 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310,
937 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe,
941 STAC 9200-32
942 102801CD (Dell Inspiron E1705/9400)
944 static unsigned int dell9200_m27_pin_configs[8] = {
945 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
946 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc,
950 static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
951 [STAC_REF] = ref9200_pin_configs,
952 [STAC_9200_DELL_D21] = dell9200_d21_pin_configs,
953 [STAC_9200_DELL_D22] = dell9200_d22_pin_configs,
954 [STAC_9200_DELL_D23] = dell9200_d23_pin_configs,
955 [STAC_9200_DELL_M21] = dell9200_m21_pin_configs,
956 [STAC_9200_DELL_M22] = dell9200_m22_pin_configs,
957 [STAC_9200_DELL_M23] = dell9200_m23_pin_configs,
958 [STAC_9200_DELL_M24] = dell9200_m24_pin_configs,
959 [STAC_9200_DELL_M25] = dell9200_m25_pin_configs,
960 [STAC_9200_DELL_M26] = dell9200_m26_pin_configs,
961 [STAC_9200_DELL_M27] = dell9200_m27_pin_configs,
964 static const char *stac9200_models[STAC_9200_MODELS] = {
965 [STAC_REF] = "ref",
966 [STAC_9200_DELL_D21] = "dell-d21",
967 [STAC_9200_DELL_D22] = "dell-d22",
968 [STAC_9200_DELL_D23] = "dell-d23",
969 [STAC_9200_DELL_M21] = "dell-m21",
970 [STAC_9200_DELL_M22] = "dell-m22",
971 [STAC_9200_DELL_M23] = "dell-m23",
972 [STAC_9200_DELL_M24] = "dell-m24",
973 [STAC_9200_DELL_M25] = "dell-m25",
974 [STAC_9200_DELL_M26] = "dell-m26",
975 [STAC_9200_DELL_M27] = "dell-m27",
976 [STAC_9200_GATEWAY] = "gateway",
979 static struct snd_pci_quirk stac9200_cfg_tbl[] = {
980 /* SigmaTel reference board */
981 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
982 "DFI LanParty", STAC_REF),
983 /* Dell laptops have BIOS problem */
984 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
985 "unknown Dell", STAC_9200_DELL_D21),
986 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
987 "Dell Inspiron 630m", STAC_9200_DELL_M21),
988 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
989 "Dell Inspiron E1505n", STAC_9200_DELL_M25),
990 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
991 "unknown Dell", STAC_9200_DELL_D22),
992 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
993 "unknown Dell", STAC_9200_DELL_D22),
994 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
995 "Dell Latitude D620", STAC_9200_DELL_M22),
996 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
997 "unknown Dell", STAC_9200_DELL_D23),
998 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
999 "unknown Dell", STAC_9200_DELL_D23),
1000 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
1001 "unknown Dell", STAC_9200_DELL_M22),
1002 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
1003 "unknown Dell", STAC_9200_DELL_M24),
1004 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
1005 "unknown Dell", STAC_9200_DELL_M24),
1006 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
1007 "Dell Latitude 120L", STAC_9200_DELL_M24),
1008 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
1009 "Dell Latitude D820", STAC_9200_DELL_M22),
1010 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
1011 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
1012 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
1013 "Dell XPS M1710", STAC_9200_DELL_M23),
1014 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
1015 "Dell Precision M90", STAC_9200_DELL_M23),
1016 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
1017 "unknown Dell", STAC_9200_DELL_M22),
1018 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
1019 "unknown Dell", STAC_9200_DELL_M22),
1020 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
1021 "unknown Dell", STAC_9200_DELL_M22),
1022 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
1023 "Dell Inspiron 640m", STAC_9200_DELL_M21),
1024 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
1025 "unknown Dell", STAC_9200_DELL_D23),
1026 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
1027 "unknown Dell", STAC_9200_DELL_D23),
1028 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
1029 "unknown Dell", STAC_9200_DELL_D21),
1030 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
1031 "unknown Dell", STAC_9200_DELL_D23),
1032 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
1033 "unknown Dell", STAC_9200_DELL_D21),
1034 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
1035 "unknown Dell", STAC_9200_DELL_M25),
1036 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
1037 "unknown Dell", STAC_9200_DELL_M25),
1038 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
1039 "Dell Inspiron 1501", STAC_9200_DELL_M26),
1040 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
1041 "unknown Dell", STAC_9200_DELL_M26),
1042 /* Panasonic */
1043 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_REF),
1044 /* Gateway machines needs EAPD to be set on resume */
1045 SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY),
1046 SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*",
1047 STAC_9200_GATEWAY),
1048 SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707",
1049 STAC_9200_GATEWAY),
1050 {} /* terminator */
1053 static unsigned int ref925x_pin_configs[8] = {
1054 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
1055 0x90a70320, 0x02214210, 0x400003f1, 0x9033032e,
1058 static unsigned int stac925x_MA6_pin_configs[8] = {
1059 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
1060 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e,
1063 static unsigned int stac925x_PA6_pin_configs[8] = {
1064 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
1065 0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e,
1068 static unsigned int stac925xM2_2_pin_configs[8] = {
1069 0x40c003f3, 0x424503f2, 0x04180011, 0x02a19020,
1070 0x50a103f0, 0x90100212, 0x400003f1, 0x9033032e,
1073 static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
1074 [STAC_REF] = ref925x_pin_configs,
1075 [STAC_M2_2] = stac925xM2_2_pin_configs,
1076 [STAC_MA6] = stac925x_MA6_pin_configs,
1077 [STAC_PA6] = stac925x_PA6_pin_configs,
1080 static const char *stac925x_models[STAC_925x_MODELS] = {
1081 [STAC_REF] = "ref",
1082 [STAC_M2_2] = "m2-2",
1083 [STAC_MA6] = "m6",
1084 [STAC_PA6] = "pa6",
1087 static struct snd_pci_quirk stac925x_cfg_tbl[] = {
1088 /* SigmaTel reference board */
1089 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
1090 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
1091 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF),
1092 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF),
1093 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6),
1094 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_PA6),
1095 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2),
1096 {} /* terminator */
1099 static unsigned int ref92hd73xx_pin_configs[12] = {
1100 0x02214030, 0x02a19040, 0x01a19020, 0x02214030,
1101 0x0181302e, 0x01014010, 0x01014020, 0x01014030,
1102 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050,
1105 static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
1106 [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs,
1109 static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
1110 [STAC_92HD73XX_REF] = "ref",
1113 static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
1114 /* SigmaTel reference board */
1115 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1116 "DFI LanParty", STAC_92HD73XX_REF),
1117 {} /* terminator */
1120 static unsigned int ref92hd71bxx_pin_configs[10] = {
1121 0x02214030, 0x02a19040, 0x01a19020, 0x01014010,
1122 0x0181302e, 0x01114010, 0x01a19020, 0x90a000f0,
1123 0x90a000f0, 0x01452050,
1126 static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
1127 [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs,
1130 static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
1131 [STAC_92HD71BXX_REF] = "ref",
1134 static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1135 /* SigmaTel reference board */
1136 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1137 "DFI LanParty", STAC_92HD71BXX_REF),
1138 {} /* terminator */
1141 static unsigned int ref922x_pin_configs[10] = {
1142 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
1143 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
1144 0x40000100, 0x40000100,
1148 STAC 922X pin configs for
1149 102801A7
1150 102801AB
1151 102801A9
1152 102801D1
1153 102801D2
1155 static unsigned int dell_922x_d81_pin_configs[10] = {
1156 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
1157 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1,
1158 0x01813122, 0x400001f2,
1162 STAC 922X pin configs for
1163 102801AC
1164 102801D0
1166 static unsigned int dell_922x_d82_pin_configs[10] = {
1167 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
1168 0x02a19020, 0x01117011, 0x01451140, 0x400001f0,
1169 0x01813122, 0x400001f1,
1173 STAC 922X pin configs for
1174 102801BF
1176 static unsigned int dell_922x_m81_pin_configs[10] = {
1177 0x0321101f, 0x01112024, 0x01111222, 0x91174220,
1178 0x03a11050, 0x01116221, 0x90a70330, 0x01452340,
1179 0x40C003f1, 0x405003f0,
1183 STAC 9221 A1 pin configs for
1184 102801D7 (Dell XPS M1210)
1186 static unsigned int dell_922x_m82_pin_configs[10] = {
1187 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310,
1188 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2,
1189 0x508003f3, 0x405003f4,
1192 static unsigned int d945gtp3_pin_configs[10] = {
1193 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
1194 0x40000100, 0x40000100, 0x40000100, 0x40000100,
1195 0x02a19120, 0x40000100,
1198 static unsigned int d945gtp5_pin_configs[10] = {
1199 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
1200 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
1201 0x02a19320, 0x40000100,
1204 static unsigned int intel_mac_v1_pin_configs[10] = {
1205 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd,
1206 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240,
1207 0x400000fc, 0x400000fb,
1210 static unsigned int intel_mac_v2_pin_configs[10] = {
1211 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
1212 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa,
1213 0x400000fc, 0x400000fb,
1216 static unsigned int intel_mac_v3_pin_configs[10] = {
1217 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
1218 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240,
1219 0x400000fc, 0x400000fb,
1222 static unsigned int intel_mac_v4_pin_configs[10] = {
1223 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
1224 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
1225 0x400000fc, 0x400000fb,
1228 static unsigned int intel_mac_v5_pin_configs[10] = {
1229 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
1230 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
1231 0x400000fc, 0x400000fb,
1235 static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
1236 [STAC_D945_REF] = ref922x_pin_configs,
1237 [STAC_D945GTP3] = d945gtp3_pin_configs,
1238 [STAC_D945GTP5] = d945gtp5_pin_configs,
1239 [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs,
1240 [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs,
1241 [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs,
1242 [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs,
1243 [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs,
1244 /* for backward compatibility */
1245 [STAC_MACMINI] = intel_mac_v3_pin_configs,
1246 [STAC_MACBOOK] = intel_mac_v5_pin_configs,
1247 [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs,
1248 [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs,
1249 [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs,
1250 [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs,
1251 [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs,
1252 [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs,
1253 [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs,
1254 [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs,
1257 static const char *stac922x_models[STAC_922X_MODELS] = {
1258 [STAC_D945_REF] = "ref",
1259 [STAC_D945GTP5] = "5stack",
1260 [STAC_D945GTP3] = "3stack",
1261 [STAC_INTEL_MAC_V1] = "intel-mac-v1",
1262 [STAC_INTEL_MAC_V2] = "intel-mac-v2",
1263 [STAC_INTEL_MAC_V3] = "intel-mac-v3",
1264 [STAC_INTEL_MAC_V4] = "intel-mac-v4",
1265 [STAC_INTEL_MAC_V5] = "intel-mac-v5",
1266 /* for backward compatibility */
1267 [STAC_MACMINI] = "macmini",
1268 [STAC_MACBOOK] = "macbook",
1269 [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1",
1270 [STAC_MACBOOK_PRO_V2] = "macbook-pro",
1271 [STAC_IMAC_INTEL] = "imac-intel",
1272 [STAC_IMAC_INTEL_20] = "imac-intel-20",
1273 [STAC_922X_DELL_D81] = "dell-d81",
1274 [STAC_922X_DELL_D82] = "dell-d82",
1275 [STAC_922X_DELL_M81] = "dell-m81",
1276 [STAC_922X_DELL_M82] = "dell-m82",
1279 static struct snd_pci_quirk stac922x_cfg_tbl[] = {
1280 /* SigmaTel reference board */
1281 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1282 "DFI LanParty", STAC_D945_REF),
1283 /* Intel 945G based systems */
1284 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
1285 "Intel D945G", STAC_D945GTP3),
1286 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
1287 "Intel D945G", STAC_D945GTP3),
1288 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
1289 "Intel D945G", STAC_D945GTP3),
1290 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
1291 "Intel D945G", STAC_D945GTP3),
1292 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
1293 "Intel D945G", STAC_D945GTP3),
1294 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
1295 "Intel D945G", STAC_D945GTP3),
1296 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
1297 "Intel D945G", STAC_D945GTP3),
1298 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
1299 "Intel D945G", STAC_D945GTP3),
1300 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
1301 "Intel D945G", STAC_D945GTP3),
1302 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
1303 "Intel D945G", STAC_D945GTP3),
1304 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
1305 "Intel D945G", STAC_D945GTP3),
1306 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
1307 "Intel D945G", STAC_D945GTP3),
1308 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
1309 "Intel D945G", STAC_D945GTP3),
1310 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
1311 "Intel D945G", STAC_D945GTP3),
1312 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
1313 "Intel D945G", STAC_D945GTP3),
1314 /* Intel D945G 5-stack systems */
1315 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
1316 "Intel D945G", STAC_D945GTP5),
1317 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
1318 "Intel D945G", STAC_D945GTP5),
1319 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
1320 "Intel D945G", STAC_D945GTP5),
1321 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
1322 "Intel D945G", STAC_D945GTP5),
1323 /* Intel 945P based systems */
1324 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
1325 "Intel D945P", STAC_D945GTP3),
1326 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
1327 "Intel D945P", STAC_D945GTP3),
1328 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
1329 "Intel D945P", STAC_D945GTP3),
1330 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
1331 "Intel D945P", STAC_D945GTP3),
1332 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
1333 "Intel D945P", STAC_D945GTP3),
1334 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
1335 "Intel D945P", STAC_D945GTP5),
1336 /* other systems */
1337 /* Apple Mac Mini (early 2006) */
1338 SND_PCI_QUIRK(0x8384, 0x7680,
1339 "Mac Mini", STAC_INTEL_MAC_V3),
1340 /* Dell systems */
1341 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
1342 "unknown Dell", STAC_922X_DELL_D81),
1343 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
1344 "unknown Dell", STAC_922X_DELL_D81),
1345 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
1346 "unknown Dell", STAC_922X_DELL_D81),
1347 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
1348 "unknown Dell", STAC_922X_DELL_D82),
1349 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
1350 "unknown Dell", STAC_922X_DELL_M81),
1351 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
1352 "unknown Dell", STAC_922X_DELL_D82),
1353 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
1354 "unknown Dell", STAC_922X_DELL_D81),
1355 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
1356 "unknown Dell", STAC_922X_DELL_D81),
1357 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
1358 "Dell XPS M1210", STAC_922X_DELL_M82),
1359 {} /* terminator */
1362 static unsigned int ref927x_pin_configs[14] = {
1363 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1364 0x01a19040, 0x01011012, 0x01016011, 0x0101201f,
1365 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070,
1366 0x01c42190, 0x40000100,
1369 static unsigned int d965_3st_pin_configs[14] = {
1370 0x0221401f, 0x02a19120, 0x40000100, 0x01014011,
1371 0x01a19021, 0x01813024, 0x40000100, 0x40000100,
1372 0x40000100, 0x40000100, 0x40000100, 0x40000100,
1373 0x40000100, 0x40000100
1376 static unsigned int d965_5st_pin_configs[14] = {
1377 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1378 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
1379 0x40000100, 0x40000100, 0x40000100, 0x01442070,
1380 0x40000100, 0x40000100
1383 static unsigned int dell_3st_pin_configs[14] = {
1384 0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
1385 0x01111212, 0x01116211, 0x01813050, 0x01112214,
1386 0x403003fa, 0x90a60040, 0x90a60040, 0x404003fb,
1387 0x40c003fc, 0x40000100
1390 static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
1391 [STAC_D965_REF] = ref927x_pin_configs,
1392 [STAC_D965_3ST] = d965_3st_pin_configs,
1393 [STAC_D965_5ST] = d965_5st_pin_configs,
1394 [STAC_DELL_3ST] = dell_3st_pin_configs,
1395 [STAC_DELL_BIOS] = NULL,
1398 static const char *stac927x_models[STAC_927X_MODELS] = {
1399 [STAC_D965_REF] = "ref",
1400 [STAC_D965_3ST] = "3stack",
1401 [STAC_D965_5ST] = "5stack",
1402 [STAC_DELL_3ST] = "dell-3stack",
1403 [STAC_DELL_BIOS] = "dell-bios",
1406 static struct snd_pci_quirk stac927x_cfg_tbl[] = {
1407 /* SigmaTel reference board */
1408 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1409 "DFI LanParty", STAC_D965_REF),
1410 /* Intel 946 based systems */
1411 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
1412 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
1413 /* 965 based 3 stack systems */
1414 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2116, "Intel D965", STAC_D965_3ST),
1415 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2115, "Intel D965", STAC_D965_3ST),
1416 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2114, "Intel D965", STAC_D965_3ST),
1417 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2113, "Intel D965", STAC_D965_3ST),
1418 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2112, "Intel D965", STAC_D965_3ST),
1419 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2111, "Intel D965", STAC_D965_3ST),
1420 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2110, "Intel D965", STAC_D965_3ST),
1421 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2009, "Intel D965", STAC_D965_3ST),
1422 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2008, "Intel D965", STAC_D965_3ST),
1423 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2007, "Intel D965", STAC_D965_3ST),
1424 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2006, "Intel D965", STAC_D965_3ST),
1425 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2005, "Intel D965", STAC_D965_3ST),
1426 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2004, "Intel D965", STAC_D965_3ST),
1427 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST),
1428 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST),
1429 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST),
1430 /* Dell 3 stack systems */
1431 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_3ST),
1432 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_3ST),
1433 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
1434 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
1435 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
1436 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_3ST),
1437 /* Dell 3 stack systems with verb table in BIOS */
1438 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell ", STAC_DELL_BIOS),
1439 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS),
1440 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
1441 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
1442 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
1443 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS),
1444 /* 965 based 5 stack systems */
1445 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST),
1446 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST),
1447 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST),
1448 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2304, "Intel D965", STAC_D965_5ST),
1449 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2305, "Intel D965", STAC_D965_5ST),
1450 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2501, "Intel D965", STAC_D965_5ST),
1451 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2502, "Intel D965", STAC_D965_5ST),
1452 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2503, "Intel D965", STAC_D965_5ST),
1453 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2504, "Intel D965", STAC_D965_5ST),
1454 {} /* terminator */
1457 static unsigned int ref9205_pin_configs[12] = {
1458 0x40000100, 0x40000100, 0x01016011, 0x01014010,
1459 0x01813122, 0x01a19021, 0x40000100, 0x40000100,
1460 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
1464 STAC 9205 pin configs for
1465 102801F1
1466 102801F2
1467 102801FC
1468 102801FD
1469 10280204
1470 1028021F
1472 static unsigned int dell_9205_m42_pin_configs[12] = {
1473 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310,
1474 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9,
1475 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE,
1479 STAC 9205 pin configs for
1480 102801F9
1481 102801FA
1482 102801FE
1483 102801FF (Dell Precision M4300)
1484 10280206
1485 10280200
1486 10280201
1488 static unsigned int dell_9205_m43_pin_configs[12] = {
1489 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310,
1490 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9,
1491 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8,
1494 static unsigned int dell_9205_m44_pin_configs[12] = {
1495 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310,
1496 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9,
1497 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe,
1500 static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
1501 [STAC_9205_REF] = ref9205_pin_configs,
1502 [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs,
1503 [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs,
1504 [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs,
1507 static const char *stac9205_models[STAC_9205_MODELS] = {
1508 [STAC_9205_REF] = "ref",
1509 [STAC_9205_DELL_M42] = "dell-m42",
1510 [STAC_9205_DELL_M43] = "dell-m43",
1511 [STAC_9205_DELL_M44] = "dell-m44",
1514 static struct snd_pci_quirk stac9205_cfg_tbl[] = {
1515 /* SigmaTel reference board */
1516 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1517 "DFI LanParty", STAC_9205_REF),
1518 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1519 "unknown Dell", STAC_9205_DELL_M42),
1520 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1521 "unknown Dell", STAC_9205_DELL_M42),
1522 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
1523 "Dell Precision", STAC_9205_DELL_M43),
1524 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
1525 "Dell Precision", STAC_9205_DELL_M43),
1526 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
1527 "Dell Precision", STAC_9205_DELL_M43),
1528 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
1529 "Dell Precision", STAC_9205_DELL_M43),
1530 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
1531 "Dell Precision", STAC_9205_DELL_M43),
1532 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1533 "unknown Dell", STAC_9205_DELL_M42),
1534 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1535 "unknown Dell", STAC_9205_DELL_M42),
1536 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
1537 "Dell Precision", STAC_9205_DELL_M43),
1538 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
1539 "Dell Precision M4300", STAC_9205_DELL_M43),
1540 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
1541 "Dell Precision", STAC_9205_DELL_M43),
1542 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1543 "Dell Inspiron", STAC_9205_DELL_M44),
1544 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1545 "Dell Inspiron", STAC_9205_DELL_M44),
1546 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1547 "Dell Inspiron", STAC_9205_DELL_M44),
1548 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1549 "Dell Inspiron", STAC_9205_DELL_M44),
1550 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
1551 "unknown Dell", STAC_9205_DELL_M42),
1552 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
1553 "Dell Inspiron", STAC_9205_DELL_M44),
1554 {} /* terminator */
1557 static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
1559 int i;
1560 struct sigmatel_spec *spec = codec->spec;
1562 if (! spec->bios_pin_configs) {
1563 spec->bios_pin_configs = kcalloc(spec->num_pins,
1564 sizeof(*spec->bios_pin_configs), GFP_KERNEL);
1565 if (! spec->bios_pin_configs)
1566 return -ENOMEM;
1569 for (i = 0; i < spec->num_pins; i++) {
1570 hda_nid_t nid = spec->pin_nids[i];
1571 unsigned int pin_cfg;
1573 pin_cfg = snd_hda_codec_read(codec, nid, 0,
1574 AC_VERB_GET_CONFIG_DEFAULT, 0x00);
1575 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n",
1576 nid, pin_cfg);
1577 spec->bios_pin_configs[i] = pin_cfg;
1580 return 0;
1583 static void stac92xx_set_config_reg(struct hda_codec *codec,
1584 hda_nid_t pin_nid, unsigned int pin_config)
1586 int i;
1587 snd_hda_codec_write(codec, pin_nid, 0,
1588 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
1589 pin_config & 0x000000ff);
1590 snd_hda_codec_write(codec, pin_nid, 0,
1591 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
1592 (pin_config & 0x0000ff00) >> 8);
1593 snd_hda_codec_write(codec, pin_nid, 0,
1594 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
1595 (pin_config & 0x00ff0000) >> 16);
1596 snd_hda_codec_write(codec, pin_nid, 0,
1597 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
1598 pin_config >> 24);
1599 i = snd_hda_codec_read(codec, pin_nid, 0,
1600 AC_VERB_GET_CONFIG_DEFAULT,
1601 0x00);
1602 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n",
1603 pin_nid, i);
1606 static void stac92xx_set_config_regs(struct hda_codec *codec)
1608 int i;
1609 struct sigmatel_spec *spec = codec->spec;
1611 if (!spec->pin_configs)
1612 return;
1614 for (i = 0; i < spec->num_pins; i++)
1615 stac92xx_set_config_reg(codec, spec->pin_nids[i],
1616 spec->pin_configs[i]);
1619 static void stac92xx_enable_gpio_mask(struct hda_codec *codec)
1621 struct sigmatel_spec *spec = codec->spec;
1622 /* Configure GPIOx as output */
1623 snd_hda_codec_write_cache(codec, codec->afg, 0,
1624 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_mask);
1625 /* Configure GPIOx as CMOS */
1626 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7e7, 0x00000000);
1627 /* Assert GPIOx */
1628 snd_hda_codec_write_cache(codec, codec->afg, 0,
1629 AC_VERB_SET_GPIO_DATA, spec->gpio_data);
1630 /* Enable GPIOx */
1631 snd_hda_codec_write_cache(codec, codec->afg, 0,
1632 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
1636 * Analog playback callbacks
1638 static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
1639 struct hda_codec *codec,
1640 struct snd_pcm_substream *substream)
1642 struct sigmatel_spec *spec = codec->spec;
1643 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
1646 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1647 struct hda_codec *codec,
1648 unsigned int stream_tag,
1649 unsigned int format,
1650 struct snd_pcm_substream *substream)
1652 struct sigmatel_spec *spec = codec->spec;
1653 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream);
1656 static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1657 struct hda_codec *codec,
1658 struct snd_pcm_substream *substream)
1660 struct sigmatel_spec *spec = codec->spec;
1661 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1665 * Digital playback callbacks
1667 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1668 struct hda_codec *codec,
1669 struct snd_pcm_substream *substream)
1671 struct sigmatel_spec *spec = codec->spec;
1672 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1675 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1676 struct hda_codec *codec,
1677 struct snd_pcm_substream *substream)
1679 struct sigmatel_spec *spec = codec->spec;
1680 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1683 static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1684 struct hda_codec *codec,
1685 unsigned int stream_tag,
1686 unsigned int format,
1687 struct snd_pcm_substream *substream)
1689 struct sigmatel_spec *spec = codec->spec;
1690 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1691 stream_tag, format, substream);
1696 * Analog capture callbacks
1698 static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1699 struct hda_codec *codec,
1700 unsigned int stream_tag,
1701 unsigned int format,
1702 struct snd_pcm_substream *substream)
1704 struct sigmatel_spec *spec = codec->spec;
1706 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1707 stream_tag, 0, format);
1708 return 0;
1711 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1712 struct hda_codec *codec,
1713 struct snd_pcm_substream *substream)
1715 struct sigmatel_spec *spec = codec->spec;
1717 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
1718 return 0;
1721 static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
1722 .substreams = 1,
1723 .channels_min = 2,
1724 .channels_max = 2,
1725 /* NID is set in stac92xx_build_pcms */
1726 .ops = {
1727 .open = stac92xx_dig_playback_pcm_open,
1728 .close = stac92xx_dig_playback_pcm_close,
1729 .prepare = stac92xx_dig_playback_pcm_prepare
1733 static struct hda_pcm_stream stac92xx_pcm_digital_capture = {
1734 .substreams = 1,
1735 .channels_min = 2,
1736 .channels_max = 2,
1737 /* NID is set in stac92xx_build_pcms */
1740 static struct hda_pcm_stream stac92xx_pcm_analog_playback = {
1741 .substreams = 1,
1742 .channels_min = 2,
1743 .channels_max = 8,
1744 .nid = 0x02, /* NID to query formats and rates */
1745 .ops = {
1746 .open = stac92xx_playback_pcm_open,
1747 .prepare = stac92xx_playback_pcm_prepare,
1748 .cleanup = stac92xx_playback_pcm_cleanup
1752 static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
1753 .substreams = 1,
1754 .channels_min = 2,
1755 .channels_max = 2,
1756 .nid = 0x06, /* NID to query formats and rates */
1757 .ops = {
1758 .open = stac92xx_playback_pcm_open,
1759 .prepare = stac92xx_playback_pcm_prepare,
1760 .cleanup = stac92xx_playback_pcm_cleanup
1764 static struct hda_pcm_stream stac92xx_pcm_analog_capture = {
1765 .channels_min = 2,
1766 .channels_max = 2,
1767 /* NID + .substreams is set in stac92xx_build_pcms */
1768 .ops = {
1769 .prepare = stac92xx_capture_pcm_prepare,
1770 .cleanup = stac92xx_capture_pcm_cleanup
1774 static int stac92xx_build_pcms(struct hda_codec *codec)
1776 struct sigmatel_spec *spec = codec->spec;
1777 struct hda_pcm *info = spec->pcm_rec;
1779 codec->num_pcms = 1;
1780 codec->pcm_info = info;
1782 info->name = "STAC92xx Analog";
1783 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
1784 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
1785 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1786 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs;
1788 if (spec->alt_switch) {
1789 codec->num_pcms++;
1790 info++;
1791 info->name = "STAC92xx Analog Alt";
1792 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback;
1795 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1796 codec->num_pcms++;
1797 info++;
1798 info->name = "STAC92xx Digital";
1799 if (spec->multiout.dig_out_nid) {
1800 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
1801 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
1803 if (spec->dig_in_nid) {
1804 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture;
1805 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
1809 return 0;
1812 static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
1814 unsigned int pincap = snd_hda_param_read(codec, nid,
1815 AC_PAR_PIN_CAP);
1816 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
1817 if (pincap & AC_PINCAP_VREF_100)
1818 return AC_PINCTL_VREF_100;
1819 if (pincap & AC_PINCAP_VREF_80)
1820 return AC_PINCTL_VREF_80;
1821 if (pincap & AC_PINCAP_VREF_50)
1822 return AC_PINCTL_VREF_50;
1823 if (pincap & AC_PINCAP_VREF_GRD)
1824 return AC_PINCTL_VREF_GRD;
1825 return 0;
1828 static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
1831 snd_hda_codec_write_cache(codec, nid, 0,
1832 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
1835 #define stac92xx_io_switch_info snd_ctl_boolean_mono_info
1837 static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1839 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1840 struct sigmatel_spec *spec = codec->spec;
1841 int io_idx = kcontrol-> private_value & 0xff;
1843 ucontrol->value.integer.value[0] = spec->io_switch[io_idx];
1844 return 0;
1847 static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1849 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1850 struct sigmatel_spec *spec = codec->spec;
1851 hda_nid_t nid = kcontrol->private_value >> 8;
1852 int io_idx = kcontrol-> private_value & 0xff;
1853 unsigned short val = !!ucontrol->value.integer.value[0];
1855 spec->io_switch[io_idx] = val;
1857 if (val)
1858 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
1859 else {
1860 unsigned int pinctl = AC_PINCTL_IN_EN;
1861 if (io_idx) /* set VREF for mic */
1862 pinctl |= stac92xx_get_vref(codec, nid);
1863 stac92xx_auto_set_pinctl(codec, nid, pinctl);
1866 /* check the auto-mute again: we need to mute/unmute the speaker
1867 * appropriately according to the pin direction
1869 if (spec->hp_detect)
1870 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
1872 return 1;
1875 #define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info
1877 static int stac92xx_clfe_switch_get(struct snd_kcontrol *kcontrol,
1878 struct snd_ctl_elem_value *ucontrol)
1880 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1881 struct sigmatel_spec *spec = codec->spec;
1883 ucontrol->value.integer.value[0] = spec->clfe_swap;
1884 return 0;
1887 static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
1888 struct snd_ctl_elem_value *ucontrol)
1890 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1891 struct sigmatel_spec *spec = codec->spec;
1892 hda_nid_t nid = kcontrol->private_value & 0xff;
1893 unsigned int val = !!ucontrol->value.integer.value[0];
1895 if (spec->clfe_swap == val)
1896 return 0;
1898 spec->clfe_swap = val;
1900 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1901 spec->clfe_swap ? 0x4 : 0x0);
1903 return 1;
1906 #define STAC_CODEC_IO_SWITCH(xname, xpval) \
1907 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1908 .name = xname, \
1909 .index = 0, \
1910 .info = stac92xx_io_switch_info, \
1911 .get = stac92xx_io_switch_get, \
1912 .put = stac92xx_io_switch_put, \
1913 .private_value = xpval, \
1916 #define STAC_CODEC_CLFE_SWITCH(xname, xpval) \
1917 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1918 .name = xname, \
1919 .index = 0, \
1920 .info = stac92xx_clfe_switch_info, \
1921 .get = stac92xx_clfe_switch_get, \
1922 .put = stac92xx_clfe_switch_put, \
1923 .private_value = xpval, \
1926 enum {
1927 STAC_CTL_WIDGET_VOL,
1928 STAC_CTL_WIDGET_MUTE,
1929 STAC_CTL_WIDGET_IO_SWITCH,
1930 STAC_CTL_WIDGET_CLFE_SWITCH
1933 static struct snd_kcontrol_new stac92xx_control_templates[] = {
1934 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
1935 HDA_CODEC_MUTE(NULL, 0, 0, 0),
1936 STAC_CODEC_IO_SWITCH(NULL, 0),
1937 STAC_CODEC_CLFE_SWITCH(NULL, 0),
1940 /* add dynamic controls */
1941 static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val)
1943 struct snd_kcontrol_new *knew;
1945 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
1946 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
1948 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
1949 if (! knew)
1950 return -ENOMEM;
1951 if (spec->kctl_alloc) {
1952 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
1953 kfree(spec->kctl_alloc);
1955 spec->kctl_alloc = knew;
1956 spec->num_kctl_alloc = num;
1959 knew = &spec->kctl_alloc[spec->num_kctl_used];
1960 *knew = stac92xx_control_templates[type];
1961 knew->name = kstrdup(name, GFP_KERNEL);
1962 if (! knew->name)
1963 return -ENOMEM;
1964 knew->private_value = val;
1965 spec->num_kctl_used++;
1966 return 0;
1969 /* flag inputs as additional dynamic lineouts */
1970 static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
1972 struct sigmatel_spec *spec = codec->spec;
1973 unsigned int wcaps, wtype;
1974 int i, num_dacs = 0;
1976 /* use the wcaps cache to count all DACs available for line-outs */
1977 for (i = 0; i < codec->num_nodes; i++) {
1978 wcaps = codec->wcaps[i];
1979 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
1981 if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL))
1982 num_dacs++;
1985 snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
1987 switch (cfg->line_outs) {
1988 case 3:
1989 /* add line-in as side */
1990 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
1991 cfg->line_out_pins[cfg->line_outs] =
1992 cfg->input_pins[AUTO_PIN_LINE];
1993 spec->line_switch = 1;
1994 cfg->line_outs++;
1996 break;
1997 case 2:
1998 /* add line-in as clfe and mic as side */
1999 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
2000 cfg->line_out_pins[cfg->line_outs] =
2001 cfg->input_pins[AUTO_PIN_LINE];
2002 spec->line_switch = 1;
2003 cfg->line_outs++;
2005 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
2006 cfg->line_out_pins[cfg->line_outs] =
2007 cfg->input_pins[AUTO_PIN_MIC];
2008 spec->mic_switch = 1;
2009 cfg->line_outs++;
2011 break;
2012 case 1:
2013 /* add line-in as surr and mic as clfe */
2014 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
2015 cfg->line_out_pins[cfg->line_outs] =
2016 cfg->input_pins[AUTO_PIN_LINE];
2017 spec->line_switch = 1;
2018 cfg->line_outs++;
2020 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
2021 cfg->line_out_pins[cfg->line_outs] =
2022 cfg->input_pins[AUTO_PIN_MIC];
2023 spec->mic_switch = 1;
2024 cfg->line_outs++;
2026 break;
2029 return 0;
2033 static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2035 int i;
2037 for (i = 0; i < spec->multiout.num_dacs; i++) {
2038 if (spec->multiout.dac_nids[i] == nid)
2039 return 1;
2042 return 0;
2046 * Fill in the dac_nids table from the parsed pin configuration
2047 * This function only works when every pin in line_out_pins[]
2048 * contains atleast one DAC in its connection list. Some 92xx
2049 * codecs are not connected directly to a DAC, such as the 9200
2050 * and 9202/925x. For those, dac_nids[] must be hard-coded.
2052 static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
2053 struct auto_pin_cfg *cfg)
2055 struct sigmatel_spec *spec = codec->spec;
2056 int i, j, conn_len = 0;
2057 hda_nid_t nid, conn[HDA_MAX_CONNECTIONS];
2058 unsigned int wcaps, wtype;
2060 for (i = 0; i < cfg->line_outs; i++) {
2061 nid = cfg->line_out_pins[i];
2062 conn_len = snd_hda_get_connections(codec, nid, conn,
2063 HDA_MAX_CONNECTIONS);
2064 for (j = 0; j < conn_len; j++) {
2065 wcaps = snd_hda_param_read(codec, conn[j],
2066 AC_PAR_AUDIO_WIDGET_CAP);
2067 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2068 if (wtype != AC_WID_AUD_OUT ||
2069 (wcaps & AC_WCAP_DIGITAL))
2070 continue;
2071 /* conn[j] is a DAC routed to this line-out */
2072 if (!is_in_dac_nids(spec, conn[j]))
2073 break;
2076 if (j == conn_len) {
2077 if (spec->multiout.num_dacs > 0) {
2078 /* we have already working output pins,
2079 * so let's drop the broken ones again
2081 cfg->line_outs = spec->multiout.num_dacs;
2082 break;
2084 /* error out, no available DAC found */
2085 snd_printk(KERN_ERR
2086 "%s: No available DAC for pin 0x%x\n",
2087 __func__, nid);
2088 return -ENODEV;
2091 spec->multiout.dac_nids[i] = conn[j];
2092 spec->multiout.num_dacs++;
2093 if (conn_len > 1) {
2094 /* select this DAC in the pin's input mux */
2095 snd_hda_codec_write_cache(codec, nid, 0,
2096 AC_VERB_SET_CONNECT_SEL, j);
2101 snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
2102 spec->multiout.num_dacs,
2103 spec->multiout.dac_nids[0],
2104 spec->multiout.dac_nids[1],
2105 spec->multiout.dac_nids[2],
2106 spec->multiout.dac_nids[3],
2107 spec->multiout.dac_nids[4]);
2108 return 0;
2111 /* create volume control/switch for the given prefx type */
2112 static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_t nid, int chs)
2114 char name[32];
2115 int err;
2117 sprintf(name, "%s Playback Volume", pfx);
2118 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name,
2119 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
2120 if (err < 0)
2121 return err;
2122 sprintf(name, "%s Playback Switch", pfx);
2123 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name,
2124 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
2125 if (err < 0)
2126 return err;
2127 return 0;
2130 /* add playback controls from the parsed DAC table */
2131 static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
2132 const struct auto_pin_cfg *cfg)
2134 static const char *chname[4] = {
2135 "Front", "Surround", NULL /*CLFE*/, "Side"
2137 hda_nid_t nid;
2138 int i, err;
2140 struct sigmatel_spec *spec = codec->spec;
2141 unsigned int wid_caps;
2144 for (i = 0; i < cfg->line_outs; i++) {
2145 if (!spec->multiout.dac_nids[i])
2146 continue;
2148 nid = spec->multiout.dac_nids[i];
2150 if (i == 2) {
2151 /* Center/LFE */
2152 err = create_controls(spec, "Center", nid, 1);
2153 if (err < 0)
2154 return err;
2155 err = create_controls(spec, "LFE", nid, 2);
2156 if (err < 0)
2157 return err;
2159 wid_caps = get_wcaps(codec, nid);
2161 if (wid_caps & AC_WCAP_LR_SWAP) {
2162 err = stac92xx_add_control(spec,
2163 STAC_CTL_WIDGET_CLFE_SWITCH,
2164 "Swap Center/LFE Playback Switch", nid);
2166 if (err < 0)
2167 return err;
2170 } else {
2171 err = create_controls(spec, chname[i], nid, 3);
2172 if (err < 0)
2173 return err;
2177 if (spec->line_switch)
2178 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Line In as Output Switch", cfg->input_pins[AUTO_PIN_LINE] << 8)) < 0)
2179 return err;
2181 if (spec->mic_switch)
2182 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Mic as Output Switch", (cfg->input_pins[AUTO_PIN_MIC] << 8) | 1)) < 0)
2183 return err;
2185 return 0;
2188 static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2190 if (is_in_dac_nids(spec, nid))
2191 return 1;
2192 if (spec->multiout.hp_nid == nid)
2193 return 1;
2194 return 0;
2197 static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
2199 if (!spec->multiout.hp_nid)
2200 spec->multiout.hp_nid = nid;
2201 else if (spec->multiout.num_dacs > 4) {
2202 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
2203 return 1;
2204 } else {
2205 spec->multiout.dac_nids[spec->multiout.num_dacs] = nid;
2206 spec->multiout.num_dacs++;
2208 return 0;
2211 /* add playback controls for Speaker and HP outputs */
2212 static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
2213 struct auto_pin_cfg *cfg)
2215 struct sigmatel_spec *spec = codec->spec;
2216 hda_nid_t nid;
2217 int i, old_num_dacs, err;
2219 old_num_dacs = spec->multiout.num_dacs;
2220 for (i = 0; i < cfg->hp_outs; i++) {
2221 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]);
2222 if (wid_caps & AC_WCAP_UNSOL_CAP)
2223 spec->hp_detect = 1;
2224 nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
2225 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2226 if (check_in_dac_nids(spec, nid))
2227 nid = 0;
2228 if (! nid)
2229 continue;
2230 add_spec_dacs(spec, nid);
2232 for (i = 0; i < cfg->speaker_outs; i++) {
2233 nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
2234 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2235 if (check_in_dac_nids(spec, nid))
2236 nid = 0;
2237 if (! nid)
2238 continue;
2239 add_spec_dacs(spec, nid);
2241 for (i = 0; i < cfg->line_outs; i++) {
2242 nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0,
2243 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2244 if (check_in_dac_nids(spec, nid))
2245 nid = 0;
2246 if (! nid)
2247 continue;
2248 add_spec_dacs(spec, nid);
2250 for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) {
2251 static const char *pfxs[] = {
2252 "Speaker", "External Speaker", "Speaker2",
2254 err = create_controls(spec, pfxs[i - old_num_dacs],
2255 spec->multiout.dac_nids[i], 3);
2256 if (err < 0)
2257 return err;
2259 if (spec->multiout.hp_nid) {
2260 const char *pfx;
2261 if (old_num_dacs == spec->multiout.num_dacs)
2262 pfx = "Master";
2263 else
2264 pfx = "Headphone";
2265 err = create_controls(spec, pfx, spec->multiout.hp_nid, 3);
2266 if (err < 0)
2267 return err;
2270 return 0;
2273 /* labels for dmic mux inputs */
2274 static const char *stac92xx_dmic_labels[5] = {
2275 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
2276 "Digital Mic 3", "Digital Mic 4"
2279 /* create playback/capture controls for input pins on dmic capable codecs */
2280 static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
2281 const struct auto_pin_cfg *cfg)
2283 struct sigmatel_spec *spec = codec->spec;
2284 struct hda_input_mux *dimux = &spec->private_dimux;
2285 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
2286 int err, i, j;
2287 char name[32];
2289 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0];
2290 dimux->items[dimux->num_items].index = 0;
2291 dimux->num_items++;
2293 for (i = 0; i < spec->num_dmics; i++) {
2294 hda_nid_t nid;
2295 int index;
2296 int num_cons;
2297 unsigned int wcaps;
2298 unsigned int def_conf;
2300 def_conf = snd_hda_codec_read(codec,
2301 spec->dmic_nids[i],
2303 AC_VERB_GET_CONFIG_DEFAULT,
2305 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
2306 continue;
2308 nid = spec->dmic_nids[i];
2309 num_cons = snd_hda_get_connections(codec,
2310 spec->dmux_nids[0],
2311 con_lst,
2312 HDA_MAX_NUM_INPUTS);
2313 for (j = 0; j < num_cons; j++)
2314 if (con_lst[j] == nid) {
2315 index = j;
2316 goto found;
2318 continue;
2319 found:
2320 wcaps = get_wcaps(codec, nid);
2322 if (wcaps & AC_WCAP_OUT_AMP) {
2323 sprintf(name, "%s Capture Volume",
2324 stac92xx_dmic_labels[dimux->num_items]);
2326 err = stac92xx_add_control(spec,
2327 STAC_CTL_WIDGET_VOL,
2328 name,
2329 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
2330 if (err < 0)
2331 return err;
2334 dimux->items[dimux->num_items].label =
2335 stac92xx_dmic_labels[dimux->num_items];
2336 dimux->items[dimux->num_items].index = index;
2337 dimux->num_items++;
2340 return 0;
2343 /* create playback/capture controls for input pins */
2344 static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
2346 struct sigmatel_spec *spec = codec->spec;
2347 struct hda_input_mux *imux = &spec->private_imux;
2348 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
2349 int i, j, k;
2351 for (i = 0; i < AUTO_PIN_LAST; i++) {
2352 int index;
2354 if (!cfg->input_pins[i])
2355 continue;
2356 index = -1;
2357 for (j = 0; j < spec->num_muxes; j++) {
2358 int num_cons;
2359 num_cons = snd_hda_get_connections(codec,
2360 spec->mux_nids[j],
2361 con_lst,
2362 HDA_MAX_NUM_INPUTS);
2363 for (k = 0; k < num_cons; k++)
2364 if (con_lst[k] == cfg->input_pins[i]) {
2365 index = k;
2366 goto found;
2369 continue;
2370 found:
2371 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2372 imux->items[imux->num_items].index = index;
2373 imux->num_items++;
2376 if (imux->num_items) {
2378 * Set the current input for the muxes.
2379 * The STAC9221 has two input muxes with identical source
2380 * NID lists. Hopefully this won't get confused.
2382 for (i = 0; i < spec->num_muxes; i++) {
2383 snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0,
2384 AC_VERB_SET_CONNECT_SEL,
2385 imux->items[0].index);
2389 return 0;
2392 static void stac92xx_auto_init_multi_out(struct hda_codec *codec)
2394 struct sigmatel_spec *spec = codec->spec;
2395 int i;
2397 for (i = 0; i < spec->autocfg.line_outs; i++) {
2398 hda_nid_t nid = spec->autocfg.line_out_pins[i];
2399 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
2403 static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
2405 struct sigmatel_spec *spec = codec->spec;
2406 int i;
2408 for (i = 0; i < spec->autocfg.hp_outs; i++) {
2409 hda_nid_t pin;
2410 pin = spec->autocfg.hp_pins[i];
2411 if (pin) /* connect to front */
2412 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
2414 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
2415 hda_nid_t pin;
2416 pin = spec->autocfg.speaker_pins[i];
2417 if (pin) /* connect to front */
2418 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN);
2422 static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in)
2424 struct sigmatel_spec *spec = codec->spec;
2425 int err;
2426 int hp_speaker_swap = 0;
2428 if ((err = snd_hda_parse_pin_def_config(codec,
2429 &spec->autocfg,
2430 spec->dmic_nids)) < 0)
2431 return err;
2432 if (! spec->autocfg.line_outs)
2433 return 0; /* can't find valid pin config */
2435 /* If we have no real line-out pin and multiple hp-outs, HPs should
2436 * be set up as multi-channel outputs.
2438 if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
2439 spec->autocfg.hp_outs > 1) {
2440 /* Copy hp_outs to line_outs, backup line_outs in
2441 * speaker_outs so that the following routines can handle
2442 * HP pins as primary outputs.
2444 memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins,
2445 sizeof(spec->autocfg.line_out_pins));
2446 spec->autocfg.speaker_outs = spec->autocfg.line_outs;
2447 memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins,
2448 sizeof(spec->autocfg.hp_pins));
2449 spec->autocfg.line_outs = spec->autocfg.hp_outs;
2450 hp_speaker_swap = 1;
2453 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
2454 return err;
2455 if (spec->multiout.num_dacs == 0)
2456 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
2457 return err;
2459 err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg);
2461 if (err < 0)
2462 return err;
2464 if (hp_speaker_swap == 1) {
2465 /* Restore the hp_outs and line_outs */
2466 memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
2467 sizeof(spec->autocfg.line_out_pins));
2468 spec->autocfg.hp_outs = spec->autocfg.line_outs;
2469 memcpy(spec->autocfg.line_out_pins, spec->autocfg.speaker_pins,
2470 sizeof(spec->autocfg.speaker_pins));
2471 spec->autocfg.line_outs = spec->autocfg.speaker_outs;
2472 memset(spec->autocfg.speaker_pins, 0,
2473 sizeof(spec->autocfg.speaker_pins));
2474 spec->autocfg.speaker_outs = 0;
2477 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
2479 if (err < 0)
2480 return err;
2482 err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
2484 if (err < 0)
2485 return err;
2487 if (spec->num_dmics > 0)
2488 if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
2489 &spec->autocfg)) < 0)
2490 return err;
2492 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2493 if (spec->multiout.max_channels > 2)
2494 spec->surr_switch = 1;
2496 if (spec->autocfg.dig_out_pin)
2497 spec->multiout.dig_out_nid = dig_out;
2498 if (spec->autocfg.dig_in_pin)
2499 spec->dig_in_nid = dig_in;
2501 if (spec->kctl_alloc)
2502 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2504 spec->input_mux = &spec->private_imux;
2505 if (!spec->dinput_mux)
2506 spec->dinput_mux = &spec->private_dimux;
2508 return 1;
2511 /* add playback controls for HP output */
2512 static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
2513 struct auto_pin_cfg *cfg)
2515 struct sigmatel_spec *spec = codec->spec;
2516 hda_nid_t pin = cfg->hp_pins[0];
2517 unsigned int wid_caps;
2519 if (! pin)
2520 return 0;
2522 wid_caps = get_wcaps(codec, pin);
2523 if (wid_caps & AC_WCAP_UNSOL_CAP)
2524 spec->hp_detect = 1;
2526 return 0;
2529 /* add playback controls for LFE output */
2530 static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec,
2531 struct auto_pin_cfg *cfg)
2533 struct sigmatel_spec *spec = codec->spec;
2534 int err;
2535 hda_nid_t lfe_pin = 0x0;
2536 int i;
2539 * search speaker outs and line outs for a mono speaker pin
2540 * with an amp. If one is found, add LFE controls
2541 * for it.
2543 for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) {
2544 hda_nid_t pin = spec->autocfg.speaker_pins[i];
2545 unsigned long wcaps = get_wcaps(codec, pin);
2546 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
2547 if (wcaps == AC_WCAP_OUT_AMP)
2548 /* found a mono speaker with an amp, must be lfe */
2549 lfe_pin = pin;
2552 /* if speaker_outs is 0, then speakers may be in line_outs */
2553 if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) {
2554 for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) {
2555 hda_nid_t pin = spec->autocfg.line_out_pins[i];
2556 unsigned long cfg;
2557 cfg = snd_hda_codec_read(codec, pin, 0,
2558 AC_VERB_GET_CONFIG_DEFAULT,
2559 0x00);
2560 if (get_defcfg_device(cfg) == AC_JACK_SPEAKER) {
2561 unsigned long wcaps = get_wcaps(codec, pin);
2562 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
2563 if (wcaps == AC_WCAP_OUT_AMP)
2564 /* found a mono speaker with an amp,
2565 must be lfe */
2566 lfe_pin = pin;
2571 if (lfe_pin) {
2572 err = create_controls(spec, "LFE", lfe_pin, 1);
2573 if (err < 0)
2574 return err;
2577 return 0;
2580 static int stac9200_parse_auto_config(struct hda_codec *codec)
2582 struct sigmatel_spec *spec = codec->spec;
2583 int err;
2585 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
2586 return err;
2588 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
2589 return err;
2591 if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)
2592 return err;
2594 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
2595 return err;
2597 if (spec->autocfg.dig_out_pin)
2598 spec->multiout.dig_out_nid = 0x05;
2599 if (spec->autocfg.dig_in_pin)
2600 spec->dig_in_nid = 0x04;
2602 if (spec->kctl_alloc)
2603 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2605 spec->input_mux = &spec->private_imux;
2606 spec->dinput_mux = &spec->private_dimux;
2608 return 1;
2612 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
2613 * funky external mute control using GPIO pins.
2616 static void stac922x_gpio_mute(struct hda_codec *codec, int pin, int muted)
2618 unsigned int gpiostate, gpiomask, gpiodir;
2620 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
2621 AC_VERB_GET_GPIO_DATA, 0);
2623 if (!muted)
2624 gpiostate |= (1 << pin);
2625 else
2626 gpiostate &= ~(1 << pin);
2628 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
2629 AC_VERB_GET_GPIO_MASK, 0);
2630 gpiomask |= (1 << pin);
2632 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
2633 AC_VERB_GET_GPIO_DIRECTION, 0);
2634 gpiodir |= (1 << pin);
2636 /* AppleHDA seems to do this -- WTF is this verb?? */
2637 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
2639 snd_hda_codec_write(codec, codec->afg, 0,
2640 AC_VERB_SET_GPIO_MASK, gpiomask);
2641 snd_hda_codec_write(codec, codec->afg, 0,
2642 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
2644 msleep(1);
2646 snd_hda_codec_write(codec, codec->afg, 0,
2647 AC_VERB_SET_GPIO_DATA, gpiostate);
2650 static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
2651 unsigned int event)
2653 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)
2654 snd_hda_codec_write_cache(codec, nid, 0,
2655 AC_VERB_SET_UNSOLICITED_ENABLE,
2656 (AC_USRSP_EN | event));
2659 static int stac92xx_init(struct hda_codec *codec)
2661 struct sigmatel_spec *spec = codec->spec;
2662 struct auto_pin_cfg *cfg = &spec->autocfg;
2663 int i;
2665 snd_hda_sequence_write(codec, spec->init);
2667 /* set up pins */
2668 if (spec->hp_detect) {
2669 /* Enable unsolicited responses on the HP widget */
2670 for (i = 0; i < cfg->hp_outs; i++)
2671 enable_pin_detect(codec, cfg->hp_pins[i],
2672 STAC_HP_EVENT);
2673 /* force to enable the first line-out; the others are set up
2674 * in unsol_event
2676 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
2677 AC_PINCTL_OUT_EN);
2678 stac92xx_auto_init_hp_out(codec);
2679 /* fake event to set up pins */
2680 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2681 } else {
2682 stac92xx_auto_init_multi_out(codec);
2683 stac92xx_auto_init_hp_out(codec);
2685 for (i = 0; i < AUTO_PIN_LAST; i++) {
2686 hda_nid_t nid = cfg->input_pins[i];
2687 if (nid) {
2688 unsigned int pinctl = AC_PINCTL_IN_EN;
2689 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
2690 pinctl |= stac92xx_get_vref(codec, nid);
2691 stac92xx_auto_set_pinctl(codec, nid, pinctl);
2694 if (spec->num_dmics > 0)
2695 for (i = 0; i < spec->num_dmics; i++)
2696 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
2697 AC_PINCTL_IN_EN);
2699 if (cfg->dig_out_pin)
2700 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
2701 AC_PINCTL_OUT_EN);
2702 if (cfg->dig_in_pin)
2703 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
2704 AC_PINCTL_IN_EN);
2706 if (spec->gpio_mute) {
2707 stac922x_gpio_mute(codec, 0, 0);
2708 stac922x_gpio_mute(codec, 1, 0);
2711 return 0;
2714 static void stac92xx_free(struct hda_codec *codec)
2716 struct sigmatel_spec *spec = codec->spec;
2717 int i;
2719 if (! spec)
2720 return;
2722 if (spec->kctl_alloc) {
2723 for (i = 0; i < spec->num_kctl_used; i++)
2724 kfree(spec->kctl_alloc[i].name);
2725 kfree(spec->kctl_alloc);
2728 if (spec->bios_pin_configs)
2729 kfree(spec->bios_pin_configs);
2731 kfree(spec);
2734 static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
2735 unsigned int flag)
2737 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
2738 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
2740 if (pin_ctl & AC_PINCTL_IN_EN) {
2742 * we need to check the current set-up direction of
2743 * shared input pins since they can be switched via
2744 * "xxx as Output" mixer switch
2746 struct sigmatel_spec *spec = codec->spec;
2747 struct auto_pin_cfg *cfg = &spec->autocfg;
2748 if ((nid == cfg->input_pins[AUTO_PIN_LINE] &&
2749 spec->line_switch) ||
2750 (nid == cfg->input_pins[AUTO_PIN_MIC] &&
2751 spec->mic_switch))
2752 return;
2755 /* if setting pin direction bits, clear the current
2756 direction bits first */
2757 if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
2758 pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
2760 snd_hda_codec_write_cache(codec, nid, 0,
2761 AC_VERB_SET_PIN_WIDGET_CONTROL,
2762 pin_ctl | flag);
2765 static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
2766 unsigned int flag)
2768 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
2769 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
2770 snd_hda_codec_write_cache(codec, nid, 0,
2771 AC_VERB_SET_PIN_WIDGET_CONTROL,
2772 pin_ctl & ~flag);
2775 static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid)
2777 if (!nid)
2778 return 0;
2779 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00)
2780 & (1 << 31)) {
2781 unsigned int pinctl;
2782 pinctl = snd_hda_codec_read(codec, nid, 0,
2783 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2784 if (pinctl & AC_PINCTL_IN_EN)
2785 return 0; /* mic- or line-input */
2786 else
2787 return 1; /* HP-output */
2789 return 0;
2792 static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
2794 struct sigmatel_spec *spec = codec->spec;
2795 struct auto_pin_cfg *cfg = &spec->autocfg;
2796 int i, presence;
2798 presence = 0;
2799 for (i = 0; i < cfg->hp_outs; i++) {
2800 presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);
2801 if (presence)
2802 break;
2805 if (presence) {
2806 /* disable lineouts, enable hp */
2807 for (i = 0; i < cfg->line_outs; i++)
2808 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
2809 AC_PINCTL_OUT_EN);
2810 for (i = 0; i < cfg->speaker_outs; i++)
2811 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
2812 AC_PINCTL_OUT_EN);
2813 } else {
2814 /* enable lineouts, disable hp */
2815 for (i = 0; i < cfg->line_outs; i++)
2816 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
2817 AC_PINCTL_OUT_EN);
2818 for (i = 0; i < cfg->speaker_outs; i++)
2819 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
2820 AC_PINCTL_OUT_EN);
2824 static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
2826 switch (res >> 26) {
2827 case STAC_HP_EVENT:
2828 stac92xx_hp_detect(codec, res);
2829 break;
2833 #ifdef SND_HDA_NEEDS_RESUME
2834 static int stac92xx_resume(struct hda_codec *codec)
2836 struct sigmatel_spec *spec = codec->spec;
2838 stac92xx_set_config_regs(codec);
2839 snd_hda_sequence_write(codec, spec->init);
2840 if (spec->gpio_mute) {
2841 stac922x_gpio_mute(codec, 0, 0);
2842 stac922x_gpio_mute(codec, 1, 0);
2844 snd_hda_codec_resume_amp(codec);
2845 snd_hda_codec_resume_cache(codec);
2846 /* invoke unsolicited event to reset the HP state */
2847 if (spec->hp_detect)
2848 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2849 return 0;
2851 #endif
2853 static struct hda_codec_ops stac92xx_patch_ops = {
2854 .build_controls = stac92xx_build_controls,
2855 .build_pcms = stac92xx_build_pcms,
2856 .init = stac92xx_init,
2857 .free = stac92xx_free,
2858 .unsol_event = stac92xx_unsol_event,
2859 #ifdef SND_HDA_NEEDS_RESUME
2860 .resume = stac92xx_resume,
2861 #endif
2864 static int patch_stac9200(struct hda_codec *codec)
2866 struct sigmatel_spec *spec;
2867 int err;
2869 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2870 if (spec == NULL)
2871 return -ENOMEM;
2873 codec->spec = spec;
2874 spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
2875 spec->pin_nids = stac9200_pin_nids;
2876 spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
2877 stac9200_models,
2878 stac9200_cfg_tbl);
2879 if (spec->board_config < 0) {
2880 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
2881 err = stac92xx_save_bios_config_regs(codec);
2882 if (err < 0) {
2883 stac92xx_free(codec);
2884 return err;
2886 spec->pin_configs = spec->bios_pin_configs;
2887 } else {
2888 spec->pin_configs = stac9200_brd_tbl[spec->board_config];
2889 stac92xx_set_config_regs(codec);
2892 spec->multiout.max_channels = 2;
2893 spec->multiout.num_dacs = 1;
2894 spec->multiout.dac_nids = stac9200_dac_nids;
2895 spec->adc_nids = stac9200_adc_nids;
2896 spec->mux_nids = stac9200_mux_nids;
2897 spec->num_muxes = 1;
2898 spec->num_dmics = 0;
2899 spec->num_adcs = 1;
2901 if (spec->board_config == STAC_9200_GATEWAY)
2902 spec->init = stac9200_eapd_init;
2903 else
2904 spec->init = stac9200_core_init;
2905 spec->mixer = stac9200_mixer;
2907 err = stac9200_parse_auto_config(codec);
2908 if (err < 0) {
2909 stac92xx_free(codec);
2910 return err;
2913 codec->patch_ops = stac92xx_patch_ops;
2915 return 0;
2918 static int patch_stac925x(struct hda_codec *codec)
2920 struct sigmatel_spec *spec;
2921 int err;
2923 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2924 if (spec == NULL)
2925 return -ENOMEM;
2927 codec->spec = spec;
2928 spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
2929 spec->pin_nids = stac925x_pin_nids;
2930 spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
2931 stac925x_models,
2932 stac925x_cfg_tbl);
2933 again:
2934 if (spec->board_config < 0) {
2935 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x,"
2936 "using BIOS defaults\n");
2937 err = stac92xx_save_bios_config_regs(codec);
2938 if (err < 0) {
2939 stac92xx_free(codec);
2940 return err;
2942 spec->pin_configs = spec->bios_pin_configs;
2943 } else if (stac925x_brd_tbl[spec->board_config] != NULL){
2944 spec->pin_configs = stac925x_brd_tbl[spec->board_config];
2945 stac92xx_set_config_regs(codec);
2948 spec->multiout.max_channels = 2;
2949 spec->multiout.num_dacs = 1;
2950 spec->multiout.dac_nids = stac925x_dac_nids;
2951 spec->adc_nids = stac925x_adc_nids;
2952 spec->mux_nids = stac925x_mux_nids;
2953 spec->num_muxes = 1;
2954 spec->num_adcs = 1;
2955 switch (codec->vendor_id) {
2956 case 0x83847632: /* STAC9202 */
2957 case 0x83847633: /* STAC9202D */
2958 case 0x83847636: /* STAC9251 */
2959 case 0x83847637: /* STAC9251D */
2960 spec->num_dmics = STAC925X_NUM_DMICS;
2961 spec->dmic_nids = stac925x_dmic_nids;
2962 spec->num_dmuxes = ARRAY_SIZE(stac925x_dmux_nids);
2963 spec->dmux_nids = stac925x_dmux_nids;
2964 break;
2965 default:
2966 spec->num_dmics = 0;
2967 break;
2970 spec->init = stac925x_core_init;
2971 spec->mixer = stac925x_mixer;
2973 err = stac92xx_parse_auto_config(codec, 0x8, 0x7);
2974 if (!err) {
2975 if (spec->board_config < 0) {
2976 printk(KERN_WARNING "hda_codec: No auto-config is "
2977 "available, default to model=ref\n");
2978 spec->board_config = STAC_925x_REF;
2979 goto again;
2981 err = -EINVAL;
2983 if (err < 0) {
2984 stac92xx_free(codec);
2985 return err;
2988 codec->patch_ops = stac92xx_patch_ops;
2990 return 0;
2993 static struct hda_input_mux stac92hd73xx_dmux = {
2994 .num_items = 4,
2995 .items = {
2996 { "Analog Inputs", 0x0b },
2997 { "CD", 0x08 },
2998 { "Digital Mic 1", 0x09 },
2999 { "Digital Mic 2", 0x0a },
3003 static int patch_stac92hd73xx(struct hda_codec *codec)
3005 struct sigmatel_spec *spec;
3006 hda_nid_t conn[STAC92HD73_DAC_COUNT + 2];
3007 int err = 0;
3009 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3010 if (spec == NULL)
3011 return -ENOMEM;
3013 codec->spec = spec;
3014 spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids);
3015 spec->pin_nids = stac92hd73xx_pin_nids;
3016 spec->board_config = snd_hda_check_board_config(codec,
3017 STAC_92HD73XX_MODELS,
3018 stac92hd73xx_models,
3019 stac92hd73xx_cfg_tbl);
3020 again:
3021 if (spec->board_config < 0) {
3022 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
3023 " STAC92HD73XX, using BIOS defaults\n");
3024 err = stac92xx_save_bios_config_regs(codec);
3025 if (err < 0) {
3026 stac92xx_free(codec);
3027 return err;
3029 spec->pin_configs = spec->bios_pin_configs;
3030 } else {
3031 spec->pin_configs = stac92hd73xx_brd_tbl[spec->board_config];
3032 stac92xx_set_config_regs(codec);
3035 spec->multiout.num_dacs = snd_hda_get_connections(codec, 0x0a,
3036 conn, STAC92HD73_DAC_COUNT + 2) - 1;
3038 if (spec->multiout.num_dacs < 0) {
3039 printk(KERN_WARNING "hda_codec: Could not determine "
3040 "number of channels defaulting to DAC count\n");
3041 spec->multiout.num_dacs = STAC92HD73_DAC_COUNT;
3044 switch (spec->multiout.num_dacs) {
3045 case 0x3: /* 6 Channel */
3046 spec->mixer = stac92hd73xx_6ch_mixer;
3047 spec->init = stac92hd73xx_6ch_core_init;
3048 break;
3049 case 0x4: /* 8 Channel */
3050 spec->multiout.hp_nid = 0x18;
3051 spec->mixer = stac92hd73xx_8ch_mixer;
3052 spec->init = stac92hd73xx_8ch_core_init;
3053 break;
3054 case 0x5: /* 10 Channel */
3055 spec->multiout.hp_nid = 0x19;
3056 spec->mixer = stac92hd73xx_10ch_mixer;
3057 spec->init = stac92hd73xx_10ch_core_init;
3060 spec->multiout.dac_nids = stac92hd73xx_dac_nids;
3061 spec->aloopback_mask = 0x01;
3062 spec->aloopback_shift = 8;
3064 spec->mux_nids = stac92hd73xx_mux_nids;
3065 spec->adc_nids = stac92hd73xx_adc_nids;
3066 spec->dmic_nids = stac92hd73xx_dmic_nids;
3067 spec->dmux_nids = stac92hd73xx_dmux_nids;
3069 spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids);
3070 spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids);
3071 spec->num_dmics = STAC92HD73XX_NUM_DMICS;
3072 spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids);
3073 spec->dinput_mux = &stac92hd73xx_dmux;
3074 /* GPIO0 High = Enable EAPD */
3075 spec->gpio_mask = spec->gpio_data = 0x000001;
3076 stac92xx_enable_gpio_mask(codec);
3078 err = stac92xx_parse_auto_config(codec, 0x22, 0x24);
3080 if (!err) {
3081 if (spec->board_config < 0) {
3082 printk(KERN_WARNING "hda_codec: No auto-config is "
3083 "available, default to model=ref\n");
3084 spec->board_config = STAC_92HD73XX_REF;
3085 goto again;
3087 err = -EINVAL;
3090 if (err < 0) {
3091 stac92xx_free(codec);
3092 return err;
3095 codec->patch_ops = stac92xx_patch_ops;
3097 return 0;
3100 static int patch_stac92hd71bxx(struct hda_codec *codec)
3102 struct sigmatel_spec *spec;
3103 int err = 0;
3105 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3106 if (spec == NULL)
3107 return -ENOMEM;
3109 codec->spec = spec;
3110 spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids);
3111 spec->pin_nids = stac92hd71bxx_pin_nids;
3112 spec->board_config = snd_hda_check_board_config(codec,
3113 STAC_92HD71BXX_MODELS,
3114 stac92hd71bxx_models,
3115 stac92hd71bxx_cfg_tbl);
3116 again:
3117 if (spec->board_config < 0) {
3118 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
3119 " STAC92HD71BXX, using BIOS defaults\n");
3120 err = stac92xx_save_bios_config_regs(codec);
3121 if (err < 0) {
3122 stac92xx_free(codec);
3123 return err;
3125 spec->pin_configs = spec->bios_pin_configs;
3126 } else {
3127 spec->pin_configs = stac92hd71bxx_brd_tbl[spec->board_config];
3128 stac92xx_set_config_regs(codec);
3131 switch (codec->vendor_id) {
3132 case 0x111d76b6: /* 4 Port without Analog Mixer */
3133 case 0x111d76b7:
3134 case 0x111d76b4: /* 6 Port without Analog Mixer */
3135 case 0x111d76b5:
3136 spec->mixer = stac92hd71bxx_mixer;
3137 spec->init = stac92hd71bxx_core_init;
3138 break;
3139 default:
3140 spec->mixer = stac92hd71bxx_analog_mixer;
3141 spec->init = stac92hd71bxx_analog_core_init;
3144 spec->aloopback_mask = 0x20;
3145 spec->aloopback_shift = 0;
3147 spec->gpio_mask = spec->gpio_data = 0x00000001; /* GPIO0 High = EAPD */
3148 stac92xx_enable_gpio_mask(codec);
3150 spec->mux_nids = stac92hd71bxx_mux_nids;
3151 spec->adc_nids = stac92hd71bxx_adc_nids;
3152 spec->dmic_nids = stac92hd71bxx_dmic_nids;
3153 spec->dmux_nids = stac92hd71bxx_dmux_nids;
3155 spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids);
3156 spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids);
3157 spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
3158 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
3160 spec->multiout.num_dacs = 2;
3161 spec->multiout.hp_nid = 0x11;
3162 spec->multiout.dac_nids = stac92hd71bxx_dac_nids;
3164 err = stac92xx_parse_auto_config(codec, 0x21, 0x23);
3165 if (!err) {
3166 if (spec->board_config < 0) {
3167 printk(KERN_WARNING "hda_codec: No auto-config is "
3168 "available, default to model=ref\n");
3169 spec->board_config = STAC_92HD71BXX_REF;
3170 goto again;
3172 err = -EINVAL;
3175 if (err < 0) {
3176 stac92xx_free(codec);
3177 return err;
3180 codec->patch_ops = stac92xx_patch_ops;
3182 return 0;
3185 static int patch_stac922x(struct hda_codec *codec)
3187 struct sigmatel_spec *spec;
3188 int err;
3190 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3191 if (spec == NULL)
3192 return -ENOMEM;
3194 codec->spec = spec;
3195 spec->num_pins = ARRAY_SIZE(stac922x_pin_nids);
3196 spec->pin_nids = stac922x_pin_nids;
3197 spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
3198 stac922x_models,
3199 stac922x_cfg_tbl);
3200 if (spec->board_config == STAC_INTEL_MAC_V3) {
3201 spec->gpio_mute = 1;
3202 /* Intel Macs have all same PCI SSID, so we need to check
3203 * codec SSID to distinguish the exact models
3205 printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id);
3206 switch (codec->subsystem_id) {
3208 case 0x106b0800:
3209 spec->board_config = STAC_INTEL_MAC_V1;
3210 break;
3211 case 0x106b0600:
3212 case 0x106b0700:
3213 spec->board_config = STAC_INTEL_MAC_V2;
3214 break;
3215 case 0x106b0e00:
3216 case 0x106b0f00:
3217 case 0x106b1600:
3218 case 0x106b1700:
3219 case 0x106b0200:
3220 case 0x106b1e00:
3221 spec->board_config = STAC_INTEL_MAC_V3;
3222 break;
3223 case 0x106b1a00:
3224 case 0x00000100:
3225 spec->board_config = STAC_INTEL_MAC_V4;
3226 break;
3227 case 0x106b0a00:
3228 case 0x106b2200:
3229 spec->board_config = STAC_INTEL_MAC_V5;
3230 break;
3234 again:
3235 if (spec->board_config < 0) {
3236 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, "
3237 "using BIOS defaults\n");
3238 err = stac92xx_save_bios_config_regs(codec);
3239 if (err < 0) {
3240 stac92xx_free(codec);
3241 return err;
3243 spec->pin_configs = spec->bios_pin_configs;
3244 } else if (stac922x_brd_tbl[spec->board_config] != NULL) {
3245 spec->pin_configs = stac922x_brd_tbl[spec->board_config];
3246 stac92xx_set_config_regs(codec);
3249 spec->adc_nids = stac922x_adc_nids;
3250 spec->mux_nids = stac922x_mux_nids;
3251 spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
3252 spec->num_adcs = ARRAY_SIZE(stac922x_adc_nids);
3253 spec->num_dmics = 0;
3255 spec->init = stac922x_core_init;
3256 spec->mixer = stac922x_mixer;
3258 spec->multiout.dac_nids = spec->dac_nids;
3260 err = stac92xx_parse_auto_config(codec, 0x08, 0x09);
3261 if (!err) {
3262 if (spec->board_config < 0) {
3263 printk(KERN_WARNING "hda_codec: No auto-config is "
3264 "available, default to model=ref\n");
3265 spec->board_config = STAC_D945_REF;
3266 goto again;
3268 err = -EINVAL;
3270 if (err < 0) {
3271 stac92xx_free(codec);
3272 return err;
3275 codec->patch_ops = stac92xx_patch_ops;
3277 /* Fix Mux capture level; max to 2 */
3278 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
3279 (0 << AC_AMPCAP_OFFSET_SHIFT) |
3280 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
3281 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
3282 (0 << AC_AMPCAP_MUTE_SHIFT));
3284 return 0;
3287 static int patch_stac927x(struct hda_codec *codec)
3289 struct sigmatel_spec *spec;
3290 int err;
3292 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3293 if (spec == NULL)
3294 return -ENOMEM;
3296 codec->spec = spec;
3297 spec->num_pins = ARRAY_SIZE(stac927x_pin_nids);
3298 spec->pin_nids = stac927x_pin_nids;
3299 spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS,
3300 stac927x_models,
3301 stac927x_cfg_tbl);
3302 again:
3303 if (spec->board_config < 0 || !stac927x_brd_tbl[spec->board_config]) {
3304 if (spec->board_config < 0)
3305 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
3306 "STAC927x, using BIOS defaults\n");
3307 err = stac92xx_save_bios_config_regs(codec);
3308 if (err < 0) {
3309 stac92xx_free(codec);
3310 return err;
3312 spec->pin_configs = spec->bios_pin_configs;
3313 } else {
3314 spec->pin_configs = stac927x_brd_tbl[spec->board_config];
3315 stac92xx_set_config_regs(codec);
3318 spec->adc_nids = stac927x_adc_nids;
3319 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
3320 spec->mux_nids = stac927x_mux_nids;
3321 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
3322 spec->multiout.dac_nids = spec->dac_nids;
3324 switch (spec->board_config) {
3325 case STAC_D965_3ST:
3326 case STAC_D965_5ST:
3327 /* GPIO0 High = Enable EAPD */
3328 spec->gpio_mask = spec->gpio_data = 0x00000001;
3329 spec->num_dmics = 0;
3331 spec->init = d965_core_init;
3332 spec->mixer = stac927x_mixer;
3333 break;
3334 case STAC_DELL_BIOS:
3335 /* correct the front input jack as a mic */
3336 stac92xx_set_config_reg(codec, 0x0e, 0x02a79130);
3337 /* fallthru */
3338 case STAC_DELL_3ST:
3339 /* GPIO2 High = Enable EAPD */
3340 spec->gpio_mask = spec->gpio_data = 0x00000004;
3341 spec->dmic_nids = stac927x_dmic_nids;
3342 spec->num_dmics = STAC927X_NUM_DMICS;
3344 spec->init = d965_core_init;
3345 spec->mixer = stac927x_mixer;
3346 spec->dmux_nids = stac927x_dmux_nids;
3347 spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
3348 break;
3349 default:
3350 /* GPIO0 High = Enable EAPD */
3351 spec->gpio_mask = spec->gpio_data = 0x00000001;
3352 spec->num_dmics = 0;
3354 spec->init = stac927x_core_init;
3355 spec->mixer = stac927x_mixer;
3358 spec->aloopback_mask = 0x40;
3359 spec->aloopback_shift = 0;
3361 stac92xx_enable_gpio_mask(codec);
3362 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
3363 if (!err) {
3364 if (spec->board_config < 0) {
3365 printk(KERN_WARNING "hda_codec: No auto-config is "
3366 "available, default to model=ref\n");
3367 spec->board_config = STAC_D965_REF;
3368 goto again;
3370 err = -EINVAL;
3372 if (err < 0) {
3373 stac92xx_free(codec);
3374 return err;
3377 codec->patch_ops = stac92xx_patch_ops;
3379 return 0;
3382 static int patch_stac9205(struct hda_codec *codec)
3384 struct sigmatel_spec *spec;
3385 int err;
3387 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3388 if (spec == NULL)
3389 return -ENOMEM;
3391 codec->spec = spec;
3392 spec->num_pins = ARRAY_SIZE(stac9205_pin_nids);
3393 spec->pin_nids = stac9205_pin_nids;
3394 spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
3395 stac9205_models,
3396 stac9205_cfg_tbl);
3397 again:
3398 if (spec->board_config < 0) {
3399 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n");
3400 err = stac92xx_save_bios_config_regs(codec);
3401 if (err < 0) {
3402 stac92xx_free(codec);
3403 return err;
3405 spec->pin_configs = spec->bios_pin_configs;
3406 } else {
3407 spec->pin_configs = stac9205_brd_tbl[spec->board_config];
3408 stac92xx_set_config_regs(codec);
3411 spec->adc_nids = stac9205_adc_nids;
3412 spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids);
3413 spec->mux_nids = stac9205_mux_nids;
3414 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
3415 spec->dmic_nids = stac9205_dmic_nids;
3416 spec->num_dmics = STAC9205_NUM_DMICS;
3417 spec->dmux_nids = stac9205_dmux_nids;
3418 spec->num_dmuxes = ARRAY_SIZE(stac9205_dmux_nids);
3420 spec->init = stac9205_core_init;
3421 spec->mixer = stac9205_mixer;
3423 spec->aloopback_mask = 0x40;
3424 spec->aloopback_shift = 0;
3425 spec->multiout.dac_nids = spec->dac_nids;
3427 switch (spec->board_config){
3428 case STAC_9205_DELL_M43:
3429 /* Enable SPDIF in/out */
3430 stac92xx_set_config_reg(codec, 0x1f, 0x01441030);
3431 stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
3433 spec->gpio_mask = 0x00000007; /* GPIO0-2 */
3434 /* GPIO0 High = EAPD, GPIO1 Low = DRM,
3435 * GPIO2 High = Headphone Mute
3437 spec->gpio_data = 0x00000005;
3438 break;
3439 default:
3440 /* GPIO0 High = EAPD */
3441 spec->gpio_mask = spec->gpio_data = 0x00000001;
3442 break;
3445 stac92xx_enable_gpio_mask(codec);
3446 err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
3447 if (!err) {
3448 if (spec->board_config < 0) {
3449 printk(KERN_WARNING "hda_codec: No auto-config is "
3450 "available, default to model=ref\n");
3451 spec->board_config = STAC_9205_REF;
3452 goto again;
3454 err = -EINVAL;
3456 if (err < 0) {
3457 stac92xx_free(codec);
3458 return err;
3461 codec->patch_ops = stac92xx_patch_ops;
3463 return 0;
3467 * STAC9872 hack
3470 /* static config for Sony VAIO FE550G and Sony VAIO AR */
3471 static hda_nid_t vaio_dacs[] = { 0x2 };
3472 #define VAIO_HP_DAC 0x5
3473 static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ };
3474 static hda_nid_t vaio_mux_nids[] = { 0x15 };
3476 static struct hda_input_mux vaio_mux = {
3477 .num_items = 3,
3478 .items = {
3479 /* { "HP", 0x0 }, */
3480 { "Mic Jack", 0x1 },
3481 { "Internal Mic", 0x2 },
3482 { "PCM", 0x3 },
3486 static struct hda_verb vaio_init[] = {
3487 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
3488 {0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT},
3489 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
3490 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
3491 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
3492 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
3493 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
3494 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
3495 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
3496 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
3497 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
3498 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
3502 static struct hda_verb vaio_ar_init[] = {
3503 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
3504 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
3505 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
3506 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
3507 /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */
3508 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
3509 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
3510 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
3511 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
3512 /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */
3513 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
3514 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
3515 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
3519 /* bind volumes of both NID 0x02 and 0x05 */
3520 static struct hda_bind_ctls vaio_bind_master_vol = {
3521 .ops = &snd_hda_bind_vol,
3522 .values = {
3523 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
3524 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
3529 /* bind volumes of both NID 0x02 and 0x05 */
3530 static struct hda_bind_ctls vaio_bind_master_sw = {
3531 .ops = &snd_hda_bind_sw,
3532 .values = {
3533 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
3534 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
3539 static struct snd_kcontrol_new vaio_mixer[] = {
3540 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
3541 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
3542 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
3543 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
3544 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
3546 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3547 .name = "Capture Source",
3548 .count = 1,
3549 .info = stac92xx_mux_enum_info,
3550 .get = stac92xx_mux_enum_get,
3551 .put = stac92xx_mux_enum_put,
3556 static struct snd_kcontrol_new vaio_ar_mixer[] = {
3557 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
3558 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
3559 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
3560 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
3561 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
3562 /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT),
3563 HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/
3565 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3566 .name = "Capture Source",
3567 .count = 1,
3568 .info = stac92xx_mux_enum_info,
3569 .get = stac92xx_mux_enum_get,
3570 .put = stac92xx_mux_enum_put,
3575 static struct hda_codec_ops stac9872_patch_ops = {
3576 .build_controls = stac92xx_build_controls,
3577 .build_pcms = stac92xx_build_pcms,
3578 .init = stac92xx_init,
3579 .free = stac92xx_free,
3580 #ifdef SND_HDA_NEEDS_RESUME
3581 .resume = stac92xx_resume,
3582 #endif
3585 static int stac9872_vaio_init(struct hda_codec *codec)
3587 int err;
3589 err = stac92xx_init(codec);
3590 if (err < 0)
3591 return err;
3592 if (codec->patch_ops.unsol_event)
3593 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
3594 return 0;
3597 static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
3599 if (get_hp_pin_presence(codec, 0x0a)) {
3600 stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
3601 stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
3602 } else {
3603 stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
3604 stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
3608 static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res)
3610 switch (res >> 26) {
3611 case STAC_HP_EVENT:
3612 stac9872_vaio_hp_detect(codec, res);
3613 break;
3617 static struct hda_codec_ops stac9872_vaio_patch_ops = {
3618 .build_controls = stac92xx_build_controls,
3619 .build_pcms = stac92xx_build_pcms,
3620 .init = stac9872_vaio_init,
3621 .free = stac92xx_free,
3622 .unsol_event = stac9872_vaio_unsol_event,
3623 #ifdef CONFIG_PM
3624 .resume = stac92xx_resume,
3625 #endif
3628 enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */
3629 CXD9872RD_VAIO,
3630 /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */
3631 STAC9872AK_VAIO,
3632 /* Unknown. id=0x83847661 and subsys=0x104D1200. */
3633 STAC9872K_VAIO,
3634 /* AR Series. id=0x83847664 and subsys=104D1300 */
3635 CXD9872AKD_VAIO,
3636 STAC_9872_MODELS,
3639 static const char *stac9872_models[STAC_9872_MODELS] = {
3640 [CXD9872RD_VAIO] = "vaio",
3641 [CXD9872AKD_VAIO] = "vaio-ar",
3644 static struct snd_pci_quirk stac9872_cfg_tbl[] = {
3645 SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
3646 SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
3647 SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
3648 SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO),
3652 static int patch_stac9872(struct hda_codec *codec)
3654 struct sigmatel_spec *spec;
3655 int board_config;
3657 board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
3658 stac9872_models,
3659 stac9872_cfg_tbl);
3660 if (board_config < 0)
3661 /* unknown config, let generic-parser do its job... */
3662 return snd_hda_parse_generic_codec(codec);
3664 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3665 if (spec == NULL)
3666 return -ENOMEM;
3668 codec->spec = spec;
3669 switch (board_config) {
3670 case CXD9872RD_VAIO:
3671 case STAC9872AK_VAIO:
3672 case STAC9872K_VAIO:
3673 spec->mixer = vaio_mixer;
3674 spec->init = vaio_init;
3675 spec->multiout.max_channels = 2;
3676 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
3677 spec->multiout.dac_nids = vaio_dacs;
3678 spec->multiout.hp_nid = VAIO_HP_DAC;
3679 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
3680 spec->adc_nids = vaio_adcs;
3681 spec->input_mux = &vaio_mux;
3682 spec->mux_nids = vaio_mux_nids;
3683 codec->patch_ops = stac9872_vaio_patch_ops;
3684 break;
3686 case CXD9872AKD_VAIO:
3687 spec->mixer = vaio_ar_mixer;
3688 spec->init = vaio_ar_init;
3689 spec->multiout.max_channels = 2;
3690 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
3691 spec->multiout.dac_nids = vaio_dacs;
3692 spec->multiout.hp_nid = VAIO_HP_DAC;
3693 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
3694 spec->adc_nids = vaio_adcs;
3695 spec->input_mux = &vaio_mux;
3696 spec->mux_nids = vaio_mux_nids;
3697 codec->patch_ops = stac9872_patch_ops;
3698 break;
3701 return 0;
3706 * patch entries
3708 struct hda_codec_preset snd_hda_preset_sigmatel[] = {
3709 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
3710 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
3711 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
3712 { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x },
3713 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
3714 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
3715 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
3716 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x },
3717 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x },
3718 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x },
3719 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x },
3720 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x },
3721 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x },
3722 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
3723 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
3724 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
3725 { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x },
3726 { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x },
3727 { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x },
3728 { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x },
3729 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x },
3730 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x },
3731 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x },
3732 { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x },
3733 { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x },
3734 { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x },
3735 { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
3736 { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
3737 { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
3738 /* The following does not take into account .id=0x83847661 when subsys =
3739 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
3740 * currently not fully supported.
3742 { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 },
3743 { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 },
3744 { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 },
3745 { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 },
3746 { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 },
3747 { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 },
3748 { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 },
3749 { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 },
3750 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
3751 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
3752 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
3753 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
3754 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },
3755 { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx },
3756 { .id = 0x111d7608, .name = "92HD71BXX", .patch = patch_stac92hd71bxx },
3757 { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
3758 { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
3759 { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
3760 { .id = 0x111d76b3, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
3761 { .id = 0x111d76b4, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
3762 { .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
3763 { .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
3764 { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
3765 {} /* terminator */