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 <linux/module.h>
33 #include <sound/core.h>
34 #include <sound/asoundef.h>
35 #include <sound/jack.h>
36 #include <sound/tlv.h>
37 #include "hda_codec.h"
38 #include "hda_local.h"
39 #include "hda_auto_parser.h"
82 STAC_92HD73XX_NO_JD, /* no jack-detection */
96 STAC_92HD83XXX_PWR_REF,
98 STAC_DELL_VOSTRO_3500,
99 STAC_92HD83XXX_HP_cNB11_INTQUAD,
102 STAC_92HD83XXX_HP_LED,
103 STAC_92HD83XXX_HP_INV_LED,
104 STAC_92HD83XXX_HP_MIC_LED,
105 STAC_92HD83XXX_HEADSET_JACK,
106 STAC_92HD83XXX_MODELS
120 STAC_92HD71BXX_NO_DMIC,
121 STAC_92HD71BXX_NO_SMUX,
122 STAC_92HD71BXX_MODELS
152 STAC_922X_INTEL_MAC_GPIO,
157 STAC_D965_REF_NO_JD, /* no jack-detection */
165 STAC_DELL_BIOS_SPDIF,
176 struct sigmatel_mic_route {
179 signed char dmux_idx;
182 #define MAX_PINS_NUM 16
183 #define MAX_ADCS_NUM 4
184 #define MAX_DMICS_NUM 4
186 struct sigmatel_spec {
187 struct snd_kcontrol_new *mixers[4];
188 unsigned int num_mixers;
191 unsigned int eapd_switch: 1;
192 unsigned int surr_switch: 1;
193 unsigned int alt_switch: 1;
194 unsigned int hp_detect: 1;
195 unsigned int spdif_mute: 1;
196 unsigned int check_volume_offset:1;
197 unsigned int auto_mic:1;
198 unsigned int linear_tone_beep:1;
199 unsigned int headset_jack:1; /* 4-pin headset jack (hp + mono mic) */
200 unsigned int volknob_init:1; /* special volume-knob initialization */
203 unsigned int eapd_mask;
204 unsigned int gpio_mask;
205 unsigned int gpio_dir;
206 unsigned int gpio_data;
207 unsigned int gpio_mute;
208 unsigned int gpio_led;
209 unsigned int gpio_led_polarity;
210 unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */
211 unsigned int vref_led;
213 unsigned int mic_mute_led_gpio; /* capture mute LED GPIO */
214 bool mic_mute_led_on; /* current mic mute state */
217 unsigned int stream_delay;
219 /* analog loopback */
220 const struct snd_kcontrol_new *aloopback_ctl;
221 unsigned char aloopback_mask;
222 unsigned char aloopback_shift;
224 /* power management */
225 unsigned int power_map_bits;
226 unsigned int num_pwrs;
227 const hda_nid_t *pwr_nids;
228 const hda_nid_t *dac_list;
231 struct hda_input_mux *mono_mux;
232 unsigned int cur_mmux;
233 struct hda_multi_out multiout;
234 hda_nid_t dac_nids[5];
235 hda_nid_t hp_dacs[5];
236 hda_nid_t speaker_dacs[5];
241 const hda_nid_t *adc_nids;
242 unsigned int num_adcs;
243 const hda_nid_t *mux_nids;
244 unsigned int num_muxes;
245 const hda_nid_t *dmic_nids;
246 unsigned int num_dmics;
247 const hda_nid_t *dmux_nids;
248 unsigned int num_dmuxes;
249 const hda_nid_t *smux_nids;
250 unsigned int num_smuxes;
251 unsigned int num_analog_muxes;
253 const unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */
254 const unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */
255 unsigned int num_caps; /* number of capture volume/switch elements */
257 struct sigmatel_mic_route ext_mic;
258 struct sigmatel_mic_route int_mic;
259 struct sigmatel_mic_route dock_mic;
261 const char * const *spdif_labels;
263 hda_nid_t dig_in_nid;
265 hda_nid_t anabeep_nid;
266 hda_nid_t digbeep_nid;
269 const hda_nid_t *pin_nids;
270 unsigned int num_pins;
272 /* codec specific stuff */
273 const struct hda_verb *init;
274 const struct snd_kcontrol_new *mixer;
277 struct hda_input_mux *dinput_mux;
278 unsigned int cur_dmux[2];
279 struct hda_input_mux *input_mux;
280 unsigned int cur_mux[3];
281 struct hda_input_mux *sinput_mux;
282 unsigned int cur_smux[2];
283 unsigned int cur_amux;
285 unsigned int powerdown_adcs;
288 unsigned int io_switch[2];
289 unsigned int clfe_swap;
290 hda_nid_t line_switch; /* shared line-in for input and output */
291 hda_nid_t mic_switch; /* shared mic-in for input and output */
292 hda_nid_t hp_switch; /* NID of HP as line-out */
293 unsigned int aloopback;
295 struct hda_pcm pcm_rec[2]; /* PCM information */
297 /* dynamic controls and input_mux */
298 struct auto_pin_cfg autocfg;
299 struct snd_array kctls;
300 struct hda_input_mux private_dimux;
301 struct hda_input_mux private_imux;
302 struct hda_input_mux private_smux;
303 struct hda_input_mux private_mono_mux;
306 unsigned auto_pin_cnt;
307 hda_nid_t auto_pin_nids[MAX_PINS_NUM];
308 unsigned auto_adc_cnt;
309 hda_nid_t auto_adc_nids[MAX_ADCS_NUM];
310 hda_nid_t auto_mux_nids[MAX_ADCS_NUM];
311 hda_nid_t auto_dmux_nids[MAX_ADCS_NUM];
312 unsigned long auto_capvols[MAX_ADCS_NUM];
313 unsigned auto_dmic_cnt;
314 hda_nid_t auto_dmic_nids[MAX_DMICS_NUM];
316 struct hda_vmaster_mute_hook vmaster_mute;
319 #define AC_VERB_IDT_SET_POWER_MAP 0x7ec
320 #define AC_VERB_IDT_GET_POWER_MAP 0xfec
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[7] = {
376 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
380 static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = {
384 static const hda_nid_t stac92hd83xxx_dmic_nids[] = {
388 static const hda_nid_t stac92hd71bxx_pwr_nids[3] = {
392 static const hda_nid_t stac92hd71bxx_adc_nids[2] = {
396 static const hda_nid_t stac92hd71bxx_mux_nids[2] = {
400 static const hda_nid_t stac92hd71bxx_dmux_nids[2] = {
404 static const hda_nid_t stac92hd71bxx_smux_nids[2] = {
408 #define STAC92HD71BXX_NUM_DMICS 2
409 static const hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
413 static const hda_nid_t stac92hd71bxx_dmic_5port_nids[STAC92HD71BXX_NUM_DMICS] = {
417 static const hda_nid_t stac92hd71bxx_slave_dig_outs[2] = {
421 #define STAC92HD71BXX_NUM_CAPS 2
422 static const unsigned long stac92hd71bxx_capvols[] = {
423 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT),
424 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
426 #define stac92hd71bxx_capsws stac92hd71bxx_capvols
428 static const hda_nid_t stac925x_adc_nids[1] = {
432 static const hda_nid_t stac925x_mux_nids[1] = {
436 static const hda_nid_t stac925x_dac_nids[1] = {
440 #define STAC925X_NUM_DMICS 1
441 static const hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = {
445 static const hda_nid_t stac925x_dmux_nids[1] = {
449 static const unsigned long stac925x_capvols[] = {
450 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
452 static const unsigned long stac925x_capsws[] = {
453 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
456 static const hda_nid_t stac922x_adc_nids[2] = {
460 static const hda_nid_t stac922x_mux_nids[2] = {
464 #define STAC922X_NUM_CAPS 2
465 static const unsigned long stac922x_capvols[] = {
466 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT),
467 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT),
469 #define stac922x_capsws stac922x_capvols
471 static const hda_nid_t stac927x_slave_dig_outs[2] = {
475 static const hda_nid_t stac927x_adc_nids[3] = {
479 static const hda_nid_t stac927x_mux_nids[3] = {
483 static const hda_nid_t stac927x_smux_nids[1] = {
487 static const hda_nid_t stac927x_dac_nids[6] = {
488 0x02, 0x03, 0x04, 0x05, 0x06, 0
491 static const hda_nid_t stac927x_dmux_nids[1] = {
495 #define STAC927X_NUM_DMICS 2
496 static const hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = {
500 #define STAC927X_NUM_CAPS 3
501 static const unsigned long stac927x_capvols[] = {
502 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT),
503 HDA_COMPOSE_AMP_VAL(0x19, 3, 0, HDA_INPUT),
504 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_INPUT),
506 static const unsigned long stac927x_capsws[] = {
507 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
508 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT),
509 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
512 static const char * const stac927x_spdif_labels[5] = {
513 "Digital Playback", "ADAT", "Analog Mux 1",
514 "Analog Mux 2", "Analog Mux 3"
517 static const hda_nid_t stac9205_adc_nids[2] = {
521 static const hda_nid_t stac9205_mux_nids[2] = {
525 static const hda_nid_t stac9205_dmux_nids[1] = {
529 static const hda_nid_t stac9205_smux_nids[1] = {
533 #define STAC9205_NUM_DMICS 2
534 static const hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
538 #define STAC9205_NUM_CAPS 2
539 static const unsigned long stac9205_capvols[] = {
540 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT),
541 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT),
543 static const unsigned long stac9205_capsws[] = {
544 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
545 HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT),
548 static const hda_nid_t stac9200_pin_nids[8] = {
549 0x08, 0x09, 0x0d, 0x0e,
550 0x0f, 0x10, 0x11, 0x12,
553 static const hda_nid_t stac925x_pin_nids[8] = {
554 0x07, 0x08, 0x0a, 0x0b,
555 0x0c, 0x0d, 0x10, 0x11,
558 static const hda_nid_t stac922x_pin_nids[10] = {
559 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
560 0x0f, 0x10, 0x11, 0x15, 0x1b,
563 static const hda_nid_t stac92hd73xx_pin_nids[13] = {
564 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
565 0x0f, 0x10, 0x11, 0x12, 0x13,
569 #define STAC92HD71BXX_NUM_PINS 13
570 static const hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = {
571 0x0a, 0x0b, 0x0c, 0x0d, 0x00,
572 0x00, 0x14, 0x18, 0x19, 0x1e,
575 static const hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = {
576 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
577 0x0f, 0x14, 0x18, 0x19, 0x1e,
581 static const hda_nid_t stac927x_pin_nids[14] = {
582 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
583 0x0f, 0x10, 0x11, 0x12, 0x13,
584 0x14, 0x21, 0x22, 0x23,
587 static const hda_nid_t stac9205_pin_nids[12] = {
588 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
589 0x0f, 0x14, 0x16, 0x17, 0x18,
593 static int stac_add_event(struct hda_codec *codec, hda_nid_t nid,
594 unsigned char type, int data);
595 static int stac_add_hp_bass_switch(struct hda_codec *codec);
596 static void stac92xx_auto_set_pinctl(struct hda_codec *codec,
597 hda_nid_t nid, int pin_type);
598 static int hp_blike_system(u32 subsystem_id);
599 static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity);
601 static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
602 struct snd_ctl_elem_info *uinfo)
604 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
605 struct sigmatel_spec *spec = codec->spec;
606 return snd_hda_input_mux_info(spec->dinput_mux, uinfo);
609 static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol,
610 struct snd_ctl_elem_value *ucontrol)
612 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
613 struct sigmatel_spec *spec = codec->spec;
614 unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
616 ucontrol->value.enumerated.item[0] = spec->cur_dmux[dmux_idx];
620 static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
621 struct snd_ctl_elem_value *ucontrol)
623 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
624 struct sigmatel_spec *spec = codec->spec;
625 unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
627 return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol,
628 spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]);
631 static int stac92xx_smux_enum_info(struct snd_kcontrol *kcontrol,
632 struct snd_ctl_elem_info *uinfo)
634 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
635 struct sigmatel_spec *spec = codec->spec;
636 return snd_hda_input_mux_info(spec->sinput_mux, uinfo);
639 static int stac92xx_smux_enum_get(struct snd_kcontrol *kcontrol,
640 struct snd_ctl_elem_value *ucontrol)
642 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
643 struct sigmatel_spec *spec = codec->spec;
644 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
646 ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx];
650 static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
651 struct snd_ctl_elem_value *ucontrol)
653 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
654 struct sigmatel_spec *spec = codec->spec;
655 struct hda_input_mux *smux = &spec->private_smux;
656 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
660 err = snd_hda_input_mux_put(codec, spec->sinput_mux, ucontrol,
661 spec->smux_nids[smux_idx], &spec->cur_smux[smux_idx]);
665 if (spec->spdif_mute) {
667 nid = spec->multiout.dig_out_nid;
669 nid = codec->slave_dig_outs[smux_idx - 1];
670 if (spec->cur_smux[smux_idx] == smux->num_items - 1)
674 /* un/mute SPDIF out */
675 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
681 static int stac_vrefout_set(struct hda_codec *codec,
682 hda_nid_t nid, unsigned int new_vref)
686 snd_printdd("%s, nid %x ctl %x\n", __func__, nid, new_vref);
687 pinctl = snd_hda_codec_read(codec, nid, 0,
688 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
694 pinctl &= ~AC_PINCTL_VREFEN;
695 pinctl |= (new_vref & AC_PINCTL_VREFEN);
697 error = snd_hda_set_pin_ctl_cache(codec, nid, pinctl);
704 static unsigned int stac92xx_vref_set(struct hda_codec *codec,
705 hda_nid_t nid, unsigned int new_vref)
709 pincfg = snd_hda_codec_read(codec, nid, 0,
710 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
713 pincfg &= ~(AC_PINCTL_VREFEN | AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
716 if (new_vref == AC_PINCTL_VREF_HIZ)
717 pincfg |= AC_PINCTL_OUT_EN;
719 pincfg |= AC_PINCTL_IN_EN;
721 error = snd_hda_set_pin_ctl_cache(codec, nid, pincfg);
728 static unsigned int stac92xx_vref_get(struct hda_codec *codec, hda_nid_t nid)
731 vref = snd_hda_codec_read(codec, nid, 0,
732 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
733 vref &= AC_PINCTL_VREFEN;
737 static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
739 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
740 struct sigmatel_spec *spec = codec->spec;
741 return snd_hda_input_mux_info(spec->input_mux, uinfo);
744 static int stac92xx_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
746 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
747 struct sigmatel_spec *spec = codec->spec;
748 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
750 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
754 static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
756 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
757 struct sigmatel_spec *spec = codec->spec;
758 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
759 const struct hda_input_mux *imux = spec->input_mux;
760 unsigned int idx, prev_idx, didx;
762 idx = ucontrol->value.enumerated.item[0];
763 if (idx >= imux->num_items)
764 idx = imux->num_items - 1;
765 prev_idx = spec->cur_mux[adc_idx];
768 if (idx < spec->num_analog_muxes) {
769 snd_hda_codec_write_cache(codec, spec->mux_nids[adc_idx], 0,
770 AC_VERB_SET_CONNECT_SEL,
771 imux->items[idx].index);
772 if (prev_idx >= spec->num_analog_muxes &&
773 spec->mux_nids[adc_idx] != spec->dmux_nids[adc_idx]) {
774 imux = spec->dinput_mux;
776 snd_hda_codec_write_cache(codec,
777 spec->dmux_nids[adc_idx], 0,
778 AC_VERB_SET_CONNECT_SEL,
779 imux->items[0].index);
782 imux = spec->dinput_mux;
783 /* first dimux item is hardcoded to select analog imux,
786 didx = idx - spec->num_analog_muxes + 1;
787 snd_hda_codec_write_cache(codec, spec->dmux_nids[adc_idx], 0,
788 AC_VERB_SET_CONNECT_SEL,
789 imux->items[didx].index);
791 spec->cur_mux[adc_idx] = idx;
795 static int stac92xx_mono_mux_enum_info(struct snd_kcontrol *kcontrol,
796 struct snd_ctl_elem_info *uinfo)
798 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
799 struct sigmatel_spec *spec = codec->spec;
800 return snd_hda_input_mux_info(spec->mono_mux, uinfo);
803 static int stac92xx_mono_mux_enum_get(struct snd_kcontrol *kcontrol,
804 struct snd_ctl_elem_value *ucontrol)
806 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
807 struct sigmatel_spec *spec = codec->spec;
809 ucontrol->value.enumerated.item[0] = spec->cur_mmux;
813 static int stac92xx_mono_mux_enum_put(struct snd_kcontrol *kcontrol,
814 struct snd_ctl_elem_value *ucontrol)
816 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
817 struct sigmatel_spec *spec = codec->spec;
819 return snd_hda_input_mux_put(codec, spec->mono_mux, ucontrol,
820 spec->mono_nid, &spec->cur_mmux);
823 #define stac92xx_aloopback_info snd_ctl_boolean_mono_info
825 static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol,
826 struct snd_ctl_elem_value *ucontrol)
828 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
829 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
830 struct sigmatel_spec *spec = codec->spec;
832 ucontrol->value.integer.value[0] = !!(spec->aloopback &
833 (spec->aloopback_mask << idx));
837 static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol,
838 struct snd_ctl_elem_value *ucontrol)
840 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
841 struct sigmatel_spec *spec = codec->spec;
842 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
843 unsigned int dac_mode;
844 unsigned int val, idx_val;
846 idx_val = spec->aloopback_mask << idx;
847 if (ucontrol->value.integer.value[0])
848 val = spec->aloopback | idx_val;
850 val = spec->aloopback & ~idx_val;
851 if (spec->aloopback == val)
854 spec->aloopback = val;
856 /* Only return the bits defined by the shift value of the
857 * first two bytes of the mask
859 dac_mode = snd_hda_codec_read(codec, codec->afg, 0,
860 kcontrol->private_value & 0xFFFF, 0x0);
861 dac_mode >>= spec->aloopback_shift;
863 if (spec->aloopback & idx_val) {
864 snd_hda_power_up(codec);
867 snd_hda_power_down(codec);
868 dac_mode &= ~idx_val;
871 snd_hda_codec_write_cache(codec, codec->afg, 0,
872 kcontrol->private_value >> 16, dac_mode);
877 static const struct hda_verb stac9200_core_init[] = {
878 /* set dac0mux for dac converter */
879 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
883 static const struct hda_verb stac9200_eapd_init[] = {
884 /* set dac0mux for dac converter */
885 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
886 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
890 static const struct hda_verb dell_eq_core_init[] = {
891 /* set master volume to max value without distortion
892 * and direct control */
893 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
897 static const struct hda_verb stac92hd73xx_core_init[] = {
898 /* set master volume and direct control */
899 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
903 static const struct hda_verb stac92hd83xxx_core_init[] = {
904 /* power state controls amps */
905 { 0x01, AC_VERB_SET_EAPD, 1 << 2},
909 static const struct hda_verb stac92hd83xxx_hp_zephyr_init[] = {
910 { 0x22, 0x785, 0x43 },
911 { 0x22, 0x782, 0xe0 },
912 { 0x22, 0x795, 0x00 },
916 static const struct hda_verb stac92hd71bxx_core_init[] = {
917 /* set master volume and direct control */
918 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
922 static const struct hda_verb stac92hd71bxx_unmute_core_init[] = {
923 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */
924 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
925 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
926 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
930 static const struct hda_verb stac925x_core_init[] = {
931 /* set dac0mux for dac converter */
932 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
933 /* mute the master volume */
934 { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
938 static const struct hda_verb stac922x_core_init[] = {
939 /* set master volume and direct control */
940 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
944 static const struct hda_verb d965_core_init[] = {
945 /* unmute node 0x1b */
946 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
947 /* select node 0x03 as DAC */
948 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
952 static const struct hda_verb dell_3st_core_init[] = {
953 /* don't set delta bit */
954 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
955 /* unmute node 0x1b */
956 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
957 /* select node 0x03 as DAC */
958 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
962 static const struct hda_verb stac927x_core_init[] = {
963 /* set master volume and direct control */
964 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
965 /* enable analog pc beep path */
966 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
970 static const struct hda_verb stac927x_volknob_core_init[] = {
971 /* don't set delta bit */
972 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
973 /* enable analog pc beep path */
974 {0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
978 static const struct hda_verb stac9205_core_init[] = {
979 /* set master volume and direct control */
980 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
981 /* enable analog pc beep path */
982 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
986 #define STAC_MONO_MUX \
988 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
989 .name = "Mono Mux", \
991 .info = stac92xx_mono_mux_enum_info, \
992 .get = stac92xx_mono_mux_enum_get, \
993 .put = stac92xx_mono_mux_enum_put, \
996 #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \
998 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
999 .name = "Analog Loopback", \
1001 .info = stac92xx_aloopback_info, \
1002 .get = stac92xx_aloopback_get, \
1003 .put = stac92xx_aloopback_put, \
1004 .private_value = verb_read | (verb_write << 16), \
1007 #define DC_BIAS(xname, idx, nid) \
1009 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1012 .info = stac92xx_dc_bias_info, \
1013 .get = stac92xx_dc_bias_get, \
1014 .put = stac92xx_dc_bias_put, \
1015 .private_value = nid, \
1018 static const struct snd_kcontrol_new stac9200_mixer[] = {
1019 HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xb, 0, HDA_OUTPUT),
1020 HDA_CODEC_MUTE("PCM Playback Switch", 0xb, 0, HDA_OUTPUT),
1021 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
1022 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
1026 static const struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = {
1027 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3),
1031 static const struct snd_kcontrol_new stac92hd73xx_8ch_loopback[] = {
1032 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4),
1036 static const struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = {
1037 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5),
1042 static const struct snd_kcontrol_new stac92hd71bxx_loopback[] = {
1043 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2)
1046 static const struct snd_kcontrol_new stac925x_mixer[] = {
1047 HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xe, 0, HDA_OUTPUT),
1048 HDA_CODEC_MUTE("PCM Playback Switch", 0x0e, 0, HDA_OUTPUT),
1052 static const struct snd_kcontrol_new stac9205_loopback[] = {
1053 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1),
1057 static const struct snd_kcontrol_new stac927x_loopback[] = {
1058 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1),
1062 static struct snd_kcontrol_new stac_dmux_mixer = {
1063 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1064 .name = "Digital Input Source",
1065 /* count set later */
1066 .info = stac92xx_dmux_enum_info,
1067 .get = stac92xx_dmux_enum_get,
1068 .put = stac92xx_dmux_enum_put,
1071 static struct snd_kcontrol_new stac_smux_mixer = {
1072 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1073 .name = "IEC958 Playback Source",
1074 /* count set later */
1075 .info = stac92xx_smux_enum_info,
1076 .get = stac92xx_smux_enum_get,
1077 .put = stac92xx_smux_enum_put,
1080 static const char * const slave_pfxs[] = {
1081 "Front", "Surround", "Center", "LFE", "Side",
1082 "Headphone", "Speaker", "Bass Speaker", "IEC958", "PCM",
1086 static void stac92xx_update_led_status(struct hda_codec *codec, int enabled);
1088 static void stac92xx_vmaster_hook(void *private_data, int val)
1090 stac92xx_update_led_status(private_data, val);
1093 static void stac92xx_free_kctls(struct hda_codec *codec);
1095 static int stac92xx_build_controls(struct hda_codec *codec)
1097 struct sigmatel_spec *spec = codec->spec;
1098 unsigned int vmaster_tlv[4];
1103 err = snd_hda_add_new_ctls(codec, spec->mixer);
1108 for (i = 0; i < spec->num_mixers; i++) {
1109 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1113 if (!spec->auto_mic && spec->num_dmuxes > 0 &&
1114 snd_hda_get_bool_hint(codec, "separate_dmux") == 1) {
1115 stac_dmux_mixer.count = spec->num_dmuxes;
1116 err = snd_hda_ctl_add(codec, 0,
1117 snd_ctl_new1(&stac_dmux_mixer, codec));
1121 if (spec->num_smuxes > 0) {
1122 int wcaps = get_wcaps(codec, spec->multiout.dig_out_nid);
1123 struct hda_input_mux *smux = &spec->private_smux;
1124 /* check for mute support on SPDIF out */
1125 if (wcaps & AC_WCAP_OUT_AMP) {
1126 snd_hda_add_imux_item(smux, "Off", 0, NULL);
1127 spec->spdif_mute = 1;
1129 stac_smux_mixer.count = spec->num_smuxes;
1130 err = snd_hda_ctl_add(codec, 0,
1131 snd_ctl_new1(&stac_smux_mixer, codec));
1136 if (spec->multiout.dig_out_nid) {
1137 err = snd_hda_create_dig_out_ctls(codec,
1138 spec->multiout.dig_out_nid,
1139 spec->multiout.dig_out_nid,
1140 spec->autocfg.dig_out_type[0]);
1143 err = snd_hda_create_spdif_share_sw(codec,
1147 spec->multiout.share_spdif = 1;
1149 if (spec->dig_in_nid && !(spec->gpio_dir & 0x01)) {
1150 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1155 /* if we have no master control, let's create it */
1156 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
1157 HDA_OUTPUT, vmaster_tlv);
1158 /* correct volume offset */
1159 vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset;
1160 /* minimum value is actually mute */
1161 vmaster_tlv[3] |= TLV_DB_SCALE_MUTE;
1162 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1163 vmaster_tlv, slave_pfxs,
1168 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
1170 "Playback Switch", true,
1171 &spec->vmaster_mute.sw_kctl);
1175 if (spec->gpio_led) {
1176 spec->vmaster_mute.hook = stac92xx_vmaster_hook;
1177 err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true);
1182 if (spec->aloopback_ctl &&
1183 snd_hda_get_bool_hint(codec, "loopback") == 1) {
1184 err = snd_hda_add_new_ctls(codec, spec->aloopback_ctl);
1189 stac92xx_free_kctls(codec); /* no longer needed */
1191 err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
1198 static const struct hda_pintbl ref9200_pin_configs[] = {
1199 { 0x08, 0x01c47010 },
1200 { 0x09, 0x01447010 },
1201 { 0x0d, 0x0221401f },
1202 { 0x0e, 0x01114010 },
1203 { 0x0f, 0x02a19020 },
1204 { 0x10, 0x01a19021 },
1205 { 0x11, 0x90100140 },
1206 { 0x12, 0x01813122 },
1210 static const struct hda_pintbl gateway9200_m4_pin_configs[] = {
1211 { 0x08, 0x400000fe },
1212 { 0x09, 0x404500f4 },
1213 { 0x0d, 0x400100f0 },
1214 { 0x0e, 0x90110010 },
1215 { 0x0f, 0x400100f1 },
1216 { 0x10, 0x02a1902e },
1217 { 0x11, 0x500000f2 },
1218 { 0x12, 0x500000f3 },
1222 static const struct hda_pintbl gateway9200_m4_2_pin_configs[] = {
1223 { 0x08, 0x400000fe },
1224 { 0x09, 0x404500f4 },
1225 { 0x0d, 0x400100f0 },
1226 { 0x0e, 0x90110010 },
1227 { 0x0f, 0x400100f1 },
1228 { 0x10, 0x02a1902e },
1229 { 0x11, 0x500000f2 },
1230 { 0x12, 0x500000f3 },
1235 STAC 9200 pin configs for
1240 static const struct hda_pintbl dell9200_d21_pin_configs[] = {
1241 { 0x08, 0x400001f0 },
1242 { 0x09, 0x400001f1 },
1243 { 0x0d, 0x02214030 },
1244 { 0x0e, 0x01014010 },
1245 { 0x0f, 0x02a19020 },
1246 { 0x10, 0x01a19021 },
1247 { 0x11, 0x90100140 },
1248 { 0x12, 0x01813122 },
1253 STAC 9200 pin configs for
1257 static const struct hda_pintbl dell9200_d22_pin_configs[] = {
1258 { 0x08, 0x400001f0 },
1259 { 0x09, 0x400001f1 },
1260 { 0x0d, 0x0221401f },
1261 { 0x0e, 0x01014010 },
1262 { 0x0f, 0x01813020 },
1263 { 0x10, 0x02a19021 },
1264 { 0x11, 0x90100140 },
1265 { 0x12, 0x400001f2 },
1270 STAC 9200 pin configs for
1271 102801C4 (Dell Dimension E310)
1278 static const struct hda_pintbl dell9200_d23_pin_configs[] = {
1279 { 0x08, 0x400001f0 },
1280 { 0x09, 0x400001f1 },
1281 { 0x0d, 0x0221401f },
1282 { 0x0e, 0x01014010 },
1283 { 0x0f, 0x01813020 },
1284 { 0x10, 0x01a19021 },
1285 { 0x11, 0x90100140 },
1286 { 0x12, 0x400001f2 },
1292 STAC 9200-32 pin configs for
1293 102801B5 (Dell Inspiron 630m)
1294 102801D8 (Dell Inspiron 640m)
1296 static const struct hda_pintbl dell9200_m21_pin_configs[] = {
1297 { 0x08, 0x40c003fa },
1298 { 0x09, 0x03441340 },
1299 { 0x0d, 0x0321121f },
1300 { 0x0e, 0x90170310 },
1301 { 0x0f, 0x408003fb },
1302 { 0x10, 0x03a11020 },
1303 { 0x11, 0x401003fc },
1304 { 0x12, 0x403003fd },
1309 STAC 9200-32 pin configs for
1310 102801C2 (Dell Latitude D620)
1312 102801CC (Dell Latitude D820)
1316 static const struct hda_pintbl dell9200_m22_pin_configs[] = {
1317 { 0x08, 0x40c003fa },
1318 { 0x09, 0x0144131f },
1319 { 0x0d, 0x0321121f },
1320 { 0x0e, 0x90170310 },
1321 { 0x0f, 0x90a70321 },
1322 { 0x10, 0x03a11020 },
1323 { 0x11, 0x401003fb },
1324 { 0x12, 0x40f000fc },
1329 STAC 9200-32 pin configs for
1330 102801CE (Dell XPS M1710)
1331 102801CF (Dell Precision M90)
1333 static const struct hda_pintbl dell9200_m23_pin_configs[] = {
1334 { 0x08, 0x40c003fa },
1335 { 0x09, 0x01441340 },
1336 { 0x0d, 0x0421421f },
1337 { 0x0e, 0x90170310 },
1338 { 0x0f, 0x408003fb },
1339 { 0x10, 0x04a1102e },
1340 { 0x11, 0x90170311 },
1341 { 0x12, 0x403003fc },
1346 STAC 9200-32 pin configs for
1349 102801CB (Dell Latitude 120L)
1352 static const struct hda_pintbl dell9200_m24_pin_configs[] = {
1353 { 0x08, 0x40c003fa },
1354 { 0x09, 0x404003fb },
1355 { 0x0d, 0x0321121f },
1356 { 0x0e, 0x90170310 },
1357 { 0x0f, 0x408003fc },
1358 { 0x10, 0x03a11020 },
1359 { 0x11, 0x401003fd },
1360 { 0x12, 0x403003fe },
1365 STAC 9200-32 pin configs for
1366 102801BD (Dell Inspiron E1505n)
1370 static const struct hda_pintbl dell9200_m25_pin_configs[] = {
1371 { 0x08, 0x40c003fa },
1372 { 0x09, 0x01441340 },
1373 { 0x0d, 0x0421121f },
1374 { 0x0e, 0x90170310 },
1375 { 0x0f, 0x408003fb },
1376 { 0x10, 0x04a11020 },
1377 { 0x11, 0x401003fc },
1378 { 0x12, 0x403003fd },
1383 STAC 9200-32 pin configs for
1384 102801F5 (Dell Inspiron 1501)
1387 static const struct hda_pintbl dell9200_m26_pin_configs[] = {
1388 { 0x08, 0x40c003fa },
1389 { 0x09, 0x404003fb },
1390 { 0x0d, 0x0421121f },
1391 { 0x0e, 0x90170310 },
1392 { 0x0f, 0x408003fc },
1393 { 0x10, 0x04a11020 },
1394 { 0x11, 0x401003fd },
1395 { 0x12, 0x403003fe },
1401 102801CD (Dell Inspiron E1705/9400)
1403 static const struct hda_pintbl dell9200_m27_pin_configs[] = {
1404 { 0x08, 0x40c003fa },
1405 { 0x09, 0x01441340 },
1406 { 0x0d, 0x0421121f },
1407 { 0x0e, 0x90170310 },
1408 { 0x0f, 0x90170310 },
1409 { 0x10, 0x04a11020 },
1410 { 0x11, 0x90170310 },
1411 { 0x12, 0x40f003fc },
1415 static const struct hda_pintbl oqo9200_pin_configs[] = {
1416 { 0x08, 0x40c000f0 },
1417 { 0x09, 0x404000f1 },
1418 { 0x0d, 0x0221121f },
1419 { 0x0e, 0x02211210 },
1420 { 0x0f, 0x90170111 },
1421 { 0x10, 0x90a70120 },
1422 { 0x11, 0x400000f2 },
1423 { 0x12, 0x400000f3 },
1428 static void stac9200_fixup_panasonic(struct hda_codec *codec,
1429 const struct hda_fixup *fix, int action)
1431 struct sigmatel_spec *spec = codec->spec;
1434 case HDA_FIXUP_ACT_PRE_PROBE:
1435 spec->gpio_mask = spec->gpio_dir = 0x09;
1436 spec->gpio_data = 0x00;
1438 case HDA_FIXUP_ACT_PROBE:
1439 /* CF-74 has no headphone detection, and the driver should *NOT*
1440 * do detection and HP/speaker toggle because the hardware does it.
1442 spec->hp_detect = 0;
1448 static const struct hda_fixup stac9200_fixups[] = {
1450 .type = HDA_FIXUP_PINS,
1451 .v.pins = ref9200_pin_configs,
1454 .type = HDA_FIXUP_PINS,
1455 .v.pins = oqo9200_pin_configs,
1457 .chain_id = STAC_9200_EAPD_INIT,
1459 [STAC_9200_DELL_D21] = {
1460 .type = HDA_FIXUP_PINS,
1461 .v.pins = dell9200_d21_pin_configs,
1463 [STAC_9200_DELL_D22] = {
1464 .type = HDA_FIXUP_PINS,
1465 .v.pins = dell9200_d22_pin_configs,
1467 [STAC_9200_DELL_D23] = {
1468 .type = HDA_FIXUP_PINS,
1469 .v.pins = dell9200_d23_pin_configs,
1471 [STAC_9200_DELL_M21] = {
1472 .type = HDA_FIXUP_PINS,
1473 .v.pins = dell9200_m21_pin_configs,
1475 [STAC_9200_DELL_M22] = {
1476 .type = HDA_FIXUP_PINS,
1477 .v.pins = dell9200_m22_pin_configs,
1479 [STAC_9200_DELL_M23] = {
1480 .type = HDA_FIXUP_PINS,
1481 .v.pins = dell9200_m23_pin_configs,
1483 [STAC_9200_DELL_M24] = {
1484 .type = HDA_FIXUP_PINS,
1485 .v.pins = dell9200_m24_pin_configs,
1487 [STAC_9200_DELL_M25] = {
1488 .type = HDA_FIXUP_PINS,
1489 .v.pins = dell9200_m25_pin_configs,
1491 [STAC_9200_DELL_M26] = {
1492 .type = HDA_FIXUP_PINS,
1493 .v.pins = dell9200_m26_pin_configs,
1495 [STAC_9200_DELL_M27] = {
1496 .type = HDA_FIXUP_PINS,
1497 .v.pins = dell9200_m27_pin_configs,
1500 .type = HDA_FIXUP_PINS,
1501 .v.pins = gateway9200_m4_pin_configs,
1503 .chain_id = STAC_9200_EAPD_INIT,
1505 [STAC_9200_M4_2] = {
1506 .type = HDA_FIXUP_PINS,
1507 .v.pins = gateway9200_m4_2_pin_configs,
1509 .chain_id = STAC_9200_EAPD_INIT,
1511 [STAC_9200_PANASONIC] = {
1512 .type = HDA_FIXUP_FUNC,
1513 .v.func = stac9200_fixup_panasonic,
1515 [STAC_9200_EAPD_INIT] = {
1516 .type = HDA_FIXUP_VERBS,
1517 .v.verbs = (const struct hda_verb[]) {
1518 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1524 static const struct hda_model_fixup stac9200_models[] = {
1525 { .id = STAC_REF, .name = "ref" },
1526 { .id = STAC_9200_OQO, .name = "oqo" },
1527 { .id = STAC_9200_DELL_D21, .name = "dell-d21" },
1528 { .id = STAC_9200_DELL_D22, .name = "dell-d22" },
1529 { .id = STAC_9200_DELL_D23, .name = "dell-d23" },
1530 { .id = STAC_9200_DELL_M21, .name = "dell-m21" },
1531 { .id = STAC_9200_DELL_M22, .name = "dell-m22" },
1532 { .id = STAC_9200_DELL_M23, .name = "dell-m23" },
1533 { .id = STAC_9200_DELL_M24, .name = "dell-m24" },
1534 { .id = STAC_9200_DELL_M25, .name = "dell-m25" },
1535 { .id = STAC_9200_DELL_M26, .name = "dell-m26" },
1536 { .id = STAC_9200_DELL_M27, .name = "dell-m27" },
1537 { .id = STAC_9200_M4, .name = "gateway-m4" },
1538 { .id = STAC_9200_M4_2, .name = "gateway-m4-2" },
1539 { .id = STAC_9200_PANASONIC, .name = "panasonic" },
1543 static const struct snd_pci_quirk stac9200_fixup_tbl[] = {
1544 /* SigmaTel reference board */
1545 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1546 "DFI LanParty", STAC_REF),
1547 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
1548 "DFI LanParty", STAC_REF),
1549 /* Dell laptops have BIOS problem */
1550 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
1551 "unknown Dell", STAC_9200_DELL_D21),
1552 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
1553 "Dell Inspiron 630m", STAC_9200_DELL_M21),
1554 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
1555 "Dell Inspiron E1505n", STAC_9200_DELL_M25),
1556 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
1557 "unknown Dell", STAC_9200_DELL_D22),
1558 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
1559 "unknown Dell", STAC_9200_DELL_D22),
1560 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
1561 "Dell Latitude D620", STAC_9200_DELL_M22),
1562 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
1563 "unknown Dell", STAC_9200_DELL_D23),
1564 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
1565 "unknown Dell", STAC_9200_DELL_D23),
1566 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
1567 "unknown Dell", STAC_9200_DELL_M22),
1568 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
1569 "unknown Dell", STAC_9200_DELL_M24),
1570 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
1571 "unknown Dell", STAC_9200_DELL_M24),
1572 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
1573 "Dell Latitude 120L", STAC_9200_DELL_M24),
1574 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
1575 "Dell Latitude D820", STAC_9200_DELL_M22),
1576 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
1577 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
1578 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
1579 "Dell XPS M1710", STAC_9200_DELL_M23),
1580 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
1581 "Dell Precision M90", STAC_9200_DELL_M23),
1582 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
1583 "unknown Dell", STAC_9200_DELL_M22),
1584 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
1585 "unknown Dell", STAC_9200_DELL_M22),
1586 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
1587 "unknown Dell", STAC_9200_DELL_M22),
1588 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
1589 "Dell Inspiron 640m", STAC_9200_DELL_M21),
1590 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
1591 "unknown Dell", STAC_9200_DELL_D23),
1592 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
1593 "unknown Dell", STAC_9200_DELL_D23),
1594 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
1595 "unknown Dell", STAC_9200_DELL_D21),
1596 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
1597 "unknown Dell", STAC_9200_DELL_D23),
1598 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
1599 "unknown Dell", STAC_9200_DELL_D21),
1600 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
1601 "unknown Dell", STAC_9200_DELL_M25),
1602 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
1603 "unknown Dell", STAC_9200_DELL_M25),
1604 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
1605 "Dell Inspiron 1501", STAC_9200_DELL_M26),
1606 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
1607 "unknown Dell", STAC_9200_DELL_M26),
1609 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC),
1610 /* Gateway machines needs EAPD to be set on resume */
1611 SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_M4),
1612 SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", STAC_9200_M4_2),
1613 SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", STAC_9200_M4_2),
1615 SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO),
1619 static const struct hda_pintbl ref925x_pin_configs[] = {
1620 { 0x07, 0x40c003f0 },
1621 { 0x08, 0x424503f2 },
1622 { 0x0a, 0x01813022 },
1623 { 0x0b, 0x02a19021 },
1624 { 0x0c, 0x90a70320 },
1625 { 0x0d, 0x02214210 },
1626 { 0x10, 0x01019020 },
1627 { 0x11, 0x9033032e },
1631 static const struct hda_pintbl stac925xM1_pin_configs[] = {
1632 { 0x07, 0x40c003f4 },
1633 { 0x08, 0x424503f2 },
1634 { 0x0a, 0x400000f3 },
1635 { 0x0b, 0x02a19020 },
1636 { 0x0c, 0x40a000f0 },
1637 { 0x0d, 0x90100210 },
1638 { 0x10, 0x400003f1 },
1639 { 0x11, 0x9033032e },
1643 static const struct hda_pintbl stac925xM1_2_pin_configs[] = {
1644 { 0x07, 0x40c003f4 },
1645 { 0x08, 0x424503f2 },
1646 { 0x0a, 0x400000f3 },
1647 { 0x0b, 0x02a19020 },
1648 { 0x0c, 0x40a000f0 },
1649 { 0x0d, 0x90100210 },
1650 { 0x10, 0x400003f1 },
1651 { 0x11, 0x9033032e },
1655 static const struct hda_pintbl stac925xM2_pin_configs[] = {
1656 { 0x07, 0x40c003f4 },
1657 { 0x08, 0x424503f2 },
1658 { 0x0a, 0x400000f3 },
1659 { 0x0b, 0x02a19020 },
1660 { 0x0c, 0x40a000f0 },
1661 { 0x0d, 0x90100210 },
1662 { 0x10, 0x400003f1 },
1663 { 0x11, 0x9033032e },
1667 static const struct hda_pintbl stac925xM2_2_pin_configs[] = {
1668 { 0x07, 0x40c003f4 },
1669 { 0x08, 0x424503f2 },
1670 { 0x0a, 0x400000f3 },
1671 { 0x0b, 0x02a19020 },
1672 { 0x0c, 0x40a000f0 },
1673 { 0x0d, 0x90100210 },
1674 { 0x10, 0x400003f1 },
1675 { 0x11, 0x9033032e },
1679 static const struct hda_pintbl stac925xM3_pin_configs[] = {
1680 { 0x07, 0x40c003f4 },
1681 { 0x08, 0x424503f2 },
1682 { 0x0a, 0x400000f3 },
1683 { 0x0b, 0x02a19020 },
1684 { 0x0c, 0x40a000f0 },
1685 { 0x0d, 0x90100210 },
1686 { 0x10, 0x400003f1 },
1687 { 0x11, 0x503303f3 },
1691 static const struct hda_pintbl stac925xM5_pin_configs[] = {
1692 { 0x07, 0x40c003f4 },
1693 { 0x08, 0x424503f2 },
1694 { 0x0a, 0x400000f3 },
1695 { 0x0b, 0x02a19020 },
1696 { 0x0c, 0x40a000f0 },
1697 { 0x0d, 0x90100210 },
1698 { 0x10, 0x400003f1 },
1699 { 0x11, 0x9033032e },
1703 static const struct hda_pintbl stac925xM6_pin_configs[] = {
1704 { 0x07, 0x40c003f4 },
1705 { 0x08, 0x424503f2 },
1706 { 0x0a, 0x400000f3 },
1707 { 0x0b, 0x02a19020 },
1708 { 0x0c, 0x40a000f0 },
1709 { 0x0d, 0x90100210 },
1710 { 0x10, 0x400003f1 },
1711 { 0x11, 0x90330320 },
1715 static const struct hda_fixup stac925x_fixups[] = {
1717 .type = HDA_FIXUP_PINS,
1718 .v.pins = ref925x_pin_configs,
1721 .type = HDA_FIXUP_PINS,
1722 .v.pins = stac925xM1_pin_configs,
1725 .type = HDA_FIXUP_PINS,
1726 .v.pins = stac925xM1_2_pin_configs,
1729 .type = HDA_FIXUP_PINS,
1730 .v.pins = stac925xM2_pin_configs,
1733 .type = HDA_FIXUP_PINS,
1734 .v.pins = stac925xM2_2_pin_configs,
1737 .type = HDA_FIXUP_PINS,
1738 .v.pins = stac925xM3_pin_configs,
1741 .type = HDA_FIXUP_PINS,
1742 .v.pins = stac925xM5_pin_configs,
1745 .type = HDA_FIXUP_PINS,
1746 .v.pins = stac925xM6_pin_configs,
1750 static const struct hda_model_fixup stac925x_models[] = {
1751 { .id = STAC_REF, .name = "ref" },
1752 { .id = STAC_M1, .name = "m1" },
1753 { .id = STAC_M1_2, .name = "m1-2" },
1754 { .id = STAC_M2, .name = "m2" },
1755 { .id = STAC_M2_2, .name = "m2-2" },
1756 { .id = STAC_M3, .name = "m3" },
1757 { .id = STAC_M5, .name = "m5" },
1758 { .id = STAC_M6, .name = "m6" },
1762 static const struct snd_pci_quirk stac925x_fixup_tbl[] = {
1763 /* SigmaTel reference board */
1764 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
1765 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF),
1766 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
1768 /* Default table for unknown ID */
1769 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2),
1771 /* gateway machines are checked via codec ssid */
1772 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2),
1773 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5),
1774 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1),
1775 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_M2),
1776 SND_PCI_QUIRK(0x107b, 0x0367, "Gateway MX6453", STAC_M1_2),
1777 /* Not sure about the brand name for those */
1778 SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M1),
1779 SND_PCI_QUIRK(0x107b, 0x0507, "Gateway mobile", STAC_M3),
1780 SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M6),
1781 SND_PCI_QUIRK(0x107b, 0x0685, "Gateway mobile", STAC_M2_2),
1785 static const struct hda_pintbl ref92hd73xx_pin_configs[] = {
1786 { 0x0a, 0x02214030 },
1787 { 0x0b, 0x02a19040 },
1788 { 0x0c, 0x01a19020 },
1789 { 0x0d, 0x02214030 },
1790 { 0x0e, 0x0181302e },
1791 { 0x0f, 0x01014010 },
1792 { 0x10, 0x01014020 },
1793 { 0x11, 0x01014030 },
1794 { 0x12, 0x02319040 },
1795 { 0x13, 0x90a000f0 },
1796 { 0x14, 0x90a000f0 },
1797 { 0x22, 0x01452050 },
1798 { 0x23, 0x01452050 },
1802 static const struct hda_pintbl dell_m6_pin_configs[] = {
1803 { 0x0a, 0x0321101f },
1804 { 0x0b, 0x4f00000f },
1805 { 0x0c, 0x4f0000f0 },
1806 { 0x0d, 0x90170110 },
1807 { 0x0e, 0x03a11020 },
1808 { 0x0f, 0x0321101f },
1809 { 0x10, 0x4f0000f0 },
1810 { 0x11, 0x4f0000f0 },
1811 { 0x12, 0x4f0000f0 },
1812 { 0x13, 0x90a60160 },
1813 { 0x14, 0x4f0000f0 },
1814 { 0x22, 0x4f0000f0 },
1815 { 0x23, 0x4f0000f0 },
1819 static const struct hda_pintbl alienware_m17x_pin_configs[] = {
1820 { 0x0a, 0x0321101f },
1821 { 0x0b, 0x0321101f },
1822 { 0x0c, 0x03a11020 },
1823 { 0x0d, 0x03014020 },
1824 { 0x0e, 0x90170110 },
1825 { 0x0f, 0x4f0000f0 },
1826 { 0x10, 0x4f0000f0 },
1827 { 0x11, 0x4f0000f0 },
1828 { 0x12, 0x4f0000f0 },
1829 { 0x13, 0x90a60160 },
1830 { 0x14, 0x4f0000f0 },
1831 { 0x22, 0x4f0000f0 },
1832 { 0x23, 0x904601b0 },
1836 static const struct hda_pintbl intel_dg45id_pin_configs[] = {
1837 { 0x0a, 0x02214230 },
1838 { 0x0b, 0x02A19240 },
1839 { 0x0c, 0x01013214 },
1840 { 0x0d, 0x01014210 },
1841 { 0x0e, 0x01A19250 },
1842 { 0x0f, 0x01011212 },
1843 { 0x10, 0x01016211 },
1847 static void stac92hd73xx_fixup_ref(struct hda_codec *codec,
1848 const struct hda_fixup *fix, int action)
1850 struct sigmatel_spec *spec = codec->spec;
1852 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1855 snd_hda_apply_pincfgs(codec, ref92hd73xx_pin_configs);
1856 spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0;
1859 static void stac92hd73xx_fixup_dell(struct hda_codec *codec)
1861 struct sigmatel_spec *spec = codec->spec;
1863 snd_hda_apply_pincfgs(codec, dell_m6_pin_configs);
1864 spec->num_smuxes = 0;
1865 spec->eapd_switch = 0;
1868 static void stac92hd73xx_fixup_dell_eq(struct hda_codec *codec,
1869 const struct hda_fixup *fix, int action)
1871 struct sigmatel_spec *spec = codec->spec;
1873 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1876 stac92hd73xx_fixup_dell(codec);
1877 snd_hda_add_verbs(codec, dell_eq_core_init);
1878 spec->volknob_init = 1;
1882 static void stac92hd73xx_fixup_dell_m6_amic(struct hda_codec *codec,
1883 const struct hda_fixup *fix, int action)
1885 struct sigmatel_spec *spec = codec->spec;
1887 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1890 stac92hd73xx_fixup_dell(codec);
1891 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
1892 spec->num_dmics = 0;
1896 static void stac92hd73xx_fixup_dell_m6_dmic(struct hda_codec *codec,
1897 const struct hda_fixup *fix, int action)
1899 struct sigmatel_spec *spec = codec->spec;
1901 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1904 stac92hd73xx_fixup_dell(codec);
1905 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
1906 spec->num_dmics = 1;
1910 static void stac92hd73xx_fixup_dell_m6_both(struct hda_codec *codec,
1911 const struct hda_fixup *fix, int action)
1913 struct sigmatel_spec *spec = codec->spec;
1915 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1918 stac92hd73xx_fixup_dell(codec);
1919 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
1920 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
1921 spec->num_dmics = 1;
1924 static void stac92hd73xx_fixup_alienware_m17x(struct hda_codec *codec,
1925 const struct hda_fixup *fix, int action)
1927 struct sigmatel_spec *spec = codec->spec;
1929 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1932 snd_hda_apply_pincfgs(codec, alienware_m17x_pin_configs);
1933 spec->num_dmics = STAC92HD73XX_NUM_DMICS;
1934 spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids);
1935 spec->eapd_switch = 0;
1938 static void stac92hd73xx_fixup_no_jd(struct hda_codec *codec,
1939 const struct hda_fixup *fix, int action)
1941 struct sigmatel_spec *spec = codec->spec;
1943 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1945 spec->hp_detect = 0;
1948 static const struct hda_fixup stac92hd73xx_fixups[] = {
1949 [STAC_92HD73XX_REF] = {
1950 .type = HDA_FIXUP_FUNC,
1951 .v.func = stac92hd73xx_fixup_ref,
1953 [STAC_DELL_M6_AMIC] = {
1954 .type = HDA_FIXUP_FUNC,
1955 .v.func = stac92hd73xx_fixup_dell_m6_amic,
1957 [STAC_DELL_M6_DMIC] = {
1958 .type = HDA_FIXUP_FUNC,
1959 .v.func = stac92hd73xx_fixup_dell_m6_dmic,
1961 [STAC_DELL_M6_BOTH] = {
1962 .type = HDA_FIXUP_FUNC,
1963 .v.func = stac92hd73xx_fixup_dell_m6_both,
1966 .type = HDA_FIXUP_FUNC,
1967 .v.func = stac92hd73xx_fixup_dell_eq,
1969 [STAC_ALIENWARE_M17X] = {
1970 .type = HDA_FIXUP_FUNC,
1971 .v.func = stac92hd73xx_fixup_alienware_m17x,
1973 [STAC_92HD73XX_INTEL] = {
1974 .type = HDA_FIXUP_PINS,
1975 .v.pins = intel_dg45id_pin_configs,
1977 [STAC_92HD73XX_NO_JD] = {
1978 .type = HDA_FIXUP_FUNC,
1979 .v.func = stac92hd73xx_fixup_no_jd,
1983 static const struct hda_model_fixup stac92hd73xx_models[] = {
1984 { .id = STAC_92HD73XX_NO_JD, .name = "no-jd" },
1985 { .id = STAC_92HD73XX_REF, .name = "ref" },
1986 { .id = STAC_92HD73XX_INTEL, .name = "intel" },
1987 { .id = STAC_DELL_M6_AMIC, .name = "dell-m6-amic" },
1988 { .id = STAC_DELL_M6_DMIC, .name = "dell-m6-dmic" },
1989 { .id = STAC_DELL_M6_BOTH, .name = "dell-m6" },
1990 { .id = STAC_DELL_EQ, .name = "dell-eq" },
1991 { .id = STAC_ALIENWARE_M17X, .name = "alienware" },
1995 static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = {
1996 /* SigmaTel reference board */
1997 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1998 "DFI LanParty", STAC_92HD73XX_REF),
1999 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
2000 "DFI LanParty", STAC_92HD73XX_REF),
2001 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5002,
2002 "Intel DG45ID", STAC_92HD73XX_INTEL),
2003 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5003,
2004 "Intel DG45FC", STAC_92HD73XX_INTEL),
2005 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254,
2006 "Dell Studio 1535", STAC_DELL_M6_DMIC),
2007 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255,
2008 "unknown Dell", STAC_DELL_M6_DMIC),
2009 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256,
2010 "unknown Dell", STAC_DELL_M6_BOTH),
2011 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257,
2012 "unknown Dell", STAC_DELL_M6_BOTH),
2013 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e,
2014 "unknown Dell", STAC_DELL_M6_AMIC),
2015 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f,
2016 "unknown Dell", STAC_DELL_M6_AMIC),
2017 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271,
2018 "unknown Dell", STAC_DELL_M6_DMIC),
2019 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0272,
2020 "unknown Dell", STAC_DELL_M6_DMIC),
2021 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f,
2022 "Dell Studio 1537", STAC_DELL_M6_DMIC),
2023 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a0,
2024 "Dell Studio 17", STAC_DELL_M6_DMIC),
2025 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02be,
2026 "Dell Studio 1555", STAC_DELL_M6_DMIC),
2027 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd,
2028 "Dell Studio 1557", STAC_DELL_M6_DMIC),
2029 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe,
2030 "Dell Studio XPS 1645", STAC_DELL_M6_DMIC),
2031 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413,
2032 "Dell Studio 1558", STAC_DELL_M6_DMIC),
2033 /* codec SSID matching */
2034 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1,
2035 "Alienware M17x", STAC_ALIENWARE_M17X),
2036 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
2037 "Alienware M17x", STAC_ALIENWARE_M17X),
2038 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490,
2039 "Alienware M17x R3", STAC_DELL_EQ),
2043 static const unsigned int ref92hd83xxx_pin_configs[10] = {
2044 0x02214030, 0x02211010, 0x02a19020, 0x02170130,
2045 0x01014050, 0x01819040, 0x01014020, 0x90a3014e,
2046 0x01451160, 0x98560170,
2049 static const unsigned int dell_s14_pin_configs[10] = {
2050 0x0221403f, 0x0221101f, 0x02a19020, 0x90170110,
2051 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a60160,
2052 0x40f000f0, 0x40f000f0,
2055 static const unsigned int dell_vostro_3500_pin_configs[10] = {
2056 0x02a11020, 0x0221101f, 0x400000f0, 0x90170110,
2057 0x400000f1, 0x400000f2, 0x400000f3, 0x90a60160,
2058 0x400000f4, 0x400000f5,
2061 static const unsigned int hp_dv7_4000_pin_configs[10] = {
2062 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110,
2063 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140,
2064 0x40f000f0, 0x40f000f0,
2067 static const unsigned int hp_zephyr_pin_configs[10] = {
2068 0x01813050, 0x0421201f, 0x04a1205e, 0x96130310,
2069 0x96130310, 0x0101401f, 0x1111611f, 0xd5a30130,
2073 static const unsigned int hp_cNB11_intquad_pin_configs[10] = {
2074 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110,
2075 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130,
2076 0x40f000f0, 0x40f000f0,
2079 static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
2080 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
2081 [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs,
2082 [STAC_DELL_S14] = dell_s14_pin_configs,
2083 [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs,
2084 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs,
2085 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
2086 [STAC_HP_ZEPHYR] = hp_zephyr_pin_configs,
2089 static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
2090 [STAC_92HD83XXX_AUTO] = "auto",
2091 [STAC_92HD83XXX_REF] = "ref",
2092 [STAC_92HD83XXX_PWR_REF] = "mic-ref",
2093 [STAC_DELL_S14] = "dell-s14",
2094 [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500",
2095 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
2096 [STAC_HP_DV7_4000] = "hp-dv7-4000",
2097 [STAC_HP_ZEPHYR] = "hp-zephyr",
2098 [STAC_92HD83XXX_HP_LED] = "hp-led",
2099 [STAC_92HD83XXX_HP_INV_LED] = "hp-inv-led",
2100 [STAC_92HD83XXX_HP_MIC_LED] = "hp-mic-led",
2101 [STAC_92HD83XXX_HEADSET_JACK] = "headset-jack",
2104 static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
2105 /* SigmaTel reference board */
2106 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2107 "DFI LanParty", STAC_92HD83XXX_REF),
2108 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
2109 "DFI LanParty", STAC_92HD83XXX_REF),
2110 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
2111 "unknown Dell", STAC_DELL_S14),
2112 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0532,
2113 "Dell Latitude E6230", STAC_92HD83XXX_HEADSET_JACK),
2114 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0533,
2115 "Dell Latitude E6330", STAC_92HD83XXX_HEADSET_JACK),
2116 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0534,
2117 "Dell Latitude E6430", STAC_92HD83XXX_HEADSET_JACK),
2118 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0535,
2119 "Dell Latitude E6530", STAC_92HD83XXX_HEADSET_JACK),
2120 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053c,
2121 "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
2122 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053d,
2123 "Dell Latitude E5530", STAC_92HD83XXX_HEADSET_JACK),
2124 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0549,
2125 "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
2126 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x057d,
2127 "Dell Latitude E6430s", STAC_92HD83XXX_HEADSET_JACK),
2128 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0584,
2129 "Dell Latitude E6430U", STAC_92HD83XXX_HEADSET_JACK),
2130 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028,
2131 "Dell Vostro 3500", STAC_DELL_VOSTRO_3500),
2132 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
2133 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2134 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657,
2135 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2136 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658,
2137 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2138 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659,
2139 "HP Pavilion dv7", STAC_HP_DV7_4000),
2140 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A,
2141 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2142 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
2143 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2144 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df,
2145 "HP Folio", STAC_92HD83XXX_HP_MIC_LED),
2146 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388,
2147 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2148 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389,
2149 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2150 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355B,
2151 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2152 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355C,
2153 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2154 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355D,
2155 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2156 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355E,
2157 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2158 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355F,
2159 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2160 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3560,
2161 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2162 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358B,
2163 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2164 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358C,
2165 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2166 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358D,
2167 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2168 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3591,
2169 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2170 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3592,
2171 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2172 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
2173 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2174 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
2175 "HP", STAC_HP_ZEPHYR),
2176 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3660,
2177 "HP Mini", STAC_92HD83XXX_HP_LED),
2178 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x144E,
2179 "HP Pavilion dv5", STAC_92HD83XXX_HP_INV_LED),
2183 static const struct snd_pci_quirk stac92hd83xxx_codec_id_cfg_tbl[] = {
2184 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
2185 "HP", STAC_HP_ZEPHYR),
2189 static const struct hda_pintbl ref92hd71bxx_pin_configs[] = {
2190 { 0x0a, 0x02214030 },
2191 { 0x0b, 0x02a19040 },
2192 { 0x0c, 0x01a19020 },
2193 { 0x0d, 0x01014010 },
2194 { 0x0e, 0x0181302e },
2195 { 0x0f, 0x01014010 },
2196 { 0x14, 0x01019020 },
2197 { 0x18, 0x90a000f0 },
2198 { 0x19, 0x90a000f0 },
2199 { 0x1e, 0x01452050 },
2200 { 0x1f, 0x01452050 },
2204 static const struct hda_pintbl dell_m4_1_pin_configs[] = {
2205 { 0x0a, 0x0421101f },
2206 { 0x0b, 0x04a11221 },
2207 { 0x0c, 0x40f000f0 },
2208 { 0x0d, 0x90170110 },
2209 { 0x0e, 0x23a1902e },
2210 { 0x0f, 0x23014250 },
2211 { 0x14, 0x40f000f0 },
2212 { 0x18, 0x90a000f0 },
2213 { 0x19, 0x40f000f0 },
2214 { 0x1e, 0x4f0000f0 },
2215 { 0x1f, 0x4f0000f0 },
2219 static const struct hda_pintbl dell_m4_2_pin_configs[] = {
2220 { 0x0a, 0x0421101f },
2221 { 0x0b, 0x04a11221 },
2222 { 0x0c, 0x90a70330 },
2223 { 0x0d, 0x90170110 },
2224 { 0x0e, 0x23a1902e },
2225 { 0x0f, 0x23014250 },
2226 { 0x14, 0x40f000f0 },
2227 { 0x18, 0x40f000f0 },
2228 { 0x19, 0x40f000f0 },
2229 { 0x1e, 0x044413b0 },
2230 { 0x1f, 0x044413b0 },
2234 static const struct hda_pintbl dell_m4_3_pin_configs[] = {
2235 { 0x0a, 0x0421101f },
2236 { 0x0b, 0x04a11221 },
2237 { 0x0c, 0x90a70330 },
2238 { 0x0d, 0x90170110 },
2239 { 0x0e, 0x40f000f0 },
2240 { 0x0f, 0x40f000f0 },
2241 { 0x14, 0x40f000f0 },
2242 { 0x18, 0x90a000f0 },
2243 { 0x19, 0x40f000f0 },
2244 { 0x1e, 0x044413b0 },
2245 { 0x1f, 0x044413b0 },
2249 static void stac92hd71bxx_fixup_ref(struct hda_codec *codec,
2250 const struct hda_fixup *fix, int action)
2252 struct sigmatel_spec *spec = codec->spec;
2254 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2257 snd_hda_apply_pincfgs(codec, ref92hd71bxx_pin_configs);
2258 spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0;
2261 static void stac92hd71bxx_fixup_no_dmic(struct hda_codec *codec,
2262 const struct hda_fixup *fix, int action)
2264 struct sigmatel_spec *spec = codec->spec;
2266 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2268 spec->num_dmics = 0;
2269 spec->num_smuxes = 0;
2270 spec->num_dmuxes = 0;
2273 static void stac92hd71bxx_fixup_no_smux(struct hda_codec *codec,
2274 const struct hda_fixup *fix, int action)
2276 struct sigmatel_spec *spec = codec->spec;
2278 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2280 spec->num_dmics = 1;
2281 spec->num_smuxes = 0;
2282 spec->num_dmuxes = 1;
2285 static void stac92hd71bxx_fixup_hp_m4(struct hda_codec *codec,
2286 const struct hda_fixup *fix, int action)
2288 struct sigmatel_spec *spec = codec->spec;
2290 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2293 /* Enable VREF power saving on GPIO1 detect */
2294 stac_add_event(codec, codec->afg, STAC_VREF_EVENT, 0x02);
2295 snd_hda_codec_write_cache(codec, codec->afg, 0,
2296 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
2297 snd_hda_jack_detect_enable(codec, codec->afg, 0);
2298 spec->gpio_mask |= 0x02;
2300 /* enable internal microphone */
2301 snd_hda_codec_set_pincfg(codec, 0x0e, 0x01813040);
2302 stac92xx_auto_set_pinctl(codec, 0x0e,
2303 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80);
2305 stac92hd71bxx_fixup_no_dmic(codec, fix, action);
2308 static void stac92hd71bxx_fixup_hp_dv4_1222nr(struct hda_codec *codec,
2309 const struct hda_fixup *fix, int action)
2311 struct sigmatel_spec *spec = codec->spec;
2313 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2315 spec->num_dmics = 1;
2316 /* I don't know if it needs 1 or 2 smuxes - will wait for
2317 * bug reports to fix if needed
2319 spec->num_smuxes = 1;
2320 spec->num_dmuxes = 1;
2323 static void stac92hd71bxx_fixup_hp_dv4(struct hda_codec *codec,
2324 const struct hda_fixup *fix, int action)
2326 struct sigmatel_spec *spec = codec->spec;
2328 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2330 spec->gpio_led = 0x01;
2333 static void stac92hd71bxx_fixup_hp_dv5(struct hda_codec *codec,
2334 const struct hda_fixup *fix, int action)
2336 struct sigmatel_spec *spec = codec->spec;
2340 case HDA_FIXUP_ACT_PRE_PROBE:
2341 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
2342 stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN);
2343 /* HP dv6 gives the headphone pin as a line-out. Thus we
2344 * need to set hp_detect flag here to force to enable HP
2347 spec->hp_detect = 1;
2350 case HDA_FIXUP_ACT_PROBE:
2351 /* enable bass on HP dv7 */
2352 cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
2353 cap &= AC_GPIO_IO_COUNT;
2355 stac_add_hp_bass_switch(codec);
2360 static void stac92hd71bxx_fixup_hp_hdx(struct hda_codec *codec,
2361 const struct hda_fixup *fix, int action)
2363 struct sigmatel_spec *spec = codec->spec;
2365 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2367 spec->gpio_led = 0x08;
2368 spec->num_dmics = 1;
2369 spec->num_smuxes = 1;
2370 spec->num_dmuxes = 1;
2374 static void stac92hd71bxx_fixup_hp(struct hda_codec *codec,
2375 const struct hda_fixup *fix, int action)
2377 struct sigmatel_spec *spec = codec->spec;
2379 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2382 if (hp_blike_system(codec->subsystem_id)) {
2383 unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f);
2384 if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT ||
2385 get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER ||
2386 get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT) {
2387 /* It was changed in the BIOS to just satisfy MS DTM.
2388 * Lets turn it back into slaved HP
2390 pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE))
2391 | (AC_JACK_HP_OUT <<
2392 AC_DEFCFG_DEVICE_SHIFT);
2393 pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC
2394 | AC_DEFCFG_SEQUENCE)))
2396 snd_hda_codec_set_pincfg(codec, 0x0f, pin_cfg);
2400 if (find_mute_led_cfg(codec, 1))
2401 snd_printd("mute LED gpio %d polarity %d\n",
2403 spec->gpio_led_polarity);
2407 static const struct hda_fixup stac92hd71bxx_fixups[] = {
2408 [STAC_92HD71BXX_REF] = {
2409 .type = HDA_FIXUP_FUNC,
2410 .v.func = stac92hd71bxx_fixup_ref,
2412 [STAC_DELL_M4_1] = {
2413 .type = HDA_FIXUP_PINS,
2414 .v.pins = dell_m4_1_pin_configs,
2416 .chain_id = STAC_92HD71BXX_NO_SMUX,
2418 [STAC_DELL_M4_2] = {
2419 .type = HDA_FIXUP_PINS,
2420 .v.pins = dell_m4_2_pin_configs,
2422 .chain_id = STAC_92HD71BXX_NO_DMIC,
2424 [STAC_DELL_M4_3] = {
2425 .type = HDA_FIXUP_PINS,
2426 .v.pins = dell_m4_3_pin_configs,
2428 .chain_id = STAC_92HD71BXX_NO_SMUX,
2431 .type = HDA_FIXUP_FUNC,
2432 .v.func = stac92hd71bxx_fixup_hp_m4,
2434 .chain_id = STAC_92HD71BXX_HP,
2437 .type = HDA_FIXUP_FUNC,
2438 .v.func = stac92hd71bxx_fixup_hp_dv4,
2440 .chain_id = STAC_HP_DV5,
2443 .type = HDA_FIXUP_FUNC,
2444 .v.func = stac92hd71bxx_fixup_hp_dv5,
2446 .chain_id = STAC_92HD71BXX_HP,
2449 .type = HDA_FIXUP_FUNC,
2450 .v.func = stac92hd71bxx_fixup_hp_hdx,
2452 .chain_id = STAC_92HD71BXX_HP,
2454 [STAC_HP_DV4_1222NR] = {
2455 .type = HDA_FIXUP_FUNC,
2456 .v.func = stac92hd71bxx_fixup_hp_dv4_1222nr,
2458 .chain_id = STAC_HP_DV4,
2460 [STAC_92HD71BXX_NO_DMIC] = {
2461 .type = HDA_FIXUP_FUNC,
2462 .v.func = stac92hd71bxx_fixup_no_dmic,
2464 [STAC_92HD71BXX_NO_SMUX] = {
2465 .type = HDA_FIXUP_FUNC,
2466 .v.func = stac92hd71bxx_fixup_no_smux,
2468 [STAC_92HD71BXX_HP] = {
2469 .type = HDA_FIXUP_FUNC,
2470 .v.func = stac92hd71bxx_fixup_hp,
2474 static const struct hda_model_fixup stac92hd71bxx_models[] = {
2475 { .id = STAC_92HD71BXX_REF, .name = "ref" },
2476 { .id = STAC_DELL_M4_1, .name = "dell-m4-1" },
2477 { .id = STAC_DELL_M4_2, .name = "dell-m4-2" },
2478 { .id = STAC_DELL_M4_3, .name = "dell-m4-3" },
2479 { .id = STAC_HP_M4, .name = "hp-m4" },
2480 { .id = STAC_HP_DV4, .name = "hp-dv4" },
2481 { .id = STAC_HP_DV5, .name = "hp-dv5" },
2482 { .id = STAC_HP_HDX, .name = "hp-hdx" },
2483 { .id = STAC_HP_DV4_1222NR, .name = "hp-dv4-1222nr" },
2487 static const struct snd_pci_quirk stac92hd71bxx_fixup_tbl[] = {
2488 /* SigmaTel reference board */
2489 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2490 "DFI LanParty", STAC_92HD71BXX_REF),
2491 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
2492 "DFI LanParty", STAC_92HD71BXX_REF),
2493 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fb,
2494 "HP dv4-1222nr", STAC_HP_DV4_1222NR),
2495 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720,
2497 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
2499 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
2500 "HP dv4-7", STAC_HP_DV4),
2501 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600,
2502 "HP dv4-7", STAC_HP_DV5),
2503 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610,
2504 "HP HDX", STAC_HP_HDX), /* HDX18 */
2505 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
2506 "HP mini 1000", STAC_HP_M4),
2507 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b,
2508 "HP HDX", STAC_HP_HDX), /* HDX16 */
2509 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620,
2510 "HP dv6", STAC_HP_DV5),
2511 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061,
2512 "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */
2513 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x363e,
2514 "HP DV6", STAC_HP_DV5),
2515 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010,
2517 SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_HP, "HP", STAC_92HD71BXX_HP),
2518 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
2519 "unknown Dell", STAC_DELL_M4_1),
2520 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234,
2521 "unknown Dell", STAC_DELL_M4_1),
2522 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0250,
2523 "unknown Dell", STAC_DELL_M4_1),
2524 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024f,
2525 "unknown Dell", STAC_DELL_M4_1),
2526 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024d,
2527 "unknown Dell", STAC_DELL_M4_1),
2528 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0251,
2529 "unknown Dell", STAC_DELL_M4_1),
2530 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0277,
2531 "unknown Dell", STAC_DELL_M4_1),
2532 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0263,
2533 "unknown Dell", STAC_DELL_M4_2),
2534 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0265,
2535 "unknown Dell", STAC_DELL_M4_2),
2536 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0262,
2537 "unknown Dell", STAC_DELL_M4_2),
2538 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264,
2539 "unknown Dell", STAC_DELL_M4_2),
2540 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02aa,
2541 "unknown Dell", STAC_DELL_M4_3),
2545 static const struct hda_pintbl ref922x_pin_configs[] = {
2546 { 0x0a, 0x01014010 },
2547 { 0x0b, 0x01016011 },
2548 { 0x0c, 0x01012012 },
2549 { 0x0d, 0x0221401f },
2550 { 0x0e, 0x01813122 },
2551 { 0x0f, 0x01011014 },
2552 { 0x10, 0x01441030 },
2553 { 0x11, 0x01c41030 },
2554 { 0x15, 0x40000100 },
2555 { 0x1b, 0x40000100 },
2560 STAC 922X pin configs for
2567 static const struct hda_pintbl dell_922x_d81_pin_configs[] = {
2568 { 0x0a, 0x02214030 },
2569 { 0x0b, 0x01a19021 },
2570 { 0x0c, 0x01111012 },
2571 { 0x0d, 0x01114010 },
2572 { 0x0e, 0x02a19020 },
2573 { 0x0f, 0x01117011 },
2574 { 0x10, 0x400001f0 },
2575 { 0x11, 0x400001f1 },
2576 { 0x15, 0x01813122 },
2577 { 0x1b, 0x400001f2 },
2582 STAC 922X pin configs for
2586 static const struct hda_pintbl dell_922x_d82_pin_configs[] = {
2587 { 0x0a, 0x02214030 },
2588 { 0x0b, 0x01a19021 },
2589 { 0x0c, 0x01111012 },
2590 { 0x0d, 0x01114010 },
2591 { 0x0e, 0x02a19020 },
2592 { 0x0f, 0x01117011 },
2593 { 0x10, 0x01451140 },
2594 { 0x11, 0x400001f0 },
2595 { 0x15, 0x01813122 },
2596 { 0x1b, 0x400001f1 },
2601 STAC 922X pin configs for
2604 static const struct hda_pintbl dell_922x_m81_pin_configs[] = {
2605 { 0x0a, 0x0321101f },
2606 { 0x0b, 0x01112024 },
2607 { 0x0c, 0x01111222 },
2608 { 0x0d, 0x91174220 },
2609 { 0x0e, 0x03a11050 },
2610 { 0x0f, 0x01116221 },
2611 { 0x10, 0x90a70330 },
2612 { 0x11, 0x01452340 },
2613 { 0x15, 0x40C003f1 },
2614 { 0x1b, 0x405003f0 },
2619 STAC 9221 A1 pin configs for
2620 102801D7 (Dell XPS M1210)
2622 static const struct hda_pintbl dell_922x_m82_pin_configs[] = {
2623 { 0x0a, 0x02211211 },
2624 { 0x0b, 0x408103ff },
2625 { 0x0c, 0x02a1123e },
2626 { 0x0d, 0x90100310 },
2627 { 0x0e, 0x408003f1 },
2628 { 0x0f, 0x0221121f },
2629 { 0x10, 0x03451340 },
2630 { 0x11, 0x40c003f2 },
2631 { 0x15, 0x508003f3 },
2632 { 0x1b, 0x405003f4 },
2636 static const struct hda_pintbl d945gtp3_pin_configs[] = {
2637 { 0x0a, 0x0221401f },
2638 { 0x0b, 0x01a19022 },
2639 { 0x0c, 0x01813021 },
2640 { 0x0d, 0x01014010 },
2641 { 0x0e, 0x40000100 },
2642 { 0x0f, 0x40000100 },
2643 { 0x10, 0x40000100 },
2644 { 0x11, 0x40000100 },
2645 { 0x15, 0x02a19120 },
2646 { 0x1b, 0x40000100 },
2650 static const struct hda_pintbl d945gtp5_pin_configs[] = {
2651 { 0x0a, 0x0221401f },
2652 { 0x0b, 0x01011012 },
2653 { 0x0c, 0x01813024 },
2654 { 0x0d, 0x01014010 },
2655 { 0x0e, 0x01a19021 },
2656 { 0x0f, 0x01016011 },
2657 { 0x10, 0x01452130 },
2658 { 0x11, 0x40000100 },
2659 { 0x15, 0x02a19320 },
2660 { 0x1b, 0x40000100 },
2664 static const struct hda_pintbl intel_mac_v1_pin_configs[] = {
2665 { 0x0a, 0x0121e21f },
2666 { 0x0b, 0x400000ff },
2667 { 0x0c, 0x9017e110 },
2668 { 0x0d, 0x400000fd },
2669 { 0x0e, 0x400000fe },
2670 { 0x0f, 0x0181e020 },
2671 { 0x10, 0x1145e030 },
2672 { 0x11, 0x11c5e240 },
2673 { 0x15, 0x400000fc },
2674 { 0x1b, 0x400000fb },
2678 static const struct hda_pintbl intel_mac_v2_pin_configs[] = {
2679 { 0x0a, 0x0121e21f },
2680 { 0x0b, 0x90a7012e },
2681 { 0x0c, 0x9017e110 },
2682 { 0x0d, 0x400000fd },
2683 { 0x0e, 0x400000fe },
2684 { 0x0f, 0x0181e020 },
2685 { 0x10, 0x1145e230 },
2686 { 0x11, 0x500000fa },
2687 { 0x15, 0x400000fc },
2688 { 0x1b, 0x400000fb },
2692 static const struct hda_pintbl intel_mac_v3_pin_configs[] = {
2693 { 0x0a, 0x0121e21f },
2694 { 0x0b, 0x90a7012e },
2695 { 0x0c, 0x9017e110 },
2696 { 0x0d, 0x400000fd },
2697 { 0x0e, 0x400000fe },
2698 { 0x0f, 0x0181e020 },
2699 { 0x10, 0x1145e230 },
2700 { 0x11, 0x11c5e240 },
2701 { 0x15, 0x400000fc },
2702 { 0x1b, 0x400000fb },
2706 static const struct hda_pintbl intel_mac_v4_pin_configs[] = {
2707 { 0x0a, 0x0321e21f },
2708 { 0x0b, 0x03a1e02e },
2709 { 0x0c, 0x9017e110 },
2710 { 0x0d, 0x9017e11f },
2711 { 0x0e, 0x400000fe },
2712 { 0x0f, 0x0381e020 },
2713 { 0x10, 0x1345e230 },
2714 { 0x11, 0x13c5e240 },
2715 { 0x15, 0x400000fc },
2716 { 0x1b, 0x400000fb },
2720 static const struct hda_pintbl intel_mac_v5_pin_configs[] = {
2721 { 0x0a, 0x0321e21f },
2722 { 0x0b, 0x03a1e02e },
2723 { 0x0c, 0x9017e110 },
2724 { 0x0d, 0x9017e11f },
2725 { 0x0e, 0x400000fe },
2726 { 0x0f, 0x0381e020 },
2727 { 0x10, 0x1345e230 },
2728 { 0x11, 0x13c5e240 },
2729 { 0x15, 0x400000fc },
2730 { 0x1b, 0x400000fb },
2734 static const struct hda_pintbl ecs202_pin_configs[] = {
2735 { 0x0a, 0x0221401f },
2736 { 0x0b, 0x02a19020 },
2737 { 0x0c, 0x01a19020 },
2738 { 0x0d, 0x01114010 },
2739 { 0x0e, 0x408000f0 },
2740 { 0x0f, 0x01813022 },
2741 { 0x10, 0x074510a0 },
2742 { 0x11, 0x40c400f1 },
2743 { 0x15, 0x9037012e },
2744 { 0x1b, 0x40e000f2 },
2748 /* codec SSIDs for Intel Mac sharing the same PCI SSID 8384:7680 */
2749 static const struct snd_pci_quirk stac922x_intel_mac_fixup_tbl[] = {
2750 SND_PCI_QUIRK(0x106b, 0x0800, "Mac", STAC_INTEL_MAC_V1),
2751 SND_PCI_QUIRK(0x106b, 0x0600, "Mac", STAC_INTEL_MAC_V2),
2752 SND_PCI_QUIRK(0x106b, 0x0700, "Mac", STAC_INTEL_MAC_V2),
2753 SND_PCI_QUIRK(0x106b, 0x0e00, "Mac", STAC_INTEL_MAC_V3),
2754 SND_PCI_QUIRK(0x106b, 0x0f00, "Mac", STAC_INTEL_MAC_V3),
2755 SND_PCI_QUIRK(0x106b, 0x1600, "Mac", STAC_INTEL_MAC_V3),
2756 SND_PCI_QUIRK(0x106b, 0x1700, "Mac", STAC_INTEL_MAC_V3),
2757 SND_PCI_QUIRK(0x106b, 0x0200, "Mac", STAC_INTEL_MAC_V3),
2758 SND_PCI_QUIRK(0x106b, 0x1e00, "Mac", STAC_INTEL_MAC_V3),
2759 SND_PCI_QUIRK(0x106b, 0x1a00, "Mac", STAC_INTEL_MAC_V4),
2760 SND_PCI_QUIRK(0x106b, 0x0a00, "Mac", STAC_INTEL_MAC_V5),
2761 SND_PCI_QUIRK(0x106b, 0x2200, "Mac", STAC_INTEL_MAC_V5),
2765 static const struct hda_fixup stac922x_fixups[];
2767 /* remap the fixup from codec SSID and apply it */
2768 static void stac922x_fixup_intel_mac_auto(struct hda_codec *codec,
2769 const struct hda_fixup *fix,
2772 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2774 snd_hda_pick_fixup(codec, NULL, stac922x_intel_mac_fixup_tbl,
2776 if (codec->fixup_id != STAC_INTEL_MAC_AUTO)
2777 snd_hda_apply_fixup(codec, action);
2780 static void stac922x_fixup_intel_mac_gpio(struct hda_codec *codec,
2781 const struct hda_fixup *fix,
2784 struct sigmatel_spec *spec = codec->spec;
2786 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2787 spec->gpio_mask = spec->gpio_dir = 0x03;
2788 spec->gpio_data = 0x03;
2792 static const struct hda_fixup stac922x_fixups[] = {
2794 .type = HDA_FIXUP_PINS,
2795 .v.pins = ref922x_pin_configs,
2798 .type = HDA_FIXUP_PINS,
2799 .v.pins = d945gtp3_pin_configs,
2802 .type = HDA_FIXUP_PINS,
2803 .v.pins = d945gtp5_pin_configs,
2805 [STAC_INTEL_MAC_AUTO] = {
2806 .type = HDA_FIXUP_FUNC,
2807 .v.func = stac922x_fixup_intel_mac_auto,
2809 [STAC_INTEL_MAC_V1] = {
2810 .type = HDA_FIXUP_PINS,
2811 .v.pins = intel_mac_v1_pin_configs,
2813 .chain_id = STAC_922X_INTEL_MAC_GPIO,
2815 [STAC_INTEL_MAC_V2] = {
2816 .type = HDA_FIXUP_PINS,
2817 .v.pins = intel_mac_v2_pin_configs,
2819 .chain_id = STAC_922X_INTEL_MAC_GPIO,
2821 [STAC_INTEL_MAC_V3] = {
2822 .type = HDA_FIXUP_PINS,
2823 .v.pins = intel_mac_v3_pin_configs,
2825 .chain_id = STAC_922X_INTEL_MAC_GPIO,
2827 [STAC_INTEL_MAC_V4] = {
2828 .type = HDA_FIXUP_PINS,
2829 .v.pins = intel_mac_v4_pin_configs,
2831 .chain_id = STAC_922X_INTEL_MAC_GPIO,
2833 [STAC_INTEL_MAC_V5] = {
2834 .type = HDA_FIXUP_PINS,
2835 .v.pins = intel_mac_v5_pin_configs,
2837 .chain_id = STAC_922X_INTEL_MAC_GPIO,
2839 [STAC_922X_INTEL_MAC_GPIO] = {
2840 .type = HDA_FIXUP_FUNC,
2841 .v.func = stac922x_fixup_intel_mac_gpio,
2844 .type = HDA_FIXUP_PINS,
2845 .v.pins = ecs202_pin_configs,
2847 [STAC_922X_DELL_D81] = {
2848 .type = HDA_FIXUP_PINS,
2849 .v.pins = dell_922x_d81_pin_configs,
2851 [STAC_922X_DELL_D82] = {
2852 .type = HDA_FIXUP_PINS,
2853 .v.pins = dell_922x_d82_pin_configs,
2855 [STAC_922X_DELL_M81] = {
2856 .type = HDA_FIXUP_PINS,
2857 .v.pins = dell_922x_m81_pin_configs,
2859 [STAC_922X_DELL_M82] = {
2860 .type = HDA_FIXUP_PINS,
2861 .v.pins = dell_922x_m82_pin_configs,
2865 static const struct hda_model_fixup stac922x_models[] = {
2866 { .id = STAC_D945_REF, .name = "ref" },
2867 { .id = STAC_D945GTP5, .name = "5stack" },
2868 { .id = STAC_D945GTP3, .name = "3stack" },
2869 { .id = STAC_INTEL_MAC_V1, .name = "intel-mac-v1" },
2870 { .id = STAC_INTEL_MAC_V2, .name = "intel-mac-v2" },
2871 { .id = STAC_INTEL_MAC_V3, .name = "intel-mac-v3" },
2872 { .id = STAC_INTEL_MAC_V4, .name = "intel-mac-v4" },
2873 { .id = STAC_INTEL_MAC_V5, .name = "intel-mac-v5" },
2874 { .id = STAC_INTEL_MAC_AUTO, .name = "intel-mac-auto" },
2875 { .id = STAC_ECS_202, .name = "ecs202" },
2876 { .id = STAC_922X_DELL_D81, .name = "dell-d81" },
2877 { .id = STAC_922X_DELL_D82, .name = "dell-d82" },
2878 { .id = STAC_922X_DELL_M81, .name = "dell-m81" },
2879 { .id = STAC_922X_DELL_M82, .name = "dell-m82" },
2880 /* for backward compatibility */
2881 { .id = STAC_INTEL_MAC_V3, .name = "macmini" },
2882 { .id = STAC_INTEL_MAC_V5, .name = "macbook" },
2883 { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro-v1" },
2884 { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro" },
2885 { .id = STAC_INTEL_MAC_V2, .name = "imac-intel" },
2886 { .id = STAC_INTEL_MAC_V3, .name = "imac-intel-20" },
2890 static const struct snd_pci_quirk stac922x_fixup_tbl[] = {
2891 /* SigmaTel reference board */
2892 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2893 "DFI LanParty", STAC_D945_REF),
2894 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
2895 "DFI LanParty", STAC_D945_REF),
2896 /* Intel 945G based systems */
2897 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
2898 "Intel D945G", STAC_D945GTP3),
2899 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
2900 "Intel D945G", STAC_D945GTP3),
2901 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
2902 "Intel D945G", STAC_D945GTP3),
2903 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
2904 "Intel D945G", STAC_D945GTP3),
2905 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
2906 "Intel D945G", STAC_D945GTP3),
2907 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
2908 "Intel D945G", STAC_D945GTP3),
2909 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
2910 "Intel D945G", STAC_D945GTP3),
2911 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
2912 "Intel D945G", STAC_D945GTP3),
2913 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
2914 "Intel D945G", STAC_D945GTP3),
2915 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
2916 "Intel D945G", STAC_D945GTP3),
2917 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
2918 "Intel D945G", STAC_D945GTP3),
2919 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
2920 "Intel D945G", STAC_D945GTP3),
2921 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
2922 "Intel D945G", STAC_D945GTP3),
2923 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
2924 "Intel D945G", STAC_D945GTP3),
2925 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
2926 "Intel D945G", STAC_D945GTP3),
2927 /* Intel D945G 5-stack systems */
2928 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
2929 "Intel D945G", STAC_D945GTP5),
2930 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
2931 "Intel D945G", STAC_D945GTP5),
2932 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
2933 "Intel D945G", STAC_D945GTP5),
2934 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
2935 "Intel D945G", STAC_D945GTP5),
2936 /* Intel 945P based systems */
2937 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
2938 "Intel D945P", STAC_D945GTP3),
2939 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
2940 "Intel D945P", STAC_D945GTP3),
2941 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
2942 "Intel D945P", STAC_D945GTP3),
2943 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
2944 "Intel D945P", STAC_D945GTP3),
2945 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
2946 "Intel D945P", STAC_D945GTP3),
2947 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
2948 "Intel D945P", STAC_D945GTP5),
2950 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0204,
2951 "Intel D945", STAC_D945_REF),
2954 /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */
2955 SND_PCI_QUIRK(0x8384, 0x7680, "Mac", STAC_INTEL_MAC_AUTO),
2958 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
2959 "unknown Dell", STAC_922X_DELL_D81),
2960 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
2961 "unknown Dell", STAC_922X_DELL_D81),
2962 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
2963 "unknown Dell", STAC_922X_DELL_D81),
2964 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
2965 "unknown Dell", STAC_922X_DELL_D82),
2966 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
2967 "unknown Dell", STAC_922X_DELL_M81),
2968 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
2969 "unknown Dell", STAC_922X_DELL_D82),
2970 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
2971 "unknown Dell", STAC_922X_DELL_D81),
2972 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
2973 "unknown Dell", STAC_922X_DELL_D81),
2974 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
2975 "Dell XPS M1210", STAC_922X_DELL_M82),
2976 /* ECS/PC Chips boards */
2977 SND_PCI_QUIRK_MASK(0x1019, 0xf000, 0x2000,
2978 "ECS/PC chips", STAC_ECS_202),
2982 static const struct hda_pintbl ref927x_pin_configs[] = {
2983 { 0x0a, 0x02214020 },
2984 { 0x0b, 0x02a19080 },
2985 { 0x0c, 0x0181304e },
2986 { 0x0d, 0x01014010 },
2987 { 0x0e, 0x01a19040 },
2988 { 0x0f, 0x01011012 },
2989 { 0x10, 0x01016011 },
2990 { 0x11, 0x0101201f },
2991 { 0x12, 0x183301f0 },
2992 { 0x13, 0x18a001f0 },
2993 { 0x14, 0x18a001f0 },
2994 { 0x21, 0x01442070 },
2995 { 0x22, 0x01c42190 },
2996 { 0x23, 0x40000100 },
3000 static const struct hda_pintbl d965_3st_pin_configs[] = {
3001 { 0x0a, 0x0221401f },
3002 { 0x0b, 0x02a19120 },
3003 { 0x0c, 0x40000100 },
3004 { 0x0d, 0x01014011 },
3005 { 0x0e, 0x01a19021 },
3006 { 0x0f, 0x01813024 },
3007 { 0x10, 0x40000100 },
3008 { 0x11, 0x40000100 },
3009 { 0x12, 0x40000100 },
3010 { 0x13, 0x40000100 },
3011 { 0x14, 0x40000100 },
3012 { 0x21, 0x40000100 },
3013 { 0x22, 0x40000100 },
3014 { 0x23, 0x40000100 },
3018 static const struct hda_pintbl d965_5st_pin_configs[] = {
3019 { 0x0a, 0x02214020 },
3020 { 0x0b, 0x02a19080 },
3021 { 0x0c, 0x0181304e },
3022 { 0x0d, 0x01014010 },
3023 { 0x0e, 0x01a19040 },
3024 { 0x0f, 0x01011012 },
3025 { 0x10, 0x01016011 },
3026 { 0x11, 0x40000100 },
3027 { 0x12, 0x40000100 },
3028 { 0x13, 0x40000100 },
3029 { 0x14, 0x40000100 },
3030 { 0x21, 0x01442070 },
3031 { 0x22, 0x40000100 },
3032 { 0x23, 0x40000100 },
3036 static const struct hda_pintbl d965_5st_no_fp_pin_configs[] = {
3037 { 0x0a, 0x40000100 },
3038 { 0x0b, 0x40000100 },
3039 { 0x0c, 0x0181304e },
3040 { 0x0d, 0x01014010 },
3041 { 0x0e, 0x01a19040 },
3042 { 0x0f, 0x01011012 },
3043 { 0x10, 0x01016011 },
3044 { 0x11, 0x40000100 },
3045 { 0x12, 0x40000100 },
3046 { 0x13, 0x40000100 },
3047 { 0x14, 0x40000100 },
3048 { 0x21, 0x01442070 },
3049 { 0x22, 0x40000100 },
3050 { 0x23, 0x40000100 },
3054 static const struct hda_pintbl dell_3st_pin_configs[] = {
3055 { 0x0a, 0x02211230 },
3056 { 0x0b, 0x02a11220 },
3057 { 0x0c, 0x01a19040 },
3058 { 0x0d, 0x01114210 },
3059 { 0x0e, 0x01111212 },
3060 { 0x0f, 0x01116211 },
3061 { 0x10, 0x01813050 },
3062 { 0x11, 0x01112214 },
3063 { 0x12, 0x403003fa },
3064 { 0x13, 0x90a60040 },
3065 { 0x14, 0x90a60040 },
3066 { 0x21, 0x404003fb },
3067 { 0x22, 0x40c003fc },
3068 { 0x23, 0x40000100 },
3072 static void stac927x_fixup_ref_no_jd(struct hda_codec *codec,
3073 const struct hda_fixup *fix, int action)
3075 struct sigmatel_spec *spec = codec->spec;
3077 /* no jack detecion for ref-no-jd model */
3078 if (action == HDA_FIXUP_ACT_PROBE)
3079 spec->hp_detect = 0;
3082 static void stac927x_fixup_ref(struct hda_codec *codec,
3083 const struct hda_fixup *fix, int action)
3085 struct sigmatel_spec *spec = codec->spec;
3087 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3088 snd_hda_apply_pincfgs(codec, ref927x_pin_configs);
3089 spec->eapd_mask = spec->gpio_mask = 0;
3090 spec->gpio_dir = spec->gpio_data = 0;
3094 static void stac927x_fixup_dell_dmic(struct hda_codec *codec,
3095 const struct hda_fixup *fix, int action)
3097 struct sigmatel_spec *spec = codec->spec;
3099 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3102 if (codec->subsystem_id != 0x1028022f) {
3103 /* GPIO2 High = Enable EAPD */
3104 spec->eapd_mask = spec->gpio_mask = 0x04;
3105 spec->gpio_dir = spec->gpio_data = 0x04;
3107 spec->dmic_nids = stac927x_dmic_nids;
3108 spec->num_dmics = STAC927X_NUM_DMICS;
3110 snd_hda_add_verbs(codec, dell_3st_core_init);
3111 spec->volknob_init = 1;
3112 spec->dmux_nids = stac927x_dmux_nids;
3113 spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
3116 static void stac927x_fixup_volknob(struct hda_codec *codec,
3117 const struct hda_fixup *fix, int action)
3119 struct sigmatel_spec *spec = codec->spec;
3121 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3122 snd_hda_add_verbs(codec, stac927x_volknob_core_init);
3123 spec->volknob_init = 1;
3127 static const struct hda_fixup stac927x_fixups[] = {
3128 [STAC_D965_REF_NO_JD] = {
3129 .type = HDA_FIXUP_FUNC,
3130 .v.func = stac927x_fixup_ref_no_jd,
3132 .chain_id = STAC_D965_REF,
3135 .type = HDA_FIXUP_FUNC,
3136 .v.func = stac927x_fixup_ref,
3139 .type = HDA_FIXUP_PINS,
3140 .v.pins = d965_3st_pin_configs,
3142 .chain_id = STAC_D965_VERBS,
3145 .type = HDA_FIXUP_PINS,
3146 .v.pins = d965_5st_pin_configs,
3148 .chain_id = STAC_D965_VERBS,
3150 [STAC_D965_VERBS] = {
3151 .type = HDA_FIXUP_VERBS,
3152 .v.verbs = d965_core_init,
3154 [STAC_D965_5ST_NO_FP] = {
3155 .type = HDA_FIXUP_PINS,
3156 .v.pins = d965_5st_no_fp_pin_configs,
3159 .type = HDA_FIXUP_PINS,
3160 .v.pins = dell_3st_pin_configs,
3162 .chain_id = STAC_927X_DELL_DMIC,
3164 [STAC_DELL_BIOS] = {
3165 .type = HDA_FIXUP_PINS,
3166 .v.pins = (const struct hda_pintbl[]) {
3167 /* configure the analog microphone on some laptops */
3168 { 0x0c, 0x90a79130 },
3169 /* correct the front output jack as a hp out */
3170 { 0x0f, 0x0227011f },
3171 /* correct the front input jack as a mic */
3172 { 0x0e, 0x02a79130 },
3176 .chain_id = STAC_927X_DELL_DMIC,
3178 [STAC_DELL_BIOS_SPDIF] = {
3179 .type = HDA_FIXUP_PINS,
3180 .v.pins = (const struct hda_pintbl[]) {
3181 /* correct the device field to SPDIF out */
3182 { 0x21, 0x01442070 },
3186 .chain_id = STAC_DELL_BIOS,
3188 [STAC_927X_DELL_DMIC] = {
3189 .type = HDA_FIXUP_FUNC,
3190 .v.func = stac927x_fixup_dell_dmic,
3192 [STAC_927X_VOLKNOB] = {
3193 .type = HDA_FIXUP_FUNC,
3194 .v.func = stac927x_fixup_volknob,
3198 static const struct hda_model_fixup stac927x_models[] = {
3199 { .id = STAC_D965_REF_NO_JD, .name = "ref-no-jd" },
3200 { .id = STAC_D965_REF, .name = "ref" },
3201 { .id = STAC_D965_3ST, .name = "3stack" },
3202 { .id = STAC_D965_5ST, .name = "5stack" },
3203 { .id = STAC_D965_5ST_NO_FP, .name = "5stack-no-fp" },
3204 { .id = STAC_DELL_3ST, .name = "dell-3stack" },
3205 { .id = STAC_DELL_BIOS, .name = "dell-bios" },
3206 { .id = STAC_927X_VOLKNOB, .name = "volknob" },
3210 static const struct snd_pci_quirk stac927x_fixup_tbl[] = {
3211 /* SigmaTel reference board */
3212 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3213 "DFI LanParty", STAC_D965_REF),
3214 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3215 "DFI LanParty", STAC_D965_REF),
3216 /* Intel 946 based systems */
3217 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
3218 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
3219 /* 965 based 3 stack systems */
3220 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2100,
3221 "Intel D965", STAC_D965_3ST),
3222 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000,
3223 "Intel D965", STAC_D965_3ST),
3224 /* Dell 3 stack systems */
3225 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
3226 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
3227 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
3228 /* Dell 3 stack systems with verb table in BIOS */
3229 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
3230 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_BIOS),
3231 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
3232 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS_SPDIF),
3233 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS),
3234 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
3235 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
3236 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
3237 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS_SPDIF),
3238 /* 965 based 5 stack systems */
3239 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2300,
3240 "Intel D965", STAC_D965_5ST),
3241 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500,
3242 "Intel D965", STAC_D965_5ST),
3243 /* volume-knob fixes */
3244 SND_PCI_QUIRK_VENDOR(0x10cf, "FSC", STAC_927X_VOLKNOB),
3248 static const struct hda_pintbl ref9205_pin_configs[] = {
3249 { 0x0a, 0x40000100 },
3250 { 0x0b, 0x40000100 },
3251 { 0x0c, 0x01016011 },
3252 { 0x0d, 0x01014010 },
3253 { 0x0e, 0x01813122 },
3254 { 0x0f, 0x01a19021 },
3255 { 0x14, 0x01019020 },
3256 { 0x16, 0x40000100 },
3257 { 0x17, 0x90a000f0 },
3258 { 0x18, 0x90a000f0 },
3259 { 0x21, 0x01441030 },
3260 { 0x22, 0x01c41030 },
3265 STAC 9205 pin configs for
3272 10280228 (Dell Vostro 1500)
3273 10280229 (Dell Vostro 1700)
3275 static const struct hda_pintbl dell_9205_m42_pin_configs[] = {
3276 { 0x0a, 0x0321101F },
3277 { 0x0b, 0x03A11020 },
3278 { 0x0c, 0x400003FA },
3279 { 0x0d, 0x90170310 },
3280 { 0x0e, 0x400003FB },
3281 { 0x0f, 0x400003FC },
3282 { 0x14, 0x400003FD },
3283 { 0x16, 0x40F000F9 },
3284 { 0x17, 0x90A60330 },
3285 { 0x18, 0x400003FF },
3286 { 0x21, 0x0144131F },
3287 { 0x22, 0x40C003FE },
3292 STAC 9205 pin configs for
3296 102801FF (Dell Precision M4300)
3301 static const struct hda_pintbl dell_9205_m43_pin_configs[] = {
3302 { 0x0a, 0x0321101f },
3303 { 0x0b, 0x03a11020 },
3304 { 0x0c, 0x90a70330 },
3305 { 0x0d, 0x90170310 },
3306 { 0x0e, 0x400000fe },
3307 { 0x0f, 0x400000ff },
3308 { 0x14, 0x400000fd },
3309 { 0x16, 0x40f000f9 },
3310 { 0x17, 0x400000fa },
3311 { 0x18, 0x400000fc },
3312 { 0x21, 0x0144131f },
3313 { 0x22, 0x40c003f8 },
3314 /* Enable SPDIF in/out */
3315 { 0x1f, 0x01441030 },
3316 { 0x20, 0x1c410030 },
3320 static const struct hda_pintbl dell_9205_m44_pin_configs[] = {
3321 { 0x0a, 0x0421101f },
3322 { 0x0b, 0x04a11020 },
3323 { 0x0c, 0x400003fa },
3324 { 0x0d, 0x90170310 },
3325 { 0x0e, 0x400003fb },
3326 { 0x0f, 0x400003fc },
3327 { 0x14, 0x400003fd },
3328 { 0x16, 0x400003f9 },
3329 { 0x17, 0x90a60330 },
3330 { 0x18, 0x400003ff },
3331 { 0x21, 0x01441340 },
3332 { 0x22, 0x40c003fe },
3336 static void stac9205_fixup_ref(struct hda_codec *codec,
3337 const struct hda_fixup *fix, int action)
3339 struct sigmatel_spec *spec = codec->spec;
3341 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3342 snd_hda_apply_pincfgs(codec, ref9205_pin_configs);
3343 /* SPDIF-In enabled */
3344 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0;
3348 static void stac9205_fixup_dell_m43(struct hda_codec *codec,
3349 const struct hda_fixup *fix, int action)
3351 struct sigmatel_spec *spec = codec->spec;
3354 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3355 snd_hda_apply_pincfgs(codec, dell_9205_m43_pin_configs);
3357 /* Enable unsol response for GPIO4/Dock HP connection */
3358 err = stac_add_event(codec, codec->afg, STAC_VREF_EVENT, 0x01);
3361 snd_hda_codec_write_cache(codec, codec->afg, 0,
3362 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
3363 snd_hda_jack_detect_enable(codec, codec->afg, 0);
3365 spec->gpio_dir = 0x0b;
3366 spec->eapd_mask = 0x01;
3367 spec->gpio_mask = 0x1b;
3368 spec->gpio_mute = 0x10;
3369 /* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute,
3372 spec->gpio_data = 0x01;
3376 static void stac9205_fixup_eapd(struct hda_codec *codec,
3377 const struct hda_fixup *fix, int action)
3379 struct sigmatel_spec *spec = codec->spec;
3381 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3382 spec->eapd_switch = 0;
3385 static const struct hda_fixup stac9205_fixups[] = {
3387 .type = HDA_FIXUP_FUNC,
3388 .v.func = stac9205_fixup_ref,
3390 [STAC_9205_DELL_M42] = {
3391 .type = HDA_FIXUP_PINS,
3392 .v.pins = dell_9205_m42_pin_configs,
3394 [STAC_9205_DELL_M43] = {
3395 .type = HDA_FIXUP_FUNC,
3396 .v.func = stac9205_fixup_dell_m43,
3398 [STAC_9205_DELL_M44] = {
3399 .type = HDA_FIXUP_PINS,
3400 .v.pins = dell_9205_m44_pin_configs,
3402 [STAC_9205_EAPD] = {
3403 .type = HDA_FIXUP_FUNC,
3404 .v.func = stac9205_fixup_eapd,
3409 static const struct hda_model_fixup stac9205_models[] = {
3410 { .id = STAC_9205_REF, .name = "ref" },
3411 { .id = STAC_9205_DELL_M42, .name = "dell-m42" },
3412 { .id = STAC_9205_DELL_M43, .name = "dell-m43" },
3413 { .id = STAC_9205_DELL_M44, .name = "dell-m44" },
3414 { .id = STAC_9205_EAPD, .name = "eapd" },
3418 static const struct snd_pci_quirk stac9205_fixup_tbl[] = {
3419 /* SigmaTel reference board */
3420 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3421 "DFI LanParty", STAC_9205_REF),
3422 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xfb30,
3423 "SigmaTel", STAC_9205_REF),
3424 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3425 "DFI LanParty", STAC_9205_REF),
3427 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
3428 "unknown Dell", STAC_9205_DELL_M42),
3429 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
3430 "unknown Dell", STAC_9205_DELL_M42),
3431 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
3432 "Dell Precision", STAC_9205_DELL_M43),
3433 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
3434 "Dell Precision", STAC_9205_DELL_M43),
3435 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
3436 "Dell Precision", STAC_9205_DELL_M43),
3437 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
3438 "unknown Dell", STAC_9205_DELL_M42),
3439 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
3440 "unknown Dell", STAC_9205_DELL_M42),
3441 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
3442 "Dell Precision", STAC_9205_DELL_M43),
3443 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
3444 "Dell Precision M4300", STAC_9205_DELL_M43),
3445 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
3446 "unknown Dell", STAC_9205_DELL_M42),
3447 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
3448 "Dell Precision", STAC_9205_DELL_M43),
3449 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
3450 "Dell Precision", STAC_9205_DELL_M43),
3451 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
3452 "Dell Precision", STAC_9205_DELL_M43),
3453 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
3454 "Dell Inspiron", STAC_9205_DELL_M44),
3455 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228,
3456 "Dell Vostro 1500", STAC_9205_DELL_M42),
3457 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0229,
3458 "Dell Vostro 1700", STAC_9205_DELL_M42),
3460 SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD),
3461 SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD),
3465 static void stac92xx_set_config_regs(struct hda_codec *codec,
3466 const unsigned int *pincfgs)
3469 struct sigmatel_spec *spec = codec->spec;
3474 for (i = 0; i < spec->num_pins; i++)
3475 if (spec->pin_nids[i] && pincfgs[i])
3476 snd_hda_codec_set_pincfg(codec, spec->pin_nids[i],
3481 * Analog playback callbacks
3483 static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
3484 struct hda_codec *codec,
3485 struct snd_pcm_substream *substream)
3487 struct sigmatel_spec *spec = codec->spec;
3488 if (spec->stream_delay)
3489 msleep(spec->stream_delay);
3490 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3494 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3495 struct hda_codec *codec,
3496 unsigned int stream_tag,
3497 unsigned int format,
3498 struct snd_pcm_substream *substream)
3500 struct sigmatel_spec *spec = codec->spec;
3501 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream);
3504 static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3505 struct hda_codec *codec,
3506 struct snd_pcm_substream *substream)
3508 struct sigmatel_spec *spec = codec->spec;
3509 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3513 * Digital playback callbacks
3515 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3516 struct hda_codec *codec,
3517 struct snd_pcm_substream *substream)
3519 struct sigmatel_spec *spec = codec->spec;
3520 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3523 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3524 struct hda_codec *codec,
3525 struct snd_pcm_substream *substream)
3527 struct sigmatel_spec *spec = codec->spec;
3528 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3531 static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3532 struct hda_codec *codec,
3533 unsigned int stream_tag,
3534 unsigned int format,
3535 struct snd_pcm_substream *substream)
3537 struct sigmatel_spec *spec = codec->spec;
3538 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3539 stream_tag, format, substream);
3542 static int stac92xx_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3543 struct hda_codec *codec,
3544 struct snd_pcm_substream *substream)
3546 struct sigmatel_spec *spec = codec->spec;
3547 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3552 * Analog capture callbacks
3554 static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3555 struct hda_codec *codec,
3556 unsigned int stream_tag,
3557 unsigned int format,
3558 struct snd_pcm_substream *substream)
3560 struct sigmatel_spec *spec = codec->spec;
3561 hda_nid_t nid = spec->adc_nids[substream->number];
3563 if (spec->powerdown_adcs) {
3565 snd_hda_codec_write(codec, nid, 0,
3566 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3568 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
3572 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3573 struct hda_codec *codec,
3574 struct snd_pcm_substream *substream)
3576 struct sigmatel_spec *spec = codec->spec;
3577 hda_nid_t nid = spec->adc_nids[substream->number];
3579 snd_hda_codec_cleanup_stream(codec, nid);
3580 if (spec->powerdown_adcs)
3581 snd_hda_codec_write(codec, nid, 0,
3582 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3586 static const struct hda_pcm_stream stac92xx_pcm_digital_playback = {
3590 /* NID is set in stac92xx_build_pcms */
3592 .open = stac92xx_dig_playback_pcm_open,
3593 .close = stac92xx_dig_playback_pcm_close,
3594 .prepare = stac92xx_dig_playback_pcm_prepare,
3595 .cleanup = stac92xx_dig_playback_pcm_cleanup
3599 static const struct hda_pcm_stream stac92xx_pcm_digital_capture = {
3603 /* NID is set in stac92xx_build_pcms */
3606 static const struct hda_pcm_stream stac92xx_pcm_analog_playback = {
3610 .nid = 0x02, /* NID to query formats and rates */
3612 .open = stac92xx_playback_pcm_open,
3613 .prepare = stac92xx_playback_pcm_prepare,
3614 .cleanup = stac92xx_playback_pcm_cleanup
3618 static const struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
3622 .nid = 0x06, /* NID to query formats and rates */
3624 .open = stac92xx_playback_pcm_open,
3625 .prepare = stac92xx_playback_pcm_prepare,
3626 .cleanup = stac92xx_playback_pcm_cleanup
3630 static const struct hda_pcm_stream stac92xx_pcm_analog_capture = {
3633 /* NID + .substreams is set in stac92xx_build_pcms */
3635 .prepare = stac92xx_capture_pcm_prepare,
3636 .cleanup = stac92xx_capture_pcm_cleanup
3640 static int stac92xx_build_pcms(struct hda_codec *codec)
3642 struct sigmatel_spec *spec = codec->spec;
3643 struct hda_pcm *info = spec->pcm_rec;
3645 codec->num_pcms = 1;
3646 codec->pcm_info = info;
3648 info->name = "STAC92xx Analog";
3649 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
3650 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3651 spec->multiout.dac_nids[0];
3652 if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
3653 spec->autocfg.line_outs == 2)
3654 info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap =
3657 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
3658 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3659 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs;
3661 if (spec->alt_switch) {
3664 info->name = "STAC92xx Analog Alt";
3665 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback;
3668 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3671 info->name = "STAC92xx Digital";
3672 info->pcm_type = spec->autocfg.dig_out_type[0];
3673 if (spec->multiout.dig_out_nid) {
3674 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
3675 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3677 if (spec->dig_in_nid) {
3678 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture;
3679 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3686 static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
3689 snd_hda_set_pin_ctl_cache(codec, nid, pin_type);
3692 #define stac92xx_hp_switch_info snd_ctl_boolean_mono_info
3694 static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol,
3695 struct snd_ctl_elem_value *ucontrol)
3697 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3698 struct sigmatel_spec *spec = codec->spec;
3700 ucontrol->value.integer.value[0] = !!spec->hp_switch;
3704 static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid);
3706 static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
3707 struct snd_ctl_elem_value *ucontrol)
3709 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3710 struct sigmatel_spec *spec = codec->spec;
3711 int nid = kcontrol->private_value;
3713 spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0;
3715 /* check to be sure that the ports are up to date with
3718 stac_issue_unsol_event(codec, nid);
3723 static int stac92xx_dc_bias_info(struct snd_kcontrol *kcontrol,
3724 struct snd_ctl_elem_info *uinfo)
3727 static const char * const texts[] = {
3728 "Mic In", "Line In", "Line Out"
3731 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3732 struct sigmatel_spec *spec = codec->spec;
3733 hda_nid_t nid = kcontrol->private_value;
3735 if (nid == spec->mic_switch || nid == spec->line_switch)
3740 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3741 uinfo->value.enumerated.items = i;
3743 if (uinfo->value.enumerated.item >= i)
3744 uinfo->value.enumerated.item = i-1;
3745 strcpy(uinfo->value.enumerated.name,
3746 texts[uinfo->value.enumerated.item]);
3751 static int stac92xx_dc_bias_get(struct snd_kcontrol *kcontrol,
3752 struct snd_ctl_elem_value *ucontrol)
3754 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3755 hda_nid_t nid = kcontrol->private_value;
3756 unsigned int vref = stac92xx_vref_get(codec, nid);
3758 if (vref == snd_hda_get_default_vref(codec, nid))
3759 ucontrol->value.enumerated.item[0] = 0;
3760 else if (vref == AC_PINCTL_VREF_GRD)
3761 ucontrol->value.enumerated.item[0] = 1;
3762 else if (vref == AC_PINCTL_VREF_HIZ)
3763 ucontrol->value.enumerated.item[0] = 2;
3768 static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol,
3769 struct snd_ctl_elem_value *ucontrol)
3771 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3772 unsigned int new_vref = 0;
3774 hda_nid_t nid = kcontrol->private_value;
3776 if (ucontrol->value.enumerated.item[0] == 0)
3777 new_vref = snd_hda_get_default_vref(codec, nid);
3778 else if (ucontrol->value.enumerated.item[0] == 1)
3779 new_vref = AC_PINCTL_VREF_GRD;
3780 else if (ucontrol->value.enumerated.item[0] == 2)
3781 new_vref = AC_PINCTL_VREF_HIZ;
3785 if (new_vref != stac92xx_vref_get(codec, nid)) {
3786 error = stac92xx_vref_set(codec, nid, new_vref);
3793 static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol,
3794 struct snd_ctl_elem_info *uinfo)
3797 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3798 struct sigmatel_spec *spec = codec->spec;
3800 if (kcontrol->private_value == spec->line_switch)
3801 texts[0] = "Line In";
3803 texts[0] = "Mic In";
3804 texts[1] = "Line Out";
3805 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3806 uinfo->value.enumerated.items = 2;
3809 if (uinfo->value.enumerated.item >= 2)
3810 uinfo->value.enumerated.item = 1;
3811 strcpy(uinfo->value.enumerated.name,
3812 texts[uinfo->value.enumerated.item]);
3817 static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3819 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3820 struct sigmatel_spec *spec = codec->spec;
3821 hda_nid_t nid = kcontrol->private_value;
3822 int io_idx = (nid == spec->mic_switch) ? 1 : 0;
3824 ucontrol->value.enumerated.item[0] = spec->io_switch[io_idx];
3828 static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3830 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3831 struct sigmatel_spec *spec = codec->spec;
3832 hda_nid_t nid = kcontrol->private_value;
3833 int io_idx = (nid == spec->mic_switch) ? 1 : 0;
3834 unsigned short val = !!ucontrol->value.enumerated.item[0];
3836 spec->io_switch[io_idx] = val;
3839 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
3841 unsigned int pinctl = AC_PINCTL_IN_EN;
3842 if (io_idx) /* set VREF for mic */
3843 pinctl |= snd_hda_get_default_vref(codec, nid);
3844 stac92xx_auto_set_pinctl(codec, nid, pinctl);
3847 /* check the auto-mute again: we need to mute/unmute the speaker
3848 * appropriately according to the pin direction
3850 if (spec->hp_detect)
3851 stac_issue_unsol_event(codec, nid);
3856 #define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info
3858 static int stac92xx_clfe_switch_get(struct snd_kcontrol *kcontrol,
3859 struct snd_ctl_elem_value *ucontrol)
3861 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3862 struct sigmatel_spec *spec = codec->spec;
3864 ucontrol->value.integer.value[0] = spec->clfe_swap;
3868 static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
3869 struct snd_ctl_elem_value *ucontrol)
3871 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3872 struct sigmatel_spec *spec = codec->spec;
3873 hda_nid_t nid = kcontrol->private_value & 0xff;
3874 unsigned int val = !!ucontrol->value.integer.value[0];
3876 if (spec->clfe_swap == val)
3879 spec->clfe_swap = val;
3881 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
3882 spec->clfe_swap ? 0x4 : 0x0);
3887 #define STAC_CODEC_HP_SWITCH(xname) \
3888 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3891 .info = stac92xx_hp_switch_info, \
3892 .get = stac92xx_hp_switch_get, \
3893 .put = stac92xx_hp_switch_put, \
3896 #define STAC_CODEC_IO_SWITCH(xname, xpval) \
3897 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3900 .info = stac92xx_io_switch_info, \
3901 .get = stac92xx_io_switch_get, \
3902 .put = stac92xx_io_switch_put, \
3903 .private_value = xpval, \
3906 #define STAC_CODEC_CLFE_SWITCH(xname, xpval) \
3907 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3910 .info = stac92xx_clfe_switch_info, \
3911 .get = stac92xx_clfe_switch_get, \
3912 .put = stac92xx_clfe_switch_put, \
3913 .private_value = xpval, \
3917 STAC_CTL_WIDGET_VOL,
3918 STAC_CTL_WIDGET_MUTE,
3919 STAC_CTL_WIDGET_MUTE_BEEP,
3920 STAC_CTL_WIDGET_MONO_MUX,
3921 STAC_CTL_WIDGET_HP_SWITCH,
3922 STAC_CTL_WIDGET_IO_SWITCH,
3923 STAC_CTL_WIDGET_CLFE_SWITCH,
3924 STAC_CTL_WIDGET_DC_BIAS
3927 static const struct snd_kcontrol_new stac92xx_control_templates[] = {
3928 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3929 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3930 HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0),
3932 STAC_CODEC_HP_SWITCH(NULL),
3933 STAC_CODEC_IO_SWITCH(NULL, 0),
3934 STAC_CODEC_CLFE_SWITCH(NULL, 0),
3935 DC_BIAS(NULL, 0, 0),
3938 /* add dynamic controls */
3939 static struct snd_kcontrol_new *
3940 stac_control_new(struct sigmatel_spec *spec,
3941 const struct snd_kcontrol_new *ktemp,
3943 unsigned int subdev)
3945 struct snd_kcontrol_new *knew;
3947 knew = snd_array_new(&spec->kctls);
3951 knew->name = kstrdup(name, GFP_KERNEL);
3954 memset(knew, 0, sizeof(*knew));
3955 spec->kctls.alloced--;
3958 knew->subdevice = subdev;
3962 static struct snd_kcontrol_new *
3963 add_control_temp(struct sigmatel_spec *spec,
3964 const struct snd_kcontrol_new *ktemp,
3965 int idx, const char *name,
3968 struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name,
3969 HDA_SUBDEV_AMP_FLAG);
3973 knew->private_value = val;
3977 static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
3978 const struct snd_kcontrol_new *ktemp,
3979 int idx, const char *name,
3982 return add_control_temp(spec, ktemp, idx, name, val) ? 0 : -ENOMEM;
3985 static inline int stac92xx_add_control_idx(struct sigmatel_spec *spec,
3986 int type, int idx, const char *name,
3989 return stac92xx_add_control_temp(spec,
3990 &stac92xx_control_templates[type],
3995 /* add dynamic controls */
3996 static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type,
3997 const char *name, unsigned long val)
3999 return stac92xx_add_control_idx(spec, type, 0, name, val);
4002 static const struct snd_kcontrol_new stac_input_src_temp = {
4003 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4004 .name = "Input Source",
4005 .info = stac92xx_mux_enum_info,
4006 .get = stac92xx_mux_enum_get,
4007 .put = stac92xx_mux_enum_put,
4010 static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec,
4011 hda_nid_t nid, int idx)
4013 int def_conf = snd_hda_codec_get_pincfg(codec, nid);
4015 struct sigmatel_spec *spec = codec->spec;
4018 if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
4019 if (spec->headset_jack && snd_hda_get_input_pin_attr(def_conf)
4020 != INPUT_PIN_ATTR_DOCK)
4022 if (snd_hda_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
4023 && nid == spec->line_switch)
4024 control = STAC_CTL_WIDGET_IO_SWITCH;
4025 else if (snd_hda_query_pin_caps(codec, nid)
4026 & (AC_PINCAP_VREF_GRD << AC_PINCAP_VREF_SHIFT))
4027 control = STAC_CTL_WIDGET_DC_BIAS;
4028 else if (nid == spec->mic_switch)
4029 control = STAC_CTL_WIDGET_IO_SWITCH;
4033 snd_hda_get_pin_label(codec, nid, &spec->autocfg,
4034 name, sizeof(name), NULL);
4035 return stac92xx_add_control(codec->spec, control,
4036 strcat(name, " Jack Mode"), nid);
4042 static int stac92xx_add_input_source(struct sigmatel_spec *spec)
4044 struct snd_kcontrol_new *knew;
4045 struct hda_input_mux *imux = &spec->private_imux;
4048 return 0; /* no need for input source */
4049 if (!spec->num_adcs || imux->num_items <= 1)
4050 return 0; /* no need for input source control */
4051 knew = stac_control_new(spec, &stac_input_src_temp,
4052 stac_input_src_temp.name, 0);
4055 knew->count = spec->num_adcs;
4059 /* check whether the line-input can be used as line-out */
4060 static hda_nid_t check_line_out_switch(struct hda_codec *codec)
4062 struct sigmatel_spec *spec = codec->spec;
4063 struct auto_pin_cfg *cfg = &spec->autocfg;
4065 unsigned int pincap;
4068 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
4070 for (i = 0; i < cfg->num_inputs; i++) {
4071 if (cfg->inputs[i].type == AUTO_PIN_LINE_IN) {
4072 nid = cfg->inputs[i].pin;
4073 pincap = snd_hda_query_pin_caps(codec, nid);
4074 if (pincap & AC_PINCAP_OUT)
4081 static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid);
4083 /* check whether the mic-input can be used as line-out */
4084 static hda_nid_t check_mic_out_switch(struct hda_codec *codec, hda_nid_t *dac)
4086 struct sigmatel_spec *spec = codec->spec;
4087 struct auto_pin_cfg *cfg = &spec->autocfg;
4088 unsigned int def_conf, pincap;
4092 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
4094 for (i = 0; i < cfg->num_inputs; i++) {
4095 hda_nid_t nid = cfg->inputs[i].pin;
4096 if (cfg->inputs[i].type != AUTO_PIN_MIC)
4098 def_conf = snd_hda_codec_get_pincfg(codec, nid);
4099 /* some laptops have an internal analog microphone
4100 * which can't be used as a output */
4101 if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
4102 pincap = snd_hda_query_pin_caps(codec, nid);
4103 if (pincap & AC_PINCAP_OUT) {
4104 *dac = get_unassigned_dac(codec, nid);
4113 static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
4117 for (i = 0; i < spec->multiout.num_dacs; i++) {
4118 if (spec->multiout.dac_nids[i] == nid)
4125 static int check_all_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
4128 if (is_in_dac_nids(spec, nid))
4130 for (i = 0; i < spec->autocfg.hp_outs; i++)
4131 if (spec->hp_dacs[i] == nid)
4133 for (i = 0; i < spec->autocfg.speaker_outs; i++)
4134 if (spec->speaker_dacs[i] == nid)
4139 static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
4141 struct sigmatel_spec *spec = codec->spec;
4142 struct auto_pin_cfg *cfg = &spec->autocfg;
4144 hda_nid_t conn[HDA_MAX_CONNECTIONS], fallback_dac;
4145 unsigned int wcaps, wtype;
4147 conn_len = snd_hda_get_connections(codec, nid, conn,
4148 HDA_MAX_CONNECTIONS);
4149 /* 92HD88: trace back up the link of nids to find the DAC */
4150 while (conn_len == 1 && (get_wcaps_type(get_wcaps(codec, conn[0]))
4151 != AC_WID_AUD_OUT)) {
4153 conn_len = snd_hda_get_connections(codec, nid, conn,
4154 HDA_MAX_CONNECTIONS);
4156 for (j = 0; j < conn_len; j++) {
4157 wcaps = get_wcaps(codec, conn[j]);
4158 wtype = get_wcaps_type(wcaps);
4159 /* we check only analog outputs */
4160 if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL))
4162 /* if this route has a free DAC, assign it */
4163 if (!check_all_dac_nids(spec, conn[j])) {
4165 /* select this DAC in the pin's input mux */
4166 snd_hda_codec_write_cache(codec, nid, 0,
4167 AC_VERB_SET_CONNECT_SEL, j);
4173 /* if all DACs are already assigned, connect to the primary DAC,
4174 unless we're assigning a secondary headphone */
4175 fallback_dac = spec->multiout.dac_nids[0];
4176 if (spec->multiout.hp_nid) {
4177 for (j = 0; j < cfg->hp_outs; j++)
4178 if (cfg->hp_pins[j] == nid) {
4179 fallback_dac = spec->multiout.hp_nid;
4185 for (j = 0; j < conn_len; j++) {
4186 if (conn[j] == fallback_dac) {
4187 snd_hda_codec_write_cache(codec, nid, 0,
4188 AC_VERB_SET_CONNECT_SEL, j);
4196 static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
4197 static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
4200 * Fill in the dac_nids table from the parsed pin configuration
4201 * This function only works when every pin in line_out_pins[]
4202 * contains atleast one DAC in its connection list. Some 92xx
4203 * codecs are not connected directly to a DAC, such as the 9200
4204 * and 9202/925x. For those, dac_nids[] must be hard-coded.
4206 static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec)
4208 struct sigmatel_spec *spec = codec->spec;
4209 struct auto_pin_cfg *cfg = &spec->autocfg;
4213 for (i = 0; i < cfg->line_outs; i++) {
4214 nid = cfg->line_out_pins[i];
4215 dac = get_unassigned_dac(codec, nid);
4217 if (spec->multiout.num_dacs > 0) {
4218 /* we have already working output pins,
4219 * so let's drop the broken ones again
4221 cfg->line_outs = spec->multiout.num_dacs;
4224 /* error out, no available DAC found */
4226 "%s: No available DAC for pin 0x%x\n",
4230 add_spec_dacs(spec, dac);
4233 for (i = 0; i < cfg->hp_outs; i++) {
4234 nid = cfg->hp_pins[i];
4235 dac = get_unassigned_dac(codec, nid);
4237 if (!spec->multiout.hp_nid)
4238 spec->multiout.hp_nid = dac;
4240 add_spec_extra_dacs(spec, dac);
4242 spec->hp_dacs[i] = dac;
4245 for (i = 0; i < cfg->speaker_outs; i++) {
4246 nid = cfg->speaker_pins[i];
4247 dac = get_unassigned_dac(codec, nid);
4249 add_spec_extra_dacs(spec, dac);
4250 spec->speaker_dacs[i] = dac;
4253 /* add line-in as output */
4254 nid = check_line_out_switch(codec);
4256 dac = get_unassigned_dac(codec, nid);
4258 snd_printdd("STAC: Add line-in 0x%x as output %d\n",
4259 nid, cfg->line_outs);
4260 cfg->line_out_pins[cfg->line_outs] = nid;
4262 spec->line_switch = nid;
4263 add_spec_dacs(spec, dac);
4266 /* add mic as output */
4267 nid = check_mic_out_switch(codec, &dac);
4269 snd_printdd("STAC: Add mic-in 0x%x as output %d\n",
4270 nid, cfg->line_outs);
4271 cfg->line_out_pins[cfg->line_outs] = nid;
4273 spec->mic_switch = nid;
4274 add_spec_dacs(spec, dac);
4277 snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
4278 spec->multiout.num_dacs,
4279 spec->multiout.dac_nids[0],
4280 spec->multiout.dac_nids[1],
4281 spec->multiout.dac_nids[2],
4282 spec->multiout.dac_nids[3],
4283 spec->multiout.dac_nids[4]);
4288 /* create volume control/switch for the given prefx type */
4289 static int create_controls_idx(struct hda_codec *codec, const char *pfx,
4290 int idx, hda_nid_t nid, int chs)
4292 struct sigmatel_spec *spec = codec->spec;
4296 if (!spec->check_volume_offset) {
4297 unsigned int caps, step, nums, db_scale;
4298 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
4299 step = (caps & AC_AMPCAP_STEP_SIZE) >>
4300 AC_AMPCAP_STEP_SIZE_SHIFT;
4301 step = (step + 1) * 25; /* in .01dB unit */
4302 nums = (caps & AC_AMPCAP_NUM_STEPS) >>
4303 AC_AMPCAP_NUM_STEPS_SHIFT;
4304 db_scale = nums * step;
4305 /* if dB scale is over -64dB, and finer enough,
4306 * let's reduce it to half
4308 if (db_scale > 6400 && nums >= 0x1f)
4309 spec->volume_offset = nums / 2;
4310 spec->check_volume_offset = 1;
4313 sprintf(name, "%s Playback Volume", pfx);
4314 err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_VOL, idx, name,
4315 HDA_COMPOSE_AMP_VAL_OFS(nid, chs, 0, HDA_OUTPUT,
4316 spec->volume_offset));
4319 sprintf(name, "%s Playback Switch", pfx);
4320 err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_MUTE, idx, name,
4321 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
4327 #define create_controls(codec, pfx, nid, chs) \
4328 create_controls_idx(codec, pfx, 0, nid, chs)
4330 static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
4332 if (spec->multiout.num_dacs > 4) {
4333 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
4336 snd_BUG_ON(spec->multiout.dac_nids != spec->dac_nids);
4337 spec->dac_nids[spec->multiout.num_dacs] = nid;
4338 spec->multiout.num_dacs++;
4343 static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
4346 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) {
4347 if (!spec->multiout.extra_out_nid[i]) {
4348 spec->multiout.extra_out_nid[i] = nid;
4352 printk(KERN_WARNING "stac92xx: No space for extra DAC 0x%x\n", nid);
4356 /* Create output controls
4357 * The mixer elements are named depending on the given type (AUTO_PIN_XXX_OUT)
4359 static int create_multi_out_ctls(struct hda_codec *codec, int num_outs,
4360 const hda_nid_t *pins,
4361 const hda_nid_t *dac_nids,
4364 struct sigmatel_spec *spec = codec->spec;
4365 static const char * const chname[4] = {
4366 "Front", "Surround", NULL /*CLFE*/, "Side"
4370 unsigned int wid_caps;
4372 for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) {
4373 if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) {
4374 if (is_jack_detectable(codec, pins[i]))
4375 spec->hp_detect = 1;
4380 if (type != AUTO_PIN_HP_OUT && i == 2) {
4382 err = create_controls(codec, "Center", nid, 1);
4385 err = create_controls(codec, "LFE", nid, 2);
4389 wid_caps = get_wcaps(codec, nid);
4391 if (wid_caps & AC_WCAP_LR_SWAP) {
4392 err = stac92xx_add_control(spec,
4393 STAC_CTL_WIDGET_CLFE_SWITCH,
4394 "Swap Center/LFE Playback Switch", nid);
4404 case AUTO_PIN_HP_OUT:
4408 case AUTO_PIN_SPEAKER_OUT:
4409 if (num_outs <= 2) {
4410 name = i ? "Bass Speaker" : "Speaker";
4414 /* Fall through in case of multi speaker outs */
4420 err = create_controls_idx(codec, name, idx, nid, 3);
4428 static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
4429 unsigned int dir_mask, unsigned int data);
4431 /* hook for controlling mic-mute LED GPIO */
4432 static int stac92xx_capture_sw_put_led(struct snd_kcontrol *kcontrol,
4433 struct snd_ctl_elem_value *ucontrol)
4435 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4436 struct sigmatel_spec *spec = codec->spec;
4440 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
4443 mute = !(ucontrol->value.integer.value[0] &&
4444 ucontrol->value.integer.value[1]);
4445 if (spec->mic_mute_led_on != mute) {
4446 spec->mic_mute_led_on = mute;
4448 spec->gpio_data |= spec->mic_mute_led_gpio;
4450 spec->gpio_data &= ~spec->mic_mute_led_gpio;
4451 stac_gpio_set(codec, spec->gpio_mask,
4452 spec->gpio_dir, spec->gpio_data);
4457 static int stac92xx_add_capvol_ctls(struct hda_codec *codec, unsigned long vol,
4458 unsigned long sw, int idx)
4460 struct sigmatel_spec *spec = codec->spec;
4461 struct snd_kcontrol_new *knew;
4464 err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx,
4465 "Capture Volume", vol);
4469 knew = add_control_temp(spec,
4470 &stac92xx_control_templates[STAC_CTL_WIDGET_MUTE],
4471 idx, "Capture Switch", sw);
4474 /* add a LED hook for some HP laptops */
4475 if (spec->mic_mute_led_gpio)
4476 knew->put = stac92xx_capture_sw_put_led;
4481 /* add playback controls from the parsed DAC table */
4482 static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
4483 const struct auto_pin_cfg *cfg)
4485 struct sigmatel_spec *spec = codec->spec;
4490 err = create_multi_out_ctls(codec, cfg->line_outs, cfg->line_out_pins,
4491 spec->multiout.dac_nids,
4492 cfg->line_out_type);
4496 if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) {
4497 err = stac92xx_add_control(spec,
4498 STAC_CTL_WIDGET_HP_SWITCH,
4499 "Headphone as Line Out Switch",
4500 cfg->hp_pins[cfg->hp_outs - 1]);
4505 for (idx = 0; idx < cfg->num_inputs; idx++) {
4506 if (cfg->inputs[idx].type > AUTO_PIN_LINE_IN)
4508 nid = cfg->inputs[idx].pin;
4509 err = stac92xx_add_jack_mode_control(codec, nid, idx);
4517 /* add playback controls for Speaker and HP outputs */
4518 static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
4519 struct auto_pin_cfg *cfg)
4521 struct sigmatel_spec *spec = codec->spec;
4524 err = create_multi_out_ctls(codec, cfg->hp_outs, cfg->hp_pins,
4525 spec->hp_dacs, AUTO_PIN_HP_OUT);
4529 err = create_multi_out_ctls(codec, cfg->speaker_outs, cfg->speaker_pins,
4530 spec->speaker_dacs, AUTO_PIN_SPEAKER_OUT);
4537 /* labels for mono mux outputs */
4538 static const char * const stac92xx_mono_labels[4] = {
4539 "DAC0", "DAC1", "Mixer", "DAC2"
4542 /* create mono mux for mono out on capable codecs */
4543 static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec)
4545 struct sigmatel_spec *spec = codec->spec;
4546 struct hda_input_mux *mono_mux = &spec->private_mono_mux;
4548 hda_nid_t con_lst[ARRAY_SIZE(stac92xx_mono_labels)];
4550 num_cons = snd_hda_get_connections(codec,
4553 HDA_MAX_NUM_INPUTS);
4554 if (num_cons <= 0 || num_cons > ARRAY_SIZE(stac92xx_mono_labels))
4557 for (i = 0; i < num_cons; i++)
4558 snd_hda_add_imux_item(mono_mux, stac92xx_mono_labels[i], i,
4561 return stac92xx_add_control(spec, STAC_CTL_WIDGET_MONO_MUX,
4562 "Mono Mux", spec->mono_nid);
4565 /* create PC beep volume controls */
4566 static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec,
4569 struct sigmatel_spec *spec = codec->spec;
4570 u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
4571 int err, type = STAC_CTL_WIDGET_MUTE_BEEP;
4573 if (spec->anabeep_nid == nid)
4574 type = STAC_CTL_WIDGET_MUTE;
4576 /* check for mute support for the the amp */
4577 if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) {
4578 err = stac92xx_add_control(spec, type,
4579 "Beep Playback Switch",
4580 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT));
4585 /* check to see if there is volume support for the amp */
4586 if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
4587 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL,
4588 "Beep Playback Volume",
4589 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT));
4596 #ifdef CONFIG_SND_HDA_INPUT_BEEP
4597 #define stac92xx_dig_beep_switch_info snd_ctl_boolean_mono_info
4599 static int stac92xx_dig_beep_switch_get(struct snd_kcontrol *kcontrol,
4600 struct snd_ctl_elem_value *ucontrol)
4602 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4603 ucontrol->value.integer.value[0] = codec->beep->enabled;
4607 static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol,
4608 struct snd_ctl_elem_value *ucontrol)
4610 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4611 return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]);
4614 static const struct snd_kcontrol_new stac92xx_dig_beep_ctrl = {
4615 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4616 .info = stac92xx_dig_beep_switch_info,
4617 .get = stac92xx_dig_beep_switch_get,
4618 .put = stac92xx_dig_beep_switch_put,
4621 static int stac92xx_beep_switch_ctl(struct hda_codec *codec)
4623 return stac92xx_add_control_temp(codec->spec, &stac92xx_dig_beep_ctrl,
4624 0, "Beep Playback Switch", 0);
4628 static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec)
4630 struct sigmatel_spec *spec = codec->spec;
4633 for (i = 0; i < spec->num_muxes; i++) {
4638 nid = spec->mux_nids[i];
4639 wcaps = get_wcaps(codec, nid);
4640 if (!(wcaps & AC_WCAP_OUT_AMP))
4643 /* check whether already the same control was created as
4644 * normal Capture Volume.
4646 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4647 for (j = 0; j < spec->num_caps; j++) {
4648 if (spec->capvols[j] == val)
4651 if (j < spec->num_caps)
4654 err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_VOL, i,
4655 "Mux Capture Volume", val);
4662 static const char * const stac92xx_spdif_labels[3] = {
4663 "Digital Playback", "Analog Mux 1", "Analog Mux 2",
4666 static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec)
4668 struct sigmatel_spec *spec = codec->spec;
4669 struct hda_input_mux *spdif_mux = &spec->private_smux;
4670 const char * const *labels = spec->spdif_labels;
4672 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
4674 num_cons = snd_hda_get_connections(codec,
4677 HDA_MAX_NUM_INPUTS);
4682 labels = stac92xx_spdif_labels;
4684 for (i = 0; i < num_cons; i++)
4685 snd_hda_add_imux_item(spdif_mux, labels[i], i, NULL);
4690 /* labels for dmic mux inputs */
4691 static const char * const stac92xx_dmic_labels[5] = {
4692 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
4693 "Digital Mic 3", "Digital Mic 4"
4696 static hda_nid_t get_connected_node(struct hda_codec *codec, hda_nid_t mux,
4699 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
4701 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
4702 if (idx >= 0 && idx < nums)
4707 /* look for NID recursively */
4708 #define get_connection_index(codec, mux, nid) \
4709 snd_hda_get_conn_index(codec, mux, nid, 1)
4711 /* create a volume assigned to the given pin (only if supported) */
4712 /* return 1 if the volume control is created */
4713 static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid,
4714 const char *label, int idx, int direction)
4716 unsigned int caps, nums;
4720 if (direction == HDA_OUTPUT)
4721 caps = AC_WCAP_OUT_AMP;
4723 caps = AC_WCAP_IN_AMP;
4724 if (!(get_wcaps(codec, nid) & caps))
4726 caps = query_amp_caps(codec, nid, direction);
4727 nums = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
4730 snprintf(name, sizeof(name), "%s Capture Volume", label);
4731 err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx, name,
4732 HDA_COMPOSE_AMP_VAL(nid, 3, 0, direction));
4738 /* create playback/capture controls for input pins on dmic capable codecs */
4739 static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
4740 const struct auto_pin_cfg *cfg)
4742 struct sigmatel_spec *spec = codec->spec;
4743 struct hda_input_mux *imux = &spec->private_imux;
4744 struct hda_input_mux *dimux = &spec->private_dimux;
4746 unsigned int def_conf;
4748 snd_hda_add_imux_item(dimux, stac92xx_dmic_labels[0], 0, NULL);
4750 for (i = 0; i < spec->num_dmics; i++) {
4752 int index, type_idx;
4755 nid = spec->dmic_nids[i];
4756 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
4758 def_conf = snd_hda_codec_get_pincfg(codec, nid);
4759 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
4762 index = get_connection_index(codec, spec->dmux_nids[0], nid);
4766 snd_hda_get_pin_label(codec, nid, &spec->autocfg,
4767 label, sizeof(label), NULL);
4768 snd_hda_add_imux_item(dimux, label, index, &type_idx);
4769 if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
4770 snd_hda_add_imux_item(imux, label, index, &type_idx);
4772 err = create_elem_capture_vol(codec, nid, label, type_idx,
4777 err = create_elem_capture_vol(codec, nid, label,
4778 type_idx, HDA_OUTPUT);
4782 nid = get_connected_node(codec,
4783 spec->dmux_nids[0], index);
4785 err = create_elem_capture_vol(codec,
4787 type_idx, HDA_INPUT);
4797 static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid,
4798 hda_nid_t *fixed, hda_nid_t *ext, hda_nid_t *dock)
4805 cfg = snd_hda_codec_get_pincfg(codec, nid);
4806 type = get_defcfg_device(cfg);
4807 switch (snd_hda_get_input_pin_attr(cfg)) {
4808 case INPUT_PIN_ATTR_INT:
4810 return 1; /* already occupied */
4811 if (type != AC_JACK_MIC_IN)
4812 return 1; /* invalid type */
4815 case INPUT_PIN_ATTR_UNUSED:
4817 case INPUT_PIN_ATTR_DOCK:
4819 return 1; /* already occupied */
4820 if (type != AC_JACK_MIC_IN && type != AC_JACK_LINE_IN)
4821 return 1; /* invalid type */
4826 return 1; /* already occupied */
4827 if (type != AC_JACK_MIC_IN)
4828 return 1; /* invalid type */
4835 static int set_mic_route(struct hda_codec *codec,
4836 struct sigmatel_mic_route *mic,
4839 struct sigmatel_spec *spec = codec->spec;
4840 struct auto_pin_cfg *cfg = &spec->autocfg;
4846 for (i = 0; i < cfg->num_inputs; i++) {
4847 if (pin == cfg->inputs[i].pin)
4850 if (i < cfg->num_inputs && cfg->inputs[i].type == AUTO_PIN_MIC) {
4852 i = get_connection_index(codec, spec->mux_nids[0], pin);
4857 if (spec->dmux_nids)
4858 mic->dmux_idx = get_connection_index(codec,
4861 } else if (spec->dmux_nids) {
4863 i = get_connection_index(codec, spec->dmux_nids[0], pin);
4869 mic->mux_idx = get_connection_index(codec,
4871 spec->dmux_nids[0]);
4876 /* return non-zero if the device is for automatic mic switch */
4877 static int stac_check_auto_mic(struct hda_codec *codec)
4879 struct sigmatel_spec *spec = codec->spec;
4880 struct auto_pin_cfg *cfg = &spec->autocfg;
4881 hda_nid_t fixed, ext, dock;
4884 fixed = ext = dock = 0;
4885 for (i = 0; i < cfg->num_inputs; i++)
4886 if (check_mic_pin(codec, cfg->inputs[i].pin,
4887 &fixed, &ext, &dock))
4889 for (i = 0; i < spec->num_dmics; i++)
4890 if (check_mic_pin(codec, spec->dmic_nids[i],
4891 &fixed, &ext, &dock))
4893 if (!fixed || (!ext && !dock))
4894 return 0; /* no input to switch */
4895 if (!is_jack_detectable(codec, ext))
4896 return 0; /* no unsol support */
4897 if (set_mic_route(codec, &spec->ext_mic, ext) ||
4898 set_mic_route(codec, &spec->int_mic, fixed) ||
4899 set_mic_route(codec, &spec->dock_mic, dock))
4900 return 0; /* something is wrong */
4904 /* create playback/capture controls for input pins */
4905 static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
4907 struct sigmatel_spec *spec = codec->spec;
4908 struct hda_input_mux *imux = &spec->private_imux;
4912 for (i = 0; i < cfg->num_inputs; i++) {
4913 hda_nid_t nid = cfg->inputs[i].pin;
4914 int index, err, type_idx;
4917 for (j = 0; j < spec->num_muxes; j++) {
4918 index = get_connection_index(codec, spec->mux_nids[j],
4926 label = hda_get_autocfg_input_label(codec, cfg, i);
4927 snd_hda_add_imux_item(imux, label, index, &type_idx);
4929 err = create_elem_capture_vol(codec, nid,
4935 spec->num_analog_muxes = imux->num_items;
4937 if (imux->num_items) {
4939 * Set the current input for the muxes.
4940 * The STAC9221 has two input muxes with identical source
4941 * NID lists. Hopefully this won't get confused.
4943 for (i = 0; i < spec->num_muxes; i++) {
4944 snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0,
4945 AC_VERB_SET_CONNECT_SEL,
4946 imux->items[0].index);
4953 static void stac92xx_auto_init_multi_out(struct hda_codec *codec)
4955 struct sigmatel_spec *spec = codec->spec;
4958 for (i = 0; i < spec->autocfg.line_outs; i++) {
4959 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4960 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
4964 static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
4966 struct sigmatel_spec *spec = codec->spec;
4969 for (i = 0; i < spec->autocfg.hp_outs; i++) {
4971 pin = spec->autocfg.hp_pins[i];
4972 if (pin) /* connect to front */
4973 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
4975 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
4977 pin = spec->autocfg.speaker_pins[i];
4978 if (pin) /* connect to front */
4979 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN);
4983 static int is_dual_headphones(struct hda_codec *codec)
4985 struct sigmatel_spec *spec = codec->spec;
4988 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT ||
4989 spec->autocfg.hp_outs <= 1)
4992 for (i = 0; i < spec->autocfg.hp_outs; i++) {
4993 hda_nid_t nid = spec->autocfg.hp_pins[i];
4994 unsigned int cfg = snd_hda_codec_get_pincfg(codec, nid);
4995 if (get_defcfg_location(cfg) & AC_JACK_LOC_SEPARATE)
4999 return (valid_hps > 1);
5003 static int stac92xx_parse_auto_config(struct hda_codec *codec)
5005 struct sigmatel_spec *spec = codec->spec;
5006 hda_nid_t dig_out = 0, dig_in = 0;
5010 if ((err = snd_hda_parse_pin_def_config(codec,
5012 spec->dmic_nids)) < 0)
5014 if (! spec->autocfg.line_outs)
5015 return 0; /* can't find valid pin config */
5017 /* If we have no real line-out pin and multiple hp-outs, HPs should
5018 * be set up as multi-channel outputs.
5020 if (is_dual_headphones(codec)) {
5021 /* Copy hp_outs to line_outs, backup line_outs in
5022 * speaker_outs so that the following routines can handle
5023 * HP pins as primary outputs.
5025 snd_printdd("stac92xx: Enabling multi-HPs workaround\n");
5026 memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins,
5027 sizeof(spec->autocfg.line_out_pins));
5028 spec->autocfg.speaker_outs = spec->autocfg.line_outs;
5029 memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins,
5030 sizeof(spec->autocfg.hp_pins));
5031 spec->autocfg.line_outs = spec->autocfg.hp_outs;
5032 spec->autocfg.line_out_type = AUTO_PIN_HP_OUT;
5033 spec->autocfg.hp_outs = 0;
5036 if (spec->autocfg.mono_out_pin) {
5037 int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) &
5038 (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP);
5039 u32 caps = query_amp_caps(codec,
5040 spec->autocfg.mono_out_pin, dir);
5041 hda_nid_t conn_list[1];
5043 /* get the mixer node and then the mono mux if it exists */
5044 if (snd_hda_get_connections(codec,
5045 spec->autocfg.mono_out_pin, conn_list, 1) &&
5046 snd_hda_get_connections(codec, conn_list[0],
5047 conn_list, 1) > 0) {
5049 int wcaps = get_wcaps(codec, conn_list[0]);
5050 int wid_type = get_wcaps_type(wcaps);
5051 /* LR swap check, some stac925x have a mux that
5052 * changes the DACs output path instead of the
5055 if (wid_type == AC_WID_AUD_SEL &&
5056 !(wcaps & AC_WCAP_LR_SWAP))
5057 spec->mono_nid = conn_list[0];
5060 hda_nid_t nid = spec->autocfg.mono_out_pin;
5062 /* most mono outs have a least a mute/unmute switch */
5063 dir = (dir & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT;
5064 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE,
5065 "Mono Playback Switch",
5066 HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir));
5069 /* check for volume support for the amp */
5070 if ((caps & AC_AMPCAP_NUM_STEPS)
5071 >> AC_AMPCAP_NUM_STEPS_SHIFT) {
5072 err = stac92xx_add_control(spec,
5073 STAC_CTL_WIDGET_VOL,
5074 "Mono Playback Volume",
5075 HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir));
5081 stac92xx_auto_set_pinctl(codec, spec->autocfg.mono_out_pin,
5085 if (!spec->multiout.num_dacs) {
5086 err = stac92xx_auto_fill_dac_nids(codec);
5089 err = stac92xx_auto_create_multi_out_ctls(codec,
5095 /* setup analog beep controls */
5096 if (spec->anabeep_nid > 0) {
5097 err = stac92xx_auto_create_beep_ctls(codec,
5103 /* setup digital beep controls and input device */
5104 #ifdef CONFIG_SND_HDA_INPUT_BEEP
5105 if (spec->digbeep_nid > 0) {
5106 hda_nid_t nid = spec->digbeep_nid;
5109 err = stac92xx_auto_create_beep_ctls(codec, nid);
5112 err = snd_hda_attach_beep_device(codec, nid);
5116 /* IDT/STAC codecs have linear beep tone parameter */
5117 codec->beep->linear_tone = spec->linear_tone_beep;
5118 /* if no beep switch is available, make its own one */
5119 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
5120 if (!(caps & AC_AMPCAP_MUTE)) {
5121 err = stac92xx_beep_switch_ctl(codec);
5129 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
5133 /* All output parsing done, now restore the swapped hp pins */
5135 memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
5136 sizeof(spec->autocfg.hp_pins));
5137 spec->autocfg.hp_outs = spec->autocfg.line_outs;
5138 spec->autocfg.line_out_type = AUTO_PIN_HP_OUT;
5139 spec->autocfg.line_outs = 0;
5142 if (stac_check_auto_mic(codec)) {
5144 /* only one capture for auto-mic */
5147 spec->num_muxes = 1;
5150 for (i = 0; i < spec->num_caps; i++) {
5151 err = stac92xx_add_capvol_ctls(codec, spec->capvols[i],
5152 spec->capsws[i], i);
5157 err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
5161 if (spec->mono_nid > 0) {
5162 err = stac92xx_auto_create_mono_output_ctls(codec);
5166 if (spec->num_dmics > 0 && !spec->dinput_mux)
5167 if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
5168 &spec->autocfg)) < 0)
5170 if (spec->num_muxes > 0) {
5171 err = stac92xx_auto_create_mux_input_ctls(codec);
5175 if (spec->num_smuxes > 0) {
5176 err = stac92xx_auto_create_spdif_mux_ctls(codec);
5181 err = stac92xx_add_input_source(spec);
5185 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5186 if (spec->multiout.max_channels > 2)
5187 spec->surr_switch = 1;
5189 /* find digital out and in converters */
5190 for (i = codec->start_nid; i < codec->start_nid + codec->num_nodes; i++) {
5191 unsigned int wid_caps = get_wcaps(codec, i);
5192 if (wid_caps & AC_WCAP_DIGITAL) {
5193 switch (get_wcaps_type(wid_caps)) {
5194 case AC_WID_AUD_OUT:
5205 if (spec->autocfg.dig_outs)
5206 spec->multiout.dig_out_nid = dig_out;
5207 if (dig_in && spec->autocfg.dig_in_pin)
5208 spec->dig_in_nid = dig_in;
5210 if (spec->kctls.list)
5211 spec->mixers[spec->num_mixers++] = spec->kctls.list;
5213 spec->input_mux = &spec->private_imux;
5214 if (!spec->dinput_mux)
5215 spec->dinput_mux = &spec->private_dimux;
5216 spec->sinput_mux = &spec->private_smux;
5217 spec->mono_mux = &spec->private_mono_mux;
5221 /* add playback controls for HP output */
5222 static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
5223 struct auto_pin_cfg *cfg)
5225 struct sigmatel_spec *spec = codec->spec;
5226 hda_nid_t pin = cfg->hp_pins[0];
5231 if (is_jack_detectable(codec, pin))
5232 spec->hp_detect = 1;
5237 /* add playback controls for LFE output */
5238 static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec,
5239 struct auto_pin_cfg *cfg)
5241 struct sigmatel_spec *spec = codec->spec;
5243 hda_nid_t lfe_pin = 0x0;
5247 * search speaker outs and line outs for a mono speaker pin
5248 * with an amp. If one is found, add LFE controls
5251 for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) {
5252 hda_nid_t pin = spec->autocfg.speaker_pins[i];
5253 unsigned int wcaps = get_wcaps(codec, pin);
5254 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
5255 if (wcaps == AC_WCAP_OUT_AMP)
5256 /* found a mono speaker with an amp, must be lfe */
5260 /* if speaker_outs is 0, then speakers may be in line_outs */
5261 if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) {
5262 for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) {
5263 hda_nid_t pin = spec->autocfg.line_out_pins[i];
5264 unsigned int defcfg;
5265 defcfg = snd_hda_codec_get_pincfg(codec, pin);
5266 if (get_defcfg_device(defcfg) == AC_JACK_SPEAKER) {
5267 unsigned int wcaps = get_wcaps(codec, pin);
5268 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
5269 if (wcaps == AC_WCAP_OUT_AMP)
5270 /* found a mono speaker with an amp,
5278 err = create_controls(codec, "LFE", lfe_pin, 1);
5286 static int stac9200_parse_auto_config(struct hda_codec *codec)
5288 struct sigmatel_spec *spec = codec->spec;
5291 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
5294 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
5297 if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)
5300 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
5303 if (spec->num_muxes > 0) {
5304 err = stac92xx_auto_create_mux_input_ctls(codec);
5309 err = stac92xx_add_input_source(spec);
5313 if (spec->autocfg.dig_outs)
5314 spec->multiout.dig_out_nid = 0x05;
5315 if (spec->autocfg.dig_in_pin)
5316 spec->dig_in_nid = 0x04;
5318 if (spec->kctls.list)
5319 spec->mixers[spec->num_mixers++] = spec->kctls.list;
5321 spec->input_mux = &spec->private_imux;
5322 spec->dinput_mux = &spec->private_dimux;
5328 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
5329 * funky external mute control using GPIO pins.
5332 static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
5333 unsigned int dir_mask, unsigned int data)
5335 unsigned int gpiostate, gpiomask, gpiodir;
5337 snd_printdd("%s msk %x dir %x gpio %x\n", __func__, mask, dir_mask, data);
5339 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5340 AC_VERB_GET_GPIO_DATA, 0);
5341 gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask);
5343 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5344 AC_VERB_GET_GPIO_MASK, 0);
5347 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5348 AC_VERB_GET_GPIO_DIRECTION, 0);
5349 gpiodir |= dir_mask;
5351 /* Configure GPIOx as CMOS */
5352 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
5354 snd_hda_codec_write(codec, codec->afg, 0,
5355 AC_VERB_SET_GPIO_MASK, gpiomask);
5356 snd_hda_codec_read(codec, codec->afg, 0,
5357 AC_VERB_SET_GPIO_DIRECTION, gpiodir); /* sync */
5361 snd_hda_codec_read(codec, codec->afg, 0,
5362 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
5365 static int stac_add_event(struct hda_codec *codec, hda_nid_t nid,
5366 unsigned char type, int data)
5368 struct hda_jack_tbl *event;
5370 event = snd_hda_jack_tbl_new(codec, nid);
5373 event->action = type;
5374 event->private_data = data;
5379 static void handle_unsol_event(struct hda_codec *codec,
5380 struct hda_jack_tbl *event);
5382 /* check if given nid is a valid pin and no other events are assigned
5383 * to it. If OK, assign the event, set the unsol flag, and returns 1.
5384 * Otherwise, returns zero.
5386 static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
5389 struct hda_jack_tbl *event;
5391 if (!is_jack_detectable(codec, nid))
5393 event = snd_hda_jack_tbl_new(codec, nid);
5396 if (event->action && event->action != type)
5398 event->action = type;
5399 event->callback = handle_unsol_event;
5400 snd_hda_jack_detect_enable(codec, nid, 0);
5404 static int is_nid_out_jack_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
5407 for (i = 0; i < cfg->hp_outs; i++)
5408 if (cfg->hp_pins[i] == nid)
5409 return 1; /* nid is a HP-Out */
5410 for (i = 0; i < cfg->line_outs; i++)
5411 if (cfg->line_out_pins[i] == nid)
5412 return 1; /* nid is a line-Out */
5413 return 0; /* nid is not a HP-Out */
5416 static void stac92xx_power_down(struct hda_codec *codec)
5418 struct sigmatel_spec *spec = codec->spec;
5420 /* power down inactive DACs */
5421 const hda_nid_t *dac;
5422 for (dac = spec->dac_list; *dac; dac++)
5423 if (!check_all_dac_nids(spec, *dac))
5424 snd_hda_codec_write(codec, *dac, 0,
5425 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5428 static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
5431 static inline bool get_int_hint(struct hda_codec *codec, const char *key,
5434 return !snd_hda_get_int_hint(codec, key, valp);
5437 /* override some hints from the hwdep entry */
5438 static void stac_store_hints(struct hda_codec *codec)
5440 struct sigmatel_spec *spec = codec->spec;
5443 val = snd_hda_get_bool_hint(codec, "hp_detect");
5445 spec->hp_detect = val;
5446 if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) {
5447 spec->eapd_mask = spec->gpio_dir = spec->gpio_data =
5450 if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir))
5451 spec->gpio_mask &= spec->gpio_mask;
5452 if (get_int_hint(codec, "gpio_data", &spec->gpio_data))
5453 spec->gpio_dir &= spec->gpio_mask;
5454 if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask))
5455 spec->eapd_mask &= spec->gpio_mask;
5456 if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute))
5457 spec->gpio_mute &= spec->gpio_mask;
5458 val = snd_hda_get_bool_hint(codec, "eapd_switch");
5460 spec->eapd_switch = val;
5463 static void stac_issue_unsol_events(struct hda_codec *codec, int num_pins,
5464 const hda_nid_t *pins)
5467 stac_issue_unsol_event(codec, *pins++);
5470 /* fake event to set up pins */
5471 static void stac_fake_hp_events(struct hda_codec *codec)
5473 struct sigmatel_spec *spec = codec->spec;
5475 if (spec->autocfg.hp_outs)
5476 stac_issue_unsol_events(codec, spec->autocfg.hp_outs,
5477 spec->autocfg.hp_pins);
5478 if (spec->autocfg.line_outs &&
5479 spec->autocfg.line_out_pins[0] != spec->autocfg.hp_pins[0])
5480 stac_issue_unsol_events(codec, spec->autocfg.line_outs,
5481 spec->autocfg.line_out_pins);
5484 static int stac92xx_init(struct hda_codec *codec)
5486 struct sigmatel_spec *spec = codec->spec;
5487 struct auto_pin_cfg *cfg = &spec->autocfg;
5492 snd_hda_sequence_write(codec, spec->init);
5494 snd_hda_apply_verbs(codec);
5496 /* power down adcs initially */
5497 if (spec->powerdown_adcs)
5498 for (i = 0; i < spec->num_adcs; i++)
5499 snd_hda_codec_write(codec,
5500 spec->adc_nids[i], 0,
5501 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5503 /* override some hints */
5504 stac_store_hints(codec);
5507 gpio = spec->gpio_data;
5508 /* turn on EAPD statically when spec->eapd_switch isn't set.
5509 * otherwise, unsol event will turn it on/off dynamically
5511 if (!spec->eapd_switch)
5512 gpio |= spec->eapd_mask;
5513 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, gpio);
5516 if (spec->hp_detect) {
5517 /* Enable unsolicited responses on the HP widget */
5518 for (i = 0; i < cfg->hp_outs; i++) {
5519 hda_nid_t nid = cfg->hp_pins[i];
5520 enable_pin_detect(codec, nid, STAC_HP_EVENT);
5522 if (cfg->line_out_type == AUTO_PIN_LINE_OUT &&
5523 cfg->speaker_outs > 0) {
5524 /* enable pin-detect for line-outs as well */
5525 for (i = 0; i < cfg->line_outs; i++) {
5526 hda_nid_t nid = cfg->line_out_pins[i];
5527 enable_pin_detect(codec, nid, STAC_LO_EVENT);
5531 /* force to enable the first line-out; the others are set up
5534 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
5536 /* fake event to set up pins */
5537 stac_fake_hp_events(codec);
5539 stac92xx_auto_init_multi_out(codec);
5540 stac92xx_auto_init_hp_out(codec);
5541 for (i = 0; i < cfg->hp_outs; i++)
5542 stac_toggle_power_map(codec, cfg->hp_pins[i], 1);
5544 if (spec->auto_mic) {
5545 /* initialize connection to analog input */
5546 if (spec->dmux_nids)
5547 snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0,
5548 AC_VERB_SET_CONNECT_SEL, 0);
5549 if (enable_pin_detect(codec, spec->ext_mic.pin, STAC_MIC_EVENT))
5550 stac_issue_unsol_event(codec, spec->ext_mic.pin);
5551 if (enable_pin_detect(codec, spec->dock_mic.pin,
5553 stac_issue_unsol_event(codec, spec->dock_mic.pin);
5555 for (i = 0; i < cfg->num_inputs; i++) {
5556 hda_nid_t nid = cfg->inputs[i].pin;
5557 int type = cfg->inputs[i].type;
5558 unsigned int pinctl, conf;
5559 if (type == AUTO_PIN_MIC) {
5560 /* for mic pins, force to initialize */
5561 pinctl = snd_hda_get_default_vref(codec, nid);
5562 pinctl |= AC_PINCTL_IN_EN;
5563 stac92xx_auto_set_pinctl(codec, nid, pinctl);
5565 pinctl = snd_hda_codec_read(codec, nid, 0,
5566 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5567 /* if PINCTL already set then skip */
5568 /* Also, if both INPUT and OUTPUT are set,
5569 * it must be a BIOS bug; need to override, too
5571 if (!(pinctl & AC_PINCTL_IN_EN) ||
5572 (pinctl & AC_PINCTL_OUT_EN)) {
5573 pinctl &= ~AC_PINCTL_OUT_EN;
5574 pinctl |= AC_PINCTL_IN_EN;
5575 stac92xx_auto_set_pinctl(codec, nid, pinctl);
5578 conf = snd_hda_codec_get_pincfg(codec, nid);
5579 if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
5580 if (enable_pin_detect(codec, nid, STAC_INSERT_EVENT))
5581 stac_issue_unsol_event(codec, nid);
5584 for (i = 0; i < spec->num_dmics; i++)
5585 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
5587 if (cfg->dig_out_pins[0])
5588 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pins[0],
5590 if (cfg->dig_in_pin)
5591 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
5593 for (i = 0; i < spec->num_pwrs; i++) {
5594 hda_nid_t nid = spec->pwr_nids[i];
5595 unsigned int pinctl, def_conf;
5597 def_conf = snd_hda_codec_get_pincfg(codec, nid);
5598 def_conf = get_defcfg_connect(def_conf);
5599 if (def_conf == AC_JACK_PORT_NONE) {
5600 /* power off unused ports */
5601 stac_toggle_power_map(codec, nid, 0);
5604 if (def_conf == AC_JACK_PORT_FIXED) {
5605 /* no need for jack detection for fixed pins */
5606 stac_toggle_power_map(codec, nid, 1);
5609 /* power on when no jack detection is available */
5610 /* or when the VREF is used for controlling LED */
5611 if (!spec->hp_detect ||
5612 spec->vref_mute_led_nid == nid ||
5613 !is_jack_detectable(codec, nid)) {
5614 stac_toggle_power_map(codec, nid, 1);
5618 if (is_nid_out_jack_pin(cfg, nid))
5619 continue; /* already has an unsol event */
5621 pinctl = snd_hda_codec_read(codec, nid, 0,
5622 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5623 /* outputs are only ports capable of power management
5624 * any attempts on powering down a input port cause the
5625 * referenced VREF to act quirky.
5627 if (pinctl & AC_PINCTL_IN_EN) {
5628 stac_toggle_power_map(codec, nid, 1);
5631 if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) {
5632 stac_issue_unsol_event(codec, nid);
5635 /* none of the above, turn the port OFF */
5636 stac_toggle_power_map(codec, nid, 0);
5640 if (spec->gpio_led) {
5641 if (spec->vmaster_mute.hook)
5642 snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
5643 else /* the very first init call doesn't have vmaster yet */
5644 stac92xx_update_led_status(codec, false);
5647 /* sync the power-map */
5649 snd_hda_codec_write(codec, codec->afg, 0,
5650 AC_VERB_IDT_SET_POWER_MAP,
5651 spec->power_map_bits);
5653 stac92xx_power_down(codec);
5657 static void stac92xx_free_kctls(struct hda_codec *codec)
5659 struct sigmatel_spec *spec = codec->spec;
5661 if (spec->kctls.list) {
5662 struct snd_kcontrol_new *kctl = spec->kctls.list;
5664 for (i = 0; i < spec->kctls.used; i++)
5665 kfree(kctl[i].name);
5667 snd_array_free(&spec->kctls);
5670 static void stac92xx_shutup_pins(struct hda_codec *codec)
5672 unsigned int i, def_conf;
5674 if (codec->bus->shutdown)
5676 for (i = 0; i < codec->init_pins.used; i++) {
5677 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
5678 def_conf = snd_hda_codec_get_pincfg(codec, pin->nid);
5679 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)
5680 snd_hda_set_pin_ctl(codec, pin->nid, 0);
5684 static void stac92xx_shutup(struct hda_codec *codec)
5686 struct sigmatel_spec *spec = codec->spec;
5688 stac92xx_shutup_pins(codec);
5690 if (spec->eapd_mask)
5691 stac_gpio_set(codec, spec->gpio_mask,
5692 spec->gpio_dir, spec->gpio_data &
5696 static void stac92xx_free(struct hda_codec *codec)
5698 struct sigmatel_spec *spec = codec->spec;
5704 snd_hda_detach_beep_device(codec);
5707 static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
5710 unsigned int old_ctl, pin_ctl;
5712 pin_ctl = snd_hda_codec_read(codec, nid,
5713 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
5715 if (pin_ctl & AC_PINCTL_IN_EN) {
5717 * we need to check the current set-up direction of
5718 * shared input pins since they can be switched via
5719 * "xxx as Output" mixer switch
5721 struct sigmatel_spec *spec = codec->spec;
5722 if (nid == spec->line_switch || nid == spec->mic_switch)
5727 /* if setting pin direction bits, clear the current
5728 direction bits first */
5729 if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
5730 pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
5733 if (old_ctl != pin_ctl)
5734 snd_hda_set_pin_ctl_cache(codec, nid, pin_ctl);
5737 static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
5740 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
5741 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
5743 snd_hda_set_pin_ctl_cache(codec, nid, pin_ctl & ~flag);
5746 static inline int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
5750 return snd_hda_jack_detect(codec, nid);
5753 static void stac92xx_line_out_detect(struct hda_codec *codec,
5756 struct sigmatel_spec *spec = codec->spec;
5757 struct auto_pin_cfg *cfg = &spec->autocfg;
5760 if (cfg->speaker_outs == 0)
5763 for (i = 0; i < cfg->line_outs; i++) {
5766 presence = get_pin_presence(codec, cfg->line_out_pins[i]);
5768 unsigned int pinctl;
5769 pinctl = snd_hda_codec_read(codec,
5770 cfg->line_out_pins[i], 0,
5771 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5772 if (pinctl & AC_PINCTL_IN_EN)
5773 presence = 0; /* mic- or line-input */
5778 /* disable speakers */
5779 for (i = 0; i < cfg->speaker_outs; i++)
5780 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
5782 if (spec->eapd_mask && spec->eapd_switch)
5783 stac_gpio_set(codec, spec->gpio_mask,
5784 spec->gpio_dir, spec->gpio_data &
5787 /* enable speakers */
5788 for (i = 0; i < cfg->speaker_outs; i++)
5789 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
5791 if (spec->eapd_mask && spec->eapd_switch)
5792 stac_gpio_set(codec, spec->gpio_mask,
5793 spec->gpio_dir, spec->gpio_data |
5798 /* return non-zero if the hp-pin of the given array index isn't
5799 * a jack-detection target
5801 static int no_hp_sensing(struct sigmatel_spec *spec, int i)
5803 struct auto_pin_cfg *cfg = &spec->autocfg;
5805 /* ignore sensing of shared line and mic jacks */
5806 if (cfg->hp_pins[i] == spec->line_switch)
5808 if (cfg->hp_pins[i] == spec->mic_switch)
5810 /* ignore if the pin is set as line-out */
5811 if (cfg->hp_pins[i] == spec->hp_switch)
5816 static void stac92xx_hp_detect(struct hda_codec *codec)
5818 struct sigmatel_spec *spec = codec->spec;
5819 struct auto_pin_cfg *cfg = &spec->autocfg;
5823 if (spec->gpio_mute)
5824 presence = !(snd_hda_codec_read(codec, codec->afg, 0,
5825 AC_VERB_GET_GPIO_DATA, 0) & spec->gpio_mute);
5827 for (i = 0; i < cfg->hp_outs; i++) {
5830 if (no_hp_sensing(spec, i))
5832 presence = get_pin_presence(codec, cfg->hp_pins[i]);
5834 unsigned int pinctl;
5835 pinctl = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
5836 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5837 if (pinctl & AC_PINCTL_IN_EN)
5838 presence = 0; /* mic- or line-input */
5843 /* disable lineouts */
5844 if (spec->hp_switch)
5845 stac92xx_reset_pinctl(codec, spec->hp_switch,
5847 for (i = 0; i < cfg->line_outs; i++)
5848 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
5851 /* enable lineouts */
5852 if (spec->hp_switch)
5853 stac92xx_set_pinctl(codec, spec->hp_switch,
5855 for (i = 0; i < cfg->line_outs; i++)
5856 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
5859 stac92xx_line_out_detect(codec, presence);
5860 /* toggle hp outs */
5861 for (i = 0; i < cfg->hp_outs; i++) {
5862 unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;
5863 if (no_hp_sensing(spec, i))
5866 stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);
5868 /* Resetting the pinctl like below may lead to (a sort of) regressions
5869 * on some devices since they use the HP pin actually for line/speaker
5870 * outs although the default pin config shows a different pin (that is
5871 * wrong and useless).
5873 * So, it's basically a problem of default pin configs, likely a BIOS issue.
5874 * But, disabling the code below just works around it, and I'm too tired of
5875 * bug reports with such devices...
5878 stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val);
5883 static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
5886 struct sigmatel_spec *spec = codec->spec;
5887 unsigned int idx, val;
5889 for (idx = 0; idx < spec->num_pwrs; idx++) {
5890 if (spec->pwr_nids[idx] == nid)
5893 if (idx >= spec->num_pwrs)
5898 val = spec->power_map_bits;
5904 /* power down unused output ports */
5905 if (val != spec->power_map_bits) {
5906 spec->power_map_bits = val;
5907 snd_hda_codec_write(codec, codec->afg, 0,
5908 AC_VERB_IDT_SET_POWER_MAP, val);
5912 static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid)
5914 stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid));
5917 /* get the pin connection (fixed, none, etc) */
5918 static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx)
5920 struct sigmatel_spec *spec = codec->spec;
5923 cfg = snd_hda_codec_get_pincfg(codec, spec->pin_nids[idx]);
5924 return get_defcfg_connect(cfg);
5927 static int stac92xx_connected_ports(struct hda_codec *codec,
5928 const hda_nid_t *nids, int num_nids)
5930 struct sigmatel_spec *spec = codec->spec;
5932 unsigned int def_conf;
5934 for (num = 0; num < num_nids; num++) {
5935 for (idx = 0; idx < spec->num_pins; idx++)
5936 if (spec->pin_nids[idx] == nids[num])
5938 if (idx >= spec->num_pins)
5940 def_conf = stac_get_defcfg_connect(codec, idx);
5941 if (def_conf == AC_JACK_PORT_NONE)
5947 static void stac92xx_mic_detect(struct hda_codec *codec)
5949 struct sigmatel_spec *spec = codec->spec;
5950 struct sigmatel_mic_route *mic;
5952 if (get_pin_presence(codec, spec->ext_mic.pin))
5953 mic = &spec->ext_mic;
5954 else if (get_pin_presence(codec, spec->dock_mic.pin))
5955 mic = &spec->dock_mic;
5957 mic = &spec->int_mic;
5958 if (mic->dmux_idx >= 0)
5959 snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0,
5960 AC_VERB_SET_CONNECT_SEL,
5962 if (mic->mux_idx >= 0)
5963 snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0,
5964 AC_VERB_SET_CONNECT_SEL,
5968 static void handle_unsol_event(struct hda_codec *codec,
5969 struct hda_jack_tbl *event)
5971 struct sigmatel_spec *spec = codec->spec;
5974 switch (event->action) {
5977 stac92xx_hp_detect(codec);
5979 case STAC_MIC_EVENT:
5980 stac92xx_mic_detect(codec);
5984 switch (event->action) {
5987 case STAC_MIC_EVENT:
5988 case STAC_INSERT_EVENT:
5989 case STAC_PWR_EVENT:
5990 if (spec->num_pwrs > 0)
5991 stac92xx_pin_sense(codec, event->nid);
5993 switch (codec->subsystem_id) {
5995 if (event->nid == 0xb) {
5996 int pin = AC_PINCTL_IN_EN;
5998 if (get_pin_presence(codec, 0xa)
5999 && get_pin_presence(codec, 0xb))
6000 pin |= AC_PINCTL_VREF_80;
6001 if (!get_pin_presence(codec, 0xb))
6002 pin |= AC_PINCTL_VREF_80;
6004 /* toggle VREF state based on mic + hp pin
6007 stac92xx_auto_set_pinctl(codec, 0x0a, pin);
6011 case STAC_VREF_EVENT:
6012 data = snd_hda_codec_read(codec, codec->afg, 0,
6013 AC_VERB_GET_GPIO_DATA, 0);
6014 /* toggle VREF state based on GPIOx status */
6015 snd_hda_codec_write(codec, codec->afg, 0, 0x7e0,
6016 !!(data & (1 << event->private_data)));
6021 static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid)
6023 struct hda_jack_tbl *event = snd_hda_jack_tbl_get(codec, nid);
6026 handle_unsol_event(codec, event);
6029 static void set_hp_led_gpio(struct hda_codec *codec)
6031 struct sigmatel_spec *spec = codec->spec;
6037 gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP);
6038 gpio &= AC_GPIO_IO_COUNT;
6040 spec->gpio_led = 0x08; /* GPIO 3 */
6042 spec->gpio_led = 0x01; /* GPIO 0 */
6046 * This method searches for the mute LED GPIO configuration
6047 * provided as OEM string in SMBIOS. The format of that string
6048 * is HP_Mute_LED_P_G or HP_Mute_LED_P
6049 * where P can be 0 or 1 and defines mute LED GPIO control state (low/high)
6050 * that corresponds to the NOT muted state of the master volume
6051 * and G is the index of the GPIO to use as the mute LED control (0..9)
6052 * If _G portion is missing it is assigned based on the codec ID
6054 * So, HP B-series like systems may have HP_Mute_LED_0 (current models)
6055 * or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings
6058 * The dv-series laptops don't seem to have the HP_Mute_LED* strings in
6059 * SMBIOS - at least the ones I have seen do not have them - which include
6060 * my own system (HP Pavilion dv6-1110ax) and my cousin's
6061 * HP Pavilion dv9500t CTO.
6062 * Need more information on whether it is true across the entire series.
6065 static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity)
6067 struct sigmatel_spec *spec = codec->spec;
6068 const struct dmi_device *dev = NULL;
6070 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
6071 get_int_hint(codec, "gpio_led_polarity",
6072 &spec->gpio_led_polarity);
6076 if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) {
6077 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING,
6079 if (sscanf(dev->name, "HP_Mute_LED_%d_%x",
6080 &spec->gpio_led_polarity,
6081 &spec->gpio_led) == 2) {
6082 unsigned int max_gpio;
6083 max_gpio = snd_hda_param_read(codec, codec->afg,
6085 max_gpio &= AC_GPIO_IO_COUNT;
6086 if (spec->gpio_led < max_gpio)
6087 spec->gpio_led = 1 << spec->gpio_led;
6089 spec->vref_mute_led_nid = spec->gpio_led;
6092 if (sscanf(dev->name, "HP_Mute_LED_%d",
6093 &spec->gpio_led_polarity) == 1) {
6094 set_hp_led_gpio(codec);
6097 /* BIOS bug: unfilled OEM string */
6098 if (strstr(dev->name, "HP_Mute_LED_P_G")) {
6099 set_hp_led_gpio(codec);
6100 switch (codec->subsystem_id) {
6102 spec->gpio_led_polarity = 0;
6105 spec->gpio_led_polarity = 1;
6113 * Fallback case - if we don't find the DMI strings,
6114 * we statically set the GPIO - if not a B-series system
6115 * and default polarity is provided
6117 if (!hp_blike_system(codec->subsystem_id) &&
6118 (default_polarity == 0 || default_polarity == 1)) {
6119 set_hp_led_gpio(codec);
6120 spec->gpio_led_polarity = default_polarity;
6127 static int hp_blike_system(u32 subsystem_id)
6129 switch (subsystem_id) {
6156 #ifdef CONFIG_PROC_FS
6157 static void stac92hd_proc_hook(struct snd_info_buffer *buffer,
6158 struct hda_codec *codec, hda_nid_t nid)
6160 if (nid == codec->afg)
6161 snd_iprintf(buffer, "Power-Map: 0x%02x\n",
6162 snd_hda_codec_read(codec, nid, 0,
6163 AC_VERB_IDT_GET_POWER_MAP, 0));
6166 static void analog_loop_proc_hook(struct snd_info_buffer *buffer,
6167 struct hda_codec *codec,
6170 snd_iprintf(buffer, "Analog Loopback: 0x%02x\n",
6171 snd_hda_codec_read(codec, codec->afg, 0, verb, 0));
6174 /* stac92hd71bxx, stac92hd73xx */
6175 static void stac92hd7x_proc_hook(struct snd_info_buffer *buffer,
6176 struct hda_codec *codec, hda_nid_t nid)
6178 stac92hd_proc_hook(buffer, codec, nid);
6179 if (nid == codec->afg)
6180 analog_loop_proc_hook(buffer, codec, 0xfa0);
6183 static void stac9205_proc_hook(struct snd_info_buffer *buffer,
6184 struct hda_codec *codec, hda_nid_t nid)
6186 if (nid == codec->afg)
6187 analog_loop_proc_hook(buffer, codec, 0xfe0);
6190 static void stac927x_proc_hook(struct snd_info_buffer *buffer,
6191 struct hda_codec *codec, hda_nid_t nid)
6193 if (nid == codec->afg)
6194 analog_loop_proc_hook(buffer, codec, 0xfeb);
6197 #define stac92hd_proc_hook NULL
6198 #define stac92hd7x_proc_hook NULL
6199 #define stac9205_proc_hook NULL
6200 #define stac927x_proc_hook NULL
6204 static int stac92xx_resume(struct hda_codec *codec)
6206 stac92xx_init(codec);
6207 snd_hda_codec_resume_amp(codec);
6208 snd_hda_codec_resume_cache(codec);
6209 /* fake event to set up pins again to override cached values */
6210 stac_fake_hp_events(codec);
6214 static int stac92xx_suspend(struct hda_codec *codec)
6216 stac92xx_shutup(codec);
6220 static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
6221 unsigned int power_state)
6223 unsigned int afg_power_state = power_state;
6224 struct sigmatel_spec *spec = codec->spec;
6226 if (power_state == AC_PWRST_D3) {
6227 if (spec->vref_mute_led_nid) {
6228 /* with vref-out pin used for mute led control
6229 * codec AFG is prevented from D3 state
6231 afg_power_state = AC_PWRST_D1;
6233 /* this delay seems necessary to avoid click noise at power-down */
6236 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
6238 snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
6241 #define stac92xx_suspend NULL
6242 #define stac92xx_resume NULL
6243 #define stac92xx_set_power_state NULL
6244 #endif /* CONFIG_PM */
6246 /* update mute-LED accoring to the master switch */
6247 static void stac92xx_update_led_status(struct hda_codec *codec, int enabled)
6249 struct sigmatel_spec *spec = codec->spec;
6250 int muted = !enabled;
6252 if (!spec->gpio_led)
6255 /* LED state is inverted on these systems */
6256 if (spec->gpio_led_polarity)
6259 if (!spec->vref_mute_led_nid) {
6261 spec->gpio_data |= spec->gpio_led;
6263 spec->gpio_data &= ~spec->gpio_led;
6264 stac_gpio_set(codec, spec->gpio_mask,
6265 spec->gpio_dir, spec->gpio_data);
6267 spec->vref_led = muted ? AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
6268 stac_vrefout_set(codec, spec->vref_mute_led_nid,
6273 static const struct hda_codec_ops stac92xx_patch_ops = {
6274 .build_controls = stac92xx_build_controls,
6275 .build_pcms = stac92xx_build_pcms,
6276 .init = stac92xx_init,
6277 .free = stac92xx_free,
6278 .unsol_event = snd_hda_jack_unsol_event,
6280 .suspend = stac92xx_suspend,
6281 .resume = stac92xx_resume,
6283 .reboot_notify = stac92xx_shutup,
6286 static int alloc_stac_spec(struct hda_codec *codec, int num_pins,
6287 const hda_nid_t *pin_nids)
6289 struct sigmatel_spec *spec;
6291 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6295 codec->no_trigger_sense = 1; /* seems common with STAC/IDT codecs */
6296 spec->num_pins = num_pins;
6297 spec->pin_nids = pin_nids;
6298 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
6302 static int patch_stac9200(struct hda_codec *codec)
6304 struct sigmatel_spec *spec;
6307 err = alloc_stac_spec(codec, ARRAY_SIZE(stac9200_pin_nids),
6313 spec->linear_tone_beep = 1;
6315 snd_hda_pick_fixup(codec, stac9200_models, stac9200_fixup_tbl,
6318 spec->multiout.max_channels = 2;
6319 spec->multiout.num_dacs = 1;
6320 spec->multiout.dac_nids = stac9200_dac_nids;
6321 spec->adc_nids = stac9200_adc_nids;
6322 spec->mux_nids = stac9200_mux_nids;
6323 spec->num_muxes = 1;
6324 spec->num_dmics = 0;
6327 snd_hda_add_verbs(codec, stac9200_eapd_init);
6329 spec->mixer = stac9200_mixer;
6331 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6333 err = stac9200_parse_auto_config(codec);
6335 stac92xx_free(codec);
6339 codec->patch_ops = stac92xx_patch_ops;
6341 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6346 static int patch_stac925x(struct hda_codec *codec)
6348 struct sigmatel_spec *spec;
6351 err = alloc_stac_spec(codec, ARRAY_SIZE(stac925x_pin_nids),
6357 spec->linear_tone_beep = 1;
6359 snd_hda_pick_fixup(codec, stac925x_models, stac925x_fixup_tbl,
6362 spec->multiout.max_channels = 2;
6363 spec->multiout.num_dacs = 1;
6364 spec->multiout.dac_nids = stac925x_dac_nids;
6365 spec->adc_nids = stac925x_adc_nids;
6366 spec->mux_nids = stac925x_mux_nids;
6367 spec->num_muxes = 1;
6370 switch (codec->vendor_id) {
6371 case 0x83847632: /* STAC9202 */
6372 case 0x83847633: /* STAC9202D */
6373 case 0x83847636: /* STAC9251 */
6374 case 0x83847637: /* STAC9251D */
6375 spec->num_dmics = STAC925X_NUM_DMICS;
6376 spec->dmic_nids = stac925x_dmic_nids;
6377 spec->num_dmuxes = ARRAY_SIZE(stac925x_dmux_nids);
6378 spec->dmux_nids = stac925x_dmux_nids;
6381 spec->num_dmics = 0;
6385 snd_hda_add_verbs(codec, stac925x_core_init);
6386 spec->mixer = stac925x_mixer;
6388 spec->capvols = stac925x_capvols;
6389 spec->capsws = stac925x_capsws;
6391 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6393 err = stac92xx_parse_auto_config(codec);
6397 stac92xx_free(codec);
6401 codec->patch_ops = stac92xx_patch_ops;
6403 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6408 static int patch_stac92hd73xx(struct hda_codec *codec)
6410 struct sigmatel_spec *spec;
6411 hda_nid_t conn[STAC92HD73_DAC_COUNT + 2];
6415 err = alloc_stac_spec(codec, ARRAY_SIZE(stac92hd73xx_pin_nids),
6416 stac92hd73xx_pin_nids);
6421 spec->linear_tone_beep = 0;
6422 codec->slave_dig_outs = stac92hd73xx_slave_dig_outs;
6424 snd_hda_pick_fixup(codec, stac92hd73xx_models, stac92hd73xx_fixup_tbl,
6425 stac92hd73xx_fixups);
6427 num_dacs = snd_hda_get_connections(codec, 0x0a,
6428 conn, STAC92HD73_DAC_COUNT + 2) - 1;
6430 if (num_dacs < 3 || num_dacs > 5) {
6431 printk(KERN_WARNING "hda_codec: Could not determine "
6432 "number of channels defaulting to DAC count\n");
6433 num_dacs = STAC92HD73_DAC_COUNT;
6437 case 0x3: /* 6 Channel */
6438 spec->aloopback_ctl = stac92hd73xx_6ch_loopback;
6440 case 0x4: /* 8 Channel */
6441 spec->aloopback_ctl = stac92hd73xx_8ch_loopback;
6443 case 0x5: /* 10 Channel */
6444 spec->aloopback_ctl = stac92hd73xx_10ch_loopback;
6447 spec->multiout.dac_nids = spec->dac_nids;
6449 spec->aloopback_mask = 0x01;
6450 spec->aloopback_shift = 8;
6452 spec->digbeep_nid = 0x1c;
6453 spec->mux_nids = stac92hd73xx_mux_nids;
6454 spec->adc_nids = stac92hd73xx_adc_nids;
6455 spec->dmic_nids = stac92hd73xx_dmic_nids;
6456 spec->dmux_nids = stac92hd73xx_dmux_nids;
6457 spec->smux_nids = stac92hd73xx_smux_nids;
6459 spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids);
6460 spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids);
6461 spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids);
6463 spec->num_caps = STAC92HD73XX_NUM_CAPS;
6464 spec->capvols = stac92hd73xx_capvols;
6465 spec->capsws = stac92hd73xx_capsws;
6467 /* GPIO0 High = Enable EAPD */
6468 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
6469 spec->gpio_data = 0x01;
6471 spec->num_dmics = STAC92HD73XX_NUM_DMICS;
6472 spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids);
6473 spec->eapd_switch = 1;
6475 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
6476 spec->pwr_nids = stac92hd73xx_pwr_nids;
6478 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6480 if (!spec->volknob_init)
6481 snd_hda_add_verbs(codec, stac92hd73xx_core_init);
6483 err = stac92xx_parse_auto_config(codec);
6488 stac92xx_free(codec);
6492 codec->patch_ops = stac92xx_patch_ops;
6494 codec->proc_widget_hook = stac92hd7x_proc_hook;
6496 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6501 static int hp_bnb2011_with_dock(struct hda_codec *codec)
6503 if (codec->vendor_id != 0x111d7605 &&
6504 codec->vendor_id != 0x111d76d1)
6507 switch (codec->subsystem_id) {
6541 static void stac92hd8x_add_pin(struct hda_codec *codec, hda_nid_t nid)
6543 struct sigmatel_spec *spec = codec->spec;
6544 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
6547 spec->auto_pin_nids[spec->auto_pin_cnt] = nid;
6548 spec->auto_pin_cnt++;
6550 if (get_defcfg_device(def_conf) == AC_JACK_MIC_IN &&
6551 get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE) {
6552 for (i = 0; i < ARRAY_SIZE(stac92hd83xxx_dmic_nids); i++) {
6553 if (nid == stac92hd83xxx_dmic_nids[i]) {
6554 spec->auto_dmic_nids[spec->auto_dmic_cnt] = nid;
6555 spec->auto_dmic_cnt++;
6561 static void stac92hd8x_add_adc(struct hda_codec *codec, hda_nid_t nid)
6563 struct sigmatel_spec *spec = codec->spec;
6565 spec->auto_adc_nids[spec->auto_adc_cnt] = nid;
6566 spec->auto_adc_cnt++;
6569 static void stac92hd8x_add_mux(struct hda_codec *codec, hda_nid_t nid)
6572 struct sigmatel_spec *spec = codec->spec;
6574 for (i = 0; i < spec->auto_adc_cnt; i++) {
6575 if (get_connection_index(codec,
6576 spec->auto_adc_nids[i], nid) >= 0) {
6577 /* mux and volume for adc_nids[i] */
6578 if (!spec->auto_mux_nids[i]) {
6579 spec->auto_mux_nids[i] = nid;
6580 /* 92hd codecs capture volume is in mux */
6581 spec->auto_capvols[i] = HDA_COMPOSE_AMP_VAL(nid,
6584 for (j = 0; j < spec->auto_dmic_cnt; j++) {
6585 if (get_connection_index(codec, nid,
6586 spec->auto_dmic_nids[j]) >= 0) {
6587 /* dmux for adc_nids[i] */
6588 if (!spec->auto_dmux_nids[i])
6589 spec->auto_dmux_nids[i] = nid;
6598 static void stac92hd8x_fill_auto_spec(struct hda_codec *codec)
6600 hda_nid_t nid, end_nid;
6601 unsigned int wid_caps, wid_type;
6602 struct sigmatel_spec *spec = codec->spec;
6604 end_nid = codec->start_nid + codec->num_nodes;
6606 for (nid = codec->start_nid; nid < end_nid; nid++) {
6607 wid_caps = get_wcaps(codec, nid);
6608 wid_type = get_wcaps_type(wid_caps);
6610 if (wid_type == AC_WID_PIN)
6611 stac92hd8x_add_pin(codec, nid);
6613 if (wid_type == AC_WID_AUD_IN && !(wid_caps & AC_WCAP_DIGITAL))
6614 stac92hd8x_add_adc(codec, nid);
6617 for (nid = codec->start_nid; nid < end_nid; nid++) {
6618 wid_caps = get_wcaps(codec, nid);
6619 wid_type = get_wcaps_type(wid_caps);
6621 if (wid_type == AC_WID_AUD_SEL)
6622 stac92hd8x_add_mux(codec, nid);
6625 spec->pin_nids = spec->auto_pin_nids;
6626 spec->num_pins = spec->auto_pin_cnt;
6627 spec->adc_nids = spec->auto_adc_nids;
6628 spec->num_adcs = spec->auto_adc_cnt;
6629 spec->capvols = spec->auto_capvols;
6630 spec->capsws = spec->auto_capvols;
6631 spec->num_caps = spec->auto_adc_cnt;
6632 spec->mux_nids = spec->auto_mux_nids;
6633 spec->num_muxes = spec->auto_adc_cnt;
6634 spec->dmux_nids = spec->auto_dmux_nids;
6635 spec->num_dmuxes = spec->auto_adc_cnt;
6636 spec->dmic_nids = spec->auto_dmic_nids;
6637 spec->num_dmics = spec->auto_dmic_cnt;
6640 static int patch_stac92hd83xxx(struct hda_codec *codec)
6642 struct sigmatel_spec *spec;
6643 int default_polarity = -1; /* no default cfg */
6646 err = alloc_stac_spec(codec, 0, NULL); /* pins filled later */
6650 if (hp_bnb2011_with_dock(codec)) {
6651 snd_hda_codec_set_pincfg(codec, 0xa, 0x2101201f);
6652 snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);
6655 codec->epss = 0; /* longer delay needed for D3 */
6656 stac92hd8x_fill_auto_spec(codec);
6659 spec->linear_tone_beep = 0;
6660 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
6661 spec->digbeep_nid = 0x21;
6662 spec->pwr_nids = stac92hd83xxx_pwr_nids;
6663 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
6664 spec->multiout.dac_nids = spec->dac_nids;
6665 spec->init = stac92hd83xxx_core_init;
6667 spec->board_config = snd_hda_check_board_config(codec,
6668 STAC_92HD83XXX_MODELS,
6669 stac92hd83xxx_models,
6670 stac92hd83xxx_cfg_tbl);
6671 /* check codec subsystem id if not found */
6672 if (spec->board_config < 0)
6673 spec->board_config =
6674 snd_hda_check_board_codec_sid_config(codec,
6675 STAC_92HD83XXX_MODELS, stac92hd83xxx_models,
6676 stac92hd83xxx_codec_id_cfg_tbl);
6678 if (spec->board_config < 0)
6679 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6682 stac92xx_set_config_regs(codec,
6683 stac92hd83xxx_brd_tbl[spec->board_config]);
6685 codec->patch_ops = stac92xx_patch_ops;
6687 switch (spec->board_config) {
6688 case STAC_HP_ZEPHYR:
6689 spec->init = stac92hd83xxx_hp_zephyr_init;
6691 case STAC_92HD83XXX_HP_LED:
6692 default_polarity = 0;
6694 case STAC_92HD83XXX_HP_INV_LED:
6695 default_polarity = 1;
6697 case STAC_92HD83XXX_HP_MIC_LED:
6698 spec->mic_mute_led_gpio = 0x08; /* GPIO3 */
6700 case STAC_92HD83XXX_HEADSET_JACK:
6701 spec->headset_jack = 1;
6705 if (find_mute_led_cfg(codec, default_polarity))
6706 snd_printd("mute LED gpio %d polarity %d\n",
6708 spec->gpio_led_polarity);
6710 if (spec->gpio_led) {
6711 if (!spec->vref_mute_led_nid) {
6712 spec->gpio_mask |= spec->gpio_led;
6713 spec->gpio_dir |= spec->gpio_led;
6714 spec->gpio_data |= spec->gpio_led;
6716 codec->patch_ops.set_power_state =
6717 stac92xx_set_power_state;
6721 if (spec->mic_mute_led_gpio) {
6722 spec->gpio_mask |= spec->mic_mute_led_gpio;
6723 spec->gpio_dir |= spec->mic_mute_led_gpio;
6724 spec->mic_mute_led_on = true;
6725 spec->gpio_data |= spec->mic_mute_led_gpio;
6728 err = stac92xx_parse_auto_config(codec);
6730 if (spec->board_config < 0) {
6731 printk(KERN_WARNING "hda_codec: No auto-config is "
6732 "available, default to model=ref\n");
6733 spec->board_config = STAC_92HD83XXX_REF;
6740 stac92xx_free(codec);
6744 codec->proc_widget_hook = stac92hd_proc_hook;
6749 static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec,
6752 struct sigmatel_spec *spec = codec->spec;
6755 for (idx = 0; idx < spec->num_pins; idx++)
6756 if (spec->pin_nids[idx] == dig0pin)
6758 if ((idx + 2) >= spec->num_pins)
6762 if (stac_get_defcfg_connect(codec, idx + 1) != AC_JACK_PORT_NONE)
6765 /* dig0pin + dig2pin case */
6766 if (stac_get_defcfg_connect(codec, idx + 2) != AC_JACK_PORT_NONE)
6768 if (stac_get_defcfg_connect(codec, idx) != AC_JACK_PORT_NONE)
6774 /* HP dv7 bass switch - GPIO5 */
6775 #define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info
6776 static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol,
6777 struct snd_ctl_elem_value *ucontrol)
6779 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6780 struct sigmatel_spec *spec = codec->spec;
6781 ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20);
6785 static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol,
6786 struct snd_ctl_elem_value *ucontrol)
6788 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6789 struct sigmatel_spec *spec = codec->spec;
6790 unsigned int gpio_data;
6792 gpio_data = (spec->gpio_data & ~0x20) |
6793 (ucontrol->value.integer.value[0] ? 0x20 : 0);
6794 if (gpio_data == spec->gpio_data)
6796 spec->gpio_data = gpio_data;
6797 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
6801 static const struct snd_kcontrol_new stac_hp_bass_sw_ctrl = {
6802 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6803 .info = stac_hp_bass_gpio_info,
6804 .get = stac_hp_bass_gpio_get,
6805 .put = stac_hp_bass_gpio_put,
6808 static int stac_add_hp_bass_switch(struct hda_codec *codec)
6810 struct sigmatel_spec *spec = codec->spec;
6812 if (!stac_control_new(spec, &stac_hp_bass_sw_ctrl,
6813 "Bass Speaker Playback Switch", 0))
6816 spec->gpio_mask |= 0x20;
6817 spec->gpio_dir |= 0x20;
6818 spec->gpio_data |= 0x20;
6822 static int patch_stac92hd71bxx(struct hda_codec *codec)
6824 struct sigmatel_spec *spec;
6825 const struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init;
6828 err = alloc_stac_spec(codec, STAC92HD71BXX_NUM_PINS,
6829 stac92hd71bxx_pin_nids_4port);
6834 spec->linear_tone_beep = 0;
6835 codec->patch_ops = stac92xx_patch_ops;
6836 switch (codec->vendor_id) {
6842 /* On 92HD75Bx 0x27 isn't a pin nid */
6846 spec->pin_nids = stac92hd71bxx_pin_nids_6port;
6848 spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
6850 snd_hda_pick_fixup(codec, stac92hd71bxx_models, stac92hd71bxx_fixup_tbl,
6851 stac92hd71bxx_fixups);
6854 spec->gpio_mask = 0x01;
6855 spec->gpio_dir = 0x01;
6856 spec->gpio_data = 0x01;
6858 spec->dmic_nids = stac92hd71bxx_dmic_nids;
6859 spec->dmux_nids = stac92hd71bxx_dmux_nids;
6861 spec->num_caps = STAC92HD71BXX_NUM_CAPS;
6862 spec->capvols = stac92hd71bxx_capvols;
6863 spec->capsws = stac92hd71bxx_capsws;
6865 switch (codec->vendor_id) {
6866 case 0x111d76b6: /* 4 Port without Analog Mixer */
6870 case 0x111d76b4: /* 6 Port without Analog Mixer */
6872 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
6873 spec->num_dmics = stac92xx_connected_ports(codec,
6874 stac92hd71bxx_dmic_nids,
6875 STAC92HD71BXX_NUM_DMICS);
6877 case 0x111d7608: /* 5 Port with Analog Mixer */
6878 if ((codec->revision_id & 0xf) == 0 ||
6879 (codec->revision_id & 0xf) == 1)
6880 spec->stream_delay = 40; /* 40 milliseconds */
6884 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0);
6885 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3);
6886 spec->dmic_nids = stac92hd71bxx_dmic_5port_nids;
6887 spec->num_dmics = stac92xx_connected_ports(codec,
6888 stac92hd71bxx_dmic_5port_nids,
6889 STAC92HD71BXX_NUM_DMICS - 1);
6891 case 0x111d7603: /* 6 Port with Analog Mixer */
6892 if ((codec->revision_id & 0xf) == 1)
6893 spec->stream_delay = 40; /* 40 milliseconds */
6897 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
6898 spec->num_dmics = stac92xx_connected_ports(codec,
6899 stac92hd71bxx_dmic_nids,
6900 STAC92HD71BXX_NUM_DMICS);
6904 if (get_wcaps_type(get_wcaps(codec, 0x28)) == AC_WID_VOL_KNB)
6905 snd_hda_add_verbs(codec, stac92hd71bxx_core_init);
6907 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP)
6908 snd_hda_sequence_write_cache(codec, unmute_init);
6910 spec->aloopback_ctl = stac92hd71bxx_loopback;
6911 spec->aloopback_mask = 0x50;
6912 spec->aloopback_shift = 0;
6914 spec->powerdown_adcs = 1;
6915 spec->digbeep_nid = 0x26;
6916 spec->mux_nids = stac92hd71bxx_mux_nids;
6917 spec->adc_nids = stac92hd71bxx_adc_nids;
6918 spec->smux_nids = stac92hd71bxx_smux_nids;
6919 spec->pwr_nids = stac92hd71bxx_pwr_nids;
6921 spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids);
6922 spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids);
6923 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
6924 spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e);
6926 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6928 if (spec->gpio_led) {
6929 if (!spec->vref_mute_led_nid) {
6930 spec->gpio_mask |= spec->gpio_led;
6931 spec->gpio_dir |= spec->gpio_led;
6932 spec->gpio_data |= spec->gpio_led;
6934 codec->patch_ops.set_power_state =
6935 stac92xx_set_power_state;
6939 spec->multiout.dac_nids = spec->dac_nids;
6941 err = stac92xx_parse_auto_config(codec);
6945 stac92xx_free(codec);
6949 codec->proc_widget_hook = stac92hd7x_proc_hook;
6951 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6956 static int patch_stac922x(struct hda_codec *codec)
6958 struct sigmatel_spec *spec;
6961 err = alloc_stac_spec(codec, ARRAY_SIZE(stac922x_pin_nids),
6967 spec->linear_tone_beep = 1;
6969 snd_hda_pick_fixup(codec, stac922x_models, stac922x_fixup_tbl,
6972 spec->adc_nids = stac922x_adc_nids;
6973 spec->mux_nids = stac922x_mux_nids;
6974 spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
6975 spec->num_adcs = ARRAY_SIZE(stac922x_adc_nids);
6976 spec->num_dmics = 0;
6979 spec->num_caps = STAC922X_NUM_CAPS;
6980 spec->capvols = stac922x_capvols;
6981 spec->capsws = stac922x_capsws;
6983 spec->multiout.dac_nids = spec->dac_nids;
6985 snd_hda_add_verbs(codec, stac922x_core_init);
6987 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6989 err = stac92xx_parse_auto_config(codec);
6993 stac92xx_free(codec);
6997 codec->patch_ops = stac92xx_patch_ops;
6999 /* Fix Mux capture level; max to 2 */
7000 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
7001 (0 << AC_AMPCAP_OFFSET_SHIFT) |
7002 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
7003 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
7004 (0 << AC_AMPCAP_MUTE_SHIFT));
7006 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
7011 static int patch_stac927x(struct hda_codec *codec)
7013 struct sigmatel_spec *spec;
7016 err = alloc_stac_spec(codec, ARRAY_SIZE(stac927x_pin_nids),
7022 spec->linear_tone_beep = 1;
7023 codec->slave_dig_outs = stac927x_slave_dig_outs;
7025 snd_hda_pick_fixup(codec, stac927x_models, stac927x_fixup_tbl,
7028 spec->digbeep_nid = 0x23;
7029 spec->adc_nids = stac927x_adc_nids;
7030 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
7031 spec->mux_nids = stac927x_mux_nids;
7032 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
7033 spec->smux_nids = stac927x_smux_nids;
7034 spec->num_smuxes = ARRAY_SIZE(stac927x_smux_nids);
7035 spec->spdif_labels = stac927x_spdif_labels;
7036 spec->dac_list = stac927x_dac_nids;
7037 spec->multiout.dac_nids = spec->dac_nids;
7039 /* GPIO0 High = Enable EAPD */
7040 spec->eapd_mask = spec->gpio_mask = 0x01;
7041 spec->gpio_dir = spec->gpio_data = 0x01;
7043 spec->num_dmics = 0;
7045 spec->num_caps = STAC927X_NUM_CAPS;
7046 spec->capvols = stac927x_capvols;
7047 spec->capsws = stac927x_capsws;
7050 spec->aloopback_ctl = stac927x_loopback;
7051 spec->aloopback_mask = 0x40;
7052 spec->aloopback_shift = 0;
7053 spec->eapd_switch = 1;
7055 if (!spec->volknob_init)
7056 snd_hda_add_verbs(codec, stac927x_core_init);
7058 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
7060 err = stac92xx_parse_auto_config(codec);
7064 stac92xx_free(codec);
7068 codec->patch_ops = stac92xx_patch_ops;
7070 codec->proc_widget_hook = stac927x_proc_hook;
7074 * The STAC927x seem to require fairly long delays for certain
7075 * command sequences. With too short delays (even if the answer
7076 * is set to RIRB properly), it results in the silence output
7077 * on some hardwares like Dell.
7079 * The below flag enables the longer delay (see get_response
7082 codec->bus->needs_damn_long_delay = 1;
7084 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
7089 static int patch_stac9205(struct hda_codec *codec)
7091 struct sigmatel_spec *spec;
7094 err = alloc_stac_spec(codec, ARRAY_SIZE(stac9205_pin_nids),
7100 spec->linear_tone_beep = 1;
7102 snd_hda_pick_fixup(codec, stac9205_models, stac9205_fixup_tbl,
7105 spec->digbeep_nid = 0x23;
7106 spec->adc_nids = stac9205_adc_nids;
7107 spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids);
7108 spec->mux_nids = stac9205_mux_nids;
7109 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
7110 spec->smux_nids = stac9205_smux_nids;
7111 spec->num_smuxes = ARRAY_SIZE(stac9205_smux_nids);
7112 spec->dmic_nids = stac9205_dmic_nids;
7113 spec->num_dmics = STAC9205_NUM_DMICS;
7114 spec->dmux_nids = stac9205_dmux_nids;
7115 spec->num_dmuxes = ARRAY_SIZE(stac9205_dmux_nids);
7118 snd_hda_add_verbs(codec, stac9205_core_init);
7119 spec->aloopback_ctl = stac9205_loopback;
7121 spec->num_caps = STAC9205_NUM_CAPS;
7122 spec->capvols = stac9205_capvols;
7123 spec->capsws = stac9205_capsws;
7125 spec->aloopback_mask = 0x40;
7126 spec->aloopback_shift = 0;
7127 spec->multiout.dac_nids = spec->dac_nids;
7129 /* GPIO0 High = EAPD */
7130 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
7131 spec->gpio_data = 0x01;
7133 /* Turn on/off EAPD per HP plugging */
7134 spec->eapd_switch = 1;
7136 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
7138 err = stac92xx_parse_auto_config(codec);
7142 stac92xx_free(codec);
7146 codec->patch_ops = stac92xx_patch_ops;
7148 codec->proc_widget_hook = stac9205_proc_hook;
7150 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
7159 static const struct hda_verb stac9872_core_init[] = {
7160 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
7161 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
7165 static const hda_nid_t stac9872_pin_nids[] = {
7166 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
7170 static const hda_nid_t stac9872_adc_nids[] = {
7174 static const hda_nid_t stac9872_mux_nids[] = {
7178 static const unsigned long stac9872_capvols[] = {
7179 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7181 #define stac9872_capsws stac9872_capvols
7183 static const struct hda_pintbl stac9872_vaio_pin_configs[] = {
7184 { 0x0a, 0x03211020 },
7185 { 0x0b, 0x411111f0 },
7186 { 0x0c, 0x411111f0 },
7187 { 0x0d, 0x03a15030 },
7188 { 0x0e, 0x411111f0 },
7189 { 0x0f, 0x90170110 },
7190 { 0x11, 0x411111f0 },
7191 { 0x13, 0x411111f0 },
7192 { 0x14, 0x90a7013e },
7196 static const struct hda_model_fixup stac9872_models[] = {
7197 { .id = STAC_9872_VAIO, .name = "vaio" },
7201 static const struct hda_fixup stac9872_fixups[] = {
7202 [STAC_9872_VAIO] = {
7203 .type = HDA_FIXUP_PINS,
7204 .v.pins = stac9872_vaio_pin_configs,
7208 static const struct snd_pci_quirk stac9872_fixup_tbl[] = {
7209 SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0,
7210 "Sony VAIO F/S", STAC_9872_VAIO),
7214 static int patch_stac9872(struct hda_codec *codec)
7216 struct sigmatel_spec *spec;
7219 err = alloc_stac_spec(codec, ARRAY_SIZE(stac9872_pin_nids),
7225 spec->linear_tone_beep = 1;
7227 snd_hda_pick_fixup(codec, stac9872_models, stac9872_fixup_tbl,
7230 spec->multiout.dac_nids = spec->dac_nids;
7231 spec->num_adcs = ARRAY_SIZE(stac9872_adc_nids);
7232 spec->adc_nids = stac9872_adc_nids;
7233 spec->num_muxes = ARRAY_SIZE(stac9872_mux_nids);
7234 spec->mux_nids = stac9872_mux_nids;
7236 spec->capvols = stac9872_capvols;
7237 spec->capsws = stac9872_capsws;
7238 snd_hda_add_verbs(codec, stac9872_core_init);
7240 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
7242 err = stac92xx_parse_auto_config(codec);
7244 stac92xx_free(codec);
7247 spec->input_mux = &spec->private_imux;
7248 codec->patch_ops = stac92xx_patch_ops;
7250 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
7259 static const struct hda_codec_preset snd_hda_preset_sigmatel[] = {
7260 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
7261 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
7262 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
7263 { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x },
7264 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
7265 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
7266 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
7267 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x },
7268 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x },
7269 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x },
7270 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x },
7271 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x },
7272 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x },
7273 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
7274 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
7275 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
7276 { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x },
7277 { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x },
7278 { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x },
7279 { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x },
7280 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x },
7281 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x },
7282 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x },
7283 { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x },
7284 { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x },
7285 { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x },
7286 { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
7287 { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
7288 { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
7289 { .id = 0x83847645, .name = "92HD206X", .patch = patch_stac927x },
7290 { .id = 0x83847646, .name = "92HD206D", .patch = patch_stac927x },
7291 /* The following does not take into account .id=0x83847661 when subsys =
7292 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
7293 * currently not fully supported.
7295 { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 },
7296 { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 },
7297 { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 },
7298 { .id = 0x83847698, .name = "STAC9205", .patch = patch_stac9205 },
7299 { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 },
7300 { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 },
7301 { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 },
7302 { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 },
7303 { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 },
7304 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
7305 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
7306 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
7307 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx},
7308 { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx},
7309 { .id = 0x111d76d4, .name = "92HD83C1C5", .patch = patch_stac92hd83xxx},
7310 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx},
7311 { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx},
7312 { .id = 0x111d76d1, .name = "92HD87B1/3", .patch = patch_stac92hd83xxx},
7313 { .id = 0x111d76d9, .name = "92HD87B2/4", .patch = patch_stac92hd83xxx},
7314 { .id = 0x111d7666, .name = "92HD88B3", .patch = patch_stac92hd83xxx},
7315 { .id = 0x111d7667, .name = "92HD88B1", .patch = patch_stac92hd83xxx},
7316 { .id = 0x111d7668, .name = "92HD88B2", .patch = patch_stac92hd83xxx},
7317 { .id = 0x111d7669, .name = "92HD88B4", .patch = patch_stac92hd83xxx},
7318 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx},
7319 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
7320 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },
7321 { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx },
7322 { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
7323 { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
7324 { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
7325 { .id = 0x111d76b3, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
7326 { .id = 0x111d76b4, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
7327 { .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
7328 { .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
7329 { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
7330 { .id = 0x111d76c0, .name = "92HD89C3", .patch = patch_stac92hd73xx },
7331 { .id = 0x111d76c1, .name = "92HD89C2", .patch = patch_stac92hd73xx },
7332 { .id = 0x111d76c2, .name = "92HD89C1", .patch = patch_stac92hd73xx },
7333 { .id = 0x111d76c3, .name = "92HD89B3", .patch = patch_stac92hd73xx },
7334 { .id = 0x111d76c4, .name = "92HD89B2", .patch = patch_stac92hd73xx },
7335 { .id = 0x111d76c5, .name = "92HD89B1", .patch = patch_stac92hd73xx },
7336 { .id = 0x111d76c6, .name = "92HD89E3", .patch = patch_stac92hd73xx },
7337 { .id = 0x111d76c7, .name = "92HD89E2", .patch = patch_stac92hd73xx },
7338 { .id = 0x111d76c8, .name = "92HD89E1", .patch = patch_stac92hd73xx },
7339 { .id = 0x111d76c9, .name = "92HD89D3", .patch = patch_stac92hd73xx },
7340 { .id = 0x111d76ca, .name = "92HD89D2", .patch = patch_stac92hd73xx },
7341 { .id = 0x111d76cb, .name = "92HD89D1", .patch = patch_stac92hd73xx },
7342 { .id = 0x111d76cc, .name = "92HD89F3", .patch = patch_stac92hd73xx },
7343 { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx },
7344 { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx },
7345 { .id = 0x111d76df, .name = "92HD93BXX", .patch = patch_stac92hd83xxx},
7346 { .id = 0x111d76e0, .name = "92HD91BXX", .patch = patch_stac92hd83xxx},
7347 { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx},
7348 { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx},
7349 { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx},
7350 { .id = 0x111d76e8, .name = "92HD66B1X5", .patch = patch_stac92hd83xxx},
7351 { .id = 0x111d76e9, .name = "92HD66B2X5", .patch = patch_stac92hd83xxx},
7352 { .id = 0x111d76ea, .name = "92HD66B3X5", .patch = patch_stac92hd83xxx},
7353 { .id = 0x111d76eb, .name = "92HD66C1X5", .patch = patch_stac92hd83xxx},
7354 { .id = 0x111d76ec, .name = "92HD66C2X5", .patch = patch_stac92hd83xxx},
7355 { .id = 0x111d76ed, .name = "92HD66C3X5", .patch = patch_stac92hd83xxx},
7356 { .id = 0x111d76ee, .name = "92HD66B1X3", .patch = patch_stac92hd83xxx},
7357 { .id = 0x111d76ef, .name = "92HD66B2X3", .patch = patch_stac92hd83xxx},
7358 { .id = 0x111d76f0, .name = "92HD66B3X3", .patch = patch_stac92hd83xxx},
7359 { .id = 0x111d76f1, .name = "92HD66C1X3", .patch = patch_stac92hd83xxx},
7360 { .id = 0x111d76f2, .name = "92HD66C2X3", .patch = patch_stac92hd83xxx},
7361 { .id = 0x111d76f3, .name = "92HD66C3/65", .patch = patch_stac92hd83xxx},
7365 MODULE_ALIAS("snd-hda-codec-id:8384*");
7366 MODULE_ALIAS("snd-hda-codec-id:111d*");
7368 MODULE_LICENSE("GPL");
7369 MODULE_DESCRIPTION("IDT/Sigmatel HD-audio codec");
7371 static struct hda_codec_preset_list sigmatel_list = {
7372 .preset = snd_hda_preset_sigmatel,
7373 .owner = THIS_MODULE,
7376 static int __init patch_sigmatel_init(void)
7378 return snd_hda_add_codec_preset(&sigmatel_list);
7381 static void __exit patch_sigmatel_exit(void)
7383 snd_hda_delete_codec_preset(&sigmatel_list);
7386 module_init(patch_sigmatel_init)
7387 module_exit(patch_sigmatel_exit)