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 <linux/dmi.h>
32 #include <sound/core.h>
33 #include <sound/asoundef.h>
34 #include <sound/jack.h>
35 #include <sound/tlv.h>
36 #include "hda_codec.h"
37 #include "hda_local.h"
81 STAC_92HD73XX_NO_JD, /* no jack-detection */
95 STAC_92HD83XXX_PWR_REF,
98 STAC_92HD83XXX_HP_cNB11_INTQUAD,
100 STAC_92HD83XXX_MODELS
114 STAC_92HD71BXX_MODELS
140 STAC_INTEL_MAC_AUTO, /* This model is selected if no module parameter
141 * is given, one of the above models will be
142 * chosen according to the subsystem id. */
143 /* for backward compatibility */
160 STAC_D965_REF_NO_JD, /* no jack-detection */
177 struct sigmatel_event {
184 struct sigmatel_mic_route {
187 signed char dmux_idx;
190 #define MAX_PINS_NUM 16
191 #define MAX_ADCS_NUM 4
192 #define MAX_DMICS_NUM 4
194 struct sigmatel_spec {
195 struct snd_kcontrol_new *mixers[4];
196 unsigned int num_mixers;
199 unsigned int eapd_switch: 1;
200 unsigned int surr_switch: 1;
201 unsigned int alt_switch: 1;
202 unsigned int hp_detect: 1;
203 unsigned int spdif_mute: 1;
204 unsigned int check_volume_offset:1;
205 unsigned int auto_mic:1;
206 unsigned int linear_tone_beep:1;
209 unsigned int eapd_mask;
210 unsigned int gpio_mask;
211 unsigned int gpio_dir;
212 unsigned int gpio_data;
213 unsigned int gpio_mute;
214 unsigned int gpio_led;
215 unsigned int gpio_led_polarity;
216 unsigned int vref_led;
219 unsigned int stream_delay;
221 /* analog loopback */
222 const struct snd_kcontrol_new *aloopback_ctl;
223 unsigned char aloopback_mask;
224 unsigned char aloopback_shift;
226 /* power management */
227 unsigned int num_pwrs;
228 const unsigned int *pwr_mapping;
229 const hda_nid_t *pwr_nids;
230 const hda_nid_t *dac_list;
233 struct snd_array events;
236 struct hda_input_mux *mono_mux;
237 unsigned int cur_mmux;
238 struct hda_multi_out multiout;
239 hda_nid_t dac_nids[5];
240 hda_nid_t hp_dacs[5];
241 hda_nid_t speaker_dacs[5];
246 const hda_nid_t *adc_nids;
247 unsigned int num_adcs;
248 const hda_nid_t *mux_nids;
249 unsigned int num_muxes;
250 const hda_nid_t *dmic_nids;
251 unsigned int num_dmics;
252 const hda_nid_t *dmux_nids;
253 unsigned int num_dmuxes;
254 const hda_nid_t *smux_nids;
255 unsigned int num_smuxes;
256 unsigned int num_analog_muxes;
258 const unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */
259 const unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */
260 unsigned int num_caps; /* number of capture volume/switch elements */
262 struct sigmatel_mic_route ext_mic;
263 struct sigmatel_mic_route int_mic;
264 struct sigmatel_mic_route dock_mic;
266 const char * const *spdif_labels;
268 hda_nid_t dig_in_nid;
270 hda_nid_t anabeep_nid;
271 hda_nid_t digbeep_nid;
274 const hda_nid_t *pin_nids;
275 unsigned int num_pins;
277 /* codec specific stuff */
278 const struct hda_verb *init;
279 const struct snd_kcontrol_new *mixer;
282 struct hda_input_mux *dinput_mux;
283 unsigned int cur_dmux[2];
284 struct hda_input_mux *input_mux;
285 unsigned int cur_mux[3];
286 struct hda_input_mux *sinput_mux;
287 unsigned int cur_smux[2];
288 unsigned int cur_amux;
290 unsigned int powerdown_adcs;
293 unsigned int io_switch[2];
294 unsigned int clfe_swap;
295 hda_nid_t line_switch; /* shared line-in for input and output */
296 hda_nid_t mic_switch; /* shared mic-in for input and output */
297 hda_nid_t hp_switch; /* NID of HP as line-out */
298 unsigned int aloopback;
300 struct hda_pcm pcm_rec[2]; /* PCM information */
302 /* dynamic controls and input_mux */
303 struct auto_pin_cfg autocfg;
304 struct snd_array kctls;
305 struct hda_input_mux private_dimux;
306 struct hda_input_mux private_imux;
307 struct hda_input_mux private_smux;
308 struct hda_input_mux private_mono_mux;
311 unsigned auto_pin_cnt;
312 hda_nid_t auto_pin_nids[MAX_PINS_NUM];
313 unsigned auto_adc_cnt;
314 hda_nid_t auto_adc_nids[MAX_ADCS_NUM];
315 hda_nid_t auto_mux_nids[MAX_ADCS_NUM];
316 hda_nid_t auto_dmux_nids[MAX_ADCS_NUM];
317 unsigned long auto_capvols[MAX_ADCS_NUM];
318 unsigned auto_dmic_cnt;
319 hda_nid_t auto_dmic_nids[MAX_DMICS_NUM];
322 static const hda_nid_t stac9200_adc_nids[1] = {
326 static const hda_nid_t stac9200_mux_nids[1] = {
330 static const hda_nid_t stac9200_dac_nids[1] = {
334 static const hda_nid_t stac92hd73xx_pwr_nids[8] = {
335 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
339 static const hda_nid_t stac92hd73xx_slave_dig_outs[2] = {
343 static const hda_nid_t stac92hd73xx_adc_nids[2] = {
347 #define STAC92HD73XX_NUM_DMICS 2
348 static const hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
352 #define STAC92HD73_DAC_COUNT 5
354 static const hda_nid_t stac92hd73xx_mux_nids[2] = {
358 static const hda_nid_t stac92hd73xx_dmux_nids[2] = {
362 static const hda_nid_t stac92hd73xx_smux_nids[2] = {
366 #define STAC92HD73XX_NUM_CAPS 2
367 static const unsigned long stac92hd73xx_capvols[] = {
368 HDA_COMPOSE_AMP_VAL(0x20, 3, 0, HDA_OUTPUT),
369 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
371 #define stac92hd73xx_capsws stac92hd73xx_capvols
373 #define STAC92HD83_DAC_COUNT 3
375 static const hda_nid_t stac92hd83xxx_pwr_nids[4] = {
379 static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = {
383 static const unsigned int stac92hd83xxx_pwr_mapping[4] = {
384 0x03, 0x0c, 0x20, 0x40,
387 static const hda_nid_t stac92hd83xxx_dmic_nids[] = {
391 static const hda_nid_t stac92hd71bxx_pwr_nids[3] = {
395 static const hda_nid_t stac92hd71bxx_adc_nids[2] = {
399 static const hda_nid_t stac92hd71bxx_mux_nids[2] = {
403 static const hda_nid_t stac92hd71bxx_dmux_nids[2] = {
407 static const hda_nid_t stac92hd71bxx_smux_nids[2] = {
411 #define STAC92HD71BXX_NUM_DMICS 2
412 static const hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
416 static const hda_nid_t stac92hd71bxx_dmic_5port_nids[STAC92HD71BXX_NUM_DMICS] = {
420 static const hda_nid_t stac92hd71bxx_slave_dig_outs[2] = {
424 #define STAC92HD71BXX_NUM_CAPS 2
425 static const unsigned long stac92hd71bxx_capvols[] = {
426 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT),
427 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
429 #define stac92hd71bxx_capsws stac92hd71bxx_capvols
431 static const hda_nid_t stac925x_adc_nids[1] = {
435 static const hda_nid_t stac925x_mux_nids[1] = {
439 static const hda_nid_t stac925x_dac_nids[1] = {
443 #define STAC925X_NUM_DMICS 1
444 static const hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = {
448 static const hda_nid_t stac925x_dmux_nids[1] = {
452 static const unsigned long stac925x_capvols[] = {
453 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
455 static const unsigned long stac925x_capsws[] = {
456 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
459 static const hda_nid_t stac922x_adc_nids[2] = {
463 static const hda_nid_t stac922x_mux_nids[2] = {
467 #define STAC922X_NUM_CAPS 2
468 static const unsigned long stac922x_capvols[] = {
469 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT),
470 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT),
472 #define stac922x_capsws stac922x_capvols
474 static const hda_nid_t stac927x_slave_dig_outs[2] = {
478 static const hda_nid_t stac927x_adc_nids[3] = {
482 static const hda_nid_t stac927x_mux_nids[3] = {
486 static const hda_nid_t stac927x_smux_nids[1] = {
490 static const hda_nid_t stac927x_dac_nids[6] = {
491 0x02, 0x03, 0x04, 0x05, 0x06, 0
494 static const hda_nid_t stac927x_dmux_nids[1] = {
498 #define STAC927X_NUM_DMICS 2
499 static const hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = {
503 #define STAC927X_NUM_CAPS 3
504 static const unsigned long stac927x_capvols[] = {
505 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT),
506 HDA_COMPOSE_AMP_VAL(0x19, 3, 0, HDA_INPUT),
507 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_INPUT),
509 static const unsigned long stac927x_capsws[] = {
510 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
511 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT),
512 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
515 static const char * const stac927x_spdif_labels[5] = {
516 "Digital Playback", "ADAT", "Analog Mux 1",
517 "Analog Mux 2", "Analog Mux 3"
520 static const hda_nid_t stac9205_adc_nids[2] = {
524 static const hda_nid_t stac9205_mux_nids[2] = {
528 static const hda_nid_t stac9205_dmux_nids[1] = {
532 static const hda_nid_t stac9205_smux_nids[1] = {
536 #define STAC9205_NUM_DMICS 2
537 static const hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
541 #define STAC9205_NUM_CAPS 2
542 static const unsigned long stac9205_capvols[] = {
543 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT),
544 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT),
546 static const unsigned long stac9205_capsws[] = {
547 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
548 HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT),
551 static const hda_nid_t stac9200_pin_nids[8] = {
552 0x08, 0x09, 0x0d, 0x0e,
553 0x0f, 0x10, 0x11, 0x12,
556 static const hda_nid_t stac925x_pin_nids[8] = {
557 0x07, 0x08, 0x0a, 0x0b,
558 0x0c, 0x0d, 0x10, 0x11,
561 static const hda_nid_t stac922x_pin_nids[10] = {
562 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
563 0x0f, 0x10, 0x11, 0x15, 0x1b,
566 static const hda_nid_t stac92hd73xx_pin_nids[13] = {
567 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
568 0x0f, 0x10, 0x11, 0x12, 0x13,
572 #define STAC92HD71BXX_NUM_PINS 13
573 static const hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = {
574 0x0a, 0x0b, 0x0c, 0x0d, 0x00,
575 0x00, 0x14, 0x18, 0x19, 0x1e,
578 static const hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = {
579 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
580 0x0f, 0x14, 0x18, 0x19, 0x1e,
584 static const hda_nid_t stac927x_pin_nids[14] = {
585 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
586 0x0f, 0x10, 0x11, 0x12, 0x13,
587 0x14, 0x21, 0x22, 0x23,
590 static const hda_nid_t stac9205_pin_nids[12] = {
591 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
592 0x0f, 0x14, 0x16, 0x17, 0x18,
596 static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
597 struct snd_ctl_elem_info *uinfo)
599 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
600 struct sigmatel_spec *spec = codec->spec;
601 return snd_hda_input_mux_info(spec->dinput_mux, uinfo);
604 static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol,
605 struct snd_ctl_elem_value *ucontrol)
607 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
608 struct sigmatel_spec *spec = codec->spec;
609 unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
611 ucontrol->value.enumerated.item[0] = spec->cur_dmux[dmux_idx];
615 static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
616 struct snd_ctl_elem_value *ucontrol)
618 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
619 struct sigmatel_spec *spec = codec->spec;
620 unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
622 return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol,
623 spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]);
626 static int stac92xx_smux_enum_info(struct snd_kcontrol *kcontrol,
627 struct snd_ctl_elem_info *uinfo)
629 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
630 struct sigmatel_spec *spec = codec->spec;
631 return snd_hda_input_mux_info(spec->sinput_mux, uinfo);
634 static int stac92xx_smux_enum_get(struct snd_kcontrol *kcontrol,
635 struct snd_ctl_elem_value *ucontrol)
637 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
638 struct sigmatel_spec *spec = codec->spec;
639 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
641 ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx];
645 static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
646 struct snd_ctl_elem_value *ucontrol)
648 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
649 struct sigmatel_spec *spec = codec->spec;
650 struct hda_input_mux *smux = &spec->private_smux;
651 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
655 err = snd_hda_input_mux_put(codec, spec->sinput_mux, ucontrol,
656 spec->smux_nids[smux_idx], &spec->cur_smux[smux_idx]);
660 if (spec->spdif_mute) {
662 nid = spec->multiout.dig_out_nid;
664 nid = codec->slave_dig_outs[smux_idx - 1];
665 if (spec->cur_smux[smux_idx] == smux->num_items - 1)
669 /* un/mute SPDIF out */
670 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
676 static int stac_vrefout_set(struct hda_codec *codec,
677 hda_nid_t nid, unsigned int new_vref)
681 snd_printdd("%s, nid %x ctl %x\n", __func__, nid, new_vref);
682 pinctl = snd_hda_codec_read(codec, nid, 0,
683 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
689 pinctl &= ~AC_PINCTL_VREFEN;
690 pinctl |= (new_vref & AC_PINCTL_VREFEN);
692 error = snd_hda_codec_write_cache(codec, nid, 0,
693 AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
700 static unsigned int stac92xx_vref_set(struct hda_codec *codec,
701 hda_nid_t nid, unsigned int new_vref)
705 pincfg = snd_hda_codec_read(codec, nid, 0,
706 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
709 pincfg &= ~(AC_PINCTL_VREFEN | AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
712 if (new_vref == AC_PINCTL_VREF_HIZ)
713 pincfg |= AC_PINCTL_OUT_EN;
715 pincfg |= AC_PINCTL_IN_EN;
717 error = snd_hda_codec_write_cache(codec, nid, 0,
718 AC_VERB_SET_PIN_WIDGET_CONTROL, pincfg);
725 static unsigned int stac92xx_vref_get(struct hda_codec *codec, hda_nid_t nid)
728 vref = snd_hda_codec_read(codec, nid, 0,
729 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
730 vref &= AC_PINCTL_VREFEN;
734 static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
736 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
737 struct sigmatel_spec *spec = codec->spec;
738 return snd_hda_input_mux_info(spec->input_mux, uinfo);
741 static int stac92xx_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
743 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
744 struct sigmatel_spec *spec = codec->spec;
745 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
747 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
751 static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
753 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
754 struct sigmatel_spec *spec = codec->spec;
755 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
756 const struct hda_input_mux *imux = spec->input_mux;
757 unsigned int idx, prev_idx, didx;
759 idx = ucontrol->value.enumerated.item[0];
760 if (idx >= imux->num_items)
761 idx = imux->num_items - 1;
762 prev_idx = spec->cur_mux[adc_idx];
765 if (idx < spec->num_analog_muxes) {
766 snd_hda_codec_write_cache(codec, spec->mux_nids[adc_idx], 0,
767 AC_VERB_SET_CONNECT_SEL,
768 imux->items[idx].index);
769 if (prev_idx >= spec->num_analog_muxes &&
770 spec->mux_nids[adc_idx] != spec->dmux_nids[adc_idx]) {
771 imux = spec->dinput_mux;
773 snd_hda_codec_write_cache(codec,
774 spec->dmux_nids[adc_idx], 0,
775 AC_VERB_SET_CONNECT_SEL,
776 imux->items[0].index);
779 imux = spec->dinput_mux;
780 /* first dimux item is hardcoded to select analog imux,
783 didx = idx - spec->num_analog_muxes + 1;
784 snd_hda_codec_write_cache(codec, spec->dmux_nids[adc_idx], 0,
785 AC_VERB_SET_CONNECT_SEL,
786 imux->items[didx].index);
788 spec->cur_mux[adc_idx] = idx;
792 static int stac92xx_mono_mux_enum_info(struct snd_kcontrol *kcontrol,
793 struct snd_ctl_elem_info *uinfo)
795 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
796 struct sigmatel_spec *spec = codec->spec;
797 return snd_hda_input_mux_info(spec->mono_mux, uinfo);
800 static int stac92xx_mono_mux_enum_get(struct snd_kcontrol *kcontrol,
801 struct snd_ctl_elem_value *ucontrol)
803 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
804 struct sigmatel_spec *spec = codec->spec;
806 ucontrol->value.enumerated.item[0] = spec->cur_mmux;
810 static int stac92xx_mono_mux_enum_put(struct snd_kcontrol *kcontrol,
811 struct snd_ctl_elem_value *ucontrol)
813 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
814 struct sigmatel_spec *spec = codec->spec;
816 return snd_hda_input_mux_put(codec, spec->mono_mux, ucontrol,
817 spec->mono_nid, &spec->cur_mmux);
820 #define stac92xx_aloopback_info snd_ctl_boolean_mono_info
822 static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol,
823 struct snd_ctl_elem_value *ucontrol)
825 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
826 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
827 struct sigmatel_spec *spec = codec->spec;
829 ucontrol->value.integer.value[0] = !!(spec->aloopback &
830 (spec->aloopback_mask << idx));
834 static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol,
835 struct snd_ctl_elem_value *ucontrol)
837 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
838 struct sigmatel_spec *spec = codec->spec;
839 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
840 unsigned int dac_mode;
841 unsigned int val, idx_val;
843 idx_val = spec->aloopback_mask << idx;
844 if (ucontrol->value.integer.value[0])
845 val = spec->aloopback | idx_val;
847 val = spec->aloopback & ~idx_val;
848 if (spec->aloopback == val)
851 spec->aloopback = val;
853 /* Only return the bits defined by the shift value of the
854 * first two bytes of the mask
856 dac_mode = snd_hda_codec_read(codec, codec->afg, 0,
857 kcontrol->private_value & 0xFFFF, 0x0);
858 dac_mode >>= spec->aloopback_shift;
860 if (spec->aloopback & idx_val) {
861 snd_hda_power_up(codec);
864 snd_hda_power_down(codec);
865 dac_mode &= ~idx_val;
868 snd_hda_codec_write_cache(codec, codec->afg, 0,
869 kcontrol->private_value >> 16, dac_mode);
874 static const struct hda_verb stac9200_core_init[] = {
875 /* set dac0mux for dac converter */
876 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
880 static const struct hda_verb stac9200_eapd_init[] = {
881 /* set dac0mux for dac converter */
882 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
883 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
887 static const struct hda_verb dell_eq_core_init[] = {
888 /* set master volume to max value without distortion
889 * and direct control */
890 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
894 static const struct hda_verb stac92hd73xx_core_init[] = {
895 /* set master volume and direct control */
896 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
900 static const struct hda_verb stac92hd83xxx_core_init[] = {
901 /* power state controls amps */
902 { 0x01, AC_VERB_SET_EAPD, 1 << 2},
906 static const struct hda_verb stac92hd71bxx_core_init[] = {
907 /* set master volume and direct control */
908 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
912 static const struct hda_verb stac92hd71bxx_unmute_core_init[] = {
913 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */
914 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
915 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
916 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
920 static const struct hda_verb stac925x_core_init[] = {
921 /* set dac0mux for dac converter */
922 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
923 /* mute the master volume */
924 { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
928 static const struct hda_verb stac922x_core_init[] = {
929 /* set master volume and direct control */
930 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
934 static const struct hda_verb d965_core_init[] = {
935 /* set master volume and direct control */
936 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
937 /* unmute node 0x1b */
938 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
939 /* select node 0x03 as DAC */
940 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
944 static const struct hda_verb dell_3st_core_init[] = {
945 /* don't set delta bit */
946 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
947 /* unmute node 0x1b */
948 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
949 /* select node 0x03 as DAC */
950 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
954 static const struct hda_verb stac927x_core_init[] = {
955 /* set master volume and direct control */
956 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
957 /* enable analog pc beep path */
958 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
962 static const struct hda_verb stac927x_volknob_core_init[] = {
963 /* don't set delta bit */
964 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
965 /* enable analog pc beep path */
966 {0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
970 static const struct hda_verb stac9205_core_init[] = {
971 /* set master volume and direct control */
972 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
973 /* enable analog pc beep path */
974 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
978 #define STAC_MONO_MUX \
980 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
981 .name = "Mono Mux", \
983 .info = stac92xx_mono_mux_enum_info, \
984 .get = stac92xx_mono_mux_enum_get, \
985 .put = stac92xx_mono_mux_enum_put, \
988 #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \
990 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
991 .name = "Analog Loopback", \
993 .info = stac92xx_aloopback_info, \
994 .get = stac92xx_aloopback_get, \
995 .put = stac92xx_aloopback_put, \
996 .private_value = verb_read | (verb_write << 16), \
999 #define DC_BIAS(xname, idx, nid) \
1001 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1004 .info = stac92xx_dc_bias_info, \
1005 .get = stac92xx_dc_bias_get, \
1006 .put = stac92xx_dc_bias_put, \
1007 .private_value = nid, \
1010 static const struct snd_kcontrol_new stac9200_mixer[] = {
1011 HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
1012 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
1013 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
1014 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
1018 static const struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = {
1019 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3),
1023 static const struct snd_kcontrol_new stac92hd73xx_8ch_loopback[] = {
1024 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4),
1028 static const struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = {
1029 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5),
1034 static const struct snd_kcontrol_new stac92hd71bxx_loopback[] = {
1035 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2)
1038 static const struct snd_kcontrol_new stac925x_mixer[] = {
1039 HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xe, 0, HDA_OUTPUT),
1040 HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT),
1044 static const struct snd_kcontrol_new stac9205_loopback[] = {
1045 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1),
1049 static const struct snd_kcontrol_new stac927x_loopback[] = {
1050 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1),
1054 static struct snd_kcontrol_new stac_dmux_mixer = {
1055 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1056 .name = "Digital Input Source",
1057 /* count set later */
1058 .info = stac92xx_dmux_enum_info,
1059 .get = stac92xx_dmux_enum_get,
1060 .put = stac92xx_dmux_enum_put,
1063 static struct snd_kcontrol_new stac_smux_mixer = {
1064 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1065 .name = "IEC958 Playback Source",
1066 /* count set later */
1067 .info = stac92xx_smux_enum_info,
1068 .get = stac92xx_smux_enum_get,
1069 .put = stac92xx_smux_enum_put,
1072 static const char * const slave_vols[] = {
1073 "Front Playback Volume",
1074 "Surround Playback Volume",
1075 "Center Playback Volume",
1076 "LFE Playback Volume",
1077 "Side Playback Volume",
1078 "Headphone Playback Volume",
1079 "Speaker Playback Volume",
1083 static const char * const slave_sws[] = {
1084 "Front Playback Switch",
1085 "Surround Playback Switch",
1086 "Center Playback Switch",
1087 "LFE Playback Switch",
1088 "Side Playback Switch",
1089 "Headphone Playback Switch",
1090 "Speaker Playback Switch",
1091 "IEC958 Playback Switch",
1095 static void stac92xx_free_kctls(struct hda_codec *codec);
1096 static int stac92xx_add_jack(struct hda_codec *codec, hda_nid_t nid, int type);
1098 static int stac92xx_build_controls(struct hda_codec *codec)
1100 struct sigmatel_spec *spec = codec->spec;
1101 struct auto_pin_cfg *cfg = &spec->autocfg;
1107 err = snd_hda_add_new_ctls(codec, spec->mixer);
1112 for (i = 0; i < spec->num_mixers; i++) {
1113 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1117 if (!spec->auto_mic && spec->num_dmuxes > 0 &&
1118 snd_hda_get_bool_hint(codec, "separate_dmux") == 1) {
1119 stac_dmux_mixer.count = spec->num_dmuxes;
1120 err = snd_hda_ctl_add(codec, 0,
1121 snd_ctl_new1(&stac_dmux_mixer, codec));
1125 if (spec->num_smuxes > 0) {
1126 int wcaps = get_wcaps(codec, spec->multiout.dig_out_nid);
1127 struct hda_input_mux *smux = &spec->private_smux;
1128 /* check for mute support on SPDIF out */
1129 if (wcaps & AC_WCAP_OUT_AMP) {
1130 snd_hda_add_imux_item(smux, "Off", 0, NULL);
1131 spec->spdif_mute = 1;
1133 stac_smux_mixer.count = spec->num_smuxes;
1134 err = snd_hda_ctl_add(codec, 0,
1135 snd_ctl_new1(&stac_smux_mixer, codec));
1140 if (spec->multiout.dig_out_nid) {
1141 err = snd_hda_create_spdif_out_ctls(codec,
1142 spec->multiout.dig_out_nid,
1143 spec->multiout.dig_out_nid);
1146 err = snd_hda_create_spdif_share_sw(codec,
1150 spec->multiout.share_spdif = 1;
1152 if (spec->dig_in_nid && !(spec->gpio_dir & 0x01)) {
1153 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1158 /* if we have no master control, let's create it */
1159 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1160 unsigned int vmaster_tlv[4];
1161 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
1162 HDA_OUTPUT, vmaster_tlv);
1163 /* correct volume offset */
1164 vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset;
1165 /* minimum value is actually mute */
1166 vmaster_tlv[3] |= TLV_DB_SCALE_MUTE;
1167 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1168 vmaster_tlv, slave_vols);
1172 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1173 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1179 if (spec->aloopback_ctl &&
1180 snd_hda_get_bool_hint(codec, "loopback") == 1) {
1181 err = snd_hda_add_new_ctls(codec, spec->aloopback_ctl);
1186 stac92xx_free_kctls(codec); /* no longer needed */
1188 /* create jack input elements */
1189 if (spec->hp_detect) {
1190 for (i = 0; i < cfg->hp_outs; i++) {
1191 int type = SND_JACK_HEADPHONE;
1192 nid = cfg->hp_pins[i];
1193 /* jack detection */
1194 if (cfg->hp_outs == i)
1195 type |= SND_JACK_LINEOUT;
1196 err = stac92xx_add_jack(codec, nid, type);
1201 for (i = 0; i < cfg->line_outs; i++) {
1202 err = stac92xx_add_jack(codec, cfg->line_out_pins[i],
1207 for (i = 0; i < cfg->num_inputs; i++) {
1208 nid = cfg->inputs[i].pin;
1209 err = stac92xx_add_jack(codec, nid, SND_JACK_MICROPHONE);
1217 static const unsigned int ref9200_pin_configs[8] = {
1218 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
1219 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
1222 static const unsigned int gateway9200_m4_pin_configs[8] = {
1223 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010,
1224 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3,
1226 static const unsigned int gateway9200_m4_2_pin_configs[8] = {
1227 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010,
1228 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3,
1232 STAC 9200 pin configs for
1237 static const unsigned int dell9200_d21_pin_configs[8] = {
1238 0x400001f0, 0x400001f1, 0x02214030, 0x01014010,
1239 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
1243 STAC 9200 pin configs for
1247 static const unsigned int dell9200_d22_pin_configs[8] = {
1248 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
1249 0x01813020, 0x02a19021, 0x90100140, 0x400001f2,
1253 STAC 9200 pin configs for
1254 102801C4 (Dell Dimension E310)
1261 static const unsigned int dell9200_d23_pin_configs[8] = {
1262 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
1263 0x01813020, 0x01a19021, 0x90100140, 0x400001f2,
1268 STAC 9200-32 pin configs for
1269 102801B5 (Dell Inspiron 630m)
1270 102801D8 (Dell Inspiron 640m)
1272 static const unsigned int dell9200_m21_pin_configs[8] = {
1273 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310,
1274 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd,
1278 STAC 9200-32 pin configs for
1279 102801C2 (Dell Latitude D620)
1281 102801CC (Dell Latitude D820)
1285 static const unsigned int dell9200_m22_pin_configs[8] = {
1286 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310,
1287 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc,
1291 STAC 9200-32 pin configs for
1292 102801CE (Dell XPS M1710)
1293 102801CF (Dell Precision M90)
1295 static const unsigned int dell9200_m23_pin_configs[8] = {
1296 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310,
1297 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc,
1301 STAC 9200-32 pin configs for
1304 102801CB (Dell Latitude 120L)
1307 static const unsigned int dell9200_m24_pin_configs[8] = {
1308 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310,
1309 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe,
1313 STAC 9200-32 pin configs for
1314 102801BD (Dell Inspiron E1505n)
1318 static const unsigned int dell9200_m25_pin_configs[8] = {
1319 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
1320 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd,
1324 STAC 9200-32 pin configs for
1325 102801F5 (Dell Inspiron 1501)
1328 static const unsigned int dell9200_m26_pin_configs[8] = {
1329 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310,
1330 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe,
1335 102801CD (Dell Inspiron E1705/9400)
1337 static const unsigned int dell9200_m27_pin_configs[8] = {
1338 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
1339 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc,
1342 static const unsigned int oqo9200_pin_configs[8] = {
1343 0x40c000f0, 0x404000f1, 0x0221121f, 0x02211210,
1344 0x90170111, 0x90a70120, 0x400000f2, 0x400000f3,
1348 static const unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
1349 [STAC_REF] = ref9200_pin_configs,
1350 [STAC_9200_OQO] = oqo9200_pin_configs,
1351 [STAC_9200_DELL_D21] = dell9200_d21_pin_configs,
1352 [STAC_9200_DELL_D22] = dell9200_d22_pin_configs,
1353 [STAC_9200_DELL_D23] = dell9200_d23_pin_configs,
1354 [STAC_9200_DELL_M21] = dell9200_m21_pin_configs,
1355 [STAC_9200_DELL_M22] = dell9200_m22_pin_configs,
1356 [STAC_9200_DELL_M23] = dell9200_m23_pin_configs,
1357 [STAC_9200_DELL_M24] = dell9200_m24_pin_configs,
1358 [STAC_9200_DELL_M25] = dell9200_m25_pin_configs,
1359 [STAC_9200_DELL_M26] = dell9200_m26_pin_configs,
1360 [STAC_9200_DELL_M27] = dell9200_m27_pin_configs,
1361 [STAC_9200_M4] = gateway9200_m4_pin_configs,
1362 [STAC_9200_M4_2] = gateway9200_m4_2_pin_configs,
1363 [STAC_9200_PANASONIC] = ref9200_pin_configs,
1366 static const char * const stac9200_models[STAC_9200_MODELS] = {
1367 [STAC_AUTO] = "auto",
1369 [STAC_9200_OQO] = "oqo",
1370 [STAC_9200_DELL_D21] = "dell-d21",
1371 [STAC_9200_DELL_D22] = "dell-d22",
1372 [STAC_9200_DELL_D23] = "dell-d23",
1373 [STAC_9200_DELL_M21] = "dell-m21",
1374 [STAC_9200_DELL_M22] = "dell-m22",
1375 [STAC_9200_DELL_M23] = "dell-m23",
1376 [STAC_9200_DELL_M24] = "dell-m24",
1377 [STAC_9200_DELL_M25] = "dell-m25",
1378 [STAC_9200_DELL_M26] = "dell-m26",
1379 [STAC_9200_DELL_M27] = "dell-m27",
1380 [STAC_9200_M4] = "gateway-m4",
1381 [STAC_9200_M4_2] = "gateway-m4-2",
1382 [STAC_9200_PANASONIC] = "panasonic",
1385 static const struct snd_pci_quirk stac9200_cfg_tbl[] = {
1386 /* SigmaTel reference board */
1387 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1388 "DFI LanParty", STAC_REF),
1389 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
1390 "DFI LanParty", STAC_REF),
1391 /* Dell laptops have BIOS problem */
1392 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
1393 "unknown Dell", STAC_9200_DELL_D21),
1394 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
1395 "Dell Inspiron 630m", STAC_9200_DELL_M21),
1396 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
1397 "Dell Inspiron E1505n", STAC_9200_DELL_M25),
1398 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
1399 "unknown Dell", STAC_9200_DELL_D22),
1400 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
1401 "unknown Dell", STAC_9200_DELL_D22),
1402 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
1403 "Dell Latitude D620", STAC_9200_DELL_M22),
1404 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
1405 "unknown Dell", STAC_9200_DELL_D23),
1406 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
1407 "unknown Dell", STAC_9200_DELL_D23),
1408 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
1409 "unknown Dell", STAC_9200_DELL_M22),
1410 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
1411 "unknown Dell", STAC_9200_DELL_M24),
1412 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
1413 "unknown Dell", STAC_9200_DELL_M24),
1414 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
1415 "Dell Latitude 120L", STAC_9200_DELL_M24),
1416 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
1417 "Dell Latitude D820", STAC_9200_DELL_M22),
1418 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
1419 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
1420 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
1421 "Dell XPS M1710", STAC_9200_DELL_M23),
1422 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
1423 "Dell Precision M90", STAC_9200_DELL_M23),
1424 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
1425 "unknown Dell", STAC_9200_DELL_M22),
1426 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
1427 "unknown Dell", STAC_9200_DELL_M22),
1428 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
1429 "unknown Dell", STAC_9200_DELL_M22),
1430 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
1431 "Dell Inspiron 640m", STAC_9200_DELL_M21),
1432 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
1433 "unknown Dell", STAC_9200_DELL_D23),
1434 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
1435 "unknown Dell", STAC_9200_DELL_D23),
1436 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
1437 "unknown Dell", STAC_9200_DELL_D21),
1438 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
1439 "unknown Dell", STAC_9200_DELL_D23),
1440 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
1441 "unknown Dell", STAC_9200_DELL_D21),
1442 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
1443 "unknown Dell", STAC_9200_DELL_M25),
1444 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
1445 "unknown Dell", STAC_9200_DELL_M25),
1446 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
1447 "Dell Inspiron 1501", STAC_9200_DELL_M26),
1448 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
1449 "unknown Dell", STAC_9200_DELL_M26),
1451 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC),
1452 /* Gateway machines needs EAPD to be set on resume */
1453 SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_M4),
1454 SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", STAC_9200_M4_2),
1455 SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", STAC_9200_M4_2),
1457 SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO),
1461 static const unsigned int ref925x_pin_configs[8] = {
1462 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
1463 0x90a70320, 0x02214210, 0x01019020, 0x9033032e,
1466 static const unsigned int stac925xM1_pin_configs[8] = {
1467 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1468 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
1471 static const unsigned int stac925xM1_2_pin_configs[8] = {
1472 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1473 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
1476 static const unsigned int stac925xM2_pin_configs[8] = {
1477 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1478 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
1481 static const unsigned int stac925xM2_2_pin_configs[8] = {
1482 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1483 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
1486 static const unsigned int stac925xM3_pin_configs[8] = {
1487 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1488 0x40a000f0, 0x90100210, 0x400003f1, 0x503303f3,
1491 static const unsigned int stac925xM5_pin_configs[8] = {
1492 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1493 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
1496 static const unsigned int stac925xM6_pin_configs[8] = {
1497 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1498 0x40a000f0, 0x90100210, 0x400003f1, 0x90330320,
1501 static const unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
1502 [STAC_REF] = ref925x_pin_configs,
1503 [STAC_M1] = stac925xM1_pin_configs,
1504 [STAC_M1_2] = stac925xM1_2_pin_configs,
1505 [STAC_M2] = stac925xM2_pin_configs,
1506 [STAC_M2_2] = stac925xM2_2_pin_configs,
1507 [STAC_M3] = stac925xM3_pin_configs,
1508 [STAC_M5] = stac925xM5_pin_configs,
1509 [STAC_M6] = stac925xM6_pin_configs,
1512 static const char * const stac925x_models[STAC_925x_MODELS] = {
1513 [STAC_925x_AUTO] = "auto",
1516 [STAC_M1_2] = "m1-2",
1518 [STAC_M2_2] = "m2-2",
1524 static const struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = {
1525 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2),
1526 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5),
1527 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1),
1528 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_M2),
1529 SND_PCI_QUIRK(0x107b, 0x0367, "Gateway MX6453", STAC_M1_2),
1530 /* Not sure about the brand name for those */
1531 SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M1),
1532 SND_PCI_QUIRK(0x107b, 0x0507, "Gateway mobile", STAC_M3),
1533 SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M6),
1534 SND_PCI_QUIRK(0x107b, 0x0685, "Gateway mobile", STAC_M2_2),
1538 static const struct snd_pci_quirk stac925x_cfg_tbl[] = {
1539 /* SigmaTel reference board */
1540 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
1541 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF),
1542 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
1544 /* Default table for unknown ID */
1545 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2),
1550 static const unsigned int ref92hd73xx_pin_configs[13] = {
1551 0x02214030, 0x02a19040, 0x01a19020, 0x02214030,
1552 0x0181302e, 0x01014010, 0x01014020, 0x01014030,
1553 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050,
1557 static const unsigned int dell_m6_pin_configs[13] = {
1558 0x0321101f, 0x4f00000f, 0x4f0000f0, 0x90170110,
1559 0x03a11020, 0x0321101f, 0x4f0000f0, 0x4f0000f0,
1560 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0,
1564 static const unsigned int alienware_m17x_pin_configs[13] = {
1565 0x0321101f, 0x0321101f, 0x03a11020, 0x03014020,
1566 0x90170110, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0,
1567 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0,
1571 static const unsigned int intel_dg45id_pin_configs[13] = {
1572 0x02214230, 0x02A19240, 0x01013214, 0x01014210,
1573 0x01A19250, 0x01011212, 0x01016211
1576 static const unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
1577 [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs,
1578 [STAC_DELL_M6_AMIC] = dell_m6_pin_configs,
1579 [STAC_DELL_M6_DMIC] = dell_m6_pin_configs,
1580 [STAC_DELL_M6_BOTH] = dell_m6_pin_configs,
1581 [STAC_DELL_EQ] = dell_m6_pin_configs,
1582 [STAC_ALIENWARE_M17X] = alienware_m17x_pin_configs,
1583 [STAC_92HD73XX_INTEL] = intel_dg45id_pin_configs,
1586 static const char * const stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
1587 [STAC_92HD73XX_AUTO] = "auto",
1588 [STAC_92HD73XX_NO_JD] = "no-jd",
1589 [STAC_92HD73XX_REF] = "ref",
1590 [STAC_92HD73XX_INTEL] = "intel",
1591 [STAC_DELL_M6_AMIC] = "dell-m6-amic",
1592 [STAC_DELL_M6_DMIC] = "dell-m6-dmic",
1593 [STAC_DELL_M6_BOTH] = "dell-m6",
1594 [STAC_DELL_EQ] = "dell-eq",
1595 [STAC_ALIENWARE_M17X] = "alienware",
1598 static const struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
1599 /* SigmaTel reference board */
1600 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1601 "DFI LanParty", STAC_92HD73XX_REF),
1602 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
1603 "DFI LanParty", STAC_92HD73XX_REF),
1604 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5002,
1605 "Intel DG45ID", STAC_92HD73XX_INTEL),
1606 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5003,
1607 "Intel DG45FC", STAC_92HD73XX_INTEL),
1608 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254,
1609 "Dell Studio 1535", STAC_DELL_M6_DMIC),
1610 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255,
1611 "unknown Dell", STAC_DELL_M6_DMIC),
1612 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256,
1613 "unknown Dell", STAC_DELL_M6_BOTH),
1614 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257,
1615 "unknown Dell", STAC_DELL_M6_BOTH),
1616 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e,
1617 "unknown Dell", STAC_DELL_M6_AMIC),
1618 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f,
1619 "unknown Dell", STAC_DELL_M6_AMIC),
1620 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271,
1621 "unknown Dell", STAC_DELL_M6_DMIC),
1622 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0272,
1623 "unknown Dell", STAC_DELL_M6_DMIC),
1624 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f,
1625 "Dell Studio 1537", STAC_DELL_M6_DMIC),
1626 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a0,
1627 "Dell Studio 17", STAC_DELL_M6_DMIC),
1628 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02be,
1629 "Dell Studio 1555", STAC_DELL_M6_DMIC),
1630 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd,
1631 "Dell Studio 1557", STAC_DELL_M6_DMIC),
1632 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe,
1633 "Dell Studio XPS 1645", STAC_DELL_M6_BOTH),
1634 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413,
1635 "Dell Studio 1558", STAC_DELL_M6_DMIC),
1639 static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = {
1640 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1,
1641 "Alienware M17x", STAC_ALIENWARE_M17X),
1642 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
1643 "Alienware M17x", STAC_ALIENWARE_M17X),
1647 static const unsigned int ref92hd83xxx_pin_configs[10] = {
1648 0x02214030, 0x02211010, 0x02a19020, 0x02170130,
1649 0x01014050, 0x01819040, 0x01014020, 0x90a3014e,
1650 0x01451160, 0x98560170,
1653 static const unsigned int dell_s14_pin_configs[10] = {
1654 0x0221403f, 0x0221101f, 0x02a19020, 0x90170110,
1655 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a60160,
1656 0x40f000f0, 0x40f000f0,
1659 static const unsigned int hp_dv7_4000_pin_configs[10] = {
1660 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110,
1661 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140,
1662 0x40f000f0, 0x40f000f0,
1665 static const unsigned int hp_cNB11_intquad_pin_configs[10] = {
1666 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110,
1667 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130,
1668 0x40f000f0, 0x40f000f0,
1671 static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
1672 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
1673 [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs,
1674 [STAC_DELL_S14] = dell_s14_pin_configs,
1675 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs,
1676 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
1679 static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1680 [STAC_92HD83XXX_AUTO] = "auto",
1681 [STAC_92HD83XXX_REF] = "ref",
1682 [STAC_92HD83XXX_PWR_REF] = "mic-ref",
1683 [STAC_DELL_S14] = "dell-s14",
1684 [STAC_92HD83XXX_HP] = "hp",
1685 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
1686 [STAC_HP_DV7_4000] = "hp-dv7-4000",
1689 static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1690 /* SigmaTel reference board */
1691 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1692 "DFI LanParty", STAC_92HD83XXX_REF),
1693 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
1694 "DFI LanParty", STAC_92HD83XXX_REF),
1695 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
1696 "unknown Dell", STAC_DELL_S14),
1697 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600,
1698 "HP", STAC_92HD83XXX_HP),
1699 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
1700 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1701 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657,
1702 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1703 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658,
1704 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1705 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659,
1706 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1707 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A,
1708 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1709 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
1710 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1711 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388,
1712 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1713 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389,
1714 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1715 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355B,
1716 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1717 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355C,
1718 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1719 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355D,
1720 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1721 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355E,
1722 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1723 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355F,
1724 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1725 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3560,
1726 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1727 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358B,
1728 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1729 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358C,
1730 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1731 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358D,
1732 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1733 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3591,
1734 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1735 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3592,
1736 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1737 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
1738 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1742 static const unsigned int ref92hd71bxx_pin_configs[STAC92HD71BXX_NUM_PINS] = {
1743 0x02214030, 0x02a19040, 0x01a19020, 0x01014010,
1744 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0,
1745 0x90a000f0, 0x01452050, 0x01452050, 0x00000000,
1749 static const unsigned int dell_m4_1_pin_configs[STAC92HD71BXX_NUM_PINS] = {
1750 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110,
1751 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0,
1752 0x40f000f0, 0x4f0000f0, 0x4f0000f0, 0x00000000,
1756 static const unsigned int dell_m4_2_pin_configs[STAC92HD71BXX_NUM_PINS] = {
1757 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110,
1758 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0,
1759 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000,
1763 static const unsigned int dell_m4_3_pin_configs[STAC92HD71BXX_NUM_PINS] = {
1764 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110,
1765 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0,
1766 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000,
1770 static const unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
1771 [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs,
1772 [STAC_DELL_M4_1] = dell_m4_1_pin_configs,
1773 [STAC_DELL_M4_2] = dell_m4_2_pin_configs,
1774 [STAC_DELL_M4_3] = dell_m4_3_pin_configs,
1775 [STAC_HP_M4] = NULL,
1776 [STAC_HP_DV4] = NULL,
1777 [STAC_HP_DV5] = NULL,
1778 [STAC_HP_HDX] = NULL,
1779 [STAC_HP_DV4_1222NR] = NULL,
1782 static const char * const stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
1783 [STAC_92HD71BXX_AUTO] = "auto",
1784 [STAC_92HD71BXX_REF] = "ref",
1785 [STAC_DELL_M4_1] = "dell-m4-1",
1786 [STAC_DELL_M4_2] = "dell-m4-2",
1787 [STAC_DELL_M4_3] = "dell-m4-3",
1788 [STAC_HP_M4] = "hp-m4",
1789 [STAC_HP_DV4] = "hp-dv4",
1790 [STAC_HP_DV5] = "hp-dv5",
1791 [STAC_HP_HDX] = "hp-hdx",
1792 [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr",
1795 static const struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1796 /* SigmaTel reference board */
1797 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1798 "DFI LanParty", STAC_92HD71BXX_REF),
1799 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
1800 "DFI LanParty", STAC_92HD71BXX_REF),
1801 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fb,
1802 "HP dv4-1222nr", STAC_HP_DV4_1222NR),
1803 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720,
1805 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
1807 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
1808 "HP dv4-7", STAC_HP_DV4),
1809 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600,
1810 "HP dv4-7", STAC_HP_DV5),
1811 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610,
1812 "HP HDX", STAC_HP_HDX), /* HDX18 */
1813 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
1814 "HP mini 1000", STAC_HP_M4),
1815 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b,
1816 "HP HDX", STAC_HP_HDX), /* HDX16 */
1817 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620,
1818 "HP dv6", STAC_HP_DV5),
1819 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061,
1820 "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */
1821 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x363e,
1822 "HP DV6", STAC_HP_DV5),
1823 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010,
1825 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
1826 "unknown Dell", STAC_DELL_M4_1),
1827 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234,
1828 "unknown Dell", STAC_DELL_M4_1),
1829 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0250,
1830 "unknown Dell", STAC_DELL_M4_1),
1831 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024f,
1832 "unknown Dell", STAC_DELL_M4_1),
1833 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024d,
1834 "unknown Dell", STAC_DELL_M4_1),
1835 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0251,
1836 "unknown Dell", STAC_DELL_M4_1),
1837 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0277,
1838 "unknown Dell", STAC_DELL_M4_1),
1839 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0263,
1840 "unknown Dell", STAC_DELL_M4_2),
1841 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0265,
1842 "unknown Dell", STAC_DELL_M4_2),
1843 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0262,
1844 "unknown Dell", STAC_DELL_M4_2),
1845 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264,
1846 "unknown Dell", STAC_DELL_M4_2),
1847 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02aa,
1848 "unknown Dell", STAC_DELL_M4_3),
1852 static const unsigned int ref922x_pin_configs[10] = {
1853 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
1854 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
1855 0x40000100, 0x40000100,
1859 STAC 922X pin configs for
1866 static const unsigned int dell_922x_d81_pin_configs[10] = {
1867 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
1868 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1,
1869 0x01813122, 0x400001f2,
1873 STAC 922X pin configs for
1877 static const unsigned int dell_922x_d82_pin_configs[10] = {
1878 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
1879 0x02a19020, 0x01117011, 0x01451140, 0x400001f0,
1880 0x01813122, 0x400001f1,
1884 STAC 922X pin configs for
1887 static const unsigned int dell_922x_m81_pin_configs[10] = {
1888 0x0321101f, 0x01112024, 0x01111222, 0x91174220,
1889 0x03a11050, 0x01116221, 0x90a70330, 0x01452340,
1890 0x40C003f1, 0x405003f0,
1894 STAC 9221 A1 pin configs for
1895 102801D7 (Dell XPS M1210)
1897 static const unsigned int dell_922x_m82_pin_configs[10] = {
1898 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310,
1899 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2,
1900 0x508003f3, 0x405003f4,
1903 static const unsigned int d945gtp3_pin_configs[10] = {
1904 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
1905 0x40000100, 0x40000100, 0x40000100, 0x40000100,
1906 0x02a19120, 0x40000100,
1909 static const unsigned int d945gtp5_pin_configs[10] = {
1910 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
1911 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
1912 0x02a19320, 0x40000100,
1915 static const unsigned int intel_mac_v1_pin_configs[10] = {
1916 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd,
1917 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240,
1918 0x400000fc, 0x400000fb,
1921 static const unsigned int intel_mac_v2_pin_configs[10] = {
1922 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
1923 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa,
1924 0x400000fc, 0x400000fb,
1927 static const unsigned int intel_mac_v3_pin_configs[10] = {
1928 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
1929 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240,
1930 0x400000fc, 0x400000fb,
1933 static const unsigned int intel_mac_v4_pin_configs[10] = {
1934 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
1935 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
1936 0x400000fc, 0x400000fb,
1939 static const unsigned int intel_mac_v5_pin_configs[10] = {
1940 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
1941 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
1942 0x400000fc, 0x400000fb,
1945 static const unsigned int ecs202_pin_configs[10] = {
1946 0x0221401f, 0x02a19020, 0x01a19020, 0x01114010,
1947 0x408000f0, 0x01813022, 0x074510a0, 0x40c400f1,
1948 0x9037012e, 0x40e000f2,
1951 static const unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
1952 [STAC_D945_REF] = ref922x_pin_configs,
1953 [STAC_D945GTP3] = d945gtp3_pin_configs,
1954 [STAC_D945GTP5] = d945gtp5_pin_configs,
1955 [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs,
1956 [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs,
1957 [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs,
1958 [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs,
1959 [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs,
1960 [STAC_INTEL_MAC_AUTO] = intel_mac_v3_pin_configs,
1961 /* for backward compatibility */
1962 [STAC_MACMINI] = intel_mac_v3_pin_configs,
1963 [STAC_MACBOOK] = intel_mac_v5_pin_configs,
1964 [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs,
1965 [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs,
1966 [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs,
1967 [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs,
1968 [STAC_ECS_202] = ecs202_pin_configs,
1969 [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs,
1970 [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs,
1971 [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs,
1972 [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs,
1975 static const char * const stac922x_models[STAC_922X_MODELS] = {
1976 [STAC_922X_AUTO] = "auto",
1977 [STAC_D945_REF] = "ref",
1978 [STAC_D945GTP5] = "5stack",
1979 [STAC_D945GTP3] = "3stack",
1980 [STAC_INTEL_MAC_V1] = "intel-mac-v1",
1981 [STAC_INTEL_MAC_V2] = "intel-mac-v2",
1982 [STAC_INTEL_MAC_V3] = "intel-mac-v3",
1983 [STAC_INTEL_MAC_V4] = "intel-mac-v4",
1984 [STAC_INTEL_MAC_V5] = "intel-mac-v5",
1985 [STAC_INTEL_MAC_AUTO] = "intel-mac-auto",
1986 /* for backward compatibility */
1987 [STAC_MACMINI] = "macmini",
1988 [STAC_MACBOOK] = "macbook",
1989 [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1",
1990 [STAC_MACBOOK_PRO_V2] = "macbook-pro",
1991 [STAC_IMAC_INTEL] = "imac-intel",
1992 [STAC_IMAC_INTEL_20] = "imac-intel-20",
1993 [STAC_ECS_202] = "ecs202",
1994 [STAC_922X_DELL_D81] = "dell-d81",
1995 [STAC_922X_DELL_D82] = "dell-d82",
1996 [STAC_922X_DELL_M81] = "dell-m81",
1997 [STAC_922X_DELL_M82] = "dell-m82",
2000 static const struct snd_pci_quirk stac922x_cfg_tbl[] = {
2001 /* SigmaTel reference board */
2002 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2003 "DFI LanParty", STAC_D945_REF),
2004 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
2005 "DFI LanParty", STAC_D945_REF),
2006 /* Intel 945G based systems */
2007 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
2008 "Intel D945G", STAC_D945GTP3),
2009 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
2010 "Intel D945G", STAC_D945GTP3),
2011 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
2012 "Intel D945G", STAC_D945GTP3),
2013 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
2014 "Intel D945G", STAC_D945GTP3),
2015 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
2016 "Intel D945G", STAC_D945GTP3),
2017 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
2018 "Intel D945G", STAC_D945GTP3),
2019 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
2020 "Intel D945G", STAC_D945GTP3),
2021 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
2022 "Intel D945G", STAC_D945GTP3),
2023 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
2024 "Intel D945G", STAC_D945GTP3),
2025 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
2026 "Intel D945G", STAC_D945GTP3),
2027 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
2028 "Intel D945G", STAC_D945GTP3),
2029 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
2030 "Intel D945G", STAC_D945GTP3),
2031 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
2032 "Intel D945G", STAC_D945GTP3),
2033 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
2034 "Intel D945G", STAC_D945GTP3),
2035 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
2036 "Intel D945G", STAC_D945GTP3),
2037 /* Intel D945G 5-stack systems */
2038 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
2039 "Intel D945G", STAC_D945GTP5),
2040 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
2041 "Intel D945G", STAC_D945GTP5),
2042 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
2043 "Intel D945G", STAC_D945GTP5),
2044 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
2045 "Intel D945G", STAC_D945GTP5),
2046 /* Intel 945P based systems */
2047 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
2048 "Intel D945P", STAC_D945GTP3),
2049 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
2050 "Intel D945P", STAC_D945GTP3),
2051 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
2052 "Intel D945P", STAC_D945GTP3),
2053 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
2054 "Intel D945P", STAC_D945GTP3),
2055 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
2056 "Intel D945P", STAC_D945GTP3),
2057 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
2058 "Intel D945P", STAC_D945GTP5),
2060 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0204,
2061 "Intel D945", STAC_D945_REF),
2063 /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */
2064 SND_PCI_QUIRK(0x8384, 0x7680,
2065 "Mac", STAC_INTEL_MAC_AUTO),
2067 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
2068 "unknown Dell", STAC_922X_DELL_D81),
2069 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
2070 "unknown Dell", STAC_922X_DELL_D81),
2071 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
2072 "unknown Dell", STAC_922X_DELL_D81),
2073 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
2074 "unknown Dell", STAC_922X_DELL_D82),
2075 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
2076 "unknown Dell", STAC_922X_DELL_M81),
2077 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
2078 "unknown Dell", STAC_922X_DELL_D82),
2079 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
2080 "unknown Dell", STAC_922X_DELL_D81),
2081 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
2082 "unknown Dell", STAC_922X_DELL_D81),
2083 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
2084 "Dell XPS M1210", STAC_922X_DELL_M82),
2085 /* ECS/PC Chips boards */
2086 SND_PCI_QUIRK_MASK(0x1019, 0xf000, 0x2000,
2087 "ECS/PC chips", STAC_ECS_202),
2091 static const unsigned int ref927x_pin_configs[14] = {
2092 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
2093 0x01a19040, 0x01011012, 0x01016011, 0x0101201f,
2094 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070,
2095 0x01c42190, 0x40000100,
2098 static const unsigned int d965_3st_pin_configs[14] = {
2099 0x0221401f, 0x02a19120, 0x40000100, 0x01014011,
2100 0x01a19021, 0x01813024, 0x40000100, 0x40000100,
2101 0x40000100, 0x40000100, 0x40000100, 0x40000100,
2102 0x40000100, 0x40000100
2105 static const unsigned int d965_5st_pin_configs[14] = {
2106 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
2107 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
2108 0x40000100, 0x40000100, 0x40000100, 0x01442070,
2109 0x40000100, 0x40000100
2112 static const unsigned int d965_5st_no_fp_pin_configs[14] = {
2113 0x40000100, 0x40000100, 0x0181304e, 0x01014010,
2114 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
2115 0x40000100, 0x40000100, 0x40000100, 0x01442070,
2116 0x40000100, 0x40000100
2119 static const unsigned int dell_3st_pin_configs[14] = {
2120 0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
2121 0x01111212, 0x01116211, 0x01813050, 0x01112214,
2122 0x403003fa, 0x90a60040, 0x90a60040, 0x404003fb,
2123 0x40c003fc, 0x40000100
2126 static const unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
2127 [STAC_D965_REF_NO_JD] = ref927x_pin_configs,
2128 [STAC_D965_REF] = ref927x_pin_configs,
2129 [STAC_D965_3ST] = d965_3st_pin_configs,
2130 [STAC_D965_5ST] = d965_5st_pin_configs,
2131 [STAC_D965_5ST_NO_FP] = d965_5st_no_fp_pin_configs,
2132 [STAC_DELL_3ST] = dell_3st_pin_configs,
2133 [STAC_DELL_BIOS] = NULL,
2134 [STAC_927X_VOLKNOB] = NULL,
2137 static const char * const stac927x_models[STAC_927X_MODELS] = {
2138 [STAC_927X_AUTO] = "auto",
2139 [STAC_D965_REF_NO_JD] = "ref-no-jd",
2140 [STAC_D965_REF] = "ref",
2141 [STAC_D965_3ST] = "3stack",
2142 [STAC_D965_5ST] = "5stack",
2143 [STAC_D965_5ST_NO_FP] = "5stack-no-fp",
2144 [STAC_DELL_3ST] = "dell-3stack",
2145 [STAC_DELL_BIOS] = "dell-bios",
2146 [STAC_927X_VOLKNOB] = "volknob",
2149 static const struct snd_pci_quirk stac927x_cfg_tbl[] = {
2150 /* SigmaTel reference board */
2151 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2152 "DFI LanParty", STAC_D965_REF),
2153 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
2154 "DFI LanParty", STAC_D965_REF),
2155 /* Intel 946 based systems */
2156 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
2157 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
2158 /* 965 based 3 stack systems */
2159 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2100,
2160 "Intel D965", STAC_D965_3ST),
2161 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000,
2162 "Intel D965", STAC_D965_3ST),
2163 /* Dell 3 stack systems */
2164 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
2165 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
2166 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
2167 /* Dell 3 stack systems with verb table in BIOS */
2168 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
2169 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_BIOS),
2170 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
2171 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS),
2172 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS),
2173 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
2174 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
2175 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
2176 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS),
2177 /* 965 based 5 stack systems */
2178 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2300,
2179 "Intel D965", STAC_D965_5ST),
2180 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500,
2181 "Intel D965", STAC_D965_5ST),
2182 /* volume-knob fixes */
2183 SND_PCI_QUIRK_VENDOR(0x10cf, "FSC", STAC_927X_VOLKNOB),
2187 static const unsigned int ref9205_pin_configs[12] = {
2188 0x40000100, 0x40000100, 0x01016011, 0x01014010,
2189 0x01813122, 0x01a19021, 0x01019020, 0x40000100,
2190 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
2194 STAC 9205 pin configs for
2201 10280228 (Dell Vostro 1500)
2202 10280229 (Dell Vostro 1700)
2204 static const unsigned int dell_9205_m42_pin_configs[12] = {
2205 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310,
2206 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9,
2207 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE,
2211 STAC 9205 pin configs for
2215 102801FF (Dell Precision M4300)
2220 static const unsigned int dell_9205_m43_pin_configs[12] = {
2221 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310,
2222 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9,
2223 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8,
2226 static const unsigned int dell_9205_m44_pin_configs[12] = {
2227 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310,
2228 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9,
2229 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe,
2232 static const unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
2233 [STAC_9205_REF] = ref9205_pin_configs,
2234 [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs,
2235 [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs,
2236 [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs,
2237 [STAC_9205_EAPD] = NULL,
2240 static const char * const stac9205_models[STAC_9205_MODELS] = {
2241 [STAC_9205_AUTO] = "auto",
2242 [STAC_9205_REF] = "ref",
2243 [STAC_9205_DELL_M42] = "dell-m42",
2244 [STAC_9205_DELL_M43] = "dell-m43",
2245 [STAC_9205_DELL_M44] = "dell-m44",
2246 [STAC_9205_EAPD] = "eapd",
2249 static const struct snd_pci_quirk stac9205_cfg_tbl[] = {
2250 /* SigmaTel reference board */
2251 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2252 "DFI LanParty", STAC_9205_REF),
2253 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xfb30,
2254 "SigmaTel", STAC_9205_REF),
2255 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
2256 "DFI LanParty", STAC_9205_REF),
2258 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
2259 "unknown Dell", STAC_9205_DELL_M42),
2260 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
2261 "unknown Dell", STAC_9205_DELL_M42),
2262 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
2263 "Dell Precision", STAC_9205_DELL_M43),
2264 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
2265 "Dell Precision", STAC_9205_DELL_M43),
2266 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
2267 "Dell Precision", STAC_9205_DELL_M43),
2268 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
2269 "unknown Dell", STAC_9205_DELL_M42),
2270 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
2271 "unknown Dell", STAC_9205_DELL_M42),
2272 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
2273 "Dell Precision", STAC_9205_DELL_M43),
2274 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
2275 "Dell Precision M4300", STAC_9205_DELL_M43),
2276 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
2277 "unknown Dell", STAC_9205_DELL_M42),
2278 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
2279 "Dell Precision", STAC_9205_DELL_M43),
2280 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
2281 "Dell Precision", STAC_9205_DELL_M43),
2282 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
2283 "Dell Precision", STAC_9205_DELL_M43),
2284 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
2285 "Dell Inspiron", STAC_9205_DELL_M44),
2286 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228,
2287 "Dell Vostro 1500", STAC_9205_DELL_M42),
2288 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0229,
2289 "Dell Vostro 1700", STAC_9205_DELL_M42),
2291 SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD),
2292 SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD),
2296 static void stac92xx_set_config_regs(struct hda_codec *codec,
2297 const unsigned int *pincfgs)
2300 struct sigmatel_spec *spec = codec->spec;
2305 for (i = 0; i < spec->num_pins; i++)
2306 if (spec->pin_nids[i] && pincfgs[i])
2307 snd_hda_codec_set_pincfg(codec, spec->pin_nids[i],
2312 * Analog playback callbacks
2314 static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
2315 struct hda_codec *codec,
2316 struct snd_pcm_substream *substream)
2318 struct sigmatel_spec *spec = codec->spec;
2319 if (spec->stream_delay)
2320 msleep(spec->stream_delay);
2321 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2325 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2326 struct hda_codec *codec,
2327 unsigned int stream_tag,
2328 unsigned int format,
2329 struct snd_pcm_substream *substream)
2331 struct sigmatel_spec *spec = codec->spec;
2332 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream);
2335 static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2336 struct hda_codec *codec,
2337 struct snd_pcm_substream *substream)
2339 struct sigmatel_spec *spec = codec->spec;
2340 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2344 * Digital playback callbacks
2346 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2347 struct hda_codec *codec,
2348 struct snd_pcm_substream *substream)
2350 struct sigmatel_spec *spec = codec->spec;
2351 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2354 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2355 struct hda_codec *codec,
2356 struct snd_pcm_substream *substream)
2358 struct sigmatel_spec *spec = codec->spec;
2359 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2362 static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2363 struct hda_codec *codec,
2364 unsigned int stream_tag,
2365 unsigned int format,
2366 struct snd_pcm_substream *substream)
2368 struct sigmatel_spec *spec = codec->spec;
2369 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2370 stream_tag, format, substream);
2373 static int stac92xx_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2374 struct hda_codec *codec,
2375 struct snd_pcm_substream *substream)
2377 struct sigmatel_spec *spec = codec->spec;
2378 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
2383 * Analog capture callbacks
2385 static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2386 struct hda_codec *codec,
2387 unsigned int stream_tag,
2388 unsigned int format,
2389 struct snd_pcm_substream *substream)
2391 struct sigmatel_spec *spec = codec->spec;
2392 hda_nid_t nid = spec->adc_nids[substream->number];
2394 if (spec->powerdown_adcs) {
2396 snd_hda_codec_write(codec, nid, 0,
2397 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
2399 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
2403 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2404 struct hda_codec *codec,
2405 struct snd_pcm_substream *substream)
2407 struct sigmatel_spec *spec = codec->spec;
2408 hda_nid_t nid = spec->adc_nids[substream->number];
2410 snd_hda_codec_cleanup_stream(codec, nid);
2411 if (spec->powerdown_adcs)
2412 snd_hda_codec_write(codec, nid, 0,
2413 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
2417 static const struct hda_pcm_stream stac92xx_pcm_digital_playback = {
2421 /* NID is set in stac92xx_build_pcms */
2423 .open = stac92xx_dig_playback_pcm_open,
2424 .close = stac92xx_dig_playback_pcm_close,
2425 .prepare = stac92xx_dig_playback_pcm_prepare,
2426 .cleanup = stac92xx_dig_playback_pcm_cleanup
2430 static const struct hda_pcm_stream stac92xx_pcm_digital_capture = {
2434 /* NID is set in stac92xx_build_pcms */
2437 static const struct hda_pcm_stream stac92xx_pcm_analog_playback = {
2441 .nid = 0x02, /* NID to query formats and rates */
2443 .open = stac92xx_playback_pcm_open,
2444 .prepare = stac92xx_playback_pcm_prepare,
2445 .cleanup = stac92xx_playback_pcm_cleanup
2449 static const struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
2453 .nid = 0x06, /* NID to query formats and rates */
2455 .open = stac92xx_playback_pcm_open,
2456 .prepare = stac92xx_playback_pcm_prepare,
2457 .cleanup = stac92xx_playback_pcm_cleanup
2461 static const struct hda_pcm_stream stac92xx_pcm_analog_capture = {
2464 /* NID + .substreams is set in stac92xx_build_pcms */
2466 .prepare = stac92xx_capture_pcm_prepare,
2467 .cleanup = stac92xx_capture_pcm_cleanup
2471 static int stac92xx_build_pcms(struct hda_codec *codec)
2473 struct sigmatel_spec *spec = codec->spec;
2474 struct hda_pcm *info = spec->pcm_rec;
2476 codec->num_pcms = 1;
2477 codec->pcm_info = info;
2479 info->name = "STAC92xx Analog";
2480 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
2481 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2482 spec->multiout.dac_nids[0];
2483 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
2484 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2485 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs;
2487 if (spec->alt_switch) {
2490 info->name = "STAC92xx Analog Alt";
2491 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback;
2494 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2497 info->name = "STAC92xx Digital";
2498 info->pcm_type = spec->autocfg.dig_out_type[0];
2499 if (spec->multiout.dig_out_nid) {
2500 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
2501 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2503 if (spec->dig_in_nid) {
2504 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture;
2505 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2512 static unsigned int stac92xx_get_default_vref(struct hda_codec *codec,
2515 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
2516 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
2517 if (pincap & AC_PINCAP_VREF_100)
2518 return AC_PINCTL_VREF_100;
2519 if (pincap & AC_PINCAP_VREF_80)
2520 return AC_PINCTL_VREF_80;
2521 if (pincap & AC_PINCAP_VREF_50)
2522 return AC_PINCTL_VREF_50;
2523 if (pincap & AC_PINCAP_VREF_GRD)
2524 return AC_PINCTL_VREF_GRD;
2528 static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
2531 snd_hda_codec_write_cache(codec, nid, 0,
2532 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
2535 #define stac92xx_hp_switch_info snd_ctl_boolean_mono_info
2537 static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol,
2538 struct snd_ctl_elem_value *ucontrol)
2540 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2541 struct sigmatel_spec *spec = codec->spec;
2543 ucontrol->value.integer.value[0] = !!spec->hp_switch;
2547 static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid);
2549 static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
2550 struct snd_ctl_elem_value *ucontrol)
2552 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2553 struct sigmatel_spec *spec = codec->spec;
2554 int nid = kcontrol->private_value;
2556 spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0;
2558 /* check to be sure that the ports are up to date with
2561 stac_issue_unsol_event(codec, nid);
2566 static int stac92xx_dc_bias_info(struct snd_kcontrol *kcontrol,
2567 struct snd_ctl_elem_info *uinfo)
2570 static const char * const texts[] = {
2571 "Mic In", "Line In", "Line Out"
2574 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2575 struct sigmatel_spec *spec = codec->spec;
2576 hda_nid_t nid = kcontrol->private_value;
2578 if (nid == spec->mic_switch || nid == spec->line_switch)
2583 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2584 uinfo->value.enumerated.items = i;
2586 if (uinfo->value.enumerated.item >= i)
2587 uinfo->value.enumerated.item = i-1;
2588 strcpy(uinfo->value.enumerated.name,
2589 texts[uinfo->value.enumerated.item]);
2594 static int stac92xx_dc_bias_get(struct snd_kcontrol *kcontrol,
2595 struct snd_ctl_elem_value *ucontrol)
2597 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2598 hda_nid_t nid = kcontrol->private_value;
2599 unsigned int vref = stac92xx_vref_get(codec, nid);
2601 if (vref == stac92xx_get_default_vref(codec, nid))
2602 ucontrol->value.enumerated.item[0] = 0;
2603 else if (vref == AC_PINCTL_VREF_GRD)
2604 ucontrol->value.enumerated.item[0] = 1;
2605 else if (vref == AC_PINCTL_VREF_HIZ)
2606 ucontrol->value.enumerated.item[0] = 2;
2611 static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol,
2612 struct snd_ctl_elem_value *ucontrol)
2614 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2615 unsigned int new_vref = 0;
2617 hda_nid_t nid = kcontrol->private_value;
2619 if (ucontrol->value.enumerated.item[0] == 0)
2620 new_vref = stac92xx_get_default_vref(codec, nid);
2621 else if (ucontrol->value.enumerated.item[0] == 1)
2622 new_vref = AC_PINCTL_VREF_GRD;
2623 else if (ucontrol->value.enumerated.item[0] == 2)
2624 new_vref = AC_PINCTL_VREF_HIZ;
2628 if (new_vref != stac92xx_vref_get(codec, nid)) {
2629 error = stac92xx_vref_set(codec, nid, new_vref);
2636 static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol,
2637 struct snd_ctl_elem_info *uinfo)
2640 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2641 struct sigmatel_spec *spec = codec->spec;
2643 if (kcontrol->private_value == spec->line_switch)
2644 texts[0] = "Line In";
2646 texts[0] = "Mic In";
2647 texts[1] = "Line Out";
2648 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2649 uinfo->value.enumerated.items = 2;
2652 if (uinfo->value.enumerated.item >= 2)
2653 uinfo->value.enumerated.item = 1;
2654 strcpy(uinfo->value.enumerated.name,
2655 texts[uinfo->value.enumerated.item]);
2660 static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2662 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2663 struct sigmatel_spec *spec = codec->spec;
2664 hda_nid_t nid = kcontrol->private_value;
2665 int io_idx = (nid == spec->mic_switch) ? 1 : 0;
2667 ucontrol->value.enumerated.item[0] = spec->io_switch[io_idx];
2671 static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2673 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2674 struct sigmatel_spec *spec = codec->spec;
2675 hda_nid_t nid = kcontrol->private_value;
2676 int io_idx = (nid == spec->mic_switch) ? 1 : 0;
2677 unsigned short val = !!ucontrol->value.enumerated.item[0];
2679 spec->io_switch[io_idx] = val;
2682 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
2684 unsigned int pinctl = AC_PINCTL_IN_EN;
2685 if (io_idx) /* set VREF for mic */
2686 pinctl |= stac92xx_get_default_vref(codec, nid);
2687 stac92xx_auto_set_pinctl(codec, nid, pinctl);
2690 /* check the auto-mute again: we need to mute/unmute the speaker
2691 * appropriately according to the pin direction
2693 if (spec->hp_detect)
2694 stac_issue_unsol_event(codec, nid);
2699 #define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info
2701 static int stac92xx_clfe_switch_get(struct snd_kcontrol *kcontrol,
2702 struct snd_ctl_elem_value *ucontrol)
2704 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2705 struct sigmatel_spec *spec = codec->spec;
2707 ucontrol->value.integer.value[0] = spec->clfe_swap;
2711 static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
2712 struct snd_ctl_elem_value *ucontrol)
2714 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2715 struct sigmatel_spec *spec = codec->spec;
2716 hda_nid_t nid = kcontrol->private_value & 0xff;
2717 unsigned int val = !!ucontrol->value.integer.value[0];
2719 if (spec->clfe_swap == val)
2722 spec->clfe_swap = val;
2724 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
2725 spec->clfe_swap ? 0x4 : 0x0);
2730 #define STAC_CODEC_HP_SWITCH(xname) \
2731 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2734 .info = stac92xx_hp_switch_info, \
2735 .get = stac92xx_hp_switch_get, \
2736 .put = stac92xx_hp_switch_put, \
2739 #define STAC_CODEC_IO_SWITCH(xname, xpval) \
2740 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2743 .info = stac92xx_io_switch_info, \
2744 .get = stac92xx_io_switch_get, \
2745 .put = stac92xx_io_switch_put, \
2746 .private_value = xpval, \
2749 #define STAC_CODEC_CLFE_SWITCH(xname, xpval) \
2750 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2753 .info = stac92xx_clfe_switch_info, \
2754 .get = stac92xx_clfe_switch_get, \
2755 .put = stac92xx_clfe_switch_put, \
2756 .private_value = xpval, \
2760 STAC_CTL_WIDGET_VOL,
2761 STAC_CTL_WIDGET_MUTE,
2762 STAC_CTL_WIDGET_MUTE_BEEP,
2763 STAC_CTL_WIDGET_MONO_MUX,
2764 STAC_CTL_WIDGET_HP_SWITCH,
2765 STAC_CTL_WIDGET_IO_SWITCH,
2766 STAC_CTL_WIDGET_CLFE_SWITCH,
2767 STAC_CTL_WIDGET_DC_BIAS
2770 static const struct snd_kcontrol_new stac92xx_control_templates[] = {
2771 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2772 HDA_CODEC_MUTE(NULL, 0, 0, 0),
2773 HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0),
2775 STAC_CODEC_HP_SWITCH(NULL),
2776 STAC_CODEC_IO_SWITCH(NULL, 0),
2777 STAC_CODEC_CLFE_SWITCH(NULL, 0),
2778 DC_BIAS(NULL, 0, 0),
2781 /* add dynamic controls */
2782 static struct snd_kcontrol_new *
2783 stac_control_new(struct sigmatel_spec *spec,
2784 const struct snd_kcontrol_new *ktemp,
2786 unsigned int subdev)
2788 struct snd_kcontrol_new *knew;
2790 snd_array_init(&spec->kctls, sizeof(*knew), 32);
2791 knew = snd_array_new(&spec->kctls);
2795 knew->name = kstrdup(name, GFP_KERNEL);
2798 memset(knew, 0, sizeof(*knew));
2799 spec->kctls.alloced--;
2802 knew->subdevice = subdev;
2806 static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
2807 const struct snd_kcontrol_new *ktemp,
2808 int idx, const char *name,
2811 struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name,
2812 HDA_SUBDEV_AMP_FLAG);
2816 knew->private_value = val;
2820 static inline int stac92xx_add_control_idx(struct sigmatel_spec *spec,
2821 int type, int idx, const char *name,
2824 return stac92xx_add_control_temp(spec,
2825 &stac92xx_control_templates[type],
2830 /* add dynamic controls */
2831 static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type,
2832 const char *name, unsigned long val)
2834 return stac92xx_add_control_idx(spec, type, 0, name, val);
2837 static const struct snd_kcontrol_new stac_input_src_temp = {
2838 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2839 .name = "Input Source",
2840 .info = stac92xx_mux_enum_info,
2841 .get = stac92xx_mux_enum_get,
2842 .put = stac92xx_mux_enum_put,
2845 static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec,
2846 hda_nid_t nid, int idx)
2848 int def_conf = snd_hda_codec_get_pincfg(codec, nid);
2850 struct sigmatel_spec *spec = codec->spec;
2853 if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
2854 if (stac92xx_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
2855 && nid == spec->line_switch)
2856 control = STAC_CTL_WIDGET_IO_SWITCH;
2857 else if (snd_hda_query_pin_caps(codec, nid)
2858 & (AC_PINCAP_VREF_GRD << AC_PINCAP_VREF_SHIFT))
2859 control = STAC_CTL_WIDGET_DC_BIAS;
2860 else if (nid == spec->mic_switch)
2861 control = STAC_CTL_WIDGET_IO_SWITCH;
2865 strcpy(name, hda_get_input_pin_label(codec, nid, 1));
2866 return stac92xx_add_control(codec->spec, control,
2867 strcat(name, " Jack Mode"), nid);
2873 static int stac92xx_add_input_source(struct sigmatel_spec *spec)
2875 struct snd_kcontrol_new *knew;
2876 struct hda_input_mux *imux = &spec->private_imux;
2879 return 0; /* no need for input source */
2880 if (!spec->num_adcs || imux->num_items <= 1)
2881 return 0; /* no need for input source control */
2882 knew = stac_control_new(spec, &stac_input_src_temp,
2883 stac_input_src_temp.name, 0);
2886 knew->count = spec->num_adcs;
2890 /* check whether the line-input can be used as line-out */
2891 static hda_nid_t check_line_out_switch(struct hda_codec *codec)
2893 struct sigmatel_spec *spec = codec->spec;
2894 struct auto_pin_cfg *cfg = &spec->autocfg;
2896 unsigned int pincap;
2899 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
2901 for (i = 0; i < cfg->num_inputs; i++) {
2902 if (cfg->inputs[i].type == AUTO_PIN_LINE_IN) {
2903 nid = cfg->inputs[i].pin;
2904 pincap = snd_hda_query_pin_caps(codec, nid);
2905 if (pincap & AC_PINCAP_OUT)
2912 static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid);
2914 /* check whether the mic-input can be used as line-out */
2915 static hda_nid_t check_mic_out_switch(struct hda_codec *codec, hda_nid_t *dac)
2917 struct sigmatel_spec *spec = codec->spec;
2918 struct auto_pin_cfg *cfg = &spec->autocfg;
2919 unsigned int def_conf, pincap;
2923 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
2925 for (i = 0; i < cfg->num_inputs; i++) {
2926 hda_nid_t nid = cfg->inputs[i].pin;
2927 if (cfg->inputs[i].type != AUTO_PIN_MIC)
2929 def_conf = snd_hda_codec_get_pincfg(codec, nid);
2930 /* some laptops have an internal analog microphone
2931 * which can't be used as a output */
2932 if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
2933 pincap = snd_hda_query_pin_caps(codec, nid);
2934 if (pincap & AC_PINCAP_OUT) {
2935 *dac = get_unassigned_dac(codec, nid);
2944 static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2948 for (i = 0; i < spec->multiout.num_dacs; i++) {
2949 if (spec->multiout.dac_nids[i] == nid)
2956 static int check_all_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2959 if (is_in_dac_nids(spec, nid))
2961 for (i = 0; i < spec->autocfg.hp_outs; i++)
2962 if (spec->hp_dacs[i] == nid)
2964 for (i = 0; i < spec->autocfg.speaker_outs; i++)
2965 if (spec->speaker_dacs[i] == nid)
2970 static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
2972 struct sigmatel_spec *spec = codec->spec;
2974 hda_nid_t conn[HDA_MAX_CONNECTIONS];
2975 unsigned int wcaps, wtype;
2977 conn_len = snd_hda_get_connections(codec, nid, conn,
2978 HDA_MAX_CONNECTIONS);
2979 /* 92HD88: trace back up the link of nids to find the DAC */
2980 while (conn_len == 1 && (get_wcaps_type(get_wcaps(codec, conn[0]))
2981 != AC_WID_AUD_OUT)) {
2983 conn_len = snd_hda_get_connections(codec, nid, conn,
2984 HDA_MAX_CONNECTIONS);
2986 for (j = 0; j < conn_len; j++) {
2987 wcaps = get_wcaps(codec, conn[j]);
2988 wtype = get_wcaps_type(wcaps);
2989 /* we check only analog outputs */
2990 if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL))
2992 /* if this route has a free DAC, assign it */
2993 if (!check_all_dac_nids(spec, conn[j])) {
2995 /* select this DAC in the pin's input mux */
2996 snd_hda_codec_write_cache(codec, nid, 0,
2997 AC_VERB_SET_CONNECT_SEL, j);
3002 /* if all DACs are already assigned, connect to the primary DAC */
3004 for (j = 0; j < conn_len; j++) {
3005 if (conn[j] == spec->multiout.dac_nids[0]) {
3006 snd_hda_codec_write_cache(codec, nid, 0,
3007 AC_VERB_SET_CONNECT_SEL, j);
3015 static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
3016 static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
3019 * Fill in the dac_nids table from the parsed pin configuration
3020 * This function only works when every pin in line_out_pins[]
3021 * contains atleast one DAC in its connection list. Some 92xx
3022 * codecs are not connected directly to a DAC, such as the 9200
3023 * and 9202/925x. For those, dac_nids[] must be hard-coded.
3025 static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec)
3027 struct sigmatel_spec *spec = codec->spec;
3028 struct auto_pin_cfg *cfg = &spec->autocfg;
3032 for (i = 0; i < cfg->line_outs; i++) {
3033 nid = cfg->line_out_pins[i];
3034 dac = get_unassigned_dac(codec, nid);
3036 if (spec->multiout.num_dacs > 0) {
3037 /* we have already working output pins,
3038 * so let's drop the broken ones again
3040 cfg->line_outs = spec->multiout.num_dacs;
3043 /* error out, no available DAC found */
3045 "%s: No available DAC for pin 0x%x\n",
3049 add_spec_dacs(spec, dac);
3052 for (i = 0; i < cfg->hp_outs; i++) {
3053 nid = cfg->hp_pins[i];
3054 dac = get_unassigned_dac(codec, nid);
3056 if (!spec->multiout.hp_nid)
3057 spec->multiout.hp_nid = dac;
3059 add_spec_extra_dacs(spec, dac);
3061 spec->hp_dacs[i] = dac;
3064 for (i = 0; i < cfg->speaker_outs; i++) {
3065 nid = cfg->speaker_pins[i];
3066 dac = get_unassigned_dac(codec, nid);
3068 add_spec_extra_dacs(spec, dac);
3069 spec->speaker_dacs[i] = dac;
3072 /* add line-in as output */
3073 nid = check_line_out_switch(codec);
3075 dac = get_unassigned_dac(codec, nid);
3077 snd_printdd("STAC: Add line-in 0x%x as output %d\n",
3078 nid, cfg->line_outs);
3079 cfg->line_out_pins[cfg->line_outs] = nid;
3081 spec->line_switch = nid;
3082 add_spec_dacs(spec, dac);
3085 /* add mic as output */
3086 nid = check_mic_out_switch(codec, &dac);
3088 snd_printdd("STAC: Add mic-in 0x%x as output %d\n",
3089 nid, cfg->line_outs);
3090 cfg->line_out_pins[cfg->line_outs] = nid;
3092 spec->mic_switch = nid;
3093 add_spec_dacs(spec, dac);
3096 snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
3097 spec->multiout.num_dacs,
3098 spec->multiout.dac_nids[0],
3099 spec->multiout.dac_nids[1],
3100 spec->multiout.dac_nids[2],
3101 spec->multiout.dac_nids[3],
3102 spec->multiout.dac_nids[4]);
3107 /* create volume control/switch for the given prefx type */
3108 static int create_controls_idx(struct hda_codec *codec, const char *pfx,
3109 int idx, hda_nid_t nid, int chs)
3111 struct sigmatel_spec *spec = codec->spec;
3115 if (!spec->check_volume_offset) {
3116 unsigned int caps, step, nums, db_scale;
3117 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
3118 step = (caps & AC_AMPCAP_STEP_SIZE) >>
3119 AC_AMPCAP_STEP_SIZE_SHIFT;
3120 step = (step + 1) * 25; /* in .01dB unit */
3121 nums = (caps & AC_AMPCAP_NUM_STEPS) >>
3122 AC_AMPCAP_NUM_STEPS_SHIFT;
3123 db_scale = nums * step;
3124 /* if dB scale is over -64dB, and finer enough,
3125 * let's reduce it to half
3127 if (db_scale > 6400 && nums >= 0x1f)
3128 spec->volume_offset = nums / 2;
3129 spec->check_volume_offset = 1;
3132 sprintf(name, "%s Playback Volume", pfx);
3133 err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_VOL, idx, name,
3134 HDA_COMPOSE_AMP_VAL_OFS(nid, chs, 0, HDA_OUTPUT,
3135 spec->volume_offset));
3138 sprintf(name, "%s Playback Switch", pfx);
3139 err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_MUTE, idx, name,
3140 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
3146 #define create_controls(codec, pfx, nid, chs) \
3147 create_controls_idx(codec, pfx, 0, nid, chs)
3149 static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)