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"
35 #include "hda_patch.h"
37 #define NUM_CONTROL_ALLOC 32
38 #define STAC_PWR_EVENT 0x20
39 #define STAC_HP_EVENT 0x30
97 /* for backward compatibility */
120 struct sigmatel_spec {
121 struct snd_kcontrol_new *mixers[4];
122 unsigned int num_mixers;
125 unsigned int surr_switch: 1;
126 unsigned int line_switch: 1;
127 unsigned int mic_switch: 1;
128 unsigned int alt_switch: 1;
129 unsigned int hp_detect: 1;
132 unsigned int eapd_mask;
133 unsigned int gpio_mask;
134 unsigned int gpio_dir;
135 unsigned int gpio_data;
136 unsigned int gpio_mute;
138 /* analog loopback */
139 unsigned char aloopback_mask;
140 unsigned char aloopback_shift;
142 /* power management */
143 unsigned int num_pwrs;
148 struct hda_input_mux *mono_mux;
149 unsigned int cur_mmux;
150 struct hda_multi_out multiout;
151 hda_nid_t dac_nids[5];
155 unsigned int num_adcs;
157 unsigned int num_muxes;
158 hda_nid_t *dmic_nids;
159 unsigned int num_dmics;
160 hda_nid_t *dmux_nids;
161 unsigned int num_dmuxes;
162 hda_nid_t dig_in_nid;
167 unsigned int num_pins;
168 unsigned int *pin_configs;
169 unsigned int *bios_pin_configs;
171 /* codec specific stuff */
172 struct hda_verb *init;
173 struct snd_kcontrol_new *mixer;
176 struct hda_input_mux *dinput_mux;
177 unsigned int cur_dmux[2];
178 struct hda_input_mux *input_mux;
179 unsigned int cur_mux[3];
182 unsigned int io_switch[2];
183 unsigned int clfe_swap;
184 unsigned int aloopback;
186 struct hda_pcm pcm_rec[2]; /* PCM information */
188 /* dynamic controls and input_mux */
189 struct auto_pin_cfg autocfg;
190 unsigned int num_kctl_alloc, num_kctl_used;
191 struct snd_kcontrol_new *kctl_alloc;
192 struct hda_input_mux private_dimux;
193 struct hda_input_mux private_imux;
194 struct hda_input_mux private_mono_mux;
197 static hda_nid_t stac9200_adc_nids[1] = {
201 static hda_nid_t stac9200_mux_nids[1] = {
205 static hda_nid_t stac9200_dac_nids[1] = {
209 static hda_nid_t stac92hd73xx_pwr_nids[8] = {
210 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
214 static hda_nid_t stac92hd73xx_adc_nids[2] = {
218 #define STAC92HD73XX_NUM_DMICS 2
219 static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
223 #define STAC92HD73_DAC_COUNT 5
224 static hda_nid_t stac92hd73xx_dac_nids[STAC92HD73_DAC_COUNT] = {
225 0x15, 0x16, 0x17, 0x18, 0x19,
228 static hda_nid_t stac92hd73xx_mux_nids[4] = {
229 0x28, 0x29, 0x2a, 0x2b,
232 static hda_nid_t stac92hd73xx_dmux_nids[2] = {
236 static hda_nid_t stac92hd71bxx_pwr_nids[3] = {
240 static hda_nid_t stac92hd71bxx_adc_nids[2] = {
244 static hda_nid_t stac92hd71bxx_mux_nids[2] = {
248 static hda_nid_t stac92hd71bxx_dmux_nids[1] = {
252 static hda_nid_t stac92hd71bxx_dac_nids[1] = {
256 #define STAC92HD71BXX_NUM_DMICS 2
257 static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
261 static hda_nid_t stac925x_adc_nids[1] = {
265 static hda_nid_t stac925x_mux_nids[1] = {
269 static hda_nid_t stac925x_dac_nids[1] = {
273 #define STAC925X_NUM_DMICS 1
274 static hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = {
278 static hda_nid_t stac925x_dmux_nids[1] = {
282 static hda_nid_t stac922x_adc_nids[2] = {
286 static hda_nid_t stac922x_mux_nids[2] = {
290 static hda_nid_t stac927x_adc_nids[3] = {
294 static hda_nid_t stac927x_mux_nids[3] = {
298 static hda_nid_t stac927x_dac_nids[6] = {
299 0x02, 0x03, 0x04, 0x05, 0x06, 0
302 static hda_nid_t stac927x_dmux_nids[1] = {
306 #define STAC927X_NUM_DMICS 2
307 static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = {
311 static hda_nid_t stac9205_adc_nids[2] = {
315 static hda_nid_t stac9205_mux_nids[2] = {
319 static hda_nid_t stac9205_dmux_nids[1] = {
323 #define STAC9205_NUM_DMICS 2
324 static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
328 static hda_nid_t stac9200_pin_nids[8] = {
329 0x08, 0x09, 0x0d, 0x0e,
330 0x0f, 0x10, 0x11, 0x12,
333 static hda_nid_t stac925x_pin_nids[8] = {
334 0x07, 0x08, 0x0a, 0x0b,
335 0x0c, 0x0d, 0x10, 0x11,
338 static hda_nid_t stac922x_pin_nids[10] = {
339 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
340 0x0f, 0x10, 0x11, 0x15, 0x1b,
343 static hda_nid_t stac92hd73xx_pin_nids[13] = {
344 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
345 0x0f, 0x10, 0x11, 0x12, 0x13,
349 static hda_nid_t stac92hd71bxx_pin_nids[10] = {
350 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
351 0x0f, 0x14, 0x18, 0x19, 0x1e,
354 static hda_nid_t stac927x_pin_nids[14] = {
355 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
356 0x0f, 0x10, 0x11, 0x12, 0x13,
357 0x14, 0x21, 0x22, 0x23,
360 static hda_nid_t stac9205_pin_nids[12] = {
361 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
362 0x0f, 0x14, 0x16, 0x17, 0x18,
366 static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
367 struct snd_ctl_elem_info *uinfo)
369 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
370 struct sigmatel_spec *spec = codec->spec;
371 return snd_hda_input_mux_info(spec->dinput_mux, uinfo);
374 static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol,
375 struct snd_ctl_elem_value *ucontrol)
377 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
378 struct sigmatel_spec *spec = codec->spec;
379 unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
381 ucontrol->value.enumerated.item[0] = spec->cur_dmux[dmux_idx];
385 static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
386 struct snd_ctl_elem_value *ucontrol)
388 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
389 struct sigmatel_spec *spec = codec->spec;
390 unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
392 return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol,
393 spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]);
396 static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
398 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
399 struct sigmatel_spec *spec = codec->spec;
400 return snd_hda_input_mux_info(spec->input_mux, uinfo);
403 static int stac92xx_mux_enum_get(struct snd_kcontrol *kcontrol, 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 adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
409 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
413 static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
415 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
416 struct sigmatel_spec *spec = codec->spec;
417 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
419 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
420 spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]);
423 static int stac92xx_mono_mux_enum_info(struct snd_kcontrol *kcontrol,
424 struct snd_ctl_elem_info *uinfo)
426 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
427 struct sigmatel_spec *spec = codec->spec;
428 return snd_hda_input_mux_info(spec->mono_mux, uinfo);
431 static int stac92xx_mono_mux_enum_get(struct snd_kcontrol *kcontrol,
432 struct snd_ctl_elem_value *ucontrol)
434 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
435 struct sigmatel_spec *spec = codec->spec;
437 ucontrol->value.enumerated.item[0] = spec->cur_mmux;
441 static int stac92xx_mono_mux_enum_put(struct snd_kcontrol *kcontrol,
442 struct snd_ctl_elem_value *ucontrol)
444 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
445 struct sigmatel_spec *spec = codec->spec;
447 return snd_hda_input_mux_put(codec, spec->mono_mux, ucontrol,
448 spec->mono_nid, &spec->cur_mmux);
451 #define stac92xx_aloopback_info snd_ctl_boolean_mono_info
453 static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol,
454 struct snd_ctl_elem_value *ucontrol)
456 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
457 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
458 struct sigmatel_spec *spec = codec->spec;
460 ucontrol->value.integer.value[0] = !!(spec->aloopback &
461 (spec->aloopback_mask << idx));
465 static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol,
466 struct snd_ctl_elem_value *ucontrol)
468 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
469 struct sigmatel_spec *spec = codec->spec;
470 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
471 unsigned int dac_mode;
472 unsigned int val, idx_val;
474 idx_val = spec->aloopback_mask << idx;
475 if (ucontrol->value.integer.value[0])
476 val = spec->aloopback | idx_val;
478 val = spec->aloopback & ~idx_val;
479 if (spec->aloopback == val)
482 spec->aloopback = val;
484 /* Only return the bits defined by the shift value of the
485 * first two bytes of the mask
487 dac_mode = snd_hda_codec_read(codec, codec->afg, 0,
488 kcontrol->private_value & 0xFFFF, 0x0);
489 dac_mode >>= spec->aloopback_shift;
491 if (spec->aloopback & idx_val) {
492 snd_hda_power_up(codec);
495 snd_hda_power_down(codec);
496 dac_mode &= ~idx_val;
499 snd_hda_codec_write_cache(codec, codec->afg, 0,
500 kcontrol->private_value >> 16, dac_mode);
505 static struct hda_verb stac9200_core_init[] = {
506 /* set dac0mux for dac converter */
507 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
511 static struct hda_verb stac9200_eapd_init[] = {
512 /* set dac0mux for dac converter */
513 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
514 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
518 static struct hda_verb stac92hd73xx_6ch_core_init[] = {
519 /* set master volume and direct control */
520 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
521 /* setup audio connections */
522 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
523 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
524 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
525 /* setup adcs to point to mixer */
526 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
527 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
528 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
529 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
530 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
531 /* setup import muxs */
532 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
533 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
534 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
535 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00},
539 static struct hda_verb dell_eq_core_init[] = {
540 /* set master volume to max value without distortion
541 * and direct control */
542 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
543 /* setup audio connections */
544 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
545 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
546 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02},
547 /* setup adcs to point to mixer */
548 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
549 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
550 /* setup import muxs */
551 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
552 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
553 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
554 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00},
558 static struct hda_verb dell_m6_core_init[] = {
559 /* set master volume and direct control */
560 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
561 /* setup audio connections */
562 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
563 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
564 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02},
565 /* setup adcs to point to mixer */
566 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
567 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
568 /* setup import muxs */
569 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
570 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
571 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
572 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00},
576 static struct hda_verb stac92hd73xx_8ch_core_init[] = {
577 /* set master volume and direct control */
578 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
579 /* setup audio connections */
580 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
581 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
582 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
583 /* connect hp ports to dac3 */
584 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x03},
585 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x03},
586 /* setup adcs to point to mixer */
587 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
588 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
589 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
590 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
591 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
592 /* setup import muxs */
593 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
594 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
595 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
596 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x03},
600 static struct hda_verb stac92hd73xx_10ch_core_init[] = {
601 /* set master volume and direct control */
602 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
603 /* setup audio connections */
604 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
605 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01 },
606 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02 },
607 /* dac3 is connected to import3 mux */
608 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f},
609 /* connect hp ports to dac4 */
610 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x04},
611 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x04},
612 /* setup adcs to point to mixer */
613 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
614 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
615 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
616 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
617 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
618 /* setup import muxs */
619 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
620 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
621 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
622 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x03},
626 static struct hda_verb stac92hd71bxx_core_init[] = {
627 /* set master volume and direct control */
628 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
629 /* connect headphone jack to dac1 */
630 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
631 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */
632 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */
633 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
634 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
635 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
638 static struct hda_verb stac92hd71bxx_analog_core_init[] = {
639 /* set master volume and direct control */
640 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
641 /* connect headphone jack to dac1 */
642 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
643 /* connect ports 0d and 0f to audio mixer */
644 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x2},
645 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2},
646 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */
647 /* unmute dac0 input in audio mixer */
648 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
649 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */
650 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
651 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
652 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
656 static struct hda_verb stac925x_core_init[] = {
657 /* set dac0mux for dac converter */
658 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
662 static struct hda_verb stac922x_core_init[] = {
663 /* set master volume and direct control */
664 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
668 static struct hda_verb d965_core_init[] = {
669 /* set master volume and direct control */
670 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
671 /* unmute node 0x1b */
672 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
673 /* select node 0x03 as DAC */
674 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
678 static struct hda_verb stac927x_core_init[] = {
679 /* set master volume and direct control */
680 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
684 static struct hda_verb stac9205_core_init[] = {
685 /* set master volume and direct control */
686 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
690 #define STAC_MONO_MUX \
692 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
693 .name = "Mono Mux", \
695 .info = stac92xx_mono_mux_enum_info, \
696 .get = stac92xx_mono_mux_enum_get, \
697 .put = stac92xx_mono_mux_enum_put, \
700 #define STAC_INPUT_SOURCE(cnt) \
702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
703 .name = "Input Source", \
705 .info = stac92xx_mux_enum_info, \
706 .get = stac92xx_mux_enum_get, \
707 .put = stac92xx_mux_enum_put, \
710 #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \
712 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
713 .name = "Analog Loopback", \
715 .info = stac92xx_aloopback_info, \
716 .get = stac92xx_aloopback_get, \
717 .put = stac92xx_aloopback_put, \
718 .private_value = verb_read | (verb_write << 16), \
721 static struct snd_kcontrol_new stac9200_mixer[] = {
722 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
723 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
724 STAC_INPUT_SOURCE(1),
725 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
726 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
727 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT),
731 static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = {
732 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3),
734 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
735 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
737 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
738 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
740 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
741 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
743 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
744 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
746 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
747 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
749 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
750 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
752 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
753 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
757 static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = {
758 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4),
760 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
761 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
763 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
764 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
766 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
767 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
769 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
770 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
772 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
773 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
775 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
776 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
778 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
779 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
783 static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = {
784 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5),
786 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
787 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
789 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
790 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
792 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
793 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
795 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
796 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
798 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
799 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
801 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
802 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
804 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
805 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
809 static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = {
810 STAC_INPUT_SOURCE(2),
812 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
813 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
814 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x0, 0x1a, 0x0, HDA_OUTPUT),
816 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT),
817 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
818 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT),
820 HDA_CODEC_MUTE("Analog Loopback 1", 0x17, 0x3, HDA_INPUT),
821 HDA_CODEC_MUTE("Analog Loopback 2", 0x17, 0x4, HDA_INPUT),
825 static struct snd_kcontrol_new stac92hd71bxx_mixer[] = {
826 STAC_INPUT_SOURCE(2),
827 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2),
829 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
830 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
831 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x0, 0x1a, 0x0, HDA_OUTPUT),
833 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT),
834 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
835 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT),
839 static struct snd_kcontrol_new stac925x_mixer[] = {
840 STAC_INPUT_SOURCE(1),
841 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
842 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT),
843 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT),
847 static struct snd_kcontrol_new stac9205_mixer[] = {
848 STAC_INPUT_SOURCE(2),
849 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1),
851 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT),
852 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT),
853 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x19, 0x0, HDA_OUTPUT),
855 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT),
856 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT),
857 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x1A, 0x0, HDA_OUTPUT),
862 /* This needs to be generated dynamically based on sequence */
863 static struct snd_kcontrol_new stac922x_mixer[] = {
864 STAC_INPUT_SOURCE(2),
865 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT),
866 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT),
867 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x12, 0x0, HDA_OUTPUT),
869 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT),
870 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT),
871 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x13, 0x0, HDA_OUTPUT),
876 static struct snd_kcontrol_new stac927x_mixer[] = {
877 STAC_INPUT_SOURCE(3),
878 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1),
880 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT),
881 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT),
882 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x15, 0x0, HDA_OUTPUT),
884 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT),
885 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT),
886 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x16, 0x0, HDA_OUTPUT),
888 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT),
889 HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT),
890 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x2, 0x17, 0x0, HDA_OUTPUT),
894 static struct snd_kcontrol_new stac_dmux_mixer = {
895 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
896 .name = "Digital Input Source",
897 /* count set later */
898 .info = stac92xx_dmux_enum_info,
899 .get = stac92xx_dmux_enum_get,
900 .put = stac92xx_dmux_enum_put,
903 static const char *slave_vols[] = {
904 "Front Playback Volume",
905 "Surround Playback Volume",
906 "Center Playback Volume",
907 "LFE Playback Volume",
908 "Side Playback Volume",
909 "Headphone Playback Volume",
910 "Headphone Playback Volume",
911 "Speaker Playback Volume",
912 "External Speaker Playback Volume",
913 "Speaker2 Playback Volume",
917 static const char *slave_sws[] = {
918 "Front Playback Switch",
919 "Surround Playback Switch",
920 "Center Playback Switch",
921 "LFE Playback Switch",
922 "Side Playback Switch",
923 "Headphone Playback Switch",
924 "Headphone Playback Switch",
925 "Speaker Playback Switch",
926 "External Speaker Playback Switch",
927 "Speaker2 Playback Switch",
928 "IEC958 Playback Switch",
932 static int stac92xx_build_controls(struct hda_codec *codec)
934 struct sigmatel_spec *spec = codec->spec;
938 err = snd_hda_add_new_ctls(codec, spec->mixer);
942 for (i = 0; i < spec->num_mixers; i++) {
943 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
947 if (spec->num_dmuxes > 0) {
948 stac_dmux_mixer.count = spec->num_dmuxes;
949 err = snd_ctl_add(codec->bus->card,
950 snd_ctl_new1(&stac_dmux_mixer, codec));
955 if (spec->multiout.dig_out_nid) {
956 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
959 err = snd_hda_create_spdif_share_sw(codec,
963 spec->multiout.share_spdif = 1;
965 if (spec->dig_in_nid) {
966 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
971 /* if we have no master control, let's create it */
972 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
973 unsigned int vmaster_tlv[4];
974 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
975 HDA_OUTPUT, vmaster_tlv);
976 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
977 vmaster_tlv, slave_vols);
981 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
982 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
991 static unsigned int ref9200_pin_configs[8] = {
992 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
993 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
997 STAC 9200 pin configs for
1002 static unsigned int dell9200_d21_pin_configs[8] = {
1003 0x400001f0, 0x400001f1, 0x02214030, 0x01014010,
1004 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
1008 STAC 9200 pin configs for
1012 static unsigned int dell9200_d22_pin_configs[8] = {
1013 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
1014 0x01813020, 0x02a19021, 0x90100140, 0x400001f2,
1018 STAC 9200 pin configs for
1019 102801C4 (Dell Dimension E310)
1026 static unsigned int dell9200_d23_pin_configs[8] = {
1027 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
1028 0x01813020, 0x01a19021, 0x90100140, 0x400001f2,
1033 STAC 9200-32 pin configs for
1034 102801B5 (Dell Inspiron 630m)
1035 102801D8 (Dell Inspiron 640m)
1037 static unsigned int dell9200_m21_pin_configs[8] = {
1038 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310,
1039 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd,
1043 STAC 9200-32 pin configs for
1044 102801C2 (Dell Latitude D620)
1046 102801CC (Dell Latitude D820)
1050 static unsigned int dell9200_m22_pin_configs[8] = {
1051 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310,
1052 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc,
1056 STAC 9200-32 pin configs for
1057 102801CE (Dell XPS M1710)
1058 102801CF (Dell Precision M90)
1060 static unsigned int dell9200_m23_pin_configs[8] = {
1061 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310,
1062 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc,
1066 STAC 9200-32 pin configs for
1069 102801CB (Dell Latitude 120L)
1072 static unsigned int dell9200_m24_pin_configs[8] = {
1073 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310,
1074 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe,
1078 STAC 9200-32 pin configs for
1079 102801BD (Dell Inspiron E1505n)
1083 static unsigned int dell9200_m25_pin_configs[8] = {
1084 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
1085 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd,
1089 STAC 9200-32 pin configs for
1090 102801F5 (Dell Inspiron 1501)
1093 static unsigned int dell9200_m26_pin_configs[8] = {
1094 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310,
1095 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe,
1100 102801CD (Dell Inspiron E1705/9400)
1102 static unsigned int dell9200_m27_pin_configs[8] = {
1103 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
1104 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc,
1107 static unsigned int oqo9200_pin_configs[8] = {
1108 0x40c000f0, 0x404000f1, 0x0221121f, 0x02211210,
1109 0x90170111, 0x90a70120, 0x400000f2, 0x400000f3,
1113 static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
1114 [STAC_REF] = ref9200_pin_configs,
1115 [STAC_9200_OQO] = oqo9200_pin_configs,
1116 [STAC_9200_DELL_D21] = dell9200_d21_pin_configs,
1117 [STAC_9200_DELL_D22] = dell9200_d22_pin_configs,
1118 [STAC_9200_DELL_D23] = dell9200_d23_pin_configs,
1119 [STAC_9200_DELL_M21] = dell9200_m21_pin_configs,
1120 [STAC_9200_DELL_M22] = dell9200_m22_pin_configs,
1121 [STAC_9200_DELL_M23] = dell9200_m23_pin_configs,
1122 [STAC_9200_DELL_M24] = dell9200_m24_pin_configs,
1123 [STAC_9200_DELL_M25] = dell9200_m25_pin_configs,
1124 [STAC_9200_DELL_M26] = dell9200_m26_pin_configs,
1125 [STAC_9200_DELL_M27] = dell9200_m27_pin_configs,
1126 [STAC_9200_PANASONIC] = ref9200_pin_configs,
1129 static const char *stac9200_models[STAC_9200_MODELS] = {
1131 [STAC_9200_OQO] = "oqo",
1132 [STAC_9200_DELL_D21] = "dell-d21",
1133 [STAC_9200_DELL_D22] = "dell-d22",
1134 [STAC_9200_DELL_D23] = "dell-d23",
1135 [STAC_9200_DELL_M21] = "dell-m21",
1136 [STAC_9200_DELL_M22] = "dell-m22",
1137 [STAC_9200_DELL_M23] = "dell-m23",
1138 [STAC_9200_DELL_M24] = "dell-m24",
1139 [STAC_9200_DELL_M25] = "dell-m25",
1140 [STAC_9200_DELL_M26] = "dell-m26",
1141 [STAC_9200_DELL_M27] = "dell-m27",
1142 [STAC_9200_GATEWAY] = "gateway",
1143 [STAC_9200_PANASONIC] = "panasonic",
1146 static struct snd_pci_quirk stac9200_cfg_tbl[] = {
1147 /* SigmaTel reference board */
1148 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1149 "DFI LanParty", STAC_REF),
1150 /* Dell laptops have BIOS problem */
1151 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
1152 "unknown Dell", STAC_9200_DELL_D21),
1153 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
1154 "Dell Inspiron 630m", STAC_9200_DELL_M21),
1155 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
1156 "Dell Inspiron E1505n", STAC_9200_DELL_M25),
1157 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
1158 "unknown Dell", STAC_9200_DELL_D22),
1159 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
1160 "unknown Dell", STAC_9200_DELL_D22),
1161 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
1162 "Dell Latitude D620", STAC_9200_DELL_M22),
1163 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
1164 "unknown Dell", STAC_9200_DELL_D23),
1165 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
1166 "unknown Dell", STAC_9200_DELL_D23),
1167 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
1168 "unknown Dell", STAC_9200_DELL_M22),
1169 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
1170 "unknown Dell", STAC_9200_DELL_M24),
1171 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
1172 "unknown Dell", STAC_9200_DELL_M24),
1173 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
1174 "Dell Latitude 120L", STAC_9200_DELL_M24),
1175 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
1176 "Dell Latitude D820", STAC_9200_DELL_M22),
1177 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
1178 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
1179 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
1180 "Dell XPS M1710", STAC_9200_DELL_M23),
1181 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
1182 "Dell Precision M90", STAC_9200_DELL_M23),
1183 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
1184 "unknown Dell", STAC_9200_DELL_M22),
1185 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
1186 "unknown Dell", STAC_9200_DELL_M22),
1187 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
1188 "unknown Dell", STAC_9200_DELL_M22),
1189 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
1190 "Dell Inspiron 640m", STAC_9200_DELL_M21),
1191 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
1192 "unknown Dell", STAC_9200_DELL_D23),
1193 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
1194 "unknown Dell", STAC_9200_DELL_D23),
1195 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
1196 "unknown Dell", STAC_9200_DELL_D21),
1197 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
1198 "unknown Dell", STAC_9200_DELL_D23),
1199 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
1200 "unknown Dell", STAC_9200_DELL_D21),
1201 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
1202 "unknown Dell", STAC_9200_DELL_M25),
1203 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
1204 "unknown Dell", STAC_9200_DELL_M25),
1205 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
1206 "Dell Inspiron 1501", STAC_9200_DELL_M26),
1207 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
1208 "unknown Dell", STAC_9200_DELL_M26),
1210 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC),
1211 /* Gateway machines needs EAPD to be set on resume */
1212 SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY),
1213 SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*",
1215 SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707",
1218 SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO),
1222 static unsigned int ref925x_pin_configs[8] = {
1223 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
1224 0x90a70320, 0x02214210, 0x01019020, 0x9033032e,
1227 static unsigned int stac925x_MA6_pin_configs[8] = {
1228 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
1229 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e,
1232 static unsigned int stac925x_PA6_pin_configs[8] = {
1233 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
1234 0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e,
1237 static unsigned int stac925xM2_2_pin_configs[8] = {
1238 0x40c003f3, 0x424503f2, 0x04180011, 0x02a19020,
1239 0x50a103f0, 0x90100212, 0x400003f1, 0x9033032e,
1242 static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
1243 [STAC_REF] = ref925x_pin_configs,
1244 [STAC_M2_2] = stac925xM2_2_pin_configs,
1245 [STAC_MA6] = stac925x_MA6_pin_configs,
1246 [STAC_PA6] = stac925x_PA6_pin_configs,
1249 static const char *stac925x_models[STAC_925x_MODELS] = {
1251 [STAC_M2_2] = "m2-2",
1256 static struct snd_pci_quirk stac925x_cfg_tbl[] = {
1257 /* SigmaTel reference board */
1258 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
1259 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
1260 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF),
1261 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF),
1262 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6),
1263 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_PA6),
1264 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2),
1268 static unsigned int ref92hd73xx_pin_configs[13] = {
1269 0x02214030, 0x02a19040, 0x01a19020, 0x02214030,
1270 0x0181302e, 0x01014010, 0x01014020, 0x01014030,
1271 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050,
1275 static unsigned int dell_m6_pin_configs[13] = {
1276 0x0321101f, 0x4f00000f, 0x4f0000f0, 0x90170110,
1277 0x03a11020, 0x03011050, 0x4f0000f0, 0x4f0000f0,
1278 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0,
1282 static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
1283 [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs,
1284 [STAC_DELL_M6] = dell_m6_pin_configs,
1287 static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
1288 [STAC_92HD73XX_REF] = "ref",
1289 [STAC_DELL_M6] = "dell-m6",
1292 static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
1293 /* SigmaTel reference board */
1294 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1295 "DFI LanParty", STAC_92HD73XX_REF),
1296 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254,
1297 "unknown Dell", STAC_DELL_M6),
1298 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255,
1299 "unknown Dell", STAC_DELL_M6),
1300 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256,
1301 "unknown Dell", STAC_DELL_M6),
1302 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257,
1303 "unknown Dell", STAC_DELL_M6),
1304 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e,
1305 "unknown Dell", STAC_DELL_M6),
1306 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f,
1307 "unknown Dell", STAC_DELL_M6),
1308 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271,
1309 "unknown Dell", STAC_DELL_M6),
1313 static unsigned int ref92hd71bxx_pin_configs[10] = {
1314 0x02214030, 0x02a19040, 0x01a19020, 0x01014010,
1315 0x0181302e, 0x01114010, 0x01019020, 0x90a000f0,
1316 0x90a000f0, 0x01452050,
1319 static unsigned int dell_m4_1_pin_configs[13] = {
1320 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110,
1321 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0,
1322 0x40f000f0, 0x4f0000f0,
1325 static unsigned int dell_m4_2_pin_configs[13] = {
1326 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110,
1327 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0,
1328 0x40f000f0, 0x044413b0,
1331 static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
1332 [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs,
1333 [STAC_DELL_M4_1] = dell_m4_1_pin_configs,
1334 [STAC_DELL_M4_2] = dell_m4_2_pin_configs,
1337 static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
1338 [STAC_92HD71BXX_REF] = "ref",
1339 [STAC_DELL_M4_1] = "dell-m4-1",
1340 [STAC_DELL_M4_2] = "dell-m4-2",
1343 static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1344 /* SigmaTel reference board */
1345 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1346 "DFI LanParty", STAC_92HD71BXX_REF),
1347 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
1348 "unknown Dell", STAC_DELL_M4_1),
1349 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234,
1350 "unknown Dell", STAC_DELL_M4_1),
1351 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0250,
1352 "unknown Dell", STAC_DELL_M4_1),
1353 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024f,
1354 "unknown Dell", STAC_DELL_M4_1),
1355 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024d,
1356 "unknown Dell", STAC_DELL_M4_1),
1357 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0251,
1358 "unknown Dell", STAC_DELL_M4_1),
1359 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0277,
1360 "unknown Dell", STAC_DELL_M4_1),
1361 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0263,
1362 "unknown Dell", STAC_DELL_M4_2),
1363 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0265,
1364 "unknown Dell", STAC_DELL_M4_2),
1365 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0262,
1366 "unknown Dell", STAC_DELL_M4_2),
1367 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264,
1368 "unknown Dell", STAC_DELL_M4_2),
1372 static unsigned int ref922x_pin_configs[10] = {
1373 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
1374 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
1375 0x40000100, 0x40000100,
1379 STAC 922X pin configs for
1386 static unsigned int dell_922x_d81_pin_configs[10] = {
1387 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
1388 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1,
1389 0x01813122, 0x400001f2,
1393 STAC 922X pin configs for
1397 static unsigned int dell_922x_d82_pin_configs[10] = {
1398 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
1399 0x02a19020, 0x01117011, 0x01451140, 0x400001f0,
1400 0x01813122, 0x400001f1,
1404 STAC 922X pin configs for
1407 static unsigned int dell_922x_m81_pin_configs[10] = {
1408 0x0321101f, 0x01112024, 0x01111222, 0x91174220,
1409 0x03a11050, 0x01116221, 0x90a70330, 0x01452340,
1410 0x40C003f1, 0x405003f0,
1414 STAC 9221 A1 pin configs for
1415 102801D7 (Dell XPS M1210)
1417 static unsigned int dell_922x_m82_pin_configs[10] = {
1418 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310,
1419 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2,
1420 0x508003f3, 0x405003f4,
1423 static unsigned int d945gtp3_pin_configs[10] = {
1424 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
1425 0x40000100, 0x40000100, 0x40000100, 0x40000100,
1426 0x02a19120, 0x40000100,
1429 static unsigned int d945gtp5_pin_configs[10] = {
1430 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
1431 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
1432 0x02a19320, 0x40000100,
1435 static unsigned int intel_mac_v1_pin_configs[10] = {
1436 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd,
1437 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240,
1438 0x400000fc, 0x400000fb,
1441 static unsigned int intel_mac_v2_pin_configs[10] = {
1442 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
1443 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa,
1444 0x400000fc, 0x400000fb,
1447 static unsigned int intel_mac_v3_pin_configs[10] = {
1448 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
1449 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240,
1450 0x400000fc, 0x400000fb,
1453 static unsigned int intel_mac_v4_pin_configs[10] = {
1454 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
1455 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
1456 0x400000fc, 0x400000fb,
1459 static unsigned int intel_mac_v5_pin_configs[10] = {
1460 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
1461 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
1462 0x400000fc, 0x400000fb,
1466 static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
1467 [STAC_D945_REF] = ref922x_pin_configs,
1468 [STAC_D945GTP3] = d945gtp3_pin_configs,
1469 [STAC_D945GTP5] = d945gtp5_pin_configs,
1470 [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs,
1471 [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs,
1472 [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs,
1473 [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs,
1474 [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs,
1475 /* for backward compatibility */
1476 [STAC_MACMINI] = intel_mac_v3_pin_configs,
1477 [STAC_MACBOOK] = intel_mac_v5_pin_configs,
1478 [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs,
1479 [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs,
1480 [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs,
1481 [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs,
1482 [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs,
1483 [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs,
1484 [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs,
1485 [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs,
1488 static const char *stac922x_models[STAC_922X_MODELS] = {
1489 [STAC_D945_REF] = "ref",
1490 [STAC_D945GTP5] = "5stack",
1491 [STAC_D945GTP3] = "3stack",
1492 [STAC_INTEL_MAC_V1] = "intel-mac-v1",
1493 [STAC_INTEL_MAC_V2] = "intel-mac-v2",
1494 [STAC_INTEL_MAC_V3] = "intel-mac-v3",
1495 [STAC_INTEL_MAC_V4] = "intel-mac-v4",
1496 [STAC_INTEL_MAC_V5] = "intel-mac-v5",
1497 /* for backward compatibility */
1498 [STAC_MACMINI] = "macmini",
1499 [STAC_MACBOOK] = "macbook",
1500 [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1",
1501 [STAC_MACBOOK_PRO_V2] = "macbook-pro",
1502 [STAC_IMAC_INTEL] = "imac-intel",
1503 [STAC_IMAC_INTEL_20] = "imac-intel-20",
1504 [STAC_922X_DELL_D81] = "dell-d81",
1505 [STAC_922X_DELL_D82] = "dell-d82",
1506 [STAC_922X_DELL_M81] = "dell-m81",
1507 [STAC_922X_DELL_M82] = "dell-m82",
1510 static struct snd_pci_quirk stac922x_cfg_tbl[] = {
1511 /* SigmaTel reference board */
1512 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1513 "DFI LanParty", STAC_D945_REF),
1514 /* Intel 945G based systems */
1515 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
1516 "Intel D945G", STAC_D945GTP3),
1517 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
1518 "Intel D945G", STAC_D945GTP3),
1519 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
1520 "Intel D945G", STAC_D945GTP3),
1521 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
1522 "Intel D945G", STAC_D945GTP3),
1523 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
1524 "Intel D945G", STAC_D945GTP3),
1525 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
1526 "Intel D945G", STAC_D945GTP3),
1527 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
1528 "Intel D945G", STAC_D945GTP3),
1529 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
1530 "Intel D945G", STAC_D945GTP3),
1531 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
1532 "Intel D945G", STAC_D945GTP3),
1533 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
1534 "Intel D945G", STAC_D945GTP3),
1535 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
1536 "Intel D945G", STAC_D945GTP3),
1537 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
1538 "Intel D945G", STAC_D945GTP3),
1539 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
1540 "Intel D945G", STAC_D945GTP3),
1541 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
1542 "Intel D945G", STAC_D945GTP3),
1543 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
1544 "Intel D945G", STAC_D945GTP3),
1545 /* Intel D945G 5-stack systems */
1546 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
1547 "Intel D945G", STAC_D945GTP5),
1548 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
1549 "Intel D945G", STAC_D945GTP5),
1550 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
1551 "Intel D945G", STAC_D945GTP5),
1552 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
1553 "Intel D945G", STAC_D945GTP5),
1554 /* Intel 945P based systems */
1555 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
1556 "Intel D945P", STAC_D945GTP3),
1557 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
1558 "Intel D945P", STAC_D945GTP3),
1559 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
1560 "Intel D945P", STAC_D945GTP3),
1561 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
1562 "Intel D945P", STAC_D945GTP3),
1563 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
1564 "Intel D945P", STAC_D945GTP3),
1565 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
1566 "Intel D945P", STAC_D945GTP5),
1568 /* Apple Mac Mini (early 2006) */
1569 SND_PCI_QUIRK(0x8384, 0x7680,
1570 "Mac Mini", STAC_INTEL_MAC_V3),
1572 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
1573 "unknown Dell", STAC_922X_DELL_D81),
1574 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
1575 "unknown Dell", STAC_922X_DELL_D81),
1576 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
1577 "unknown Dell", STAC_922X_DELL_D81),
1578 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
1579 "unknown Dell", STAC_922X_DELL_D82),
1580 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
1581 "unknown Dell", STAC_922X_DELL_M81),
1582 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
1583 "unknown Dell", STAC_922X_DELL_D82),
1584 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
1585 "unknown Dell", STAC_922X_DELL_D81),
1586 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
1587 "unknown Dell", STAC_922X_DELL_D81),
1588 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
1589 "Dell XPS M1210", STAC_922X_DELL_M82),
1593 static unsigned int ref927x_pin_configs[14] = {
1594 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1595 0x01a19040, 0x01011012, 0x01016011, 0x0101201f,
1596 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070,
1597 0x01c42190, 0x40000100,
1600 static unsigned int d965_3st_pin_configs[14] = {
1601 0x0221401f, 0x02a19120, 0x40000100, 0x01014011,
1602 0x01a19021, 0x01813024, 0x40000100, 0x40000100,
1603 0x40000100, 0x40000100, 0x40000100, 0x40000100,
1604 0x40000100, 0x40000100
1607 static unsigned int d965_5st_pin_configs[14] = {
1608 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1609 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
1610 0x40000100, 0x40000100, 0x40000100, 0x01442070,
1611 0x40000100, 0x40000100
1614 static unsigned int dell_3st_pin_configs[14] = {
1615 0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
1616 0x01111212, 0x01116211, 0x01813050, 0x01112214,
1617 0x403003fa, 0x90a60040, 0x90a60040, 0x404003fb,
1618 0x40c003fc, 0x40000100
1621 static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
1622 [STAC_D965_REF] = ref927x_pin_configs,
1623 [STAC_D965_3ST] = d965_3st_pin_configs,
1624 [STAC_D965_5ST] = d965_5st_pin_configs,
1625 [STAC_DELL_3ST] = dell_3st_pin_configs,
1626 [STAC_DELL_BIOS] = NULL,
1629 static const char *stac927x_models[STAC_927X_MODELS] = {
1630 [STAC_D965_REF] = "ref",
1631 [STAC_D965_3ST] = "3stack",
1632 [STAC_D965_5ST] = "5stack",
1633 [STAC_DELL_3ST] = "dell-3stack",
1634 [STAC_DELL_BIOS] = "dell-bios",
1637 static struct snd_pci_quirk stac927x_cfg_tbl[] = {
1638 /* SigmaTel reference board */
1639 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1640 "DFI LanParty", STAC_D965_REF),
1641 /* Intel 946 based systems */
1642 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
1643 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
1644 /* 965 based 3 stack systems */
1645 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2116, "Intel D965", STAC_D965_3ST),
1646 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2115, "Intel D965", STAC_D965_3ST),
1647 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2114, "Intel D965", STAC_D965_3ST),
1648 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2113, "Intel D965", STAC_D965_3ST),
1649 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2112, "Intel D965", STAC_D965_3ST),
1650 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2111, "Intel D965", STAC_D965_3ST),
1651 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2110, "Intel D965", STAC_D965_3ST),
1652 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2009, "Intel D965", STAC_D965_3ST),
1653 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2008, "Intel D965", STAC_D965_3ST),
1654 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2007, "Intel D965", STAC_D965_3ST),
1655 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2006, "Intel D965", STAC_D965_3ST),
1656 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2005, "Intel D965", STAC_D965_3ST),
1657 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2004, "Intel D965", STAC_D965_3ST),
1658 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST),
1659 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST),
1660 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST),
1661 /* Dell 3 stack systems */
1662 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_3ST),
1663 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
1664 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
1665 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
1666 /* Dell 3 stack systems with verb table in BIOS */
1667 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
1668 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
1669 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell ", STAC_DELL_BIOS),
1670 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS),
1671 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
1672 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
1673 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
1674 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS),
1675 /* 965 based 5 stack systems */
1676 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST),
1677 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST),
1678 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST),
1679 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2304, "Intel D965", STAC_D965_5ST),
1680 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2305, "Intel D965", STAC_D965_5ST),
1681 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2501, "Intel D965", STAC_D965_5ST),
1682 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2502, "Intel D965", STAC_D965_5ST),
1683 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2503, "Intel D965", STAC_D965_5ST),
1684 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2504, "Intel D965", STAC_D965_5ST),
1688 static unsigned int ref9205_pin_configs[12] = {
1689 0x40000100, 0x40000100, 0x01016011, 0x01014010,
1690 0x01813122, 0x01a19021, 0x01019020, 0x40000100,
1691 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
1695 STAC 9205 pin configs for
1702 10280228 (Dell Vostro 1500)
1704 static unsigned int dell_9205_m42_pin_configs[12] = {
1705 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310,
1706 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9,
1707 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE,
1711 STAC 9205 pin configs for
1715 102801FF (Dell Precision M4300)
1720 static unsigned int dell_9205_m43_pin_configs[12] = {
1721 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310,
1722 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9,
1723 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8,
1726 static unsigned int dell_9205_m44_pin_configs[12] = {
1727 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310,
1728 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9,
1729 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe,
1732 static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
1733 [STAC_9205_REF] = ref9205_pin_configs,
1734 [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs,
1735 [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs,
1736 [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs,
1739 static const char *stac9205_models[STAC_9205_MODELS] = {
1740 [STAC_9205_REF] = "ref",
1741 [STAC_9205_DELL_M42] = "dell-m42",
1742 [STAC_9205_DELL_M43] = "dell-m43",
1743 [STAC_9205_DELL_M44] = "dell-m44",
1746 static struct snd_pci_quirk stac9205_cfg_tbl[] = {
1747 /* SigmaTel reference board */
1748 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1749 "DFI LanParty", STAC_9205_REF),
1750 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1751 "unknown Dell", STAC_9205_DELL_M42),
1752 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1753 "unknown Dell", STAC_9205_DELL_M42),
1754 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
1755 "Dell Precision", STAC_9205_DELL_M43),
1756 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
1757 "Dell Precision", STAC_9205_DELL_M43),
1758 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
1759 "Dell Precision", STAC_9205_DELL_M43),
1760 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
1761 "Dell Precision", STAC_9205_DELL_M43),
1762 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
1763 "Dell Precision", STAC_9205_DELL_M43),
1764 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1765 "unknown Dell", STAC_9205_DELL_M42),
1766 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1767 "unknown Dell", STAC_9205_DELL_M42),
1768 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
1769 "Dell Precision", STAC_9205_DELL_M43),
1770 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
1771 "Dell Precision M4300", STAC_9205_DELL_M43),
1772 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
1773 "Dell Precision", STAC_9205_DELL_M43),
1774 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1775 "Dell Inspiron", STAC_9205_DELL_M44),
1776 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1777 "Dell Inspiron", STAC_9205_DELL_M44),
1778 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1779 "Dell Inspiron", STAC_9205_DELL_M44),
1780 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1781 "Dell Inspiron", STAC_9205_DELL_M44),
1782 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
1783 "unknown Dell", STAC_9205_DELL_M42),
1784 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
1785 "Dell Inspiron", STAC_9205_DELL_M44),
1786 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228,
1787 "Dell Vostro 1500", STAC_9205_DELL_M42),
1791 static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
1794 struct sigmatel_spec *spec = codec->spec;
1796 if (! spec->bios_pin_configs) {
1797 spec->bios_pin_configs = kcalloc(spec->num_pins,
1798 sizeof(*spec->bios_pin_configs), GFP_KERNEL);
1799 if (! spec->bios_pin_configs)
1803 for (i = 0; i < spec->num_pins; i++) {
1804 hda_nid_t nid = spec->pin_nids[i];
1805 unsigned int pin_cfg;
1807 pin_cfg = snd_hda_codec_read(codec, nid, 0,
1808 AC_VERB_GET_CONFIG_DEFAULT, 0x00);
1809 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n",
1811 spec->bios_pin_configs[i] = pin_cfg;
1817 static void stac92xx_set_config_reg(struct hda_codec *codec,
1818 hda_nid_t pin_nid, unsigned int pin_config)
1821 snd_hda_codec_write(codec, pin_nid, 0,
1822 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
1823 pin_config & 0x000000ff);
1824 snd_hda_codec_write(codec, pin_nid, 0,
1825 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
1826 (pin_config & 0x0000ff00) >> 8);
1827 snd_hda_codec_write(codec, pin_nid, 0,
1828 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
1829 (pin_config & 0x00ff0000) >> 16);
1830 snd_hda_codec_write(codec, pin_nid, 0,
1831 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
1833 i = snd_hda_codec_read(codec, pin_nid, 0,
1834 AC_VERB_GET_CONFIG_DEFAULT,
1836 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n",
1840 static void stac92xx_set_config_regs(struct hda_codec *codec)
1843 struct sigmatel_spec *spec = codec->spec;
1845 if (!spec->pin_configs)
1848 for (i = 0; i < spec->num_pins; i++)
1849 stac92xx_set_config_reg(codec, spec->pin_nids[i],
1850 spec->pin_configs[i]);
1854 * Analog playback callbacks
1856 static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
1857 struct hda_codec *codec,
1858 struct snd_pcm_substream *substream)
1860 struct sigmatel_spec *spec = codec->spec;
1861 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
1865 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1866 struct hda_codec *codec,
1867 unsigned int stream_tag,
1868 unsigned int format,
1869 struct snd_pcm_substream *substream)
1871 struct sigmatel_spec *spec = codec->spec;
1872 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream);
1875 static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1876 struct hda_codec *codec,
1877 struct snd_pcm_substream *substream)
1879 struct sigmatel_spec *spec = codec->spec;
1880 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1884 * Digital playback callbacks
1886 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1887 struct hda_codec *codec,
1888 struct snd_pcm_substream *substream)
1890 struct sigmatel_spec *spec = codec->spec;
1891 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1894 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1895 struct hda_codec *codec,
1896 struct snd_pcm_substream *substream)
1898 struct sigmatel_spec *spec = codec->spec;
1899 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1902 static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1903 struct hda_codec *codec,
1904 unsigned int stream_tag,
1905 unsigned int format,
1906 struct snd_pcm_substream *substream)
1908 struct sigmatel_spec *spec = codec->spec;
1909 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1910 stream_tag, format, substream);
1915 * Analog capture callbacks
1917 static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1918 struct hda_codec *codec,
1919 unsigned int stream_tag,
1920 unsigned int format,
1921 struct snd_pcm_substream *substream)
1923 struct sigmatel_spec *spec = codec->spec;
1925 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1926 stream_tag, 0, format);
1930 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1931 struct hda_codec *codec,
1932 struct snd_pcm_substream *substream)
1934 struct sigmatel_spec *spec = codec->spec;
1936 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
1940 static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
1944 /* NID is set in stac92xx_build_pcms */
1946 .open = stac92xx_dig_playback_pcm_open,
1947 .close = stac92xx_dig_playback_pcm_close,
1948 .prepare = stac92xx_dig_playback_pcm_prepare
1952 static struct hda_pcm_stream stac92xx_pcm_digital_capture = {
1956 /* NID is set in stac92xx_build_pcms */
1959 static struct hda_pcm_stream stac92xx_pcm_analog_playback = {
1963 .nid = 0x02, /* NID to query formats and rates */
1965 .open = stac92xx_playback_pcm_open,
1966 .prepare = stac92xx_playback_pcm_prepare,
1967 .cleanup = stac92xx_playback_pcm_cleanup
1971 static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
1975 .nid = 0x06, /* NID to query formats and rates */
1977 .open = stac92xx_playback_pcm_open,
1978 .prepare = stac92xx_playback_pcm_prepare,
1979 .cleanup = stac92xx_playback_pcm_cleanup
1983 static struct hda_pcm_stream stac92xx_pcm_analog_capture = {
1986 /* NID + .substreams is set in stac92xx_build_pcms */
1988 .prepare = stac92xx_capture_pcm_prepare,
1989 .cleanup = stac92xx_capture_pcm_cleanup
1993 static int stac92xx_build_pcms(struct hda_codec *codec)
1995 struct sigmatel_spec *spec = codec->spec;
1996 struct hda_pcm *info = spec->pcm_rec;
1998 codec->num_pcms = 1;
1999 codec->pcm_info = info;
2001 info->name = "STAC92xx Analog";
2002 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
2003 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
2004 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2005 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs;
2007 if (spec->alt_switch) {
2010 info->name = "STAC92xx Analog Alt";
2011 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback;
2014 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2017 info->name = "STAC92xx Digital";
2018 info->pcm_type = HDA_PCM_TYPE_SPDIF;
2019 if (spec->multiout.dig_out_nid) {
2020 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
2021 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2023 if (spec->dig_in_nid) {
2024 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture;
2025 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2032 static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
2034 unsigned int pincap = snd_hda_param_read(codec, nid,
2036 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
2037 if (pincap & AC_PINCAP_VREF_100)
2038 return AC_PINCTL_VREF_100;
2039 if (pincap & AC_PINCAP_VREF_80)
2040 return AC_PINCTL_VREF_80;
2041 if (pincap & AC_PINCAP_VREF_50)
2042 return AC_PINCTL_VREF_50;
2043 if (pincap & AC_PINCAP_VREF_GRD)
2044 return AC_PINCTL_VREF_GRD;
2048 static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
2051 snd_hda_codec_write_cache(codec, nid, 0,
2052 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
2055 #define stac92xx_io_switch_info snd_ctl_boolean_mono_info
2057 static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2059 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2060 struct sigmatel_spec *spec = codec->spec;
2061 int io_idx = kcontrol-> private_value & 0xff;
2063 ucontrol->value.integer.value[0] = spec->io_switch[io_idx];
2067 static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2069 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2070 struct sigmatel_spec *spec = codec->spec;
2071 hda_nid_t nid = kcontrol->private_value >> 8;
2072 int io_idx = kcontrol-> private_value & 0xff;
2073 unsigned short val = !!ucontrol->value.integer.value[0];
2075 spec->io_switch[io_idx] = val;
2078 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
2080 unsigned int pinctl = AC_PINCTL_IN_EN;
2081 if (io_idx) /* set VREF for mic */
2082 pinctl |= stac92xx_get_vref(codec, nid);
2083 stac92xx_auto_set_pinctl(codec, nid, pinctl);
2086 /* check the auto-mute again: we need to mute/unmute the speaker
2087 * appropriately according to the pin direction
2089 if (spec->hp_detect)
2090 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2095 #define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info
2097 static int stac92xx_clfe_switch_get(struct snd_kcontrol *kcontrol,
2098 struct snd_ctl_elem_value *ucontrol)
2100 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2101 struct sigmatel_spec *spec = codec->spec;
2103 ucontrol->value.integer.value[0] = spec->clfe_swap;
2107 static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
2108 struct snd_ctl_elem_value *ucontrol)
2110 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2111 struct sigmatel_spec *spec = codec->spec;
2112 hda_nid_t nid = kcontrol->private_value & 0xff;
2113 unsigned int val = !!ucontrol->value.integer.value[0];
2115 if (spec->clfe_swap == val)
2118 spec->clfe_swap = val;
2120 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
2121 spec->clfe_swap ? 0x4 : 0x0);
2126 #define STAC_CODEC_IO_SWITCH(xname, xpval) \
2127 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2130 .info = stac92xx_io_switch_info, \
2131 .get = stac92xx_io_switch_get, \
2132 .put = stac92xx_io_switch_put, \
2133 .private_value = xpval, \
2136 #define STAC_CODEC_CLFE_SWITCH(xname, xpval) \
2137 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2140 .info = stac92xx_clfe_switch_info, \
2141 .get = stac92xx_clfe_switch_get, \
2142 .put = stac92xx_clfe_switch_put, \
2143 .private_value = xpval, \
2147 STAC_CTL_WIDGET_VOL,
2148 STAC_CTL_WIDGET_MUTE,
2149 STAC_CTL_WIDGET_MONO_MUX,
2150 STAC_CTL_WIDGET_IO_SWITCH,
2151 STAC_CTL_WIDGET_CLFE_SWITCH
2154 static struct snd_kcontrol_new stac92xx_control_templates[] = {
2155 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2156 HDA_CODEC_MUTE(NULL, 0, 0, 0),
2158 STAC_CODEC_IO_SWITCH(NULL, 0),
2159 STAC_CODEC_CLFE_SWITCH(NULL, 0),
2162 /* add dynamic controls */
2163 static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val)
2165 struct snd_kcontrol_new *knew;
2167 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2168 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2170 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
2173 if (spec->kctl_alloc) {
2174 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
2175 kfree(spec->kctl_alloc);
2177 spec->kctl_alloc = knew;
2178 spec->num_kctl_alloc = num;
2181 knew = &spec->kctl_alloc[spec->num_kctl_used];
2182 *knew = stac92xx_control_templates[type];
2183 knew->name = kstrdup(name, GFP_KERNEL);
2186 knew->private_value = val;
2187 spec->num_kctl_used++;
2191 /* flag inputs as additional dynamic lineouts */
2192 static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
2194 struct sigmatel_spec *spec = codec->spec;
2195 unsigned int wcaps, wtype;
2196 int i, num_dacs = 0;
2198 /* use the wcaps cache to count all DACs available for line-outs */
2199 for (i = 0; i < codec->num_nodes; i++) {
2200 wcaps = codec->wcaps[i];
2201 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2203 if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL))
2207 snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
2209 switch (cfg->line_outs) {
2211 /* add line-in as side */
2212 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
2213 cfg->line_out_pins[cfg->line_outs] =
2214 cfg->input_pins[AUTO_PIN_LINE];
2215 spec->line_switch = 1;
2220 /* add line-in as clfe and mic as side */
2221 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
2222 cfg->line_out_pins[cfg->line_outs] =
2223 cfg->input_pins[AUTO_PIN_LINE];
2224 spec->line_switch = 1;
2227 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
2228 cfg->line_out_pins[cfg->line_outs] =
2229 cfg->input_pins[AUTO_PIN_MIC];
2230 spec->mic_switch = 1;
2235 /* add line-in as surr and mic as clfe */
2236 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
2237 cfg->line_out_pins[cfg->line_outs] =
2238 cfg->input_pins[AUTO_PIN_LINE];
2239 spec->line_switch = 1;
2242 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
2243 cfg->line_out_pins[cfg->line_outs] =
2244 cfg->input_pins[AUTO_PIN_MIC];
2245 spec->mic_switch = 1;
2255 static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2259 for (i = 0; i < spec->multiout.num_dacs; i++) {
2260 if (spec->multiout.dac_nids[i] == nid)
2268 * Fill in the dac_nids table from the parsed pin configuration
2269 * This function only works when every pin in line_out_pins[]
2270 * contains atleast one DAC in its connection list. Some 92xx
2271 * codecs are not connected directly to a DAC, such as the 9200
2272 * and 9202/925x. For those, dac_nids[] must be hard-coded.
2274 static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
2275 struct auto_pin_cfg *cfg)
2277 struct sigmatel_spec *spec = codec->spec;
2278 int i, j, conn_len = 0;
2279 hda_nid_t nid, conn[HDA_MAX_CONNECTIONS];
2280 unsigned int wcaps, wtype;
2282 for (i = 0; i < cfg->line_outs; i++) {
2283 nid = cfg->line_out_pins[i];
2284 conn_len = snd_hda_get_connections(codec, nid, conn,
2285 HDA_MAX_CONNECTIONS);
2286 for (j = 0; j < conn_len; j++) {
2287 wcaps = snd_hda_param_read(codec, conn[j],
2288 AC_PAR_AUDIO_WIDGET_CAP);
2289 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2290 if (wtype != AC_WID_AUD_OUT ||
2291 (wcaps & AC_WCAP_DIGITAL))
2293 /* conn[j] is a DAC routed to this line-out */
2294 if (!is_in_dac_nids(spec, conn[j]))
2298 if (j == conn_len) {
2299 if (spec->multiout.num_dacs > 0) {
2300 /* we have already working output pins,
2301 * so let's drop the broken ones again
2303 cfg->line_outs = spec->multiout.num_dacs;
2306 /* error out, no available DAC found */
2308 "%s: No available DAC for pin 0x%x\n",
2313 spec->multiout.dac_nids[i] = conn[j];
2314 spec->multiout.num_dacs++;
2316 /* select this DAC in the pin's input mux */
2317 snd_hda_codec_write_cache(codec, nid, 0,
2318 AC_VERB_SET_CONNECT_SEL, j);
2323 snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
2324 spec->multiout.num_dacs,
2325 spec->multiout.dac_nids[0],
2326 spec->multiout.dac_nids[1],
2327 spec->multiout.dac_nids[2],
2328 spec->multiout.dac_nids[3],
2329 spec->multiout.dac_nids[4]);
2333 /* create volume control/switch for the given prefx type */
2334 static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_t nid, int chs)
2339 sprintf(name, "%s Playback Volume", pfx);
2340 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name,
2341 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
2344 sprintf(name, "%s Playback Switch", pfx);
2345 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name,
2346 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
2352 static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
2354 if (!spec->multiout.hp_nid)
2355 spec->multiout.hp_nid = nid;
2356 else if (spec->multiout.num_dacs > 4) {
2357 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
2360 spec->multiout.dac_nids[spec->multiout.num_dacs] = nid;
2361 spec->multiout.num_dacs++;
2366 static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2368 if (is_in_dac_nids(spec, nid))
2370 if (spec->multiout.hp_nid == nid)
2375 /* add playback controls from the parsed DAC table */
2376 static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
2377 const struct auto_pin_cfg *cfg)
2379 static const char *chname[4] = {
2380 "Front", "Surround", NULL /*CLFE*/, "Side"
2385 struct sigmatel_spec *spec = codec->spec;
2386 unsigned int wid_caps, pincap;
2389 for (i = 0; i < cfg->line_outs && i < spec->multiout.num_dacs; i++) {
2390 if (!spec->multiout.dac_nids[i])
2393 nid = spec->multiout.dac_nids[i];
2397 err = create_controls(spec, "Center", nid, 1);
2400 err = create_controls(spec, "LFE", nid, 2);
2404 wid_caps = get_wcaps(codec, nid);
2406 if (wid_caps & AC_WCAP_LR_SWAP) {
2407 err = stac92xx_add_control(spec,
2408 STAC_CTL_WIDGET_CLFE_SWITCH,
2409 "Swap Center/LFE Playback Switch", nid);
2416 err = create_controls(spec, chname[i], nid, 3);
2422 if (spec->line_switch) {
2423 nid = cfg->input_pins[AUTO_PIN_LINE];
2424 pincap = snd_hda_param_read(codec, nid,
2426 if (pincap & AC_PINCAP_OUT) {
2427 err = stac92xx_add_control(spec,
2428 STAC_CTL_WIDGET_IO_SWITCH,
2429 "Line In as Output Switch", nid << 8);
2435 if (spec->mic_switch) {
2436 unsigned int def_conf;
2437 unsigned int mic_pin = AUTO_PIN_MIC;
2439 nid = cfg->input_pins[mic_pin];
2440 def_conf = snd_hda_codec_read(codec, nid, 0,
2441 AC_VERB_GET_CONFIG_DEFAULT, 0);
2442 /* some laptops have an internal analog microphone
2443 * which can't be used as a output */
2444 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) {
2445 pincap = snd_hda_param_read(codec, nid,
2447 if (pincap & AC_PINCAP_OUT) {
2448 err = stac92xx_add_control(spec,
2449 STAC_CTL_WIDGET_IO_SWITCH,
2450 "Mic as Output Switch", (nid << 8) | 1);
2451 nid = snd_hda_codec_read(codec, nid, 0,
2452 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2453 if (!check_in_dac_nids(spec, nid))
2454 add_spec_dacs(spec, nid);
2458 } else if (mic_pin == AUTO_PIN_MIC) {
2459 mic_pin = AUTO_PIN_FRONT_MIC;
2467 /* add playback controls for Speaker and HP outputs */
2468 static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
2469 struct auto_pin_cfg *cfg)
2471 struct sigmatel_spec *spec = codec->spec;
2473 int i, old_num_dacs, err;
2475 old_num_dacs = spec->multiout.num_dacs;
2476 for (i = 0; i < cfg->hp_outs; i++) {
2477 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]);
2478 if (wid_caps & AC_WCAP_UNSOL_CAP)
2479 spec->hp_detect = 1;
2480 nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
2481 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2482 if (check_in_dac_nids(spec, nid))
2486 add_spec_dacs(spec, nid);
2488 for (i = 0; i < cfg->speaker_outs; i++) {
2489 nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
2490 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2491 if (check_in_dac_nids(spec, nid))
2495 add_spec_dacs(spec, nid);
2497 for (i = 0; i < cfg->line_outs; i++) {
2498 nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0,
2499 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2500 if (check_in_dac_nids(spec, nid))
2504 add_spec_dacs(spec, nid);
2506 for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) {
2507 static const char *pfxs[] = {
2508 "Speaker", "External Speaker", "Speaker2",
2510 err = create_controls(spec, pfxs[i - old_num_dacs],
2511 spec->multiout.dac_nids[i], 3);
2515 if (spec->multiout.hp_nid) {
2516 err = create_controls(spec, "Headphone",
2517 spec->multiout.hp_nid, 3);
2525 /* labels for mono mux outputs */
2526 static const char *stac92xx_mono_labels[3] = {
2527 "DAC0", "DAC1", "Mixer"
2530 /* create mono mux for mono out on capable codecs */
2531 static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec)
2533 struct sigmatel_spec *spec = codec->spec;
2534 struct hda_input_mux *mono_mux = &spec->private_mono_mux;
2536 hda_nid_t con_lst[ARRAY_SIZE(stac92xx_mono_labels)];
2538 num_cons = snd_hda_get_connections(codec,
2541 HDA_MAX_NUM_INPUTS);
2542 if (!num_cons || num_cons > ARRAY_SIZE(stac92xx_mono_labels))
2545 for (i = 0; i < num_cons; i++) {
2546 mono_mux->items[mono_mux->num_items].label =
2547 stac92xx_mono_labels[i];
2548 mono_mux->items[mono_mux->num_items].index = i;
2549 mono_mux->num_items++;
2552 return stac92xx_add_control(spec, STAC_CTL_WIDGET_MONO_MUX,
2553 "Mono Mux", spec->mono_nid);
2556 /* labels for dmic mux inputs */
2557 static const char *stac92xx_dmic_labels[5] = {
2558 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
2559 "Digital Mic 3", "Digital Mic 4"
2562 /* create playback/capture controls for input pins on dmic capable codecs */
2563 static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
2564 const struct auto_pin_cfg *cfg)
2566 struct sigmatel_spec *spec = codec->spec;
2567 struct hda_input_mux *dimux = &spec->private_dimux;
2568 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
2572 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0];
2573 dimux->items[dimux->num_items].index = 0;
2576 for (i = 0; i < spec->num_dmics; i++) {
2581 unsigned int def_conf;
2583 def_conf = snd_hda_codec_read(codec,
2586 AC_VERB_GET_CONFIG_DEFAULT,
2588 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
2591 nid = spec->dmic_nids[i];
2592 num_cons = snd_hda_get_connections(codec,
2595 HDA_MAX_NUM_INPUTS);
2596 for (j = 0; j < num_cons; j++)
2597 if (con_lst[j] == nid) {
2603 wcaps = get_wcaps(codec, nid);
2605 if (wcaps & AC_WCAP_OUT_AMP) {
2606 sprintf(name, "%s Capture Volume",
2607 stac92xx_dmic_labels[dimux->num_items]);
2609 err = stac92xx_add_control(spec,
2610 STAC_CTL_WIDGET_VOL,
2612 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
2617 dimux->items[dimux->num_items].label =
2618 stac92xx_dmic_labels[dimux->num_items];
2619 dimux->items[dimux->num_items].index = index;
2626 /* create playback/capture controls for input pins */
2627 static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
2629 struct sigmatel_spec *spec = codec->spec;
2630 struct hda_input_mux *imux = &spec->private_imux;
2631 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
2634 for (i = 0; i < AUTO_PIN_LAST; i++) {
2637 if (!cfg->input_pins[i])
2640 for (j = 0; j < spec->num_muxes; j++) {
2642 num_cons = snd_hda_get_connections(codec,
2645 HDA_MAX_NUM_INPUTS);
2646 for (k = 0; k < num_cons; k++)
2647 if (con_lst[k] == cfg->input_pins[i]) {
2654 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2655 imux->items[imux->num_items].index = index;
2659 if (imux->num_items) {
2661 * Set the current input for the muxes.
2662 * The STAC9221 has two input muxes with identical source
2663 * NID lists. Hopefully this won't get confused.
2665 for (i = 0; i < spec->num_muxes; i++) {
2666 snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0,
2667 AC_VERB_SET_CONNECT_SEL,
2668 imux->items[0].index);
2675 static void stac92xx_auto_init_multi_out(struct hda_codec *codec)
2677 struct sigmatel_spec *spec = codec->spec;
2680 for (i = 0; i < spec->autocfg.line_outs; i++) {
2681 hda_nid_t nid = spec->autocfg.line_out_pins[i];
2682 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
2686 static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
2688 struct sigmatel_spec *spec = codec->spec;
2691 for (i = 0; i < spec->autocfg.hp_outs; i++) {
2693 pin = spec->autocfg.hp_pins[i];
2694 if (pin) /* connect to front */
2695 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
2697 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
2699 pin = spec->autocfg.speaker_pins[i];
2700 if (pin) /* connect to front */
2701 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN);
2705 static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in)
2707 struct sigmatel_spec *spec = codec->spec;
2709 int hp_speaker_swap = 0;
2711 if ((err = snd_hda_parse_pin_def_config(codec,
2713 spec->dmic_nids)) < 0)
2715 if (! spec->autocfg.line_outs)
2716 return 0; /* can't find valid pin config */
2718 /* If we have no real line-out pin and multiple hp-outs, HPs should
2719 * be set up as multi-channel outputs.
2721 if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
2722 spec->autocfg.hp_outs > 1) {
2723 /* Copy hp_outs to line_outs, backup line_outs in
2724 * speaker_outs so that the following routines can handle
2725 * HP pins as primary outputs.
2727 memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins,
2728 sizeof(spec->autocfg.line_out_pins));
2729 spec->autocfg.speaker_outs = spec->autocfg.line_outs;
2730 memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins,
2731 sizeof(spec->autocfg.hp_pins));
2732 spec->autocfg.line_outs = spec->autocfg.hp_outs;
2733 hp_speaker_swap = 1;
2735 if (spec->autocfg.mono_out_pin) {
2736 int dir = (get_wcaps(codec, spec->autocfg.mono_out_pin)
2737 & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT;
2738 u32 caps = query_amp_caps(codec,
2739 spec->autocfg.mono_out_pin, dir);
2740 hda_nid_t conn_list[1];
2742 /* get the mixer node and then the mono mux if it exists */
2743 if (snd_hda_get_connections(codec,
2744 spec->autocfg.mono_out_pin, conn_list, 1) &&
2745 snd_hda_get_connections(codec, conn_list[0],
2748 int wcaps = get_wcaps(codec, conn_list[0]);
2749 int wid_type = (wcaps & AC_WCAP_TYPE)
2750 >> AC_WCAP_TYPE_SHIFT;
2751 /* LR swap check, some stac925x have a mux that
2752 * changes the DACs output path instead of the
2755 if (wid_type == AC_WID_AUD_SEL &&
2756 !(wcaps & AC_WCAP_LR_SWAP))
2757 spec->mono_nid = conn_list[0];
2759 /* all mono outs have a least a mute/unmute switch */
2760 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE,
2761 "Mono Playback Switch",
2762 HDA_COMPOSE_AMP_VAL(spec->autocfg.mono_out_pin,
2766 /* check to see if there is volume support for the amp */
2767 if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
2768 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL,
2769 "Mono Playback Volume",
2770 HDA_COMPOSE_AMP_VAL(spec->autocfg.mono_out_pin,
2776 stac92xx_auto_set_pinctl(codec, spec->autocfg.mono_out_pin,
2780 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
2782 if (spec->multiout.num_dacs == 0)
2783 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
2786 err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg);
2791 if (hp_speaker_swap == 1) {
2792 /* Restore the hp_outs and line_outs */
2793 memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
2794 sizeof(spec->autocfg.line_out_pins));
2795 spec->autocfg.hp_outs = spec->autocfg.line_outs;
2796 memcpy(spec->autocfg.line_out_pins, spec->autocfg.speaker_pins,
2797 sizeof(spec->autocfg.speaker_pins));
2798 spec->autocfg.line_outs = spec->autocfg.speaker_outs;
2799 memset(spec->autocfg.speaker_pins, 0,
2800 sizeof(spec->autocfg.speaker_pins));
2801 spec->autocfg.speaker_outs = 0;
2804 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
2809 err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
2814 if (spec->mono_nid > 0) {
2815 err = stac92xx_auto_create_mono_output_ctls(codec);
2820 if (spec->num_dmics > 0)
2821 if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
2822 &spec->autocfg)) < 0)
2825 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2826 if (spec->multiout.max_channels > 2)
2827 spec->surr_switch = 1;
2829 if (spec->autocfg.dig_out_pin)
2830 spec->multiout.dig_out_nid = dig_out;
2831 if (spec->autocfg.dig_in_pin)
2832 spec->dig_in_nid = dig_in;
2834 if (spec->kctl_alloc)
2835 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2837 spec->input_mux = &spec->private_imux;
2838 if (!spec->dinput_mux)
2839 spec->dinput_mux = &spec->private_dimux;
2840 spec->mono_mux = &spec->private_mono_mux;
2845 /* add playback controls for HP output */
2846 static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
2847 struct auto_pin_cfg *cfg)
2849 struct sigmatel_spec *spec = codec->spec;
2850 hda_nid_t pin = cfg->hp_pins[0];
2851 unsigned int wid_caps;
2856 wid_caps = get_wcaps(codec, pin);
2857 if (wid_caps & AC_WCAP_UNSOL_CAP)
2858 spec->hp_detect = 1;
2863 /* add playback controls for LFE output */
2864 static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec,
2865 struct auto_pin_cfg *cfg)
2867 struct sigmatel_spec *spec = codec->spec;
2869 hda_nid_t lfe_pin = 0x0;
2873 * search speaker outs and line outs for a mono speaker pin
2874 * with an amp. If one is found, add LFE controls
2877 for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) {
2878 hda_nid_t pin = spec->autocfg.speaker_pins[i];
2879 unsigned int wcaps = get_wcaps(codec, pin);
2880 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
2881 if (wcaps == AC_WCAP_OUT_AMP)
2882 /* found a mono speaker with an amp, must be lfe */
2886 /* if speaker_outs is 0, then speakers may be in line_outs */
2887 if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) {
2888 for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) {
2889 hda_nid_t pin = spec->autocfg.line_out_pins[i];
2890 unsigned int defcfg;
2891 defcfg = snd_hda_codec_read(codec, pin, 0,
2892 AC_VERB_GET_CONFIG_DEFAULT,
2894 if (get_defcfg_device(defcfg) == AC_JACK_SPEAKER) {
2895 unsigned int wcaps = get_wcaps(codec, pin);
2896 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
2897 if (wcaps == AC_WCAP_OUT_AMP)
2898 /* found a mono speaker with an amp,
2906 err = create_controls(spec, "LFE", lfe_pin, 1);
2914 static int stac9200_parse_auto_config(struct hda_codec *codec)
2916 struct sigmatel_spec *spec = codec->spec;
2919 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
2922 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
2925 if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)
2928 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
2931 if (spec->autocfg.dig_out_pin)
2932 spec->multiout.dig_out_nid = 0x05;
2933 if (spec->autocfg.dig_in_pin)
2934 spec->dig_in_nid = 0x04;
2936 if (spec->kctl_alloc)
2937 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2939 spec->input_mux = &spec->private_imux;
2940 spec->dinput_mux = &spec->private_dimux;
2946 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
2947 * funky external mute control using GPIO pins.
2950 static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
2951 unsigned int dir_mask, unsigned int data)
2953 unsigned int gpiostate, gpiomask, gpiodir;
2955 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
2956 AC_VERB_GET_GPIO_DATA, 0);
2957 gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask);
2959 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
2960 AC_VERB_GET_GPIO_MASK, 0);
2963 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
2964 AC_VERB_GET_GPIO_DIRECTION, 0);
2965 gpiodir |= dir_mask;
2967 /* Configure GPIOx as CMOS */
2968 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
2970 snd_hda_codec_write(codec, codec->afg, 0,
2971 AC_VERB_SET_GPIO_MASK, gpiomask);
2972 snd_hda_codec_read(codec, codec->afg, 0,
2973 AC_VERB_SET_GPIO_DIRECTION, gpiodir); /* sync */
2977 snd_hda_codec_read(codec, codec->afg, 0,
2978 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
2981 static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
2984 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)
2985 snd_hda_codec_write_cache(codec, nid, 0,
2986 AC_VERB_SET_UNSOLICITED_ENABLE,
2987 (AC_USRSP_EN | event));
2990 static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
2993 for (i = 0; i < cfg->hp_outs; i++)
2994 if (cfg->hp_pins[i] == nid)
2995 return 1; /* nid is a HP-Out */
2997 return 0; /* nid is not a HP-Out */
3000 static void stac92xx_power_down(struct hda_codec *codec)
3002 struct sigmatel_spec *spec = codec->spec;
3004 /* power down inactive DACs */
3006 for (dac = spec->dac_list; *dac; dac++)
3007 if (!is_in_dac_nids(spec, *dac) &&
3008 spec->multiout.hp_nid != *dac)
3009 snd_hda_codec_write_cache(codec, *dac, 0,
3010 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3013 static int stac92xx_init(struct hda_codec *codec)
3015 struct sigmatel_spec *spec = codec->spec;
3016 struct auto_pin_cfg *cfg = &spec->autocfg;
3019 snd_hda_sequence_write(codec, spec->init);
3022 if (spec->hp_detect) {
3023 /* Enable unsolicited responses on the HP widget */
3024 for (i = 0; i < cfg->hp_outs; i++)
3025 enable_pin_detect(codec, cfg->hp_pins[i],
3027 /* force to enable the first line-out; the others are set up
3030 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
3032 stac92xx_auto_init_hp_out(codec);
3033 /* fake event to set up pins */
3034 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
3036 stac92xx_auto_init_multi_out(codec);
3037 stac92xx_auto_init_hp_out(codec);
3039 for (i = 0; i < AUTO_PIN_LAST; i++) {
3040 hda_nid_t nid = cfg->input_pins[i];
3042 unsigned int pinctl = AC_PINCTL_IN_EN;
3043 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
3044 pinctl |= stac92xx_get_vref(codec, nid);
3045 stac92xx_auto_set_pinctl(codec, nid, pinctl);
3048 for (i = 0; i < spec->num_dmics; i++)
3049 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
3051 for (i = 0; i < spec->num_pwrs; i++) {
3052 int event = is_nid_hp_pin(cfg, spec->pwr_nids[i])
3053 ? STAC_HP_EVENT : STAC_PWR_EVENT;
3054 int pinctl = snd_hda_codec_read(codec, spec->pwr_nids[i],
3055 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3056 int def_conf = snd_hda_codec_read(codec, spec->pwr_nids[i],
3057 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
3058 /* outputs are only ports capable of power management
3059 * any attempts on powering down a input port cause the
3060 * referenced VREF to act quirky.
3062 if (pinctl & AC_PINCTL_IN_EN)
3064 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED)
3066 enable_pin_detect(codec, spec->pwr_nids[i], event | i);
3067 codec->patch_ops.unsol_event(codec, (event | i) << 26);
3070 stac92xx_power_down(codec);
3071 if (cfg->dig_out_pin)
3072 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
3074 if (cfg->dig_in_pin)
3075 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
3078 stac_gpio_set(codec, spec->gpio_mask,
3079 spec->gpio_dir, spec->gpio_data);
3084 static void stac92xx_free(struct hda_codec *codec)
3086 struct sigmatel_spec *spec = codec->spec;
3092 if (spec->kctl_alloc) {
3093 for (i = 0; i < spec->num_kctl_used; i++)
3094 kfree(spec->kctl_alloc[i].name);
3095 kfree(spec->kctl_alloc);
3098 if (spec->bios_pin_configs)
3099 kfree(spec->bios_pin_configs);
3104 static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
3107 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
3108 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
3110 if (pin_ctl & AC_PINCTL_IN_EN) {
3112 * we need to check the current set-up direction of
3113 * shared input pins since they can be switched via
3114 * "xxx as Output" mixer switch
3116 struct sigmatel_spec *spec = codec->spec;
3117 struct auto_pin_cfg *cfg = &spec->autocfg;
3118 if ((nid == cfg->input_pins[AUTO_PIN_LINE] &&
3119 spec->line_switch) ||
3120 (nid == cfg->input_pins[AUTO_PIN_MIC] &&
3125 /* if setting pin direction bits, clear the current
3126 direction bits first */
3127 if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
3128 pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
3130 snd_hda_codec_write_cache(codec, nid, 0,
3131 AC_VERB_SET_PIN_WIDGET_CONTROL,
3135 static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
3138 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
3139 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
3140 snd_hda_codec_write_cache(codec, nid, 0,
3141 AC_VERB_SET_PIN_WIDGET_CONTROL,
3145 static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid)
3149 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00)
3151 unsigned int pinctl;
3152 pinctl = snd_hda_codec_read(codec, nid, 0,
3153 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3154 if (pinctl & AC_PINCTL_IN_EN)
3155 return 0; /* mic- or line-input */
3157 return 1; /* HP-output */
3162 static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
3164 struct sigmatel_spec *spec = codec->spec;
3165 struct auto_pin_cfg *cfg = &spec->autocfg;
3169 if (spec->gpio_mute)
3170 presence = !(snd_hda_codec_read(codec, codec->afg, 0,
3171 AC_VERB_GET_GPIO_DATA, 0) & spec->gpio_mute);
3173 for (i = 0; i < cfg->hp_outs; i++) {
3176 presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);
3180 /* disable lineouts, enable hp */
3181 for (i = 0; i < cfg->line_outs; i++)
3182 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
3184 for (i = 0; i < cfg->speaker_outs; i++)
3185 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
3187 if (spec->eapd_mask)
3188 stac_gpio_set(codec, spec->gpio_mask,
3189 spec->gpio_dir, spec->gpio_data &
3192 /* enable lineouts, disable hp */
3193 for (i = 0; i < cfg->line_outs; i++)
3194 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
3196 for (i = 0; i < cfg->speaker_outs; i++)
3197 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
3199 if (spec->eapd_mask)
3200 stac_gpio_set(codec, spec->gpio_mask,
3201 spec->gpio_dir, spec->gpio_data |
3206 static void stac92xx_pin_sense(struct hda_codec *codec, int idx)
3208 struct sigmatel_spec *spec = codec->spec;
3209 hda_nid_t nid = spec->pwr_nids[idx];
3211 val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0)
3213 presence = get_hp_pin_presence(codec, nid);
3221 /* power down unused output ports */
3222 snd_hda_codec_write(codec, codec->afg, 0, 0x7ec, val);
3225 static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
3227 struct sigmatel_spec *spec = codec->spec;
3228 int idx = res >> 26 & 0x0f;
3230 switch ((res >> 26) & 0x30) {
3232 stac92xx_hp_detect(codec, res);
3234 case STAC_PWR_EVENT:
3235 if (spec->num_pwrs > 0)
3236 stac92xx_pin_sense(codec, idx);
3240 #ifdef SND_HDA_NEEDS_RESUME
3241 static int stac92xx_resume(struct hda_codec *codec)
3243 struct sigmatel_spec *spec = codec->spec;
3245 stac92xx_set_config_regs(codec);
3246 snd_hda_sequence_write(codec, spec->init);
3247 stac_gpio_set(codec, spec->gpio_mask,
3248 spec->gpio_dir, spec->gpio_data);
3249 snd_hda_codec_resume_amp(codec);
3250 snd_hda_codec_resume_cache(codec);
3251 /* power down inactive DACs */
3253 stac92xx_power_down(codec);
3254 /* invoke unsolicited event to reset the HP state */
3255 if (spec->hp_detect)
3256 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
3261 static struct hda_codec_ops stac92xx_patch_ops = {
3262 .build_controls = stac92xx_build_controls,
3263 .build_pcms = stac92xx_build_pcms,
3264 .init = stac92xx_init,
3265 .free = stac92xx_free,
3266 .unsol_event = stac92xx_unsol_event,
3267 #ifdef SND_HDA_NEEDS_RESUME
3268 .resume = stac92xx_resume,
3272 static int patch_stac9200(struct hda_codec *codec)
3274 struct sigmatel_spec *spec;
3277 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3282 spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
3283 spec->pin_nids = stac9200_pin_nids;
3284 spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
3287 if (spec->board_config < 0) {
3288 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
3289 err = stac92xx_save_bios_config_regs(codec);
3291 stac92xx_free(codec);
3294 spec->pin_configs = spec->bios_pin_configs;
3296 spec->pin_configs = stac9200_brd_tbl[spec->board_config];
3297 stac92xx_set_config_regs(codec);
3300 spec->multiout.max_channels = 2;
3301 spec->multiout.num_dacs = 1;
3302 spec->multiout.dac_nids = stac9200_dac_nids;
3303 spec->adc_nids = stac9200_adc_nids;
3304 spec->mux_nids = stac9200_mux_nids;
3305 spec->num_muxes = 1;
3306 spec->num_dmics = 0;
3310 if (spec->board_config == STAC_9200_GATEWAY ||
3311 spec->board_config == STAC_9200_OQO)
3312 spec->init = stac9200_eapd_init;
3314 spec->init = stac9200_core_init;
3315 spec->mixer = stac9200_mixer;
3317 if (spec->board_config == STAC_9200_PANASONIC) {
3318 spec->gpio_mask = spec->gpio_dir = 0x09;
3319 spec->gpio_data = 0x00;
3322 err = stac9200_parse_auto_config(codec);
3324 stac92xx_free(codec);
3328 codec->patch_ops = stac92xx_patch_ops;
3333 static int patch_stac925x(struct hda_codec *codec)
3335 struct sigmatel_spec *spec;
3338 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3343 spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
3344 spec->pin_nids = stac925x_pin_nids;
3345 spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
3349 if (spec->board_config < 0) {
3350 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x,"
3351 "using BIOS defaults\n");
3352 err = stac92xx_save_bios_config_regs(codec);
3354 stac92xx_free(codec);
3357 spec->pin_configs = spec->bios_pin_configs;
3358 } else if (stac925x_brd_tbl[spec->board_config] != NULL){
3359 spec->pin_configs = stac925x_brd_tbl[spec->board_config];
3360 stac92xx_set_config_regs(codec);
3363 spec->multiout.max_channels = 2;
3364 spec->multiout.num_dacs = 1;
3365 spec->multiout.dac_nids = stac925x_dac_nids;
3366 spec->adc_nids = stac925x_adc_nids;
3367 spec->mux_nids = stac925x_mux_nids;
3368 spec->num_muxes = 1;
3371 switch (codec->vendor_id) {
3372 case 0x83847632: /* STAC9202 */
3373 case 0x83847633: /* STAC9202D */
3374 case 0x83847636: /* STAC9251 */
3375 case 0x83847637: /* STAC9251D */
3376 spec->num_dmics = STAC925X_NUM_DMICS;
3377 spec->dmic_nids = stac925x_dmic_nids;
3378 spec->num_dmuxes = ARRAY_SIZE(stac925x_dmux_nids);
3379 spec->dmux_nids = stac925x_dmux_nids;
3382 spec->num_dmics = 0;
3386 spec->init = stac925x_core_init;
3387 spec->mixer = stac925x_mixer;
3389 err = stac92xx_parse_auto_config(codec, 0x8, 0x7);
3391 if (spec->board_config < 0) {
3392 printk(KERN_WARNING "hda_codec: No auto-config is "
3393 "available, default to model=ref\n");
3394 spec->board_config = STAC_925x_REF;
3400 stac92xx_free(codec);
3404 codec->patch_ops = stac92xx_patch_ops;
3409 static struct hda_input_mux stac92hd73xx_dmux = {
3412 { "Analog Inputs", 0x0b },
3414 { "Digital Mic 1", 0x09 },
3415 { "Digital Mic 2", 0x0a },
3419 static int patch_stac92hd73xx(struct hda_codec *codec)
3421 struct sigmatel_spec *spec;
3422 hda_nid_t conn[STAC92HD73_DAC_COUNT + 2];
3425 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3430 spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids);
3431 spec->pin_nids = stac92hd73xx_pin_nids;
3432 spec->board_config = snd_hda_check_board_config(codec,
3433 STAC_92HD73XX_MODELS,
3434 stac92hd73xx_models,
3435 stac92hd73xx_cfg_tbl);
3437 if (spec->board_config < 0) {
3438 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
3439 " STAC92HD73XX, using BIOS defaults\n");
3440 err = stac92xx_save_bios_config_regs(codec);
3442 stac92xx_free(codec);
3445 spec->pin_configs = spec->bios_pin_configs;
3447 spec->pin_configs = stac92hd73xx_brd_tbl[spec->board_config];
3448 stac92xx_set_config_regs(codec);
3451 spec->multiout.num_dacs = snd_hda_get_connections(codec, 0x0a,
3452 conn, STAC92HD73_DAC_COUNT + 2) - 1;
3454 if (spec->multiout.num_dacs < 0) {
3455 printk(KERN_WARNING "hda_codec: Could not determine "
3456 "number of channels defaulting to DAC count\n");
3457 spec->multiout.num_dacs = STAC92HD73_DAC_COUNT;
3460 switch (spec->multiout.num_dacs) {
3461 case 0x3: /* 6 Channel */
3462 spec->mixer = stac92hd73xx_6ch_mixer;
3463 spec->init = stac92hd73xx_6ch_core_init;
3465 case 0x4: /* 8 Channel */
3466 spec->multiout.hp_nid = 0x18;
3467 spec->mixer = stac92hd73xx_8ch_mixer;
3468 spec->init = stac92hd73xx_8ch_core_init;
3470 case 0x5: /* 10 Channel */
3471 spec->multiout.hp_nid = 0x19;
3472 spec->mixer = stac92hd73xx_10ch_mixer;
3473 spec->init = stac92hd73xx_10ch_core_init;
3476 spec->multiout.dac_nids = stac92hd73xx_dac_nids;
3477 spec->aloopback_mask = 0x01;
3478 spec->aloopback_shift = 8;
3480 spec->mux_nids = stac92hd73xx_mux_nids;
3481 spec->adc_nids = stac92hd73xx_adc_nids;
3482 spec->dmic_nids = stac92hd73xx_dmic_nids;
3483 spec->dmux_nids = stac92hd73xx_dmux_nids;
3485 spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids);
3486 spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids);
3487 spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids);
3488 spec->dinput_mux = &stac92hd73xx_dmux;
3489 /* GPIO0 High = Enable EAPD */
3490 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
3491 spec->gpio_data = 0x01;
3493 switch (spec->board_config) {
3495 spec->init = dell_eq_core_init;
3496 switch (codec->subsystem_id) {
3497 case 0x1028025e: /* Analog Mics */
3499 stac92xx_set_config_reg(codec, 0x0b, 0x90A70170);
3500 spec->num_dmics = 0;
3502 case 0x10280271: /* Digital Mics */
3504 spec->init = dell_m6_core_init;
3508 stac92xx_set_config_reg(codec, 0x13, 0x90A60160);
3509 spec->num_dmics = 1;
3511 case 0x10280256: /* Both */
3513 stac92xx_set_config_reg(codec, 0x0b, 0x90A70170);
3514 stac92xx_set_config_reg(codec, 0x13, 0x90A60160);
3515 spec->num_dmics = 1;
3520 spec->num_dmics = STAC92HD73XX_NUM_DMICS;
3523 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
3524 spec->pwr_nids = stac92hd73xx_pwr_nids;
3526 err = stac92xx_parse_auto_config(codec, 0x22, 0x24);
3529 if (spec->board_config < 0) {
3530 printk(KERN_WARNING "hda_codec: No auto-config is "
3531 "available, default to model=ref\n");
3532 spec->board_config = STAC_92HD73XX_REF;
3539 stac92xx_free(codec);
3543 codec->patch_ops = stac92xx_patch_ops;
3548 static int patch_stac92hd71bxx(struct hda_codec *codec)
3550 struct sigmatel_spec *spec;
3553 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3558 spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids);
3559 spec->pin_nids = stac92hd71bxx_pin_nids;
3560 spec->board_config = snd_hda_check_board_config(codec,
3561 STAC_92HD71BXX_MODELS,
3562 stac92hd71bxx_models,
3563 stac92hd71bxx_cfg_tbl);
3565 if (spec->board_config < 0) {
3566 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
3567 " STAC92HD71BXX, using BIOS defaults\n");
3568 err = stac92xx_save_bios_config_regs(codec);
3570 stac92xx_free(codec);
3573 spec->pin_configs = spec->bios_pin_configs;
3575 spec->pin_configs = stac92hd71bxx_brd_tbl[spec->board_config];
3576 stac92xx_set_config_regs(codec);
3579 switch (codec->vendor_id) {
3580 case 0x111d76b6: /* 4 Port without Analog Mixer */
3582 case 0x111d76b4: /* 6 Port without Analog Mixer */
3584 spec->mixer = stac92hd71bxx_mixer;
3585 spec->init = stac92hd71bxx_core_init;
3588 spec->mixer = stac92hd71bxx_analog_mixer;
3589 spec->init = stac92hd71bxx_analog_core_init;
3592 spec->aloopback_mask = 0x20;
3593 spec->aloopback_shift = 0;
3595 /* GPIO0 High = EAPD */
3596 spec->gpio_mask = 0x01;
3597 spec->gpio_dir = 0x01;
3598 spec->gpio_mask = 0x01;
3599 spec->gpio_data = 0x01;
3601 spec->mux_nids = stac92hd71bxx_mux_nids;
3602 spec->adc_nids = stac92hd71bxx_adc_nids;
3603 spec->dmic_nids = stac92hd71bxx_dmic_nids;
3604 spec->dmux_nids = stac92hd71bxx_dmux_nids;
3606 spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids);
3607 spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids);
3608 spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
3609 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
3611 spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
3612 spec->pwr_nids = stac92hd71bxx_pwr_nids;
3614 spec->multiout.num_dacs = 1;
3615 spec->multiout.hp_nid = 0x11;
3616 spec->multiout.dac_nids = stac92hd71bxx_dac_nids;
3618 err = stac92xx_parse_auto_config(codec, 0x21, 0x23);
3620 if (spec->board_config < 0) {
3621 printk(KERN_WARNING "hda_codec: No auto-config is "
3622 "available, default to model=ref\n");
3623 spec->board_config = STAC_92HD71BXX_REF;
3630 stac92xx_free(codec);
3634 codec->patch_ops = stac92xx_patch_ops;
3639 static int patch_stac922x(struct hda_codec *codec)
3641 struct sigmatel_spec *spec;
3644 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3649 spec->num_pins = ARRAY_SIZE(stac922x_pin_nids);
3650 spec->pin_nids = stac922x_pin_nids;
3651 spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
3654 if (spec->board_config == STAC_INTEL_MAC_V3) {
3655 spec->gpio_mask = spec->gpio_dir = 0x03;
3656 spec->gpio_data = 0x03;
3657 /* Intel Macs have all same PCI SSID, so we need to check
3658 * codec SSID to distinguish the exact models
3660 printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id);
3661 switch (codec->subsystem_id) {
3664 spec->board_config = STAC_INTEL_MAC_V1;
3668 spec->board_config = STAC_INTEL_MAC_V2;
3676 spec->board_config = STAC_INTEL_MAC_V3;
3680 spec->board_config = STAC_INTEL_MAC_V4;
3684 spec->board_config = STAC_INTEL_MAC_V5;
3690 if (spec->board_config < 0) {
3691 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, "
3692 "using BIOS defaults\n");
3693 err = stac92xx_save_bios_config_regs(codec);
3695 stac92xx_free(codec);
3698 spec->pin_configs = spec->bios_pin_configs;
3699 } else if (stac922x_brd_tbl[spec->board_config] != NULL) {
3700 spec->pin_configs = stac922x_brd_tbl[spec->board_config];
3701 stac92xx_set_config_regs(codec);
3704 spec->adc_nids = stac922x_adc_nids;
3705 spec->mux_nids = stac922x_mux_nids;
3706 spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
3707 spec->num_adcs = ARRAY_SIZE(stac922x_adc_nids);
3708 spec->num_dmics = 0;
3711 spec->init = stac922x_core_init;
3712 spec->mixer = stac922x_mixer;
3714 spec->multiout.dac_nids = spec->dac_nids;
3716 err = stac92xx_parse_auto_config(codec, 0x08, 0x09);
3718 if (spec->board_config < 0) {
3719 printk(KERN_WARNING "hda_codec: No auto-config is "
3720 "available, default to model=ref\n");
3721 spec->board_config = STAC_D945_REF;
3727 stac92xx_free(codec);
3731 codec->patch_ops = stac92xx_patch_ops;
3733 /* Fix Mux capture level; max to 2 */
3734 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
3735 (0 << AC_AMPCAP_OFFSET_SHIFT) |
3736 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
3737 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
3738 (0 << AC_AMPCAP_MUTE_SHIFT));
3743 static int patch_stac927x(struct hda_codec *codec)
3745 struct sigmatel_spec *spec;
3748 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3753 spec->num_pins = ARRAY_SIZE(stac927x_pin_nids);
3754 spec->pin_nids = stac927x_pin_nids;
3755 spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS,
3759 if (spec->board_config < 0 || !stac927x_brd_tbl[spec->board_config]) {
3760 if (spec->board_config < 0)
3761 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
3762 "STAC927x, using BIOS defaults\n");
3763 err = stac92xx_save_bios_config_regs(codec);
3765 stac92xx_free(codec);
3768 spec->pin_configs = spec->bios_pin_configs;
3770 spec->pin_configs = stac927x_brd_tbl[spec->board_config];
3771 stac92xx_set_config_regs(codec);
3774 spec->adc_nids = stac927x_adc_nids;
3775 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
3776 spec->mux_nids = stac927x_mux_nids;
3777 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
3778 spec->dac_list = stac927x_dac_nids;
3779 spec->multiout.dac_nids = spec->dac_nids;
3781 switch (spec->board_config) {
3784 /* GPIO0 High = Enable EAPD */
3785 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x01;
3786 spec->gpio_data = 0x01;
3787 spec->num_dmics = 0;
3789 spec->init = d965_core_init;
3790 spec->mixer = stac927x_mixer;
3792 case STAC_DELL_BIOS:
3793 switch (codec->subsystem_id) {
3796 /* correct the device field to SPDIF out */
3797 stac92xx_set_config_reg(codec, 0x21, 0x01442070);
3800 /* configure the analog microphone on some laptops */
3801 stac92xx_set_config_reg(codec, 0x0c, 0x90a79130);
3802 /* correct the front output jack as a hp out */
3803 stac92xx_set_config_reg(codec, 0x0f, 0x0227011f);
3804 /* correct the front input jack as a mic */
3805 stac92xx_set_config_reg(codec, 0x0e, 0x02a79130);
3808 /* GPIO2 High = Enable EAPD */
3809 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x04;
3810 spec->gpio_data = 0x04;
3811 spec->dmic_nids = stac927x_dmic_nids;
3812 spec->num_dmics = STAC927X_NUM_DMICS;
3814 spec->init = d965_core_init;
3815 spec->mixer = stac927x_mixer;
3816 spec->dmux_nids = stac927x_dmux_nids;
3817 spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
3820 /* GPIO0 High = Enable EAPD */
3821 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
3822 spec->gpio_data = 0x01;
3823 spec->num_dmics = 0;
3825 spec->init = stac927x_core_init;
3826 spec->mixer = stac927x_mixer;
3830 spec->aloopback_mask = 0x40;
3831 spec->aloopback_shift = 0;
3833 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
3835 if (spec->board_config < 0) {
3836 printk(KERN_WARNING "hda_codec: No auto-config is "
3837 "available, default to model=ref\n");
3838 spec->board_config = STAC_D965_REF;
3844 stac92xx_free(codec);
3848 codec->patch_ops = stac92xx_patch_ops;
3852 * The STAC927x seem to require fairly long delays for certain
3853 * command sequences. With too short delays (even if the answer
3854 * is set to RIRB properly), it results in the silence output
3855 * on some hardwares like Dell.
3857 * The below flag enables the longer delay (see get_response
3860 codec->bus->needs_damn_long_delay = 1;
3865 static int patch_stac9205(struct hda_codec *codec)
3867 struct sigmatel_spec *spec;
3870 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3875 spec->num_pins = ARRAY_SIZE(stac9205_pin_nids);
3876 spec->pin_nids = stac9205_pin_nids;
3877 spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
3881 if (spec->board_config < 0) {
3882 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n");
3883 err = stac92xx_save_bios_config_regs(codec);
3885 stac92xx_free(codec);
3888 spec->pin_configs = spec->bios_pin_configs;
3890 spec->pin_configs = stac9205_brd_tbl[spec->board_config];
3891 stac92xx_set_config_regs(codec);
3894 spec->adc_nids = stac9205_adc_nids;
3895 spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids);
3896 spec->mux_nids = stac9205_mux_nids;
3897 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
3898 spec->dmic_nids = stac9205_dmic_nids;
3899 spec->num_dmics = STAC9205_NUM_DMICS;
3900 spec->dmux_nids = stac9205_dmux_nids;
3901 spec->num_dmuxes = ARRAY_SIZE(stac9205_dmux_nids);
3904 spec->init = stac9205_core_init;
3905 spec->mixer = stac9205_mixer;
3907 spec->aloopback_mask = 0x40;
3908 spec->aloopback_shift = 0;
3909 spec->multiout.dac_nids = spec->dac_nids;
3911 switch (spec->board_config){
3912 case STAC_9205_DELL_M43:
3913 /* Enable SPDIF in/out */
3914 stac92xx_set_config_reg(codec, 0x1f, 0x01441030);
3915 stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
3917 /* Enable unsol response for GPIO4/Dock HP connection */
3918 snd_hda_codec_write(codec, codec->afg, 0,
3919 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
3920 snd_hda_codec_write_cache(codec, codec->afg, 0,
3921 AC_VERB_SET_UNSOLICITED_ENABLE,
3922 (AC_USRSP_EN | STAC_HP_EVENT));
3924 spec->gpio_dir = 0x0b;
3925 spec->eapd_mask = 0x01;
3926 spec->gpio_mask = 0x1b;
3927 spec->gpio_mute = 0x10;
3928 /* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute,
3931 spec->gpio_data = 0x01;
3934 /* GPIO0 High = EAPD */
3935 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
3936 spec->gpio_data = 0x01;
3940 err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
3942 if (spec->board_config < 0) {
3943 printk(KERN_WARNING "hda_codec: No auto-config is "
3944 "available, default to model=ref\n");
3945 spec->board_config = STAC_9205_REF;
3951 stac92xx_free(codec);
3955 codec->patch_ops = stac92xx_patch_ops;
3964 /* static config for Sony VAIO FE550G and Sony VAIO AR */
3965 static hda_nid_t vaio_dacs[] = { 0x2 };
3966 #define VAIO_HP_DAC 0x5
3967 static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ };
3968 static hda_nid_t vaio_mux_nids[] = { 0x15 };
3970 static struct hda_input_mux vaio_mux = {
3973 /* { "HP", 0x0 }, */
3974 { "Mic Jack", 0x1 },
3975 { "Internal Mic", 0x2 },
3980 static struct hda_verb vaio_init[] = {
3981 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
3982 {0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT},
3983 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
3984 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
3985 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
3986 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
3987 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
3988 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
3989 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
3990 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
3991 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
3992 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
3996 static struct hda_verb vaio_ar_init[] = {
3997 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
3998 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
3999 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
4000 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
4001 /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */
4002 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
4003 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
4004 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
4005 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
4006 /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */
4007 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
4008 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
4009 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
4013 /* bind volumes of both NID 0x02 and 0x05 */
4014 static struct hda_bind_ctls vaio_bind_master_vol = {
4015 .ops = &snd_hda_bind_vol,
4017 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
4018 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
4023 /* bind volumes of both NID 0x02 and 0x05 */
4024 static struct hda_bind_ctls vaio_bind_master_sw = {
4025 .ops = &snd_hda_bind_sw,
4027 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
4028 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
4033 static struct snd_kcontrol_new vaio_mixer[] = {
4034 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
4035 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
4036 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
4037 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
4038 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
4040 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4041 .name = "Capture Source",
4043 .info = stac92xx_mux_enum_info,
4044 .get = stac92xx_mux_enum_get,
4045 .put = stac92xx_mux_enum_put,
4050 static struct snd_kcontrol_new vaio_ar_mixer[] = {
4051 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
4052 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
4053 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
4054 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
4055 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
4056 /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT),
4057 HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/
4059 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4060 .name = "Capture Source",
4062 .info = stac92xx_mux_enum_info,
4063 .get = stac92xx_mux_enum_get,
4064 .put = stac92xx_mux_enum_put,
4069 static struct hda_codec_ops stac9872_patch_ops = {
4070 .build_controls = stac92xx_build_controls,
4071 .build_pcms = stac92xx_build_pcms,
4072 .init = stac92xx_init,
4073 .free = stac92xx_free,
4074 #ifdef SND_HDA_NEEDS_RESUME
4075 .resume = stac92xx_resume,
4079 static int stac9872_vaio_init(struct hda_codec *codec)
4083 err = stac92xx_init(codec);
4086 if (codec->patch_ops.unsol_event)
4087 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
4091 static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
4093 if (get_hp_pin_presence(codec, 0x0a)) {
4094 stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
4095 stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
4097 stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
4098 stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
4102 static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res)
4104 switch (res >> 26) {
4106 stac9872_vaio_hp_detect(codec, res);
4111 static struct hda_codec_ops stac9872_vaio_patch_ops = {
4112 .build_controls = stac92xx_build_controls,
4113 .build_pcms = stac92xx_build_pcms,
4114 .init = stac9872_vaio_init,
4115 .free = stac92xx_free,
4116 .unsol_event = stac9872_vaio_unsol_event,
4118 .resume = stac92xx_resume,
4122 enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */
4124 /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */
4126 /* Unknown. id=0x83847661 and subsys=0x104D1200. */
4128 /* AR Series. id=0x83847664 and subsys=104D1300 */
4133 static const char *stac9872_models[STAC_9872_MODELS] = {
4134 [CXD9872RD_VAIO] = "vaio",
4135 [CXD9872AKD_VAIO] = "vaio-ar",
4138 static struct snd_pci_quirk stac9872_cfg_tbl[] = {
4139 SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
4140 SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
4141 SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
4142 SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO),
4146 static int patch_stac9872(struct hda_codec *codec)
4148 struct sigmatel_spec *spec;
4151 board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
4154 if (board_config < 0)
4155 /* unknown config, let generic-parser do its job... */
4156 return snd_hda_parse_generic_codec(codec);
4158 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4163 switch (board_config) {
4164 case CXD9872RD_VAIO:
4165 case STAC9872AK_VAIO:
4166 case STAC9872K_VAIO:
4167 spec->mixer = vaio_mixer;
4168 spec->init = vaio_init;
4169 spec->multiout.max_channels = 2;
4170 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
4171 spec->multiout.dac_nids = vaio_dacs;
4172 spec->multiout.hp_nid = VAIO_HP_DAC;
4173 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
4174 spec->adc_nids = vaio_adcs;
4176 spec->input_mux = &vaio_mux;
4177 spec->mux_nids = vaio_mux_nids;
4178 codec->patch_ops = stac9872_vaio_patch_ops;
4181 case CXD9872AKD_VAIO:
4182 spec->mixer = vaio_ar_mixer;
4183 spec->init = vaio_ar_init;
4184 spec->multiout.max_channels = 2;
4185 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
4186 spec->multiout.dac_nids = vaio_dacs;
4187 spec->multiout.hp_nid = VAIO_HP_DAC;
4188 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
4190 spec->adc_nids = vaio_adcs;
4191 spec->input_mux = &vaio_mux;
4192 spec->mux_nids = vaio_mux_nids;
4193 codec->patch_ops = stac9872_patch_ops;
4204 struct hda_codec_preset snd_hda_preset_sigmatel[] = {
4205 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
4206 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
4207 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
4208 { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x },
4209 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
4210 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
4211 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
4212 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x },
4213 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x },
4214 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x },
4215 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x },
4216 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x },
4217 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x },
4218 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
4219 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
4220 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
4221 { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x },
4222 { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x },
4223 { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x },
4224 { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x },
4225 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x },
4226 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x },
4227 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x },
4228 { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x },
4229 { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x },
4230 { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x },
4231 { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
4232 { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
4233 { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
4234 /* The following does not take into account .id=0x83847661 when subsys =
4235 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
4236 * currently not fully supported.
4238 { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 },
4239 { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 },
4240 { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 },
4241 { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 },
4242 { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 },
4243 { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 },
4244 { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 },
4245 { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 },
4246 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
4247 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
4248 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
4249 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
4250 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },
4251 { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx },
4252 { .id = 0x111d7608, .name = "92HD71BXX", .patch = patch_stac92hd71bxx },
4253 { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
4254 { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
4255 { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
4256 { .id = 0x111d76b3, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
4257 { .id = 0x111d76b4, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
4258 { .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
4259 { .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
4260 { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },