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
96 /* for backward compatibility */
119 struct sigmatel_spec {
120 struct snd_kcontrol_new *mixers[4];
121 unsigned int num_mixers;
124 unsigned int surr_switch: 1;
125 unsigned int line_switch: 1;
126 unsigned int mic_switch: 1;
127 unsigned int alt_switch: 1;
128 unsigned int hp_detect: 1;
131 unsigned int gpio_mask;
132 unsigned int gpio_dir;
133 unsigned int gpio_data;
134 unsigned int gpio_mute;
136 /* analog loopback */
137 unsigned char aloopback_mask;
138 unsigned char aloopback_shift;
140 /* power management */
141 unsigned int num_pwrs;
146 struct hda_input_mux *mono_mux;
147 unsigned int cur_mmux;
148 struct hda_multi_out multiout;
149 hda_nid_t dac_nids[5];
153 unsigned int num_adcs;
155 unsigned int num_muxes;
156 hda_nid_t *dmic_nids;
157 unsigned int num_dmics;
158 hda_nid_t *dmux_nids;
159 unsigned int num_dmuxes;
160 hda_nid_t dig_in_nid;
165 unsigned int num_pins;
166 unsigned int *pin_configs;
167 unsigned int *bios_pin_configs;
169 /* codec specific stuff */
170 struct hda_verb *init;
171 struct snd_kcontrol_new *mixer;
174 struct hda_input_mux *dinput_mux;
175 unsigned int cur_dmux[2];
176 struct hda_input_mux *input_mux;
177 unsigned int cur_mux[3];
180 unsigned int io_switch[2];
181 unsigned int clfe_swap;
182 unsigned int aloopback;
184 struct hda_pcm pcm_rec[2]; /* PCM information */
186 /* dynamic controls and input_mux */
187 struct auto_pin_cfg autocfg;
188 unsigned int num_kctl_alloc, num_kctl_used;
189 struct snd_kcontrol_new *kctl_alloc;
190 struct hda_input_mux private_dimux;
191 struct hda_input_mux private_imux;
192 struct hda_input_mux private_mono_mux;
195 static hda_nid_t stac9200_adc_nids[1] = {
199 static hda_nid_t stac9200_mux_nids[1] = {
203 static hda_nid_t stac9200_dac_nids[1] = {
207 static hda_nid_t stac92hd73xx_pwr_nids[8] = {
208 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
212 static hda_nid_t stac92hd73xx_adc_nids[2] = {
216 #define STAC92HD73XX_NUM_DMICS 2
217 static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
221 #define STAC92HD73_DAC_COUNT 5
222 static hda_nid_t stac92hd73xx_dac_nids[STAC92HD73_DAC_COUNT] = {
223 0x15, 0x16, 0x17, 0x18, 0x19,
226 static hda_nid_t stac92hd73xx_mux_nids[4] = {
227 0x28, 0x29, 0x2a, 0x2b,
230 static hda_nid_t stac92hd73xx_dmux_nids[2] = {
234 static hda_nid_t stac92hd71bxx_pwr_nids[3] = {
238 static hda_nid_t stac92hd71bxx_adc_nids[2] = {
242 static hda_nid_t stac92hd71bxx_mux_nids[2] = {
246 static hda_nid_t stac92hd71bxx_dmux_nids[1] = {
250 static hda_nid_t stac92hd71bxx_dac_nids[1] = {
254 #define STAC92HD71BXX_NUM_DMICS 2
255 static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
259 static hda_nid_t stac925x_adc_nids[1] = {
263 static hda_nid_t stac925x_mux_nids[1] = {
267 static hda_nid_t stac925x_dac_nids[1] = {
271 #define STAC925X_NUM_DMICS 1
272 static hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = {
276 static hda_nid_t stac925x_dmux_nids[1] = {
280 static hda_nid_t stac922x_adc_nids[2] = {
284 static hda_nid_t stac922x_mux_nids[2] = {
288 static hda_nid_t stac927x_adc_nids[3] = {
292 static hda_nid_t stac927x_mux_nids[3] = {
296 static hda_nid_t stac927x_dac_nids[6] = {
297 0x02, 0x03, 0x04, 0x05, 0x06, 0
300 static hda_nid_t stac927x_dmux_nids[1] = {
304 #define STAC927X_NUM_DMICS 2
305 static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = {
309 static hda_nid_t stac9205_adc_nids[2] = {
313 static hda_nid_t stac9205_mux_nids[2] = {
317 static hda_nid_t stac9205_dmux_nids[1] = {
321 #define STAC9205_NUM_DMICS 2
322 static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
326 static hda_nid_t stac9200_pin_nids[8] = {
327 0x08, 0x09, 0x0d, 0x0e,
328 0x0f, 0x10, 0x11, 0x12,
331 static hda_nid_t stac925x_pin_nids[8] = {
332 0x07, 0x08, 0x0a, 0x0b,
333 0x0c, 0x0d, 0x10, 0x11,
336 static hda_nid_t stac922x_pin_nids[10] = {
337 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
338 0x0f, 0x10, 0x11, 0x15, 0x1b,
341 static hda_nid_t stac92hd73xx_pin_nids[13] = {
342 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
343 0x0f, 0x10, 0x11, 0x12, 0x13,
347 static hda_nid_t stac92hd71bxx_pin_nids[10] = {
348 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
349 0x0f, 0x14, 0x18, 0x19, 0x1e,
352 static hda_nid_t stac927x_pin_nids[14] = {
353 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
354 0x0f, 0x10, 0x11, 0x12, 0x13,
355 0x14, 0x21, 0x22, 0x23,
358 static hda_nid_t stac9205_pin_nids[12] = {
359 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
360 0x0f, 0x14, 0x16, 0x17, 0x18,
364 static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
365 struct snd_ctl_elem_info *uinfo)
367 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
368 struct sigmatel_spec *spec = codec->spec;
369 return snd_hda_input_mux_info(spec->dinput_mux, uinfo);
372 static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol,
373 struct snd_ctl_elem_value *ucontrol)
375 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
376 struct sigmatel_spec *spec = codec->spec;
377 unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
379 ucontrol->value.enumerated.item[0] = spec->cur_dmux[dmux_idx];
383 static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
384 struct snd_ctl_elem_value *ucontrol)
386 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
387 struct sigmatel_spec *spec = codec->spec;
388 unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
390 return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol,
391 spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]);
394 static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
396 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
397 struct sigmatel_spec *spec = codec->spec;
398 return snd_hda_input_mux_info(spec->input_mux, uinfo);
401 static int stac92xx_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
403 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
404 struct sigmatel_spec *spec = codec->spec;
405 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
407 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
411 static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
413 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
414 struct sigmatel_spec *spec = codec->spec;
415 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
417 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
418 spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]);
421 static int stac92xx_mono_mux_enum_info(struct snd_kcontrol *kcontrol,
422 struct snd_ctl_elem_info *uinfo)
424 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
425 struct sigmatel_spec *spec = codec->spec;
426 return snd_hda_input_mux_info(spec->mono_mux, uinfo);
429 static int stac92xx_mono_mux_enum_get(struct snd_kcontrol *kcontrol,
430 struct snd_ctl_elem_value *ucontrol)
432 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
433 struct sigmatel_spec *spec = codec->spec;
435 ucontrol->value.enumerated.item[0] = spec->cur_mmux;
439 static int stac92xx_mono_mux_enum_put(struct snd_kcontrol *kcontrol,
440 struct snd_ctl_elem_value *ucontrol)
442 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
443 struct sigmatel_spec *spec = codec->spec;
445 return snd_hda_input_mux_put(codec, spec->mono_mux, ucontrol,
446 spec->mono_nid, &spec->cur_mmux);
449 #define stac92xx_aloopback_info snd_ctl_boolean_mono_info
451 static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol,
452 struct snd_ctl_elem_value *ucontrol)
454 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
455 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
456 struct sigmatel_spec *spec = codec->spec;
458 ucontrol->value.integer.value[0] = !!(spec->aloopback &
459 (spec->aloopback_mask << idx));
463 static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol,
464 struct snd_ctl_elem_value *ucontrol)
466 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
467 struct sigmatel_spec *spec = codec->spec;
468 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
469 unsigned int dac_mode;
470 unsigned int val, idx_val;
472 idx_val = spec->aloopback_mask << idx;
473 if (ucontrol->value.integer.value[0])
474 val = spec->aloopback | idx_val;
476 val = spec->aloopback & ~idx_val;
477 if (spec->aloopback == val)
480 spec->aloopback = val;
482 /* Only return the bits defined by the shift value of the
483 * first two bytes of the mask
485 dac_mode = snd_hda_codec_read(codec, codec->afg, 0,
486 kcontrol->private_value & 0xFFFF, 0x0);
487 dac_mode >>= spec->aloopback_shift;
489 if (spec->aloopback & idx_val) {
490 snd_hda_power_up(codec);
493 snd_hda_power_down(codec);
494 dac_mode &= ~idx_val;
497 snd_hda_codec_write_cache(codec, codec->afg, 0,
498 kcontrol->private_value >> 16, dac_mode);
503 static struct hda_verb stac9200_core_init[] = {
504 /* set dac0mux for dac converter */
505 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
509 static struct hda_verb stac9200_eapd_init[] = {
510 /* set dac0mux for dac converter */
511 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
512 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
516 static struct hda_verb stac92hd73xx_6ch_core_init[] = {
517 /* set master volume and direct control */
518 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
519 /* setup audio connections */
520 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
521 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
522 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
523 /* setup adcs to point to mixer */
524 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
525 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
526 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
527 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
528 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
529 /* setup import muxs */
530 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
531 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
532 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
533 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00},
537 static struct hda_verb dell_eq_core_init[] = {
538 /* set master volume to max value without distortion
539 * and direct control */
540 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
541 /* setup audio connections */
542 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
543 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
544 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02},
545 /* setup adcs to point to mixer */
546 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
547 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
548 /* setup import muxs */
549 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
550 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
551 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
552 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00},
556 static struct hda_verb dell_m6_core_init[] = {
557 /* set master volume and direct control */
558 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
559 /* setup audio connections */
560 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
561 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
562 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02},
563 /* setup adcs to point to mixer */
564 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
565 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
566 /* setup import muxs */
567 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
568 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
569 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
570 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00},
574 static struct hda_verb stac92hd73xx_8ch_core_init[] = {
575 /* set master volume and direct control */
576 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
577 /* setup audio connections */
578 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
579 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
580 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
581 /* connect hp ports to dac3 */
582 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x03},
583 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x03},
584 /* setup adcs to point to mixer */
585 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
586 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
587 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
588 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
589 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
590 /* setup import muxs */
591 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
592 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
593 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
594 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x03},
598 static struct hda_verb stac92hd73xx_10ch_core_init[] = {
599 /* set master volume and direct control */
600 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
601 /* setup audio connections */
602 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
603 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01 },
604 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02 },
605 /* dac3 is connected to import3 mux */
606 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f},
607 /* connect hp ports to dac4 */
608 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x04},
609 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x04},
610 /* setup adcs to point to mixer */
611 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
612 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
613 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
614 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
615 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
616 /* setup import muxs */
617 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
618 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
619 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
620 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x03},
624 static struct hda_verb stac92hd71bxx_core_init[] = {
625 /* set master volume and direct control */
626 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
627 /* connect headphone jack to dac1 */
628 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
629 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */
630 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */
631 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
632 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
633 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
636 static struct hda_verb stac92hd71bxx_analog_core_init[] = {
637 /* set master volume and direct control */
638 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
639 /* connect headphone jack to dac1 */
640 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
641 /* connect ports 0d and 0f to audio mixer */
642 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x2},
643 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2},
644 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */
645 /* unmute dac0 input in audio mixer */
646 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
647 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */
648 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
649 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
650 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
654 static struct hda_verb stac925x_core_init[] = {
655 /* set dac0mux for dac converter */
656 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
660 static struct hda_verb stac922x_core_init[] = {
661 /* set master volume and direct control */
662 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
666 static struct hda_verb d965_core_init[] = {
667 /* set master volume and direct control */
668 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
669 /* unmute node 0x1b */
670 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
671 /* select node 0x03 as DAC */
672 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
676 static struct hda_verb stac927x_core_init[] = {
677 /* set master volume and direct control */
678 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
682 static struct hda_verb stac9205_core_init[] = {
683 /* set master volume and direct control */
684 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
688 #define STAC_MONO_MUX \
690 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
691 .name = "Mono Mux", \
693 .info = stac92xx_mono_mux_enum_info, \
694 .get = stac92xx_mono_mux_enum_get, \
695 .put = stac92xx_mono_mux_enum_put, \
698 #define STAC_INPUT_SOURCE(cnt) \
700 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
701 .name = "Input Source", \
703 .info = stac92xx_mux_enum_info, \
704 .get = stac92xx_mux_enum_get, \
705 .put = stac92xx_mux_enum_put, \
708 #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \
710 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
711 .name = "Analog Loopback", \
713 .info = stac92xx_aloopback_info, \
714 .get = stac92xx_aloopback_get, \
715 .put = stac92xx_aloopback_put, \
716 .private_value = verb_read | (verb_write << 16), \
719 static struct snd_kcontrol_new stac9200_mixer[] = {
720 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
721 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
722 STAC_INPUT_SOURCE(1),
723 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
724 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
725 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT),
729 static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = {
730 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3),
732 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
733 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
735 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
736 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
738 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
739 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
741 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
742 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
744 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
745 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
747 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
748 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
750 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
751 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
755 static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = {
756 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4),
758 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
759 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
761 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
762 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
764 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
765 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
767 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
768 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
770 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
771 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
773 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
774 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
776 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
777 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
781 static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = {
782 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5),
784 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
785 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
787 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
788 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
790 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
791 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
793 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
794 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
796 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
797 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
799 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
800 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
802 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
803 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
807 static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = {
808 STAC_INPUT_SOURCE(2),
810 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
811 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
812 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x0, 0x1a, 0x0, HDA_OUTPUT),
814 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT),
815 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
816 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT),
818 HDA_CODEC_MUTE("Analog Loopback 1", 0x17, 0x3, HDA_INPUT),
819 HDA_CODEC_MUTE("Analog Loopback 2", 0x17, 0x4, HDA_INPUT),
823 static struct snd_kcontrol_new stac92hd71bxx_mixer[] = {
824 STAC_INPUT_SOURCE(2),
825 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2),
827 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
828 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
829 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x0, 0x1a, 0x0, HDA_OUTPUT),
831 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT),
832 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
833 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT),
837 static struct snd_kcontrol_new stac925x_mixer[] = {
838 STAC_INPUT_SOURCE(1),
839 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
840 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT),
841 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT),
845 static struct snd_kcontrol_new stac9205_mixer[] = {
846 STAC_INPUT_SOURCE(2),
847 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1),
849 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT),
850 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT),
851 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x19, 0x0, HDA_OUTPUT),
853 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT),
854 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT),
855 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x1A, 0x0, HDA_OUTPUT),
860 /* This needs to be generated dynamically based on sequence */
861 static struct snd_kcontrol_new stac922x_mixer[] = {
862 STAC_INPUT_SOURCE(2),
863 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT),
864 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT),
865 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x12, 0x0, HDA_OUTPUT),
867 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT),
868 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT),
869 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x13, 0x0, HDA_OUTPUT),
874 static struct snd_kcontrol_new stac927x_mixer[] = {
875 STAC_INPUT_SOURCE(3),
876 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1),
878 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT),
879 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT),
880 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x15, 0x0, HDA_OUTPUT),
882 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT),
883 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT),
884 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x16, 0x0, HDA_OUTPUT),
886 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT),
887 HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT),
888 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x2, 0x17, 0x0, HDA_OUTPUT),
892 static struct snd_kcontrol_new stac_dmux_mixer = {
893 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
894 .name = "Digital Input Source",
895 /* count set later */
896 .info = stac92xx_dmux_enum_info,
897 .get = stac92xx_dmux_enum_get,
898 .put = stac92xx_dmux_enum_put,
901 static const char *slave_vols[] = {
902 "Front Playback Volume",
903 "Surround Playback Volume",
904 "Center Playback Volume",
905 "LFE Playback Volume",
906 "Side Playback Volume",
907 "Headphone Playback Volume",
908 "Headphone Playback Volume",
909 "Speaker Playback Volume",
910 "External Speaker Playback Volume",
911 "Speaker2 Playback Volume",
915 static const char *slave_sws[] = {
916 "Front Playback Switch",
917 "Surround Playback Switch",
918 "Center Playback Switch",
919 "LFE Playback Switch",
920 "Side Playback Switch",
921 "Headphone Playback Switch",
922 "Headphone Playback Switch",
923 "Speaker Playback Switch",
924 "External Speaker Playback Switch",
925 "Speaker2 Playback Switch",
926 "IEC958 Playback Switch",
930 static int stac92xx_build_controls(struct hda_codec *codec)
932 struct sigmatel_spec *spec = codec->spec;
936 err = snd_hda_add_new_ctls(codec, spec->mixer);
940 for (i = 0; i < spec->num_mixers; i++) {
941 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
945 if (spec->num_dmuxes > 0) {
946 stac_dmux_mixer.count = spec->num_dmuxes;
947 err = snd_ctl_add(codec->bus->card,
948 snd_ctl_new1(&stac_dmux_mixer, codec));
953 if (spec->multiout.dig_out_nid) {
954 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
957 err = snd_hda_create_spdif_share_sw(codec,
961 spec->multiout.share_spdif = 1;
963 if (spec->dig_in_nid) {
964 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
969 /* if we have no master control, let's create it */
970 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
971 unsigned int vmaster_tlv[4];
972 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
973 HDA_OUTPUT, vmaster_tlv);
974 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
975 vmaster_tlv, slave_vols);
979 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
980 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
989 static unsigned int ref9200_pin_configs[8] = {
990 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
991 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
995 STAC 9200 pin configs for
1000 static unsigned int dell9200_d21_pin_configs[8] = {
1001 0x400001f0, 0x400001f1, 0x02214030, 0x01014010,
1002 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
1006 STAC 9200 pin configs for
1010 static unsigned int dell9200_d22_pin_configs[8] = {
1011 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
1012 0x01813020, 0x02a19021, 0x90100140, 0x400001f2,
1016 STAC 9200 pin configs for
1017 102801C4 (Dell Dimension E310)
1024 static unsigned int dell9200_d23_pin_configs[8] = {
1025 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
1026 0x01813020, 0x01a19021, 0x90100140, 0x400001f2,
1031 STAC 9200-32 pin configs for
1032 102801B5 (Dell Inspiron 630m)
1033 102801D8 (Dell Inspiron 640m)
1035 static unsigned int dell9200_m21_pin_configs[8] = {
1036 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310,
1037 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd,
1041 STAC 9200-32 pin configs for
1042 102801C2 (Dell Latitude D620)
1044 102801CC (Dell Latitude D820)
1048 static unsigned int dell9200_m22_pin_configs[8] = {
1049 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310,
1050 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc,
1054 STAC 9200-32 pin configs for
1055 102801CE (Dell XPS M1710)
1056 102801CF (Dell Precision M90)
1058 static unsigned int dell9200_m23_pin_configs[8] = {
1059 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310,
1060 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc,
1064 STAC 9200-32 pin configs for
1067 102801CB (Dell Latitude 120L)
1070 static unsigned int dell9200_m24_pin_configs[8] = {
1071 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310,
1072 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe,
1076 STAC 9200-32 pin configs for
1077 102801BD (Dell Inspiron E1505n)
1081 static unsigned int dell9200_m25_pin_configs[8] = {
1082 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
1083 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd,
1087 STAC 9200-32 pin configs for
1088 102801F5 (Dell Inspiron 1501)
1091 static unsigned int dell9200_m26_pin_configs[8] = {
1092 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310,
1093 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe,
1098 102801CD (Dell Inspiron E1705/9400)
1100 static unsigned int dell9200_m27_pin_configs[8] = {
1101 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
1102 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc,
1105 static unsigned int oqo9200_pin_configs[8] = {
1106 0x40c000f0, 0x404000f1, 0x0221121f, 0x02211210,
1107 0x90170111, 0x90a70120, 0x400000f2, 0x400000f3,
1111 static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
1112 [STAC_REF] = ref9200_pin_configs,
1113 [STAC_9200_OQO] = oqo9200_pin_configs,
1114 [STAC_9200_DELL_D21] = dell9200_d21_pin_configs,
1115 [STAC_9200_DELL_D22] = dell9200_d22_pin_configs,
1116 [STAC_9200_DELL_D23] = dell9200_d23_pin_configs,
1117 [STAC_9200_DELL_M21] = dell9200_m21_pin_configs,
1118 [STAC_9200_DELL_M22] = dell9200_m22_pin_configs,
1119 [STAC_9200_DELL_M23] = dell9200_m23_pin_configs,
1120 [STAC_9200_DELL_M24] = dell9200_m24_pin_configs,
1121 [STAC_9200_DELL_M25] = dell9200_m25_pin_configs,
1122 [STAC_9200_DELL_M26] = dell9200_m26_pin_configs,
1123 [STAC_9200_DELL_M27] = dell9200_m27_pin_configs,
1126 static const char *stac9200_models[STAC_9200_MODELS] = {
1128 [STAC_9200_OQO] = "oqo",
1129 [STAC_9200_DELL_D21] = "dell-d21",
1130 [STAC_9200_DELL_D22] = "dell-d22",
1131 [STAC_9200_DELL_D23] = "dell-d23",
1132 [STAC_9200_DELL_M21] = "dell-m21",
1133 [STAC_9200_DELL_M22] = "dell-m22",
1134 [STAC_9200_DELL_M23] = "dell-m23",
1135 [STAC_9200_DELL_M24] = "dell-m24",
1136 [STAC_9200_DELL_M25] = "dell-m25",
1137 [STAC_9200_DELL_M26] = "dell-m26",
1138 [STAC_9200_DELL_M27] = "dell-m27",
1139 [STAC_9200_GATEWAY] = "gateway",
1142 static struct snd_pci_quirk stac9200_cfg_tbl[] = {
1143 /* SigmaTel reference board */
1144 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1145 "DFI LanParty", STAC_REF),
1146 /* Dell laptops have BIOS problem */
1147 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
1148 "unknown Dell", STAC_9200_DELL_D21),
1149 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
1150 "Dell Inspiron 630m", STAC_9200_DELL_M21),
1151 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
1152 "Dell Inspiron E1505n", STAC_9200_DELL_M25),
1153 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
1154 "unknown Dell", STAC_9200_DELL_D22),
1155 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
1156 "unknown Dell", STAC_9200_DELL_D22),
1157 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
1158 "Dell Latitude D620", STAC_9200_DELL_M22),
1159 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
1160 "unknown Dell", STAC_9200_DELL_D23),
1161 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
1162 "unknown Dell", STAC_9200_DELL_D23),
1163 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
1164 "unknown Dell", STAC_9200_DELL_M22),
1165 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
1166 "unknown Dell", STAC_9200_DELL_M24),
1167 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
1168 "unknown Dell", STAC_9200_DELL_M24),
1169 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
1170 "Dell Latitude 120L", STAC_9200_DELL_M24),
1171 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
1172 "Dell Latitude D820", STAC_9200_DELL_M22),
1173 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
1174 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
1175 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
1176 "Dell XPS M1710", STAC_9200_DELL_M23),
1177 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
1178 "Dell Precision M90", STAC_9200_DELL_M23),
1179 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
1180 "unknown Dell", STAC_9200_DELL_M22),
1181 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
1182 "unknown Dell", STAC_9200_DELL_M22),
1183 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
1184 "unknown Dell", STAC_9200_DELL_M22),
1185 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
1186 "Dell Inspiron 640m", STAC_9200_DELL_M21),
1187 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
1188 "unknown Dell", STAC_9200_DELL_D23),
1189 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
1190 "unknown Dell", STAC_9200_DELL_D23),
1191 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
1192 "unknown Dell", STAC_9200_DELL_D21),
1193 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
1194 "unknown Dell", STAC_9200_DELL_D23),
1195 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
1196 "unknown Dell", STAC_9200_DELL_D21),
1197 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
1198 "unknown Dell", STAC_9200_DELL_M25),
1199 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
1200 "unknown Dell", STAC_9200_DELL_M25),
1201 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
1202 "Dell Inspiron 1501", STAC_9200_DELL_M26),
1203 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
1204 "unknown Dell", STAC_9200_DELL_M26),
1206 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_REF),
1207 /* Gateway machines needs EAPD to be set on resume */
1208 SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY),
1209 SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*",
1211 SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707",
1214 SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO),
1218 static unsigned int ref925x_pin_configs[8] = {
1219 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
1220 0x90a70320, 0x02214210, 0x01019020, 0x9033032e,
1223 static unsigned int stac925x_MA6_pin_configs[8] = {
1224 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
1225 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e,
1228 static unsigned int stac925x_PA6_pin_configs[8] = {
1229 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
1230 0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e,
1233 static unsigned int stac925xM2_2_pin_configs[8] = {
1234 0x40c003f3, 0x424503f2, 0x04180011, 0x02a19020,
1235 0x50a103f0, 0x90100212, 0x400003f1, 0x9033032e,
1238 static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
1239 [STAC_REF] = ref925x_pin_configs,
1240 [STAC_M2_2] = stac925xM2_2_pin_configs,
1241 [STAC_MA6] = stac925x_MA6_pin_configs,
1242 [STAC_PA6] = stac925x_PA6_pin_configs,
1245 static const char *stac925x_models[STAC_925x_MODELS] = {
1247 [STAC_M2_2] = "m2-2",
1252 static struct snd_pci_quirk stac925x_cfg_tbl[] = {
1253 /* SigmaTel reference board */
1254 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
1255 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
1256 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF),
1257 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF),
1258 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6),
1259 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_PA6),
1260 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2),
1264 static unsigned int ref92hd73xx_pin_configs[13] = {
1265 0x02214030, 0x02a19040, 0x01a19020, 0x02214030,
1266 0x0181302e, 0x01014010, 0x01014020, 0x01014030,
1267 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050,
1271 static unsigned int dell_m6_pin_configs[13] = {
1272 0x0321101f, 0x4f00000f, 0x4f0000f0, 0x90170110,
1273 0x03a11020, 0x03011050, 0x4f0000f0, 0x4f0000f0,
1274 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0,
1278 static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
1279 [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs,
1280 [STAC_DELL_M6] = dell_m6_pin_configs,
1283 static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
1284 [STAC_92HD73XX_REF] = "ref",
1285 [STAC_DELL_M6] = "dell-m6",
1288 static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
1289 /* SigmaTel reference board */
1290 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1291 "DFI LanParty", STAC_92HD73XX_REF),
1292 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254,
1293 "unknown Dell", STAC_DELL_M6),
1294 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255,
1295 "unknown Dell", STAC_DELL_M6),
1296 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256,
1297 "unknown Dell", STAC_DELL_M6),
1298 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257,
1299 "unknown Dell", STAC_DELL_M6),
1300 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e,
1301 "unknown Dell", STAC_DELL_M6),
1302 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f,
1303 "unknown Dell", STAC_DELL_M6),
1304 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271,
1305 "unknown Dell", STAC_DELL_M6),
1309 static unsigned int ref92hd71bxx_pin_configs[10] = {
1310 0x02214030, 0x02a19040, 0x01a19020, 0x01014010,
1311 0x0181302e, 0x01114010, 0x01019020, 0x90a000f0,
1312 0x90a000f0, 0x01452050,
1315 static unsigned int dell_m4_1_pin_configs[13] = {
1316 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110,
1317 0x23a1902e, 0x23014250, 0x40f000f0, 0x4f0000f0,
1318 0x40f000f0, 0x4f0000f0,
1321 static unsigned int dell_m4_2_pin_configs[13] = {
1322 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110,
1323 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0,
1324 0x40f000f0, 0x044413b0,
1327 static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
1328 [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs,
1329 [STAC_DELL_M4_1] = dell_m4_1_pin_configs,
1330 [STAC_DELL_M4_2] = dell_m4_2_pin_configs,
1333 static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
1334 [STAC_92HD71BXX_REF] = "ref",
1335 [STAC_DELL_M4_1] = "dell-m4-1",
1336 [STAC_DELL_M4_2] = "dell-m4-2",
1339 static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1340 /* SigmaTel reference board */
1341 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1342 "DFI LanParty", STAC_92HD71BXX_REF),
1343 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
1344 "unknown Dell", STAC_DELL_M4_1),
1345 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234,
1346 "unknown Dell", STAC_DELL_M4_1),
1347 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0250,
1348 "unknown Dell", STAC_DELL_M4_1),
1349 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024f,
1350 "unknown Dell", STAC_DELL_M4_1),
1351 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024d,
1352 "unknown Dell", STAC_DELL_M4_1),
1353 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0251,
1354 "unknown Dell", STAC_DELL_M4_1),
1355 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0277,
1356 "unknown Dell", STAC_DELL_M4_1),
1357 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0263,
1358 "unknown Dell", STAC_DELL_M4_2),
1359 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0265,
1360 "unknown Dell", STAC_DELL_M4_2),
1361 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0262,
1362 "unknown Dell", STAC_DELL_M4_2),
1363 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264,
1364 "unknown Dell", STAC_DELL_M4_2),
1368 static unsigned int ref922x_pin_configs[10] = {
1369 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
1370 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
1371 0x40000100, 0x40000100,
1375 STAC 922X pin configs for
1382 static unsigned int dell_922x_d81_pin_configs[10] = {
1383 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
1384 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1,
1385 0x01813122, 0x400001f2,
1389 STAC 922X pin configs for
1393 static unsigned int dell_922x_d82_pin_configs[10] = {
1394 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
1395 0x02a19020, 0x01117011, 0x01451140, 0x400001f0,
1396 0x01813122, 0x400001f1,
1400 STAC 922X pin configs for
1403 static unsigned int dell_922x_m81_pin_configs[10] = {
1404 0x0321101f, 0x01112024, 0x01111222, 0x91174220,
1405 0x03a11050, 0x01116221, 0x90a70330, 0x01452340,
1406 0x40C003f1, 0x405003f0,
1410 STAC 9221 A1 pin configs for
1411 102801D7 (Dell XPS M1210)
1413 static unsigned int dell_922x_m82_pin_configs[10] = {
1414 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310,
1415 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2,
1416 0x508003f3, 0x405003f4,
1419 static unsigned int d945gtp3_pin_configs[10] = {
1420 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
1421 0x40000100, 0x40000100, 0x40000100, 0x40000100,
1422 0x02a19120, 0x40000100,
1425 static unsigned int d945gtp5_pin_configs[10] = {
1426 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
1427 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
1428 0x02a19320, 0x40000100,
1431 static unsigned int intel_mac_v1_pin_configs[10] = {
1432 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd,
1433 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240,
1434 0x400000fc, 0x400000fb,
1437 static unsigned int intel_mac_v2_pin_configs[10] = {
1438 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
1439 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa,
1440 0x400000fc, 0x400000fb,
1443 static unsigned int intel_mac_v3_pin_configs[10] = {
1444 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
1445 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240,
1446 0x400000fc, 0x400000fb,
1449 static unsigned int intel_mac_v4_pin_configs[10] = {
1450 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
1451 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
1452 0x400000fc, 0x400000fb,
1455 static unsigned int intel_mac_v5_pin_configs[10] = {
1456 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
1457 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
1458 0x400000fc, 0x400000fb,
1462 static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
1463 [STAC_D945_REF] = ref922x_pin_configs,
1464 [STAC_D945GTP3] = d945gtp3_pin_configs,
1465 [STAC_D945GTP5] = d945gtp5_pin_configs,
1466 [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs,
1467 [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs,
1468 [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs,
1469 [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs,
1470 [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs,
1471 /* for backward compatibility */
1472 [STAC_MACMINI] = intel_mac_v3_pin_configs,
1473 [STAC_MACBOOK] = intel_mac_v5_pin_configs,
1474 [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs,
1475 [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs,
1476 [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs,
1477 [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs,
1478 [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs,
1479 [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs,
1480 [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs,
1481 [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs,
1484 static const char *stac922x_models[STAC_922X_MODELS] = {
1485 [STAC_D945_REF] = "ref",
1486 [STAC_D945GTP5] = "5stack",
1487 [STAC_D945GTP3] = "3stack",
1488 [STAC_INTEL_MAC_V1] = "intel-mac-v1",
1489 [STAC_INTEL_MAC_V2] = "intel-mac-v2",
1490 [STAC_INTEL_MAC_V3] = "intel-mac-v3",
1491 [STAC_INTEL_MAC_V4] = "intel-mac-v4",
1492 [STAC_INTEL_MAC_V5] = "intel-mac-v5",
1493 /* for backward compatibility */
1494 [STAC_MACMINI] = "macmini",
1495 [STAC_MACBOOK] = "macbook",
1496 [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1",
1497 [STAC_MACBOOK_PRO_V2] = "macbook-pro",
1498 [STAC_IMAC_INTEL] = "imac-intel",
1499 [STAC_IMAC_INTEL_20] = "imac-intel-20",
1500 [STAC_922X_DELL_D81] = "dell-d81",
1501 [STAC_922X_DELL_D82] = "dell-d82",
1502 [STAC_922X_DELL_M81] = "dell-m81",
1503 [STAC_922X_DELL_M82] = "dell-m82",
1506 static struct snd_pci_quirk stac922x_cfg_tbl[] = {
1507 /* SigmaTel reference board */
1508 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1509 "DFI LanParty", STAC_D945_REF),
1510 /* Intel 945G based systems */
1511 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
1512 "Intel D945G", STAC_D945GTP3),
1513 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
1514 "Intel D945G", STAC_D945GTP3),
1515 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
1516 "Intel D945G", STAC_D945GTP3),
1517 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
1518 "Intel D945G", STAC_D945GTP3),
1519 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
1520 "Intel D945G", STAC_D945GTP3),
1521 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
1522 "Intel D945G", STAC_D945GTP3),
1523 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
1524 "Intel D945G", STAC_D945GTP3),
1525 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
1526 "Intel D945G", STAC_D945GTP3),
1527 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
1528 "Intel D945G", STAC_D945GTP3),
1529 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
1530 "Intel D945G", STAC_D945GTP3),
1531 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
1532 "Intel D945G", STAC_D945GTP3),
1533 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
1534 "Intel D945G", STAC_D945GTP3),
1535 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
1536 "Intel D945G", STAC_D945GTP3),
1537 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
1538 "Intel D945G", STAC_D945GTP3),
1539 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
1540 "Intel D945G", STAC_D945GTP3),
1541 /* Intel D945G 5-stack systems */
1542 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
1543 "Intel D945G", STAC_D945GTP5),
1544 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
1545 "Intel D945G", STAC_D945GTP5),
1546 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
1547 "Intel D945G", STAC_D945GTP5),
1548 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
1549 "Intel D945G", STAC_D945GTP5),
1550 /* Intel 945P based systems */
1551 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
1552 "Intel D945P", STAC_D945GTP3),
1553 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
1554 "Intel D945P", STAC_D945GTP3),
1555 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
1556 "Intel D945P", STAC_D945GTP3),
1557 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
1558 "Intel D945P", STAC_D945GTP3),
1559 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
1560 "Intel D945P", STAC_D945GTP3),
1561 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
1562 "Intel D945P", STAC_D945GTP5),
1564 /* Apple Mac Mini (early 2006) */
1565 SND_PCI_QUIRK(0x8384, 0x7680,
1566 "Mac Mini", STAC_INTEL_MAC_V3),
1568 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
1569 "unknown Dell", STAC_922X_DELL_D81),
1570 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
1571 "unknown Dell", STAC_922X_DELL_D81),
1572 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
1573 "unknown Dell", STAC_922X_DELL_D81),
1574 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
1575 "unknown Dell", STAC_922X_DELL_D82),
1576 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
1577 "unknown Dell", STAC_922X_DELL_M81),
1578 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
1579 "unknown Dell", STAC_922X_DELL_D82),
1580 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
1581 "unknown Dell", STAC_922X_DELL_D81),
1582 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
1583 "unknown Dell", STAC_922X_DELL_D81),
1584 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
1585 "Dell XPS M1210", STAC_922X_DELL_M82),
1589 static unsigned int ref927x_pin_configs[14] = {
1590 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1591 0x01a19040, 0x01011012, 0x01016011, 0x0101201f,
1592 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070,
1593 0x01c42190, 0x40000100,
1596 static unsigned int d965_3st_pin_configs[14] = {
1597 0x0221401f, 0x02a19120, 0x40000100, 0x01014011,
1598 0x01a19021, 0x01813024, 0x40000100, 0x40000100,
1599 0x40000100, 0x40000100, 0x40000100, 0x40000100,
1600 0x40000100, 0x40000100
1603 static unsigned int d965_5st_pin_configs[14] = {
1604 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1605 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
1606 0x40000100, 0x40000100, 0x40000100, 0x01442070,
1607 0x40000100, 0x40000100
1610 static unsigned int dell_3st_pin_configs[14] = {
1611 0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
1612 0x01111212, 0x01116211, 0x01813050, 0x01112214,
1613 0x403003fa, 0x90a60040, 0x90a60040, 0x404003fb,
1614 0x40c003fc, 0x40000100
1617 static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
1618 [STAC_D965_REF] = ref927x_pin_configs,
1619 [STAC_D965_3ST] = d965_3st_pin_configs,
1620 [STAC_D965_5ST] = d965_5st_pin_configs,
1621 [STAC_DELL_3ST] = dell_3st_pin_configs,
1622 [STAC_DELL_BIOS] = NULL,
1625 static const char *stac927x_models[STAC_927X_MODELS] = {
1626 [STAC_D965_REF] = "ref",
1627 [STAC_D965_3ST] = "3stack",
1628 [STAC_D965_5ST] = "5stack",
1629 [STAC_DELL_3ST] = "dell-3stack",
1630 [STAC_DELL_BIOS] = "dell-bios",
1633 static struct snd_pci_quirk stac927x_cfg_tbl[] = {
1634 /* SigmaTel reference board */
1635 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1636 "DFI LanParty", STAC_D965_REF),
1637 /* Intel 946 based systems */
1638 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
1639 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
1640 /* 965 based 3 stack systems */
1641 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2116, "Intel D965", STAC_D965_3ST),
1642 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2115, "Intel D965", STAC_D965_3ST),
1643 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2114, "Intel D965", STAC_D965_3ST),
1644 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2113, "Intel D965", STAC_D965_3ST),
1645 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2112, "Intel D965", STAC_D965_3ST),
1646 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2111, "Intel D965", STAC_D965_3ST),
1647 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2110, "Intel D965", STAC_D965_3ST),
1648 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2009, "Intel D965", STAC_D965_3ST),
1649 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2008, "Intel D965", STAC_D965_3ST),
1650 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2007, "Intel D965", STAC_D965_3ST),
1651 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2006, "Intel D965", STAC_D965_3ST),
1652 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2005, "Intel D965", STAC_D965_3ST),
1653 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2004, "Intel D965", STAC_D965_3ST),
1654 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST),
1655 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST),
1656 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST),
1657 /* Dell 3 stack systems */
1658 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_3ST),
1659 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
1660 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
1661 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
1662 /* Dell 3 stack systems with verb table in BIOS */
1663 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
1664 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
1665 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell ", STAC_DELL_BIOS),
1666 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS),
1667 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
1668 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
1669 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
1670 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS),
1671 /* 965 based 5 stack systems */
1672 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST),
1673 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST),
1674 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST),
1675 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2304, "Intel D965", STAC_D965_5ST),
1676 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2305, "Intel D965", STAC_D965_5ST),
1677 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2501, "Intel D965", STAC_D965_5ST),
1678 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2502, "Intel D965", STAC_D965_5ST),
1679 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2503, "Intel D965", STAC_D965_5ST),
1680 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2504, "Intel D965", STAC_D965_5ST),
1684 static unsigned int ref9205_pin_configs[12] = {
1685 0x40000100, 0x40000100, 0x01016011, 0x01014010,
1686 0x01813122, 0x01a19021, 0x01019020, 0x40000100,
1687 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
1691 STAC 9205 pin configs for
1698 10280228 (Dell Vostro 1500)
1700 static unsigned int dell_9205_m42_pin_configs[12] = {
1701 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310,
1702 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9,
1703 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE,
1707 STAC 9205 pin configs for
1711 102801FF (Dell Precision M4300)
1716 static unsigned int dell_9205_m43_pin_configs[12] = {
1717 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310,
1718 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9,
1719 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8,
1722 static unsigned int dell_9205_m44_pin_configs[12] = {
1723 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310,
1724 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9,
1725 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe,
1728 static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
1729 [STAC_9205_REF] = ref9205_pin_configs,
1730 [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs,
1731 [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs,
1732 [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs,
1735 static const char *stac9205_models[STAC_9205_MODELS] = {
1736 [STAC_9205_REF] = "ref",
1737 [STAC_9205_DELL_M42] = "dell-m42",
1738 [STAC_9205_DELL_M43] = "dell-m43",
1739 [STAC_9205_DELL_M44] = "dell-m44",
1742 static struct snd_pci_quirk stac9205_cfg_tbl[] = {
1743 /* SigmaTel reference board */
1744 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1745 "DFI LanParty", STAC_9205_REF),
1746 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1747 "unknown Dell", STAC_9205_DELL_M42),
1748 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1749 "unknown Dell", STAC_9205_DELL_M42),
1750 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
1751 "Dell Precision", STAC_9205_DELL_M43),
1752 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
1753 "Dell Precision", STAC_9205_DELL_M43),
1754 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
1755 "Dell Precision", STAC_9205_DELL_M43),
1756 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
1757 "Dell Precision", STAC_9205_DELL_M43),
1758 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
1759 "Dell Precision", STAC_9205_DELL_M43),
1760 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1761 "unknown Dell", STAC_9205_DELL_M42),
1762 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1763 "unknown Dell", STAC_9205_DELL_M42),
1764 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
1765 "Dell Precision", STAC_9205_DELL_M43),
1766 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
1767 "Dell Precision M4300", STAC_9205_DELL_M43),
1768 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
1769 "Dell Precision", STAC_9205_DELL_M43),
1770 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1771 "Dell Inspiron", STAC_9205_DELL_M44),
1772 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1773 "Dell Inspiron", STAC_9205_DELL_M44),
1774 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1775 "Dell Inspiron", STAC_9205_DELL_M44),
1776 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1777 "Dell Inspiron", STAC_9205_DELL_M44),
1778 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
1779 "unknown Dell", STAC_9205_DELL_M42),
1780 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
1781 "Dell Inspiron", STAC_9205_DELL_M44),
1782 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228,
1783 "Dell Vostro 1500", STAC_9205_DELL_M42),
1787 static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
1790 struct sigmatel_spec *spec = codec->spec;
1792 if (! spec->bios_pin_configs) {
1793 spec->bios_pin_configs = kcalloc(spec->num_pins,
1794 sizeof(*spec->bios_pin_configs), GFP_KERNEL);
1795 if (! spec->bios_pin_configs)
1799 for (i = 0; i < spec->num_pins; i++) {
1800 hda_nid_t nid = spec->pin_nids[i];
1801 unsigned int pin_cfg;
1803 pin_cfg = snd_hda_codec_read(codec, nid, 0,
1804 AC_VERB_GET_CONFIG_DEFAULT, 0x00);
1805 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n",
1807 spec->bios_pin_configs[i] = pin_cfg;
1813 static void stac92xx_set_config_reg(struct hda_codec *codec,
1814 hda_nid_t pin_nid, unsigned int pin_config)
1817 snd_hda_codec_write(codec, pin_nid, 0,
1818 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
1819 pin_config & 0x000000ff);
1820 snd_hda_codec_write(codec, pin_nid, 0,
1821 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
1822 (pin_config & 0x0000ff00) >> 8);
1823 snd_hda_codec_write(codec, pin_nid, 0,
1824 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
1825 (pin_config & 0x00ff0000) >> 16);
1826 snd_hda_codec_write(codec, pin_nid, 0,
1827 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
1829 i = snd_hda_codec_read(codec, pin_nid, 0,
1830 AC_VERB_GET_CONFIG_DEFAULT,
1832 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n",
1836 static void stac92xx_set_config_regs(struct hda_codec *codec)
1839 struct sigmatel_spec *spec = codec->spec;
1841 if (!spec->pin_configs)
1844 for (i = 0; i < spec->num_pins; i++)
1845 stac92xx_set_config_reg(codec, spec->pin_nids[i],
1846 spec->pin_configs[i]);
1850 * Analog playback callbacks
1852 static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
1853 struct hda_codec *codec,
1854 struct snd_pcm_substream *substream)
1856 struct sigmatel_spec *spec = codec->spec;
1857 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
1861 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1862 struct hda_codec *codec,
1863 unsigned int stream_tag,
1864 unsigned int format,
1865 struct snd_pcm_substream *substream)
1867 struct sigmatel_spec *spec = codec->spec;
1868 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream);
1871 static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1872 struct hda_codec *codec,
1873 struct snd_pcm_substream *substream)
1875 struct sigmatel_spec *spec = codec->spec;
1876 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1880 * Digital playback callbacks
1882 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1883 struct hda_codec *codec,
1884 struct snd_pcm_substream *substream)
1886 struct sigmatel_spec *spec = codec->spec;
1887 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1890 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1891 struct hda_codec *codec,
1892 struct snd_pcm_substream *substream)
1894 struct sigmatel_spec *spec = codec->spec;
1895 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1898 static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1899 struct hda_codec *codec,
1900 unsigned int stream_tag,
1901 unsigned int format,
1902 struct snd_pcm_substream *substream)
1904 struct sigmatel_spec *spec = codec->spec;
1905 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1906 stream_tag, format, substream);
1911 * Analog capture callbacks
1913 static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1914 struct hda_codec *codec,
1915 unsigned int stream_tag,
1916 unsigned int format,
1917 struct snd_pcm_substream *substream)
1919 struct sigmatel_spec *spec = codec->spec;
1921 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1922 stream_tag, 0, format);
1926 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1927 struct hda_codec *codec,
1928 struct snd_pcm_substream *substream)
1930 struct sigmatel_spec *spec = codec->spec;
1932 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
1936 static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
1940 /* NID is set in stac92xx_build_pcms */
1942 .open = stac92xx_dig_playback_pcm_open,
1943 .close = stac92xx_dig_playback_pcm_close,
1944 .prepare = stac92xx_dig_playback_pcm_prepare
1948 static struct hda_pcm_stream stac92xx_pcm_digital_capture = {
1952 /* NID is set in stac92xx_build_pcms */
1955 static struct hda_pcm_stream stac92xx_pcm_analog_playback = {
1959 .nid = 0x02, /* NID to query formats and rates */
1961 .open = stac92xx_playback_pcm_open,
1962 .prepare = stac92xx_playback_pcm_prepare,
1963 .cleanup = stac92xx_playback_pcm_cleanup
1967 static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
1971 .nid = 0x06, /* NID to query formats and rates */
1973 .open = stac92xx_playback_pcm_open,
1974 .prepare = stac92xx_playback_pcm_prepare,
1975 .cleanup = stac92xx_playback_pcm_cleanup
1979 static struct hda_pcm_stream stac92xx_pcm_analog_capture = {
1982 /* NID + .substreams is set in stac92xx_build_pcms */
1984 .prepare = stac92xx_capture_pcm_prepare,
1985 .cleanup = stac92xx_capture_pcm_cleanup
1989 static int stac92xx_build_pcms(struct hda_codec *codec)
1991 struct sigmatel_spec *spec = codec->spec;
1992 struct hda_pcm *info = spec->pcm_rec;
1994 codec->num_pcms = 1;
1995 codec->pcm_info = info;
1997 info->name = "STAC92xx Analog";
1998 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
1999 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
2000 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2001 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs;
2003 if (spec->alt_switch) {
2006 info->name = "STAC92xx Analog Alt";
2007 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback;
2010 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2013 info->name = "STAC92xx Digital";
2014 info->pcm_type = HDA_PCM_TYPE_SPDIF;
2015 if (spec->multiout.dig_out_nid) {
2016 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
2017 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2019 if (spec->dig_in_nid) {
2020 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture;
2021 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2028 static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
2030 unsigned int pincap = snd_hda_param_read(codec, nid,
2032 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
2033 if (pincap & AC_PINCAP_VREF_100)
2034 return AC_PINCTL_VREF_100;
2035 if (pincap & AC_PINCAP_VREF_80)
2036 return AC_PINCTL_VREF_80;
2037 if (pincap & AC_PINCAP_VREF_50)
2038 return AC_PINCTL_VREF_50;
2039 if (pincap & AC_PINCAP_VREF_GRD)
2040 return AC_PINCTL_VREF_GRD;
2044 static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
2047 snd_hda_codec_write_cache(codec, nid, 0,
2048 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
2051 #define stac92xx_io_switch_info snd_ctl_boolean_mono_info
2053 static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2055 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2056 struct sigmatel_spec *spec = codec->spec;
2057 int io_idx = kcontrol-> private_value & 0xff;
2059 ucontrol->value.integer.value[0] = spec->io_switch[io_idx];
2063 static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2065 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2066 struct sigmatel_spec *spec = codec->spec;
2067 hda_nid_t nid = kcontrol->private_value >> 8;
2068 int io_idx = kcontrol-> private_value & 0xff;
2069 unsigned short val = !!ucontrol->value.integer.value[0];
2071 spec->io_switch[io_idx] = val;
2074 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
2076 unsigned int pinctl = AC_PINCTL_IN_EN;
2077 if (io_idx) /* set VREF for mic */
2078 pinctl |= stac92xx_get_vref(codec, nid);
2079 stac92xx_auto_set_pinctl(codec, nid, pinctl);
2082 /* check the auto-mute again: we need to mute/unmute the speaker
2083 * appropriately according to the pin direction
2085 if (spec->hp_detect)
2086 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
2091 #define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info
2093 static int stac92xx_clfe_switch_get(struct snd_kcontrol *kcontrol,
2094 struct snd_ctl_elem_value *ucontrol)
2096 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2097 struct sigmatel_spec *spec = codec->spec;
2099 ucontrol->value.integer.value[0] = spec->clfe_swap;
2103 static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
2104 struct snd_ctl_elem_value *ucontrol)
2106 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2107 struct sigmatel_spec *spec = codec->spec;
2108 hda_nid_t nid = kcontrol->private_value & 0xff;
2109 unsigned int val = !!ucontrol->value.integer.value[0];
2111 if (spec->clfe_swap == val)
2114 spec->clfe_swap = val;
2116 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
2117 spec->clfe_swap ? 0x4 : 0x0);
2122 #define STAC_CODEC_IO_SWITCH(xname, xpval) \
2123 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2126 .info = stac92xx_io_switch_info, \
2127 .get = stac92xx_io_switch_get, \
2128 .put = stac92xx_io_switch_put, \
2129 .private_value = xpval, \
2132 #define STAC_CODEC_CLFE_SWITCH(xname, xpval) \
2133 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2136 .info = stac92xx_clfe_switch_info, \
2137 .get = stac92xx_clfe_switch_get, \
2138 .put = stac92xx_clfe_switch_put, \
2139 .private_value = xpval, \
2143 STAC_CTL_WIDGET_VOL,
2144 STAC_CTL_WIDGET_MUTE,
2145 STAC_CTL_WIDGET_MONO_MUX,
2146 STAC_CTL_WIDGET_IO_SWITCH,
2147 STAC_CTL_WIDGET_CLFE_SWITCH
2150 static struct snd_kcontrol_new stac92xx_control_templates[] = {
2151 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2152 HDA_CODEC_MUTE(NULL, 0, 0, 0),
2154 STAC_CODEC_IO_SWITCH(NULL, 0),
2155 STAC_CODEC_CLFE_SWITCH(NULL, 0),
2158 /* add dynamic controls */
2159 static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val)
2161 struct snd_kcontrol_new *knew;
2163 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2164 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2166 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
2169 if (spec->kctl_alloc) {
2170 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
2171 kfree(spec->kctl_alloc);
2173 spec->kctl_alloc = knew;
2174 spec->num_kctl_alloc = num;
2177 knew = &spec->kctl_alloc[spec->num_kctl_used];
2178 *knew = stac92xx_control_templates[type];
2179 knew->name = kstrdup(name, GFP_KERNEL);
2182 knew->private_value = val;
2183 spec->num_kctl_used++;
2187 /* flag inputs as additional dynamic lineouts */
2188 static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
2190 struct sigmatel_spec *spec = codec->spec;
2191 unsigned int wcaps, wtype;
2192 int i, num_dacs = 0;
2194 /* use the wcaps cache to count all DACs available for line-outs */
2195 for (i = 0; i < codec->num_nodes; i++) {
2196 wcaps = codec->wcaps[i];
2197 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2199 if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL))
2203 snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
2205 switch (cfg->line_outs) {
2207 /* add line-in as side */
2208 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
2209 cfg->line_out_pins[cfg->line_outs] =
2210 cfg->input_pins[AUTO_PIN_LINE];
2211 spec->line_switch = 1;
2216 /* add line-in as clfe and mic as side */
2217 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
2218 cfg->line_out_pins[cfg->line_outs] =
2219 cfg->input_pins[AUTO_PIN_LINE];
2220 spec->line_switch = 1;
2223 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
2224 cfg->line_out_pins[cfg->line_outs] =
2225 cfg->input_pins[AUTO_PIN_MIC];
2226 spec->mic_switch = 1;
2231 /* add line-in as surr and mic as clfe */
2232 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
2233 cfg->line_out_pins[cfg->line_outs] =
2234 cfg->input_pins[AUTO_PIN_LINE];
2235 spec->line_switch = 1;
2238 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
2239 cfg->line_out_pins[cfg->line_outs] =
2240 cfg->input_pins[AUTO_PIN_MIC];
2241 spec->mic_switch = 1;
2251 static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2255 for (i = 0; i < spec->multiout.num_dacs; i++) {
2256 if (spec->multiout.dac_nids[i] == nid)
2264 * Fill in the dac_nids table from the parsed pin configuration
2265 * This function only works when every pin in line_out_pins[]
2266 * contains atleast one DAC in its connection list. Some 92xx
2267 * codecs are not connected directly to a DAC, such as the 9200
2268 * and 9202/925x. For those, dac_nids[] must be hard-coded.
2270 static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
2271 struct auto_pin_cfg *cfg)
2273 struct sigmatel_spec *spec = codec->spec;
2274 int i, j, conn_len = 0;
2275 hda_nid_t nid, conn[HDA_MAX_CONNECTIONS];
2276 unsigned int wcaps, wtype;
2278 for (i = 0; i < cfg->line_outs; i++) {
2279 nid = cfg->line_out_pins[i];
2280 conn_len = snd_hda_get_connections(codec, nid, conn,
2281 HDA_MAX_CONNECTIONS);
2282 for (j = 0; j < conn_len; j++) {
2283 wcaps = snd_hda_param_read(codec, conn[j],
2284 AC_PAR_AUDIO_WIDGET_CAP);
2285 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2286 if (wtype != AC_WID_AUD_OUT ||
2287 (wcaps & AC_WCAP_DIGITAL))
2289 /* conn[j] is a DAC routed to this line-out */
2290 if (!is_in_dac_nids(spec, conn[j]))
2294 if (j == conn_len) {
2295 if (spec->multiout.num_dacs > 0) {
2296 /* we have already working output pins,
2297 * so let's drop the broken ones again
2299 cfg->line_outs = spec->multiout.num_dacs;
2302 /* error out, no available DAC found */
2304 "%s: No available DAC for pin 0x%x\n",
2309 spec->multiout.dac_nids[i] = conn[j];
2310 spec->multiout.num_dacs++;
2312 /* select this DAC in the pin's input mux */
2313 snd_hda_codec_write_cache(codec, nid, 0,
2314 AC_VERB_SET_CONNECT_SEL, j);
2319 snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
2320 spec->multiout.num_dacs,
2321 spec->multiout.dac_nids[0],
2322 spec->multiout.dac_nids[1],
2323 spec->multiout.dac_nids[2],
2324 spec->multiout.dac_nids[3],
2325 spec->multiout.dac_nids[4]);
2329 /* create volume control/switch for the given prefx type */
2330 static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_t nid, int chs)
2335 sprintf(name, "%s Playback Volume", pfx);
2336 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name,
2337 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
2340 sprintf(name, "%s Playback Switch", pfx);
2341 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name,
2342 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
2348 static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
2350 if (!spec->multiout.hp_nid)
2351 spec->multiout.hp_nid = nid;
2352 else if (spec->multiout.num_dacs > 4) {
2353 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
2356 spec->multiout.dac_nids[spec->multiout.num_dacs] = nid;
2357 spec->multiout.num_dacs++;
2362 static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2364 if (is_in_dac_nids(spec, nid))
2366 if (spec->multiout.hp_nid == nid)
2371 /* add playback controls from the parsed DAC table */
2372 static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
2373 const struct auto_pin_cfg *cfg)
2375 static const char *chname[4] = {
2376 "Front", "Surround", NULL /*CLFE*/, "Side"
2381 struct sigmatel_spec *spec = codec->spec;
2382 unsigned int wid_caps, pincap;
2385 for (i = 0; i < cfg->line_outs && i < spec->multiout.num_dacs; i++) {
2386 if (!spec->multiout.dac_nids[i])
2389 nid = spec->multiout.dac_nids[i];
2393 err = create_controls(spec, "Center", nid, 1);
2396 err = create_controls(spec, "LFE", nid, 2);
2400 wid_caps = get_wcaps(codec, nid);
2402 if (wid_caps & AC_WCAP_LR_SWAP) {
2403 err = stac92xx_add_control(spec,
2404 STAC_CTL_WIDGET_CLFE_SWITCH,
2405 "Swap Center/LFE Playback Switch", nid);
2412 err = create_controls(spec, chname[i], nid, 3);
2418 if (spec->line_switch) {
2419 nid = cfg->input_pins[AUTO_PIN_LINE];
2420 pincap = snd_hda_param_read(codec, nid,
2422 if (pincap & AC_PINCAP_OUT) {
2423 err = stac92xx_add_control(spec,
2424 STAC_CTL_WIDGET_IO_SWITCH,
2425 "Line In as Output Switch", nid << 8);
2431 if (spec->mic_switch) {
2432 unsigned int def_conf;
2433 unsigned int mic_pin = AUTO_PIN_MIC;
2435 nid = cfg->input_pins[mic_pin];
2436 def_conf = snd_hda_codec_read(codec, nid, 0,
2437 AC_VERB_GET_CONFIG_DEFAULT, 0);
2438 /* some laptops have an internal analog microphone
2439 * which can't be used as a output */
2440 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) {
2441 pincap = snd_hda_param_read(codec, nid,
2443 if (pincap & AC_PINCAP_OUT) {
2444 err = stac92xx_add_control(spec,
2445 STAC_CTL_WIDGET_IO_SWITCH,
2446 "Mic as Output Switch", (nid << 8) | 1);
2447 nid = snd_hda_codec_read(codec, nid, 0,
2448 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2449 if (!check_in_dac_nids(spec, nid))
2450 add_spec_dacs(spec, nid);
2454 } else if (mic_pin == AUTO_PIN_MIC) {
2455 mic_pin = AUTO_PIN_FRONT_MIC;
2463 /* add playback controls for Speaker and HP outputs */
2464 static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
2465 struct auto_pin_cfg *cfg)
2467 struct sigmatel_spec *spec = codec->spec;
2469 int i, old_num_dacs, err;
2471 old_num_dacs = spec->multiout.num_dacs;
2472 for (i = 0; i < cfg->hp_outs; i++) {
2473 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]);
2474 if (wid_caps & AC_WCAP_UNSOL_CAP)
2475 spec->hp_detect = 1;
2476 nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
2477 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2478 if (check_in_dac_nids(spec, nid))
2482 add_spec_dacs(spec, nid);
2484 for (i = 0; i < cfg->speaker_outs; i++) {
2485 nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
2486 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2487 if (check_in_dac_nids(spec, nid))
2491 add_spec_dacs(spec, nid);
2493 for (i = 0; i < cfg->line_outs; i++) {
2494 nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0,
2495 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2496 if (check_in_dac_nids(spec, nid))
2500 add_spec_dacs(spec, nid);
2502 for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) {
2503 static const char *pfxs[] = {
2504 "Speaker", "External Speaker", "Speaker2",
2506 err = create_controls(spec, pfxs[i - old_num_dacs],
2507 spec->multiout.dac_nids[i], 3);
2511 if (spec->multiout.hp_nid) {
2512 err = create_controls(spec, "Headphone",
2513 spec->multiout.hp_nid, 3);
2521 /* labels for mono mux outputs */
2522 static const char *stac92xx_mono_labels[3] = {
2523 "DAC0", "DAC1", "Mixer"
2526 /* create mono mux for mono out on capable codecs */
2527 static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec)
2529 struct sigmatel_spec *spec = codec->spec;
2530 struct hda_input_mux *mono_mux = &spec->private_mono_mux;
2532 hda_nid_t con_lst[ARRAY_SIZE(stac92xx_mono_labels)];
2534 num_cons = snd_hda_get_connections(codec,
2537 HDA_MAX_NUM_INPUTS);
2538 if (!num_cons || num_cons > ARRAY_SIZE(stac92xx_mono_labels))
2541 for (i = 0; i < num_cons; i++) {
2542 mono_mux->items[mono_mux->num_items].label =
2543 stac92xx_mono_labels[i];
2544 mono_mux->items[mono_mux->num_items].index = i;
2545 mono_mux->num_items++;
2548 return stac92xx_add_control(spec, STAC_CTL_WIDGET_MONO_MUX,
2549 "Mono Mux", spec->mono_nid);
2552 /* labels for dmic mux inputs */
2553 static const char *stac92xx_dmic_labels[5] = {
2554 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
2555 "Digital Mic 3", "Digital Mic 4"
2558 /* create playback/capture controls for input pins on dmic capable codecs */
2559 static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
2560 const struct auto_pin_cfg *cfg)
2562 struct sigmatel_spec *spec = codec->spec;
2563 struct hda_input_mux *dimux = &spec->private_dimux;
2564 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
2568 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0];
2569 dimux->items[dimux->num_items].index = 0;
2572 for (i = 0; i < spec->num_dmics; i++) {
2577 unsigned int def_conf;
2579 def_conf = snd_hda_codec_read(codec,
2582 AC_VERB_GET_CONFIG_DEFAULT,
2584 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
2587 nid = spec->dmic_nids[i];
2588 num_cons = snd_hda_get_connections(codec,
2591 HDA_MAX_NUM_INPUTS);
2592 for (j = 0; j < num_cons; j++)
2593 if (con_lst[j] == nid) {
2599 wcaps = get_wcaps(codec, nid);
2601 if (wcaps & AC_WCAP_OUT_AMP) {
2602 sprintf(name, "%s Capture Volume",
2603 stac92xx_dmic_labels[dimux->num_items]);
2605 err = stac92xx_add_control(spec,
2606 STAC_CTL_WIDGET_VOL,
2608 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
2613 dimux->items[dimux->num_items].label =
2614 stac92xx_dmic_labels[dimux->num_items];
2615 dimux->items[dimux->num_items].index = index;
2622 /* create playback/capture controls for input pins */
2623 static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
2625 struct sigmatel_spec *spec = codec->spec;
2626 struct hda_input_mux *imux = &spec->private_imux;
2627 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
2630 for (i = 0; i < AUTO_PIN_LAST; i++) {
2633 if (!cfg->input_pins[i])
2636 for (j = 0; j < spec->num_muxes; j++) {
2638 num_cons = snd_hda_get_connections(codec,
2641 HDA_MAX_NUM_INPUTS);
2642 for (k = 0; k < num_cons; k++)
2643 if (con_lst[k] == cfg->input_pins[i]) {
2650 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2651 imux->items[imux->num_items].index = index;
2655 if (imux->num_items) {
2657 * Set the current input for the muxes.
2658 * The STAC9221 has two input muxes with identical source
2659 * NID lists. Hopefully this won't get confused.
2661 for (i = 0; i < spec->num_muxes; i++) {
2662 snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0,
2663 AC_VERB_SET_CONNECT_SEL,
2664 imux->items[0].index);
2671 static void stac92xx_auto_init_multi_out(struct hda_codec *codec)
2673 struct sigmatel_spec *spec = codec->spec;
2676 for (i = 0; i < spec->autocfg.line_outs; i++) {
2677 hda_nid_t nid = spec->autocfg.line_out_pins[i];
2678 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
2682 static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
2684 struct sigmatel_spec *spec = codec->spec;
2687 for (i = 0; i < spec->autocfg.hp_outs; i++) {
2689 pin = spec->autocfg.hp_pins[i];
2690 if (pin) /* connect to front */
2691 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
2693 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
2695 pin = spec->autocfg.speaker_pins[i];
2696 if (pin) /* connect to front */
2697 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN);
2701 static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in)
2703 struct sigmatel_spec *spec = codec->spec;
2705 int hp_speaker_swap = 0;
2707 if ((err = snd_hda_parse_pin_def_config(codec,
2709 spec->dmic_nids)) < 0)
2711 if (! spec->autocfg.line_outs)
2712 return 0; /* can't find valid pin config */
2714 /* If we have no real line-out pin and multiple hp-outs, HPs should
2715 * be set up as multi-channel outputs.
2717 if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
2718 spec->autocfg.hp_outs > 1) {
2719 /* Copy hp_outs to line_outs, backup line_outs in
2720 * speaker_outs so that the following routines can handle
2721 * HP pins as primary outputs.
2723 memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins,
2724 sizeof(spec->autocfg.line_out_pins));
2725 spec->autocfg.speaker_outs = spec->autocfg.line_outs;
2726 memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins,
2727 sizeof(spec->autocfg.hp_pins));
2728 spec->autocfg.line_outs = spec->autocfg.hp_outs;
2729 hp_speaker_swap = 1;
2731 if (spec->autocfg.mono_out_pin) {
2732 int dir = (get_wcaps(codec, spec->autocfg.mono_out_pin)
2733 & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT;
2734 u32 caps = query_amp_caps(codec,
2735 spec->autocfg.mono_out_pin, dir);
2736 hda_nid_t conn_list[1];
2738 /* get the mixer node and then the mono mux if it exists */
2739 if (snd_hda_get_connections(codec,
2740 spec->autocfg.mono_out_pin, conn_list, 1) &&
2741 snd_hda_get_connections(codec, conn_list[0],
2744 int wcaps = get_wcaps(codec, conn_list[0]);
2745 int wid_type = (wcaps & AC_WCAP_TYPE)
2746 >> AC_WCAP_TYPE_SHIFT;
2747 /* LR swap check, some stac925x have a mux that
2748 * changes the DACs output path instead of the
2751 if (wid_type == AC_WID_AUD_SEL &&
2752 !(wcaps & AC_WCAP_LR_SWAP))
2753 spec->mono_nid = conn_list[0];
2755 /* all mono outs have a least a mute/unmute switch */
2756 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE,
2757 "Mono Playback Switch",
2758 HDA_COMPOSE_AMP_VAL(spec->autocfg.mono_out_pin,
2762 /* check to see if there is volume support for the amp */
2763 if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
2764 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL,
2765 "Mono Playback Volume",
2766 HDA_COMPOSE_AMP_VAL(spec->autocfg.mono_out_pin,
2772 stac92xx_auto_set_pinctl(codec, spec->autocfg.mono_out_pin,
2776 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
2778 if (spec->multiout.num_dacs == 0)
2779 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
2782 err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg);
2787 if (hp_speaker_swap == 1) {
2788 /* Restore the hp_outs and line_outs */
2789 memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
2790 sizeof(spec->autocfg.line_out_pins));
2791 spec->autocfg.hp_outs = spec->autocfg.line_outs;
2792 memcpy(spec->autocfg.line_out_pins, spec->autocfg.speaker_pins,
2793 sizeof(spec->autocfg.speaker_pins));
2794 spec->autocfg.line_outs = spec->autocfg.speaker_outs;
2795 memset(spec->autocfg.speaker_pins, 0,
2796 sizeof(spec->autocfg.speaker_pins));
2797 spec->autocfg.speaker_outs = 0;
2800 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
2805 err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
2810 if (spec->mono_nid > 0) {
2811 err = stac92xx_auto_create_mono_output_ctls(codec);
2816 if (spec->num_dmics > 0)
2817 if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
2818 &spec->autocfg)) < 0)
2821 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2822 if (spec->multiout.max_channels > 2)
2823 spec->surr_switch = 1;
2825 if (spec->autocfg.dig_out_pin)
2826 spec->multiout.dig_out_nid = dig_out;
2827 if (spec->autocfg.dig_in_pin)
2828 spec->dig_in_nid = dig_in;
2830 if (spec->kctl_alloc)
2831 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2833 spec->input_mux = &spec->private_imux;
2834 if (!spec->dinput_mux)
2835 spec->dinput_mux = &spec->private_dimux;
2836 spec->mono_mux = &spec->private_mono_mux;
2841 /* add playback controls for HP output */
2842 static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
2843 struct auto_pin_cfg *cfg)
2845 struct sigmatel_spec *spec = codec->spec;
2846 hda_nid_t pin = cfg->hp_pins[0];
2847 unsigned int wid_caps;
2852 wid_caps = get_wcaps(codec, pin);
2853 if (wid_caps & AC_WCAP_UNSOL_CAP)
2854 spec->hp_detect = 1;
2859 /* add playback controls for LFE output */
2860 static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec,
2861 struct auto_pin_cfg *cfg)
2863 struct sigmatel_spec *spec = codec->spec;
2865 hda_nid_t lfe_pin = 0x0;
2869 * search speaker outs and line outs for a mono speaker pin
2870 * with an amp. If one is found, add LFE controls
2873 for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) {
2874 hda_nid_t pin = spec->autocfg.speaker_pins[i];
2875 unsigned int wcaps = get_wcaps(codec, pin);
2876 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
2877 if (wcaps == AC_WCAP_OUT_AMP)
2878 /* found a mono speaker with an amp, must be lfe */
2882 /* if speaker_outs is 0, then speakers may be in line_outs */
2883 if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) {
2884 for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) {
2885 hda_nid_t pin = spec->autocfg.line_out_pins[i];
2886 unsigned int defcfg;
2887 defcfg = snd_hda_codec_read(codec, pin, 0,
2888 AC_VERB_GET_CONFIG_DEFAULT,
2890 if (get_defcfg_device(defcfg) == AC_JACK_SPEAKER) {
2891 unsigned int wcaps = get_wcaps(codec, pin);
2892 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
2893 if (wcaps == AC_WCAP_OUT_AMP)
2894 /* found a mono speaker with an amp,
2902 err = create_controls(spec, "LFE", lfe_pin, 1);
2910 static int stac9200_parse_auto_config(struct hda_codec *codec)
2912 struct sigmatel_spec *spec = codec->spec;
2915 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
2918 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
2921 if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)
2924 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
2927 if (spec->autocfg.dig_out_pin)
2928 spec->multiout.dig_out_nid = 0x05;
2929 if (spec->autocfg.dig_in_pin)
2930 spec->dig_in_nid = 0x04;
2932 if (spec->kctl_alloc)
2933 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2935 spec->input_mux = &spec->private_imux;
2936 spec->dinput_mux = &spec->private_dimux;
2942 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
2943 * funky external mute control using GPIO pins.
2946 static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
2947 unsigned int dir_mask, unsigned int data)
2949 unsigned int gpiostate, gpiomask, gpiodir;
2951 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
2952 AC_VERB_GET_GPIO_DATA, 0);
2953 gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask);
2955 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
2956 AC_VERB_GET_GPIO_MASK, 0);
2959 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
2960 AC_VERB_GET_GPIO_DIRECTION, 0);
2961 gpiodir |= dir_mask;
2963 /* Configure GPIOx as CMOS */
2964 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
2966 snd_hda_codec_write(codec, codec->afg, 0,
2967 AC_VERB_SET_GPIO_MASK, gpiomask);
2968 snd_hda_codec_read(codec, codec->afg, 0,
2969 AC_VERB_SET_GPIO_DIRECTION, gpiodir); /* sync */
2973 snd_hda_codec_read(codec, codec->afg, 0,
2974 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
2977 static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
2980 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)
2981 snd_hda_codec_write_cache(codec, nid, 0,
2982 AC_VERB_SET_UNSOLICITED_ENABLE,
2983 (AC_USRSP_EN | event));
2986 static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
2989 for (i = 0; i < cfg->hp_outs; i++)
2990 if (cfg->hp_pins[i] == nid)
2991 return 1; /* nid is a HP-Out */
2993 return 0; /* nid is not a HP-Out */
2996 static void stac92xx_power_down(struct hda_codec *codec)
2998 struct sigmatel_spec *spec = codec->spec;
3000 /* power down inactive DACs */
3002 for (dac = spec->dac_list; *dac; dac++)
3003 if (!is_in_dac_nids(spec, *dac) &&
3004 spec->multiout.hp_nid != *dac)
3005 snd_hda_codec_write_cache(codec, *dac, 0,
3006 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3009 static int stac92xx_init(struct hda_codec *codec)
3011 struct sigmatel_spec *spec = codec->spec;
3012 struct auto_pin_cfg *cfg = &spec->autocfg;
3015 snd_hda_sequence_write(codec, spec->init);
3018 if (spec->hp_detect) {
3019 /* Enable unsolicited responses on the HP widget */
3020 for (i = 0; i < cfg->hp_outs; i++)
3021 enable_pin_detect(codec, cfg->hp_pins[i],
3023 /* force to enable the first line-out; the others are set up
3026 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
3028 stac92xx_auto_init_hp_out(codec);
3029 /* fake event to set up pins */
3030 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
3032 stac92xx_auto_init_multi_out(codec);
3033 stac92xx_auto_init_hp_out(codec);
3035 for (i = 0; i < AUTO_PIN_LAST; i++) {
3036 hda_nid_t nid = cfg->input_pins[i];
3038 unsigned int pinctl = AC_PINCTL_IN_EN;
3039 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
3040 pinctl |= stac92xx_get_vref(codec, nid);
3041 stac92xx_auto_set_pinctl(codec, nid, pinctl);
3044 for (i = 0; i < spec->num_dmics; i++)
3045 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
3047 for (i = 0; i < spec->num_pwrs; i++) {
3048 int event = is_nid_hp_pin(cfg, spec->pwr_nids[i])
3049 ? STAC_HP_EVENT : STAC_PWR_EVENT;
3050 int pinctl = snd_hda_codec_read(codec, spec->pwr_nids[i],
3051 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3052 int def_conf = snd_hda_codec_read(codec, spec->pwr_nids[i],
3053 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
3054 /* outputs are only ports capable of power management
3055 * any attempts on powering down a input port cause the
3056 * referenced VREF to act quirky.
3058 if (pinctl & AC_PINCTL_IN_EN)
3060 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED)
3062 enable_pin_detect(codec, spec->pwr_nids[i], event | i);
3063 codec->patch_ops.unsol_event(codec, (event | i) << 26);
3066 stac92xx_power_down(codec);
3067 if (cfg->dig_out_pin)
3068 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
3070 if (cfg->dig_in_pin)
3071 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
3074 stac_gpio_set(codec, spec->gpio_mask,
3075 spec->gpio_dir, spec->gpio_data);
3080 static void stac92xx_free(struct hda_codec *codec)
3082 struct sigmatel_spec *spec = codec->spec;
3088 if (spec->kctl_alloc) {
3089 for (i = 0; i < spec->num_kctl_used; i++)
3090 kfree(spec->kctl_alloc[i].name);
3091 kfree(spec->kctl_alloc);
3094 if (spec->bios_pin_configs)
3095 kfree(spec->bios_pin_configs);
3100 static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
3103 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
3104 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
3106 if (pin_ctl & AC_PINCTL_IN_EN) {
3108 * we need to check the current set-up direction of
3109 * shared input pins since they can be switched via
3110 * "xxx as Output" mixer switch
3112 struct sigmatel_spec *spec = codec->spec;
3113 struct auto_pin_cfg *cfg = &spec->autocfg;
3114 if ((nid == cfg->input_pins[AUTO_PIN_LINE] &&
3115 spec->line_switch) ||
3116 (nid == cfg->input_pins[AUTO_PIN_MIC] &&
3121 /* if setting pin direction bits, clear the current
3122 direction bits first */
3123 if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
3124 pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
3126 snd_hda_codec_write_cache(codec, nid, 0,
3127 AC_VERB_SET_PIN_WIDGET_CONTROL,
3131 static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
3134 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
3135 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
3136 snd_hda_codec_write_cache(codec, nid, 0,
3137 AC_VERB_SET_PIN_WIDGET_CONTROL,
3141 static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid)
3145 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00)
3147 unsigned int pinctl;
3148 pinctl = snd_hda_codec_read(codec, nid, 0,
3149 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3150 if (pinctl & AC_PINCTL_IN_EN)
3151 return 0; /* mic- or line-input */
3153 return 1; /* HP-output */
3158 static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
3160 struct sigmatel_spec *spec = codec->spec;
3161 struct auto_pin_cfg *cfg = &spec->autocfg;
3165 if (spec->gpio_mute)
3166 presence = !(snd_hda_codec_read(codec, codec->afg, 0,
3167 AC_VERB_GET_GPIO_DATA, 0) & spec->gpio_mute);
3169 for (i = 0; i < cfg->hp_outs; i++) {
3172 presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);
3176 /* disable lineouts, enable hp */
3177 for (i = 0; i < cfg->line_outs; i++)
3178 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
3180 for (i = 0; i < cfg->speaker_outs; i++)
3181 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
3184 /* enable lineouts, disable hp */
3185 for (i = 0; i < cfg->line_outs; i++)
3186 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
3188 for (i = 0; i < cfg->speaker_outs; i++)
3189 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
3194 static void stac92xx_pin_sense(struct hda_codec *codec, int idx)
3196 struct sigmatel_spec *spec = codec->spec;
3197 hda_nid_t nid = spec->pwr_nids[idx];
3199 val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0)
3201 presence = get_hp_pin_presence(codec, nid);
3209 /* power down unused output ports */
3210 snd_hda_codec_write(codec, codec->afg, 0, 0x7ec, val);
3213 static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
3215 struct sigmatel_spec *spec = codec->spec;
3216 int idx = res >> 26 & 0x0f;
3218 switch ((res >> 26) & 0x30) {
3220 stac92xx_hp_detect(codec, res);
3222 case STAC_PWR_EVENT:
3223 if (spec->num_pwrs > 0)
3224 stac92xx_pin_sense(codec, idx);
3228 #ifdef SND_HDA_NEEDS_RESUME
3229 static int stac92xx_resume(struct hda_codec *codec)
3231 struct sigmatel_spec *spec = codec->spec;
3233 stac92xx_set_config_regs(codec);
3234 snd_hda_sequence_write(codec, spec->init);
3235 stac_gpio_set(codec, spec->gpio_mask,
3236 spec->gpio_dir, spec->gpio_data);
3237 snd_hda_codec_resume_amp(codec);
3238 snd_hda_codec_resume_cache(codec);
3239 /* power down inactive DACs */
3241 stac92xx_power_down(codec);
3242 /* invoke unsolicited event to reset the HP state */
3243 if (spec->hp_detect)
3244 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
3249 static struct hda_codec_ops stac92xx_patch_ops = {
3250 .build_controls = stac92xx_build_controls,
3251 .build_pcms = stac92xx_build_pcms,
3252 .init = stac92xx_init,
3253 .free = stac92xx_free,
3254 .unsol_event = stac92xx_unsol_event,
3255 #ifdef SND_HDA_NEEDS_RESUME
3256 .resume = stac92xx_resume,
3260 static int patch_stac9200(struct hda_codec *codec)
3262 struct sigmatel_spec *spec;
3265 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3270 spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
3271 spec->pin_nids = stac9200_pin_nids;
3272 spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
3275 if (spec->board_config < 0) {
3276 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
3277 err = stac92xx_save_bios_config_regs(codec);
3279 stac92xx_free(codec);
3282 spec->pin_configs = spec->bios_pin_configs;
3284 spec->pin_configs = stac9200_brd_tbl[spec->board_config];
3285 stac92xx_set_config_regs(codec);
3288 spec->multiout.max_channels = 2;
3289 spec->multiout.num_dacs = 1;
3290 spec->multiout.dac_nids = stac9200_dac_nids;
3291 spec->adc_nids = stac9200_adc_nids;
3292 spec->mux_nids = stac9200_mux_nids;
3293 spec->num_muxes = 1;
3294 spec->num_dmics = 0;
3298 if (spec->board_config == STAC_9200_GATEWAY ||
3299 spec->board_config == STAC_9200_OQO)
3300 spec->init = stac9200_eapd_init;
3302 spec->init = stac9200_core_init;
3303 spec->mixer = stac9200_mixer;
3305 err = stac9200_parse_auto_config(codec);
3307 stac92xx_free(codec);
3311 codec->patch_ops = stac92xx_patch_ops;
3316 static int patch_stac925x(struct hda_codec *codec)
3318 struct sigmatel_spec *spec;
3321 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3326 spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
3327 spec->pin_nids = stac925x_pin_nids;
3328 spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
3332 if (spec->board_config < 0) {
3333 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x,"
3334 "using BIOS defaults\n");
3335 err = stac92xx_save_bios_config_regs(codec);
3337 stac92xx_free(codec);
3340 spec->pin_configs = spec->bios_pin_configs;
3341 } else if (stac925x_brd_tbl[spec->board_config] != NULL){
3342 spec->pin_configs = stac925x_brd_tbl[spec->board_config];
3343 stac92xx_set_config_regs(codec);
3346 spec->multiout.max_channels = 2;
3347 spec->multiout.num_dacs = 1;
3348 spec->multiout.dac_nids = stac925x_dac_nids;
3349 spec->adc_nids = stac925x_adc_nids;
3350 spec->mux_nids = stac925x_mux_nids;
3351 spec->num_muxes = 1;
3354 switch (codec->vendor_id) {
3355 case 0x83847632: /* STAC9202 */
3356 case 0x83847633: /* STAC9202D */
3357 case 0x83847636: /* STAC9251 */
3358 case 0x83847637: /* STAC9251D */
3359 spec->num_dmics = STAC925X_NUM_DMICS;
3360 spec->dmic_nids = stac925x_dmic_nids;
3361 spec->num_dmuxes = ARRAY_SIZE(stac925x_dmux_nids);
3362 spec->dmux_nids = stac925x_dmux_nids;
3365 spec->num_dmics = 0;
3369 spec->init = stac925x_core_init;
3370 spec->mixer = stac925x_mixer;
3372 err = stac92xx_parse_auto_config(codec, 0x8, 0x7);
3374 if (spec->board_config < 0) {
3375 printk(KERN_WARNING "hda_codec: No auto-config is "
3376 "available, default to model=ref\n");
3377 spec->board_config = STAC_925x_REF;
3383 stac92xx_free(codec);
3387 codec->patch_ops = stac92xx_patch_ops;
3392 static struct hda_input_mux stac92hd73xx_dmux = {
3395 { "Analog Inputs", 0x0b },
3397 { "Digital Mic 1", 0x09 },
3398 { "Digital Mic 2", 0x0a },
3402 static int patch_stac92hd73xx(struct hda_codec *codec)
3404 struct sigmatel_spec *spec;
3405 hda_nid_t conn[STAC92HD73_DAC_COUNT + 2];
3408 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3413 spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids);
3414 spec->pin_nids = stac92hd73xx_pin_nids;
3415 spec->board_config = snd_hda_check_board_config(codec,
3416 STAC_92HD73XX_MODELS,
3417 stac92hd73xx_models,
3418 stac92hd73xx_cfg_tbl);
3420 if (spec->board_config < 0) {
3421 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
3422 " STAC92HD73XX, using BIOS defaults\n");
3423 err = stac92xx_save_bios_config_regs(codec);
3425 stac92xx_free(codec);
3428 spec->pin_configs = spec->bios_pin_configs;
3430 spec->pin_configs = stac92hd73xx_brd_tbl[spec->board_config];
3431 stac92xx_set_config_regs(codec);
3434 spec->multiout.num_dacs = snd_hda_get_connections(codec, 0x0a,
3435 conn, STAC92HD73_DAC_COUNT + 2) - 1;
3437 if (spec->multiout.num_dacs < 0) {
3438 printk(KERN_WARNING "hda_codec: Could not determine "
3439 "number of channels defaulting to DAC count\n");
3440 spec->multiout.num_dacs = STAC92HD73_DAC_COUNT;
3443 switch (spec->multiout.num_dacs) {
3444 case 0x3: /* 6 Channel */
3445 spec->mixer = stac92hd73xx_6ch_mixer;
3446 spec->init = stac92hd73xx_6ch_core_init;
3448 case 0x4: /* 8 Channel */
3449 spec->multiout.hp_nid = 0x18;
3450 spec->mixer = stac92hd73xx_8ch_mixer;
3451 spec->init = stac92hd73xx_8ch_core_init;
3453 case 0x5: /* 10 Channel */
3454 spec->multiout.hp_nid = 0x19;
3455 spec->mixer = stac92hd73xx_10ch_mixer;
3456 spec->init = stac92hd73xx_10ch_core_init;
3459 spec->multiout.dac_nids = stac92hd73xx_dac_nids;
3460 spec->aloopback_mask = 0x01;
3461 spec->aloopback_shift = 8;
3463 spec->mux_nids = stac92hd73xx_mux_nids;
3464 spec->adc_nids = stac92hd73xx_adc_nids;
3465 spec->dmic_nids = stac92hd73xx_dmic_nids;
3466 spec->dmux_nids = stac92hd73xx_dmux_nids;
3468 spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids);
3469 spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids);
3470 spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids);
3471 spec->dinput_mux = &stac92hd73xx_dmux;
3472 /* GPIO0 High = Enable EAPD */
3473 spec->gpio_mask = spec->gpio_dir = 0x1;
3474 spec->gpio_data = 0x01;
3476 switch (spec->board_config) {
3478 spec->init = dell_eq_core_init;
3479 switch (codec->subsystem_id) {
3480 case 0x1028025e: /* Analog Mics */
3482 stac92xx_set_config_reg(codec, 0x0b, 0x90A70170);
3483 spec->num_dmics = 0;
3485 case 0x10280271: /* Digital Mics */
3487 spec->init = dell_m6_core_init;
3491 stac92xx_set_config_reg(codec, 0x13, 0x90A60160);
3492 spec->num_dmics = 1;
3494 case 0x10280256: /* Both */
3496 stac92xx_set_config_reg(codec, 0x0b, 0x90A70170);
3497 stac92xx_set_config_reg(codec, 0x13, 0x90A60160);
3498 spec->num_dmics = 1;
3503 spec->num_dmics = STAC92HD73XX_NUM_DMICS;
3506 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
3507 spec->pwr_nids = stac92hd73xx_pwr_nids;
3509 err = stac92xx_parse_auto_config(codec, 0x22, 0x24);
3512 if (spec->board_config < 0) {
3513 printk(KERN_WARNING "hda_codec: No auto-config is "
3514 "available, default to model=ref\n");
3515 spec->board_config = STAC_92HD73XX_REF;
3522 stac92xx_free(codec);
3526 codec->patch_ops = stac92xx_patch_ops;
3531 static int patch_stac92hd71bxx(struct hda_codec *codec)
3533 struct sigmatel_spec *spec;
3536 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3541 spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids);
3542 spec->pin_nids = stac92hd71bxx_pin_nids;
3543 spec->board_config = snd_hda_check_board_config(codec,
3544 STAC_92HD71BXX_MODELS,
3545 stac92hd71bxx_models,
3546 stac92hd71bxx_cfg_tbl);
3548 if (spec->board_config < 0) {
3549 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
3550 " STAC92HD71BXX, using BIOS defaults\n");
3551 err = stac92xx_save_bios_config_regs(codec);
3553 stac92xx_free(codec);
3556 spec->pin_configs = spec->bios_pin_configs;
3558 spec->pin_configs = stac92hd71bxx_brd_tbl[spec->board_config];
3559 stac92xx_set_config_regs(codec);
3562 switch (codec->vendor_id) {
3563 case 0x111d76b6: /* 4 Port without Analog Mixer */
3565 case 0x111d76b4: /* 6 Port without Analog Mixer */
3567 spec->mixer = stac92hd71bxx_mixer;
3568 spec->init = stac92hd71bxx_core_init;
3571 spec->mixer = stac92hd71bxx_analog_mixer;
3572 spec->init = stac92hd71bxx_analog_core_init;
3575 spec->aloopback_mask = 0x20;
3576 spec->aloopback_shift = 0;
3578 /* GPIO0 High = EAPD */
3579 spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0x1;
3581 spec->mux_nids = stac92hd71bxx_mux_nids;
3582 spec->adc_nids = stac92hd71bxx_adc_nids;
3583 spec->dmic_nids = stac92hd71bxx_dmic_nids;
3584 spec->dmux_nids = stac92hd71bxx_dmux_nids;
3586 spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids);
3587 spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids);
3588 spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
3589 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
3591 spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
3592 spec->pwr_nids = stac92hd71bxx_pwr_nids;
3594 spec->multiout.num_dacs = 1;
3595 spec->multiout.hp_nid = 0x11;
3596 spec->multiout.dac_nids = stac92hd71bxx_dac_nids;
3598 err = stac92xx_parse_auto_config(codec, 0x21, 0x23);
3600 if (spec->board_config < 0) {
3601 printk(KERN_WARNING "hda_codec: No auto-config is "
3602 "available, default to model=ref\n");
3603 spec->board_config = STAC_92HD71BXX_REF;
3610 stac92xx_free(codec);
3614 codec->patch_ops = stac92xx_patch_ops;
3619 static int patch_stac922x(struct hda_codec *codec)
3621 struct sigmatel_spec *spec;
3624 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3629 spec->num_pins = ARRAY_SIZE(stac922x_pin_nids);
3630 spec->pin_nids = stac922x_pin_nids;
3631 spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
3634 if (spec->board_config == STAC_INTEL_MAC_V3) {
3635 spec->gpio_mask = spec->gpio_dir = 0x03;
3636 spec->gpio_data = 0x03;
3637 /* Intel Macs have all same PCI SSID, so we need to check
3638 * codec SSID to distinguish the exact models
3640 printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id);
3641 switch (codec->subsystem_id) {
3644 spec->board_config = STAC_INTEL_MAC_V1;
3648 spec->board_config = STAC_INTEL_MAC_V2;
3656 spec->board_config = STAC_INTEL_MAC_V3;
3660 spec->board_config = STAC_INTEL_MAC_V4;
3664 spec->board_config = STAC_INTEL_MAC_V5;
3670 if (spec->board_config < 0) {
3671 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, "
3672 "using BIOS defaults\n");
3673 err = stac92xx_save_bios_config_regs(codec);
3675 stac92xx_free(codec);
3678 spec->pin_configs = spec->bios_pin_configs;
3679 } else if (stac922x_brd_tbl[spec->board_config] != NULL) {
3680 spec->pin_configs = stac922x_brd_tbl[spec->board_config];
3681 stac92xx_set_config_regs(codec);
3684 spec->adc_nids = stac922x_adc_nids;
3685 spec->mux_nids = stac922x_mux_nids;
3686 spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
3687 spec->num_adcs = ARRAY_SIZE(stac922x_adc_nids);
3688 spec->num_dmics = 0;
3691 spec->init = stac922x_core_init;
3692 spec->mixer = stac922x_mixer;
3694 spec->multiout.dac_nids = spec->dac_nids;
3696 err = stac92xx_parse_auto_config(codec, 0x08, 0x09);
3698 if (spec->board_config < 0) {
3699 printk(KERN_WARNING "hda_codec: No auto-config is "
3700 "available, default to model=ref\n");
3701 spec->board_config = STAC_D945_REF;
3707 stac92xx_free(codec);
3711 codec->patch_ops = stac92xx_patch_ops;
3713 /* Fix Mux capture level; max to 2 */
3714 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
3715 (0 << AC_AMPCAP_OFFSET_SHIFT) |
3716 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
3717 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
3718 (0 << AC_AMPCAP_MUTE_SHIFT));
3723 static int patch_stac927x(struct hda_codec *codec)
3725 struct sigmatel_spec *spec;
3728 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3733 spec->num_pins = ARRAY_SIZE(stac927x_pin_nids);
3734 spec->pin_nids = stac927x_pin_nids;
3735 spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS,
3739 if (spec->board_config < 0 || !stac927x_brd_tbl[spec->board_config]) {
3740 if (spec->board_config < 0)
3741 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
3742 "STAC927x, using BIOS defaults\n");
3743 err = stac92xx_save_bios_config_regs(codec);
3745 stac92xx_free(codec);
3748 spec->pin_configs = spec->bios_pin_configs;
3750 spec->pin_configs = stac927x_brd_tbl[spec->board_config];
3751 stac92xx_set_config_regs(codec);
3754 spec->adc_nids = stac927x_adc_nids;
3755 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
3756 spec->mux_nids = stac927x_mux_nids;
3757 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
3758 spec->dac_list = stac927x_dac_nids;
3759 spec->multiout.dac_nids = spec->dac_nids;
3761 switch (spec->board_config) {
3764 /* GPIO0 High = Enable EAPD */
3765 spec->gpio_mask = spec->gpio_dir = 0x01;
3766 spec->gpio_data = 0x01;
3767 spec->num_dmics = 0;
3769 spec->init = d965_core_init;
3770 spec->mixer = stac927x_mixer;
3772 case STAC_DELL_BIOS:
3773 /* configure the analog microphone on some laptops */
3774 stac92xx_set_config_reg(codec, 0x0c, 0x90a79130);
3775 /* correct the front output jack as a hp out */
3776 stac92xx_set_config_reg(codec, 0x0f, 0x0227011f);
3777 /* correct the front input jack as a mic */
3778 stac92xx_set_config_reg(codec, 0x0e, 0x02a79130);
3781 /* GPIO2 High = Enable EAPD */
3782 spec->gpio_mask = spec->gpio_dir = 0x04;
3783 spec->gpio_data = 0x04;
3784 spec->dmic_nids = stac927x_dmic_nids;
3785 spec->num_dmics = STAC927X_NUM_DMICS;
3787 spec->init = d965_core_init;
3788 spec->mixer = stac927x_mixer;
3789 spec->dmux_nids = stac927x_dmux_nids;
3790 spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
3793 /* GPIO0 High = Enable EAPD */
3794 spec->gpio_mask = spec->gpio_dir = 0x1;
3795 spec->gpio_data = 0x01;
3796 spec->num_dmics = 0;
3798 spec->init = stac927x_core_init;
3799 spec->mixer = stac927x_mixer;
3803 spec->aloopback_mask = 0x40;
3804 spec->aloopback_shift = 0;
3806 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
3808 if (spec->board_config < 0) {
3809 printk(KERN_WARNING "hda_codec: No auto-config is "
3810 "available, default to model=ref\n");
3811 spec->board_config = STAC_D965_REF;
3817 stac92xx_free(codec);
3821 codec->patch_ops = stac92xx_patch_ops;
3825 * The STAC927x seem to require fairly long delays for certain
3826 * command sequences. With too short delays (even if the answer
3827 * is set to RIRB properly), it results in the silence output
3828 * on some hardwares like Dell.
3830 * The below flag enables the longer delay (see get_response
3833 codec->bus->needs_damn_long_delay = 1;
3838 static int patch_stac9205(struct hda_codec *codec)
3840 struct sigmatel_spec *spec;
3843 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3848 spec->num_pins = ARRAY_SIZE(stac9205_pin_nids);
3849 spec->pin_nids = stac9205_pin_nids;
3850 spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
3854 if (spec->board_config < 0) {
3855 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n");
3856 err = stac92xx_save_bios_config_regs(codec);
3858 stac92xx_free(codec);
3861 spec->pin_configs = spec->bios_pin_configs;
3863 spec->pin_configs = stac9205_brd_tbl[spec->board_config];
3864 stac92xx_set_config_regs(codec);
3867 spec->adc_nids = stac9205_adc_nids;
3868 spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids);
3869 spec->mux_nids = stac9205_mux_nids;
3870 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
3871 spec->dmic_nids = stac9205_dmic_nids;
3872 spec->num_dmics = STAC9205_NUM_DMICS;
3873 spec->dmux_nids = stac9205_dmux_nids;
3874 spec->num_dmuxes = ARRAY_SIZE(stac9205_dmux_nids);
3877 spec->init = stac9205_core_init;
3878 spec->mixer = stac9205_mixer;
3880 spec->aloopback_mask = 0x40;
3881 spec->aloopback_shift = 0;
3882 spec->multiout.dac_nids = spec->dac_nids;
3884 switch (spec->board_config){
3885 case STAC_9205_DELL_M43:
3886 /* Enable SPDIF in/out */
3887 stac92xx_set_config_reg(codec, 0x1f, 0x01441030);
3888 stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
3890 /* Enable unsol response for GPIO4/Dock HP connection */
3891 snd_hda_codec_write(codec, codec->afg, 0,
3892 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
3893 snd_hda_codec_write_cache(codec, codec->afg, 0,
3894 AC_VERB_SET_UNSOLICITED_ENABLE,
3895 (AC_USRSP_EN | STAC_HP_EVENT));
3897 spec->gpio_dir = 0x0b;
3898 spec->gpio_mask = 0x1b;
3899 spec->gpio_mute = 0x10;
3900 /* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute,
3903 spec->gpio_data = 0x01;
3906 /* GPIO0 High = EAPD */
3907 spec->gpio_mask = spec->gpio_dir = 0x1;
3908 spec->gpio_data = 0x01;
3912 err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
3914 if (spec->board_config < 0) {
3915 printk(KERN_WARNING "hda_codec: No auto-config is "
3916 "available, default to model=ref\n");
3917 spec->board_config = STAC_9205_REF;
3923 stac92xx_free(codec);
3927 codec->patch_ops = stac92xx_patch_ops;
3936 /* static config for Sony VAIO FE550G and Sony VAIO AR */
3937 static hda_nid_t vaio_dacs[] = { 0x2 };
3938 #define VAIO_HP_DAC 0x5
3939 static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ };
3940 static hda_nid_t vaio_mux_nids[] = { 0x15 };
3942 static struct hda_input_mux vaio_mux = {
3945 /* { "HP", 0x0 }, */
3946 { "Mic Jack", 0x1 },
3947 { "Internal Mic", 0x2 },
3952 static struct hda_verb vaio_init[] = {
3953 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
3954 {0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT},
3955 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
3956 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
3957 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
3958 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
3959 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
3960 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
3961 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
3962 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
3963 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
3964 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
3968 static struct hda_verb vaio_ar_init[] = {
3969 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
3970 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
3971 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
3972 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
3973 /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */
3974 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
3975 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
3976 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
3977 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
3978 /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */
3979 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
3980 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
3981 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
3985 /* bind volumes of both NID 0x02 and 0x05 */
3986 static struct hda_bind_ctls vaio_bind_master_vol = {
3987 .ops = &snd_hda_bind_vol,
3989 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
3990 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
3995 /* bind volumes of both NID 0x02 and 0x05 */
3996 static struct hda_bind_ctls vaio_bind_master_sw = {
3997 .ops = &snd_hda_bind_sw,
3999 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
4000 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
4005 static struct snd_kcontrol_new vaio_mixer[] = {
4006 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
4007 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
4008 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
4009 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
4010 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
4012 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4013 .name = "Capture Source",
4015 .info = stac92xx_mux_enum_info,
4016 .get = stac92xx_mux_enum_get,
4017 .put = stac92xx_mux_enum_put,
4022 static struct snd_kcontrol_new vaio_ar_mixer[] = {
4023 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
4024 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
4025 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
4026 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
4027 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
4028 /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT),
4029 HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/
4031 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4032 .name = "Capture Source",
4034 .info = stac92xx_mux_enum_info,
4035 .get = stac92xx_mux_enum_get,
4036 .put = stac92xx_mux_enum_put,
4041 static struct hda_codec_ops stac9872_patch_ops = {
4042 .build_controls = stac92xx_build_controls,
4043 .build_pcms = stac92xx_build_pcms,
4044 .init = stac92xx_init,
4045 .free = stac92xx_free,
4046 #ifdef SND_HDA_NEEDS_RESUME
4047 .resume = stac92xx_resume,
4051 static int stac9872_vaio_init(struct hda_codec *codec)
4055 err = stac92xx_init(codec);
4058 if (codec->patch_ops.unsol_event)
4059 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
4063 static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
4065 if (get_hp_pin_presence(codec, 0x0a)) {
4066 stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
4067 stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
4069 stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
4070 stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
4074 static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res)
4076 switch (res >> 26) {
4078 stac9872_vaio_hp_detect(codec, res);
4083 static struct hda_codec_ops stac9872_vaio_patch_ops = {
4084 .build_controls = stac92xx_build_controls,
4085 .build_pcms = stac92xx_build_pcms,
4086 .init = stac9872_vaio_init,
4087 .free = stac92xx_free,
4088 .unsol_event = stac9872_vaio_unsol_event,
4090 .resume = stac92xx_resume,
4094 enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */
4096 /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */
4098 /* Unknown. id=0x83847661 and subsys=0x104D1200. */
4100 /* AR Series. id=0x83847664 and subsys=104D1300 */
4105 static const char *stac9872_models[STAC_9872_MODELS] = {
4106 [CXD9872RD_VAIO] = "vaio",
4107 [CXD9872AKD_VAIO] = "vaio-ar",
4110 static struct snd_pci_quirk stac9872_cfg_tbl[] = {
4111 SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
4112 SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
4113 SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
4114 SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO),
4118 static int patch_stac9872(struct hda_codec *codec)
4120 struct sigmatel_spec *spec;
4123 board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
4126 if (board_config < 0)
4127 /* unknown config, let generic-parser do its job... */
4128 return snd_hda_parse_generic_codec(codec);
4130 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4135 switch (board_config) {
4136 case CXD9872RD_VAIO:
4137 case STAC9872AK_VAIO:
4138 case STAC9872K_VAIO:
4139 spec->mixer = vaio_mixer;
4140 spec->init = vaio_init;
4141 spec->multiout.max_channels = 2;
4142 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
4143 spec->multiout.dac_nids = vaio_dacs;
4144 spec->multiout.hp_nid = VAIO_HP_DAC;
4145 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
4146 spec->adc_nids = vaio_adcs;
4148 spec->input_mux = &vaio_mux;
4149 spec->mux_nids = vaio_mux_nids;
4150 codec->patch_ops = stac9872_vaio_patch_ops;
4153 case CXD9872AKD_VAIO:
4154 spec->mixer = vaio_ar_mixer;
4155 spec->init = vaio_ar_init;
4156 spec->multiout.max_channels = 2;
4157 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
4158 spec->multiout.dac_nids = vaio_dacs;
4159 spec->multiout.hp_nid = VAIO_HP_DAC;
4160 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
4162 spec->adc_nids = vaio_adcs;
4163 spec->input_mux = &vaio_mux;
4164 spec->mux_nids = vaio_mux_nids;
4165 codec->patch_ops = stac9872_patch_ops;
4176 struct hda_codec_preset snd_hda_preset_sigmatel[] = {
4177 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
4178 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
4179 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
4180 { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x },
4181 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
4182 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
4183 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
4184 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x },
4185 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x },
4186 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x },
4187 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x },
4188 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x },
4189 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x },
4190 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
4191 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
4192 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
4193 { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x },
4194 { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x },
4195 { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x },
4196 { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x },
4197 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x },
4198 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x },
4199 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x },
4200 { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x },
4201 { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x },
4202 { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x },
4203 { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
4204 { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
4205 { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
4206 /* The following does not take into account .id=0x83847661 when subsys =
4207 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
4208 * currently not fully supported.
4210 { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 },
4211 { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 },
4212 { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 },
4213 { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 },
4214 { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 },
4215 { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 },
4216 { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 },
4217 { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 },
4218 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
4219 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
4220 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
4221 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
4222 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },
4223 { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx },
4224 { .id = 0x111d7608, .name = "92HD71BXX", .patch = patch_stac92hd71bxx },
4225 { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
4226 { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
4227 { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
4228 { .id = 0x111d76b3, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
4229 { .id = 0x111d76b4, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
4230 { .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
4231 { .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
4232 { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },