/* * Universal Interface for Intel High Definition Audio Codec * * HD audio interface patch for SigmaTel STAC92xx * * Copyright (c) 2005 Embedded Alley Solutions, Inc. * Matt Porter * * Based on patch_cmedia.c and patch_realtek.c * Copyright (c) 2004 Takashi Iwai * * This driver is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This driver is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include "hda_codec.h" #include "hda_local.h" #include "hda_auto_parser.h" #include "hda_beep.h" #include "hda_jack.h" enum { STAC_VREF_EVENT = 1, STAC_INSERT_EVENT, STAC_PWR_EVENT, STAC_HP_EVENT, STAC_LO_EVENT, STAC_MIC_EVENT, }; enum { STAC_AUTO, STAC_REF, STAC_9200_OQO, STAC_9200_DELL_D21, STAC_9200_DELL_D22, STAC_9200_DELL_D23, STAC_9200_DELL_M21, STAC_9200_DELL_M22, STAC_9200_DELL_M23, STAC_9200_DELL_M24, STAC_9200_DELL_M25, STAC_9200_DELL_M26, STAC_9200_DELL_M27, STAC_9200_M4, STAC_9200_M4_2, STAC_9200_PANASONIC, STAC_9200_MODELS }; enum { STAC_9205_AUTO, STAC_9205_REF, STAC_9205_DELL_M42, STAC_9205_DELL_M43, STAC_9205_DELL_M44, STAC_9205_EAPD, STAC_9205_MODELS }; enum { STAC_92HD73XX_AUTO, STAC_92HD73XX_NO_JD, /* no jack-detection */ STAC_92HD73XX_REF, STAC_92HD73XX_INTEL, STAC_DELL_M6_AMIC, STAC_DELL_M6_DMIC, STAC_DELL_M6_BOTH, STAC_DELL_EQ, STAC_ALIENWARE_M17X, STAC_92HD73XX_MODELS }; enum { STAC_92HD83XXX_AUTO, STAC_92HD83XXX_REF, STAC_92HD83XXX_PWR_REF, STAC_DELL_S14, STAC_DELL_VOSTRO_3500, STAC_92HD83XXX_HP_cNB11_INTQUAD, STAC_HP_DV7_4000, STAC_HP_ZEPHYR, STAC_92HD83XXX_MODELS }; enum { STAC_92HD71BXX_AUTO, STAC_92HD71BXX_REF, STAC_DELL_M4_1, STAC_DELL_M4_2, STAC_DELL_M4_3, STAC_HP_M4, STAC_HP_DV4, STAC_HP_DV5, STAC_HP_HDX, STAC_HP_DV4_1222NR, STAC_92HD71BXX_MODELS }; enum { STAC_925x_AUTO, STAC_925x_REF, STAC_M1, STAC_M1_2, STAC_M2, STAC_M2_2, STAC_M3, STAC_M5, STAC_M6, STAC_925x_MODELS }; enum { STAC_922X_AUTO, STAC_D945_REF, STAC_D945GTP3, STAC_D945GTP5, STAC_INTEL_MAC_V1, STAC_INTEL_MAC_V2, STAC_INTEL_MAC_V3, STAC_INTEL_MAC_V4, STAC_INTEL_MAC_V5, STAC_INTEL_MAC_AUTO, /* This model is selected if no module parameter * is given, one of the above models will be * chosen according to the subsystem id. */ /* for backward compatibility */ STAC_MACMINI, STAC_MACBOOK, STAC_MACBOOK_PRO_V1, STAC_MACBOOK_PRO_V2, STAC_IMAC_INTEL, STAC_IMAC_INTEL_20, STAC_ECS_202, STAC_922X_DELL_D81, STAC_922X_DELL_D82, STAC_922X_DELL_M81, STAC_922X_DELL_M82, STAC_922X_MODELS }; enum { STAC_927X_AUTO, STAC_D965_REF_NO_JD, /* no jack-detection */ STAC_D965_REF, STAC_D965_3ST, STAC_D965_5ST, STAC_D965_5ST_NO_FP, STAC_DELL_3ST, STAC_DELL_BIOS, STAC_927X_VOLKNOB, STAC_927X_MODELS }; enum { STAC_9872_AUTO, STAC_9872_VAIO, STAC_9872_MODELS }; struct sigmatel_mic_route { hda_nid_t pin; signed char mux_idx; signed char dmux_idx; }; #define MAX_PINS_NUM 16 #define MAX_ADCS_NUM 4 #define MAX_DMICS_NUM 4 struct sigmatel_spec { struct snd_kcontrol_new *mixers[4]; unsigned int num_mixers; int board_config; unsigned int eapd_switch: 1; unsigned int surr_switch: 1; unsigned int alt_switch: 1; unsigned int hp_detect: 1; unsigned int spdif_mute: 1; unsigned int check_volume_offset:1; unsigned int auto_mic:1; unsigned int linear_tone_beep:1; /* gpio lines */ unsigned int eapd_mask; unsigned int gpio_mask; unsigned int gpio_dir; unsigned int gpio_data; unsigned int gpio_mute; unsigned int gpio_led; unsigned int gpio_led_polarity; unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */ unsigned int vref_led; /* stream */ unsigned int stream_delay; /* analog loopback */ const struct snd_kcontrol_new *aloopback_ctl; unsigned char aloopback_mask; unsigned char aloopback_shift; /* power management */ unsigned int power_map_bits; unsigned int num_pwrs; const hda_nid_t *pwr_nids; const hda_nid_t *dac_list; /* playback */ struct hda_input_mux *mono_mux; unsigned int cur_mmux; struct hda_multi_out multiout; hda_nid_t dac_nids[5]; hda_nid_t hp_dacs[5]; hda_nid_t speaker_dacs[5]; int volume_offset; /* capture */ const hda_nid_t *adc_nids; unsigned int num_adcs; const hda_nid_t *mux_nids; unsigned int num_muxes; const hda_nid_t *dmic_nids; unsigned int num_dmics; const hda_nid_t *dmux_nids; unsigned int num_dmuxes; const hda_nid_t *smux_nids; unsigned int num_smuxes; unsigned int num_analog_muxes; const unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */ const unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */ unsigned int num_caps; /* number of capture volume/switch elements */ struct sigmatel_mic_route ext_mic; struct sigmatel_mic_route int_mic; struct sigmatel_mic_route dock_mic; const char * const *spdif_labels; hda_nid_t dig_in_nid; hda_nid_t mono_nid; hda_nid_t anabeep_nid; hda_nid_t digbeep_nid; /* pin widgets */ const hda_nid_t *pin_nids; unsigned int num_pins; /* codec specific stuff */ const struct hda_verb *init; const struct snd_kcontrol_new *mixer; /* capture source */ struct hda_input_mux *dinput_mux; unsigned int cur_dmux[2]; struct hda_input_mux *input_mux; unsigned int cur_mux[3]; struct hda_input_mux *sinput_mux; unsigned int cur_smux[2]; unsigned int cur_amux; hda_nid_t *amp_nids; unsigned int powerdown_adcs; /* i/o switches */ unsigned int io_switch[2]; unsigned int clfe_swap; hda_nid_t line_switch; /* shared line-in for input and output */ hda_nid_t mic_switch; /* shared mic-in for input and output */ hda_nid_t hp_switch; /* NID of HP as line-out */ unsigned int aloopback; struct hda_pcm pcm_rec[2]; /* PCM information */ /* dynamic controls and input_mux */ struct auto_pin_cfg autocfg; struct snd_array kctls; struct hda_input_mux private_dimux; struct hda_input_mux private_imux; struct hda_input_mux private_smux; struct hda_input_mux private_mono_mux; /* auto spec */ unsigned auto_pin_cnt; hda_nid_t auto_pin_nids[MAX_PINS_NUM]; unsigned auto_adc_cnt; hda_nid_t auto_adc_nids[MAX_ADCS_NUM]; hda_nid_t auto_mux_nids[MAX_ADCS_NUM]; hda_nid_t auto_dmux_nids[MAX_ADCS_NUM]; unsigned long auto_capvols[MAX_ADCS_NUM]; unsigned auto_dmic_cnt; hda_nid_t auto_dmic_nids[MAX_DMICS_NUM]; struct hda_vmaster_mute_hook vmaster_mute; }; #define AC_VERB_IDT_SET_POWER_MAP 0x7ec #define AC_VERB_IDT_GET_POWER_MAP 0xfec static const hda_nid_t stac9200_adc_nids[1] = { 0x03, }; static const hda_nid_t stac9200_mux_nids[1] = { 0x0c, }; static const hda_nid_t stac9200_dac_nids[1] = { 0x02, }; static const hda_nid_t stac92hd73xx_pwr_nids[8] = { 0x0a, 0x0b, 0x0c, 0xd, 0x0e, 0x0f, 0x10, 0x11 }; static const hda_nid_t stac92hd73xx_slave_dig_outs[2] = { 0x26, 0, }; static const hda_nid_t stac92hd73xx_adc_nids[2] = { 0x1a, 0x1b }; #define STAC92HD73XX_NUM_DMICS 2 static const hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { 0x13, 0x14, 0 }; #define STAC92HD73_DAC_COUNT 5 static const hda_nid_t stac92hd73xx_mux_nids[2] = { 0x20, 0x21, }; static const hda_nid_t stac92hd73xx_dmux_nids[2] = { 0x20, 0x21, }; static const hda_nid_t stac92hd73xx_smux_nids[2] = { 0x22, 0x23, }; #define STAC92HD73XX_NUM_CAPS 2 static const unsigned long stac92hd73xx_capvols[] = { HDA_COMPOSE_AMP_VAL(0x20, 3, 0, HDA_OUTPUT), HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), }; #define stac92hd73xx_capsws stac92hd73xx_capvols #define STAC92HD83_DAC_COUNT 3 static const hda_nid_t stac92hd83xxx_pwr_nids[7] = { 0x0a, 0x0b, 0x0c, 0xd, 0x0e, 0x0f, 0x10 }; static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { 0x1e, 0, }; static const hda_nid_t stac92hd83xxx_dmic_nids[] = { 0x11, 0x20, }; static const hda_nid_t stac92hd71bxx_pwr_nids[3] = { 0x0a, 0x0d, 0x0f }; static const hda_nid_t stac92hd71bxx_adc_nids[2] = { 0x12, 0x13, }; static const hda_nid_t stac92hd71bxx_mux_nids[2] = { 0x1a, 0x1b }; static const hda_nid_t stac92hd71bxx_dmux_nids[2] = { 0x1c, 0x1d, }; static const hda_nid_t stac92hd71bxx_smux_nids[2] = { 0x24, 0x25, }; #define STAC92HD71BXX_NUM_DMICS 2 static const hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = { 0x18, 0x19, 0 }; static const hda_nid_t stac92hd71bxx_dmic_5port_nids[STAC92HD71BXX_NUM_DMICS] = { 0x18, 0 }; static const hda_nid_t stac92hd71bxx_slave_dig_outs[2] = { 0x22, 0 }; #define STAC92HD71BXX_NUM_CAPS 2 static const unsigned long stac92hd71bxx_capvols[] = { HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), }; #define stac92hd71bxx_capsws stac92hd71bxx_capvols static const hda_nid_t stac925x_adc_nids[1] = { 0x03, }; static const hda_nid_t stac925x_mux_nids[1] = { 0x0f, }; static const hda_nid_t stac925x_dac_nids[1] = { 0x02, }; #define STAC925X_NUM_DMICS 1 static const hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = { 0x15, 0 }; static const hda_nid_t stac925x_dmux_nids[1] = { 0x14, }; static const unsigned long stac925x_capvols[] = { HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), }; static const unsigned long stac925x_capsws[] = { HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), }; static const hda_nid_t stac922x_adc_nids[2] = { 0x06, 0x07, }; static const hda_nid_t stac922x_mux_nids[2] = { 0x12, 0x13, }; #define STAC922X_NUM_CAPS 2 static const unsigned long stac922x_capvols[] = { HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT), HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), }; #define stac922x_capsws stac922x_capvols static const hda_nid_t stac927x_slave_dig_outs[2] = { 0x1f, 0, }; static const hda_nid_t stac927x_adc_nids[3] = { 0x07, 0x08, 0x09 }; static const hda_nid_t stac927x_mux_nids[3] = { 0x15, 0x16, 0x17 }; static const hda_nid_t stac927x_smux_nids[1] = { 0x21, }; static const hda_nid_t stac927x_dac_nids[6] = { 0x02, 0x03, 0x04, 0x05, 0x06, 0 }; static const hda_nid_t stac927x_dmux_nids[1] = { 0x1b, }; #define STAC927X_NUM_DMICS 2 static const hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = { 0x13, 0x14, 0 }; #define STAC927X_NUM_CAPS 3 static const unsigned long stac927x_capvols[] = { HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), HDA_COMPOSE_AMP_VAL(0x19, 3, 0, HDA_INPUT), HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_INPUT), }; static const unsigned long stac927x_capsws[] = { HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), }; static const char * const stac927x_spdif_labels[5] = { "Digital Playback", "ADAT", "Analog Mux 1", "Analog Mux 2", "Analog Mux 3" }; static const hda_nid_t stac9205_adc_nids[2] = { 0x12, 0x13 }; static const hda_nid_t stac9205_mux_nids[2] = { 0x19, 0x1a }; static const hda_nid_t stac9205_dmux_nids[1] = { 0x1d, }; static const hda_nid_t stac9205_smux_nids[1] = { 0x21, }; #define STAC9205_NUM_DMICS 2 static const hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { 0x17, 0x18, 0 }; #define STAC9205_NUM_CAPS 2 static const unsigned long stac9205_capvols[] = { HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT), HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT), }; static const unsigned long stac9205_capsws[] = { HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT), }; static const hda_nid_t stac9200_pin_nids[8] = { 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, }; static const hda_nid_t stac925x_pin_nids[8] = { 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0x0d, 0x10, 0x11, }; static const hda_nid_t stac922x_pin_nids[10] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x15, 0x1b, }; static const hda_nid_t stac92hd73xx_pin_nids[13] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x22, 0x23 }; #define STAC92HD71BXX_NUM_PINS 13 static const hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x00, 0x00, 0x14, 0x18, 0x19, 0x1e, 0x1f, 0x20, 0x27 }; static const hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x14, 0x18, 0x19, 0x1e, 0x1f, 0x20, 0x27 }; static const hda_nid_t stac927x_pin_nids[14] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, }; static const hda_nid_t stac9205_pin_nids[12] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x14, 0x16, 0x17, 0x18, 0x21, 0x22, }; static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; return snd_hda_input_mux_info(spec->dinput_mux, uinfo); } static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); ucontrol->value.enumerated.item[0] = spec->cur_dmux[dmux_idx]; return 0; } static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol, spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]); } static int stac92xx_smux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; return snd_hda_input_mux_info(spec->sinput_mux, uinfo); } static int stac92xx_smux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx]; return 0; } static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; struct hda_input_mux *smux = &spec->private_smux; unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); int err, val; hda_nid_t nid; err = snd_hda_input_mux_put(codec, spec->sinput_mux, ucontrol, spec->smux_nids[smux_idx], &spec->cur_smux[smux_idx]); if (err < 0) return err; if (spec->spdif_mute) { if (smux_idx == 0) nid = spec->multiout.dig_out_nid; else nid = codec->slave_dig_outs[smux_idx - 1]; if (spec->cur_smux[smux_idx] == smux->num_items - 1) val = HDA_AMP_MUTE; else val = 0; /* un/mute SPDIF out */ snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE, val); } return 0; } static int stac_vrefout_set(struct hda_codec *codec, hda_nid_t nid, unsigned int new_vref) { int error, pinctl; snd_printdd("%s, nid %x ctl %x\n", __func__, nid, new_vref); pinctl = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); if (pinctl < 0) return pinctl; pinctl &= 0xff; pinctl &= ~AC_PINCTL_VREFEN; pinctl |= (new_vref & AC_PINCTL_VREFEN); error = snd_hda_set_pin_ctl_cache(codec, nid, pinctl); if (error < 0) return error; return 1; } static unsigned int stac92xx_vref_set(struct hda_codec *codec, hda_nid_t nid, unsigned int new_vref) { int error; unsigned int pincfg; pincfg = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); pincfg &= 0xff; pincfg &= ~(AC_PINCTL_VREFEN | AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); pincfg |= new_vref; if (new_vref == AC_PINCTL_VREF_HIZ) pincfg |= AC_PINCTL_OUT_EN; else pincfg |= AC_PINCTL_IN_EN; error = snd_hda_set_pin_ctl_cache(codec, nid, pincfg); if (error < 0) return error; else return 1; } static unsigned int stac92xx_vref_get(struct hda_codec *codec, hda_nid_t nid) { unsigned int vref; vref = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); vref &= AC_PINCTL_VREFEN; return vref; } static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; return snd_hda_input_mux_info(spec->input_mux, uinfo); } static int stac92xx_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; return 0; } static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); const struct hda_input_mux *imux = spec->input_mux; unsigned int idx, prev_idx, didx; idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; prev_idx = spec->cur_mux[adc_idx]; if (prev_idx == idx) return 0; if (idx < spec->num_analog_muxes) { snd_hda_codec_write_cache(codec, spec->mux_nids[adc_idx], 0, AC_VERB_SET_CONNECT_SEL, imux->items[idx].index); if (prev_idx >= spec->num_analog_muxes && spec->mux_nids[adc_idx] != spec->dmux_nids[adc_idx]) { imux = spec->dinput_mux; /* 0 = analog */ snd_hda_codec_write_cache(codec, spec->dmux_nids[adc_idx], 0, AC_VERB_SET_CONNECT_SEL, imux->items[0].index); } } else { imux = spec->dinput_mux; /* first dimux item is hardcoded to select analog imux, * so lets skip it */ didx = idx - spec->num_analog_muxes + 1; snd_hda_codec_write_cache(codec, spec->dmux_nids[adc_idx], 0, AC_VERB_SET_CONNECT_SEL, imux->items[didx].index); } spec->cur_mux[adc_idx] = idx; return 1; } static int stac92xx_mono_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; return snd_hda_input_mux_info(spec->mono_mux, uinfo); } static int stac92xx_mono_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; ucontrol->value.enumerated.item[0] = spec->cur_mmux; return 0; } static int stac92xx_mono_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; return snd_hda_input_mux_put(codec, spec->mono_mux, ucontrol, spec->mono_nid, &spec->cur_mmux); } #define stac92xx_aloopback_info snd_ctl_boolean_mono_info static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); struct sigmatel_spec *spec = codec->spec; ucontrol->value.integer.value[0] = !!(spec->aloopback & (spec->aloopback_mask << idx)); return 0; } static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); unsigned int dac_mode; unsigned int val, idx_val; idx_val = spec->aloopback_mask << idx; if (ucontrol->value.integer.value[0]) val = spec->aloopback | idx_val; else val = spec->aloopback & ~idx_val; if (spec->aloopback == val) return 0; spec->aloopback = val; /* Only return the bits defined by the shift value of the * first two bytes of the mask */ dac_mode = snd_hda_codec_read(codec, codec->afg, 0, kcontrol->private_value & 0xFFFF, 0x0); dac_mode >>= spec->aloopback_shift; if (spec->aloopback & idx_val) { snd_hda_power_up(codec); dac_mode |= idx_val; } else { snd_hda_power_down(codec); dac_mode &= ~idx_val; } snd_hda_codec_write_cache(codec, codec->afg, 0, kcontrol->private_value >> 16, dac_mode); return 1; } static const struct hda_verb stac9200_core_init[] = { /* set dac0mux for dac converter */ { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, {} }; static const struct hda_verb stac9200_eapd_init[] = { /* set dac0mux for dac converter */ {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, {} }; static const struct hda_verb dell_eq_core_init[] = { /* set master volume to max value without distortion * and direct control */ { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, {} }; static const struct hda_verb stac92hd73xx_core_init[] = { /* set master volume and direct control */ { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, {} }; static const struct hda_verb stac92hd83xxx_core_init[] = { /* power state controls amps */ { 0x01, AC_VERB_SET_EAPD, 1 << 2}, {} }; static const struct hda_verb stac92hd83xxx_hp_zephyr_init[] = { { 0x22, 0x785, 0x43 }, { 0x22, 0x782, 0xe0 }, { 0x22, 0x795, 0x00 }, {} }; static const struct hda_verb stac92hd71bxx_core_init[] = { /* set master volume and direct control */ { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, {} }; static const struct hda_verb stac92hd71bxx_unmute_core_init[] = { /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */ { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {} }; static const struct hda_verb stac925x_core_init[] = { /* set dac0mux for dac converter */ { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, /* mute the master volume */ { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, {} }; static const struct hda_verb stac922x_core_init[] = { /* set master volume and direct control */ { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, {} }; static const struct hda_verb d965_core_init[] = { /* set master volume and direct control */ { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, /* unmute node 0x1b */ { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, /* select node 0x03 as DAC */ { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01}, {} }; static const struct hda_verb dell_3st_core_init[] = { /* don't set delta bit */ {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f}, /* unmute node 0x1b */ {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, /* select node 0x03 as DAC */ {0x0b, AC_VERB_SET_CONNECT_SEL, 0x01}, {} }; static const struct hda_verb stac927x_core_init[] = { /* set master volume and direct control */ { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, /* enable analog pc beep path */ { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, {} }; static const struct hda_verb stac927x_volknob_core_init[] = { /* don't set delta bit */ {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f}, /* enable analog pc beep path */ {0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, {} }; static const struct hda_verb stac9205_core_init[] = { /* set master volume and direct control */ { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, /* enable analog pc beep path */ { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, {} }; #define STAC_MONO_MUX \ { \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = "Mono Mux", \ .count = 1, \ .info = stac92xx_mono_mux_enum_info, \ .get = stac92xx_mono_mux_enum_get, \ .put = stac92xx_mono_mux_enum_put, \ } #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \ { \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = "Analog Loopback", \ .count = cnt, \ .info = stac92xx_aloopback_info, \ .get = stac92xx_aloopback_get, \ .put = stac92xx_aloopback_put, \ .private_value = verb_read | (verb_write << 16), \ } #define DC_BIAS(xname, idx, nid) \ { \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = idx, \ .info = stac92xx_dc_bias_info, \ .get = stac92xx_dc_bias_get, \ .put = stac92xx_dc_bias_put, \ .private_value = nid, \ } static const struct snd_kcontrol_new stac9200_mixer[] = { HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xb, 0, HDA_OUTPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0xb, 0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), { } /* end */ }; static const struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = { STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), {} }; static const struct snd_kcontrol_new stac92hd73xx_8ch_loopback[] = { STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4), {} }; static const struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = { STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5), {} }; static const struct snd_kcontrol_new stac92hd71bxx_loopback[] = { STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) }; static const struct snd_kcontrol_new stac925x_mixer[] = { HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xe, 0, HDA_OUTPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x0e, 0, HDA_OUTPUT), { } /* end */ }; static const struct snd_kcontrol_new stac9205_loopback[] = { STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1), {} }; static const struct snd_kcontrol_new stac927x_loopback[] = { STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), {} }; static struct snd_kcontrol_new stac_dmux_mixer = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Digital Input Source", /* count set later */ .info = stac92xx_dmux_enum_info, .get = stac92xx_dmux_enum_get, .put = stac92xx_dmux_enum_put, }; static struct snd_kcontrol_new stac_smux_mixer = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "IEC958 Playback Source", /* count set later */ .info = stac92xx_smux_enum_info, .get = stac92xx_smux_enum_get, .put = stac92xx_smux_enum_put, }; static const char * const slave_pfxs[] = { "Front", "Surround", "Center", "LFE", "Side", "Headphone", "Speaker", "IEC958", NULL }; static void stac92xx_update_led_status(struct hda_codec *codec, int enabled); static void stac92xx_vmaster_hook(void *private_data, int val) { stac92xx_update_led_status(private_data, val); } static void stac92xx_free_kctls(struct hda_codec *codec); static int stac92xx_build_controls(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; unsigned int vmaster_tlv[4]; int err; int i; if (spec->mixer) { err = snd_hda_add_new_ctls(codec, spec->mixer); if (err < 0) return err; } for (i = 0; i < spec->num_mixers; i++) { err = snd_hda_add_new_ctls(codec, spec->mixers[i]); if (err < 0) return err; } if (!spec->auto_mic && spec->num_dmuxes > 0 && snd_hda_get_bool_hint(codec, "separate_dmux") == 1) { stac_dmux_mixer.count = spec->num_dmuxes; err = snd_hda_ctl_add(codec, 0, snd_ctl_new1(&stac_dmux_mixer, codec)); if (err < 0) return err; } if (spec->num_smuxes > 0) { int wcaps = get_wcaps(codec, spec->multiout.dig_out_nid); struct hda_input_mux *smux = &spec->private_smux; /* check for mute support on SPDIF out */ if (wcaps & AC_WCAP_OUT_AMP) { snd_hda_add_imux_item(smux, "Off", 0, NULL); spec->spdif_mute = 1; } stac_smux_mixer.count = spec->num_smuxes; err = snd_hda_ctl_add(codec, 0, snd_ctl_new1(&stac_smux_mixer, codec)); if (err < 0) return err; } if (spec->multiout.dig_out_nid) { err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid, spec->multiout.dig_out_nid); if (err < 0) return err; err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); if (err < 0) return err; spec->multiout.share_spdif = 1; } if (spec->dig_in_nid && !(spec->gpio_dir & 0x01)) { err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); if (err < 0) return err; } /* if we have no master control, let's create it */ snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], HDA_OUTPUT, vmaster_tlv); /* correct volume offset */ vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset; /* minimum value is actually mute */ vmaster_tlv[3] |= TLV_DB_SCALE_MUTE; err = snd_hda_add_vmaster(codec, "Master Playback Volume", vmaster_tlv, slave_pfxs, "Playback Volume"); if (err < 0) return err; err = __snd_hda_add_vmaster(codec, "Master Playback Switch", NULL, slave_pfxs, "Playback Switch", true, &spec->vmaster_mute.sw_kctl); if (err < 0) return err; if (spec->gpio_led) { spec->vmaster_mute.hook = stac92xx_vmaster_hook; err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true); if (err < 0) return err; } if (spec->aloopback_ctl && snd_hda_get_bool_hint(codec, "loopback") == 1) { err = snd_hda_add_new_ctls(codec, spec->aloopback_ctl); if (err < 0) return err; } stac92xx_free_kctls(codec); /* no longer needed */ err = snd_hda_jack_add_kctls(codec, &spec->autocfg); if (err < 0) return err; return 0; } static const unsigned int ref9200_pin_configs[8] = { 0x01c47010, 0x01447010, 0x0221401f, 0x01114010, 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, }; static const unsigned int gateway9200_m4_pin_configs[8] = { 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, }; static const unsigned int gateway9200_m4_2_pin_configs[8] = { 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, }; /* STAC 9200 pin configs for 102801A8 102801DE 102801E8 */ static const unsigned int dell9200_d21_pin_configs[8] = { 0x400001f0, 0x400001f1, 0x02214030, 0x01014010, 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, }; /* STAC 9200 pin configs for 102801C0 102801C1 */ static const unsigned int dell9200_d22_pin_configs[8] = { 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, 0x01813020, 0x02a19021, 0x90100140, 0x400001f2, }; /* STAC 9200 pin configs for 102801C4 (Dell Dimension E310) 102801C5 102801C7 102801D9 102801DA 102801E3 */ static const unsigned int dell9200_d23_pin_configs[8] = { 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, 0x01813020, 0x01a19021, 0x90100140, 0x400001f2, }; /* STAC 9200-32 pin configs for 102801B5 (Dell Inspiron 630m) 102801D8 (Dell Inspiron 640m) */ static const unsigned int dell9200_m21_pin_configs[8] = { 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310, 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd, }; /* STAC 9200-32 pin configs for 102801C2 (Dell Latitude D620) 102801C8 102801CC (Dell Latitude D820) 102801D4 102801D6 */ static const unsigned int dell9200_m22_pin_configs[8] = { 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310, 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc, }; /* STAC 9200-32 pin configs for 102801CE (Dell XPS M1710) 102801CF (Dell Precision M90) */ static const unsigned int dell9200_m23_pin_configs[8] = { 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310, 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc, }; /* STAC 9200-32 pin configs for 102801C9 102801CA 102801CB (Dell Latitude 120L) 102801D3 */ static const unsigned int dell9200_m24_pin_configs[8] = { 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310, 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe, }; /* STAC 9200-32 pin configs for 102801BD (Dell Inspiron E1505n) 102801EE 102801EF */ static const unsigned int dell9200_m25_pin_configs[8] = { 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd, }; /* STAC 9200-32 pin configs for 102801F5 (Dell Inspiron 1501) 102801F6 */ static const unsigned int dell9200_m26_pin_configs[8] = { 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310, 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe, }; /* STAC 9200-32 102801CD (Dell Inspiron E1705/9400) */ static const unsigned int dell9200_m27_pin_configs[8] = { 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc, }; static const unsigned int oqo9200_pin_configs[8] = { 0x40c000f0, 0x404000f1, 0x0221121f, 0x02211210, 0x90170111, 0x90a70120, 0x400000f2, 0x400000f3, }; static const unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { [STAC_REF] = ref9200_pin_configs, [STAC_9200_OQO] = oqo9200_pin_configs, [STAC_9200_DELL_D21] = dell9200_d21_pin_configs, [STAC_9200_DELL_D22] = dell9200_d22_pin_configs, [STAC_9200_DELL_D23] = dell9200_d23_pin_configs, [STAC_9200_DELL_M21] = dell9200_m21_pin_configs, [STAC_9200_DELL_M22] = dell9200_m22_pin_configs, [STAC_9200_DELL_M23] = dell9200_m23_pin_configs, [STAC_9200_DELL_M24] = dell9200_m24_pin_configs, [STAC_9200_DELL_M25] = dell9200_m25_pin_configs, [STAC_9200_DELL_M26] = dell9200_m26_pin_configs, [STAC_9200_DELL_M27] = dell9200_m27_pin_configs, [STAC_9200_M4] = gateway9200_m4_pin_configs, [STAC_9200_M4_2] = gateway9200_m4_2_pin_configs, [STAC_9200_PANASONIC] = ref9200_pin_configs, }; static const char * const stac9200_models[STAC_9200_MODELS] = { [STAC_AUTO] = "auto", [STAC_REF] = "ref", [STAC_9200_OQO] = "oqo", [STAC_9200_DELL_D21] = "dell-d21", [STAC_9200_DELL_D22] = "dell-d22", [STAC_9200_DELL_D23] = "dell-d23", [STAC_9200_DELL_M21] = "dell-m21", [STAC_9200_DELL_M22] = "dell-m22", [STAC_9200_DELL_M23] = "dell-m23", [STAC_9200_DELL_M24] = "dell-m24", [STAC_9200_DELL_M25] = "dell-m25", [STAC_9200_DELL_M26] = "dell-m26", [STAC_9200_DELL_M27] = "dell-m27", [STAC_9200_M4] = "gateway-m4", [STAC_9200_M4_2] = "gateway-m4-2", [STAC_9200_PANASONIC] = "panasonic", }; static const struct snd_pci_quirk stac9200_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF), /* Dell laptops have BIOS problem */ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8, "unknown Dell", STAC_9200_DELL_D21), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5, "Dell Inspiron 630m", STAC_9200_DELL_M21), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd, "Dell Inspiron E1505n", STAC_9200_DELL_M25), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0, "unknown Dell", STAC_9200_DELL_D22), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1, "unknown Dell", STAC_9200_DELL_D22), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2, "Dell Latitude D620", STAC_9200_DELL_M22), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5, "unknown Dell", STAC_9200_DELL_D23), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7, "unknown Dell", STAC_9200_DELL_D23), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8, "unknown Dell", STAC_9200_DELL_M22), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9, "unknown Dell", STAC_9200_DELL_M24), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca, "unknown Dell", STAC_9200_DELL_M24), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb, "Dell Latitude 120L", STAC_9200_DELL_M24), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc, "Dell Latitude D820", STAC_9200_DELL_M22), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd, "Dell Inspiron E1705/9400", STAC_9200_DELL_M27), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce, "Dell XPS M1710", STAC_9200_DELL_M23), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf, "Dell Precision M90", STAC_9200_DELL_M23), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3, "unknown Dell", STAC_9200_DELL_M22), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4, "unknown Dell", STAC_9200_DELL_M22), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6, "unknown Dell", STAC_9200_DELL_M22), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8, "Dell Inspiron 640m", STAC_9200_DELL_M21), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9, "unknown Dell", STAC_9200_DELL_D23), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da, "unknown Dell", STAC_9200_DELL_D23), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de, "unknown Dell", STAC_9200_DELL_D21), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3, "unknown Dell", STAC_9200_DELL_D23), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8, "unknown Dell", STAC_9200_DELL_D21), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee, "unknown Dell", STAC_9200_DELL_M25), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef, "unknown Dell", STAC_9200_DELL_M25), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5, "Dell Inspiron 1501", STAC_9200_DELL_M26), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6, "unknown Dell", STAC_9200_DELL_M26), /* Panasonic */ SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC), /* Gateway machines needs EAPD to be set on resume */ SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_M4), SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", STAC_9200_M4_2), SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", STAC_9200_M4_2), /* OQO Mobile */ SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO), {} /* terminator */ }; static const unsigned int ref925x_pin_configs[8] = { 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, 0x90a70320, 0x02214210, 0x01019020, 0x9033032e, }; static const unsigned int stac925xM1_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, }; static const unsigned int stac925xM1_2_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, }; static const unsigned int stac925xM2_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, }; static const unsigned int stac925xM2_2_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, }; static const unsigned int stac925xM3_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x503303f3, }; static const unsigned int stac925xM5_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, }; static const unsigned int stac925xM6_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x90330320, }; static const unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { [STAC_REF] = ref925x_pin_configs, [STAC_M1] = stac925xM1_pin_configs, [STAC_M1_2] = stac925xM1_2_pin_configs, [STAC_M2] = stac925xM2_pin_configs, [STAC_M2_2] = stac925xM2_2_pin_configs, [STAC_M3] = stac925xM3_pin_configs, [STAC_M5] = stac925xM5_pin_configs, [STAC_M6] = stac925xM6_pin_configs, }; static const char * const stac925x_models[STAC_925x_MODELS] = { [STAC_925x_AUTO] = "auto", [STAC_REF] = "ref", [STAC_M1] = "m1", [STAC_M1_2] = "m1-2", [STAC_M2] = "m2", [STAC_M2_2] = "m2-2", [STAC_M3] = "m3", [STAC_M5] = "m5", [STAC_M6] = "m6", }; static const struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2), SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5), SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1), SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_M2), SND_PCI_QUIRK(0x107b, 0x0367, "Gateway MX6453", STAC_M1_2), /* Not sure about the brand name for those */ SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M1), SND_PCI_QUIRK(0x107b, 0x0507, "Gateway mobile", STAC_M3), SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M6), SND_PCI_QUIRK(0x107b, 0x0685, "Gateway mobile", STAC_M2_2), {} /* terminator */ }; static const struct snd_pci_quirk stac925x_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF), SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF), /* Default table for unknown ID */ SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2), {} /* terminator */ }; static const unsigned int ref92hd73xx_pin_configs[13] = { 0x02214030, 0x02a19040, 0x01a19020, 0x02214030, 0x0181302e, 0x01014010, 0x01014020, 0x01014030, 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050, 0x01452050, }; static const unsigned int dell_m6_pin_configs[13] = { 0x0321101f, 0x4f00000f, 0x4f0000f0, 0x90170110, 0x03a11020, 0x0321101f, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0, }; static const unsigned int alienware_m17x_pin_configs[13] = { 0x0321101f, 0x0321101f, 0x03a11020, 0x03014020, 0x90170110, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0, 0x904601b0, }; static const unsigned int intel_dg45id_pin_configs[13] = { 0x02214230, 0x02A19240, 0x01013214, 0x01014210, 0x01A19250, 0x01011212, 0x01016211 }; static const unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, [STAC_DELL_M6_AMIC] = dell_m6_pin_configs, [STAC_DELL_M6_DMIC] = dell_m6_pin_configs, [STAC_DELL_M6_BOTH] = dell_m6_pin_configs, [STAC_DELL_EQ] = dell_m6_pin_configs, [STAC_ALIENWARE_M17X] = alienware_m17x_pin_configs, [STAC_92HD73XX_INTEL] = intel_dg45id_pin_configs, }; static const char * const stac92hd73xx_models[STAC_92HD73XX_MODELS] = { [STAC_92HD73XX_AUTO] = "auto", [STAC_92HD73XX_NO_JD] = "no-jd", [STAC_92HD73XX_REF] = "ref", [STAC_92HD73XX_INTEL] = "intel", [STAC_DELL_M6_AMIC] = "dell-m6-amic", [STAC_DELL_M6_DMIC] = "dell-m6-dmic", [STAC_DELL_M6_BOTH] = "dell-m6", [STAC_DELL_EQ] = "dell-eq", [STAC_ALIENWARE_M17X] = "alienware", }; static const struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_92HD73XX_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_92HD73XX_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5002, "Intel DG45ID", STAC_92HD73XX_INTEL), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5003, "Intel DG45FC", STAC_92HD73XX_INTEL), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254, "Dell Studio 1535", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255, "unknown Dell", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256, "unknown Dell", STAC_DELL_M6_BOTH), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257, "unknown Dell", STAC_DELL_M6_BOTH), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e, "unknown Dell", STAC_DELL_M6_AMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f, "unknown Dell", STAC_DELL_M6_AMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271, "unknown Dell", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0272, "unknown Dell", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f, "Dell Studio 1537", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a0, "Dell Studio 17", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02be, "Dell Studio 1555", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd, "Dell Studio 1557", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe, "Dell Studio XPS 1645", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413, "Dell Studio 1558", STAC_DELL_M6_DMIC), {} /* terminator */ }; static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1, "Alienware M17x", STAC_ALIENWARE_M17X), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, "Alienware M17x", STAC_ALIENWARE_M17X), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490, "Alienware M17x R3", STAC_DELL_EQ), {} /* terminator */ }; static const unsigned int ref92hd83xxx_pin_configs[10] = { 0x02214030, 0x02211010, 0x02a19020, 0x02170130, 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, 0x01451160, 0x98560170, }; static const unsigned int dell_s14_pin_configs[10] = { 0x0221403f, 0x0221101f, 0x02a19020, 0x90170110, 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a60160, 0x40f000f0, 0x40f000f0, }; static const unsigned int dell_vostro_3500_pin_configs[10] = { 0x02a11020, 0x0221101f, 0x400000f0, 0x90170110, 0x400000f1, 0x400000f2, 0x400000f3, 0x90a60160, 0x400000f4, 0x400000f5, }; static const unsigned int hp_dv7_4000_pin_configs[10] = { 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, 0x40f000f0, 0x40f000f0, }; static const unsigned int hp_zephyr_pin_configs[10] = { 0x01813050, 0x0421201f, 0x04a1205e, 0x96130310, 0x96130310, 0x0101401f, 0x1111611f, 0xd5a30130, 0, 0, }; static const unsigned int hp_cNB11_intquad_pin_configs[10] = { 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110, 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130, 0x40f000f0, 0x40f000f0, }; static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, [STAC_DELL_S14] = dell_s14_pin_configs, [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs, [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, [STAC_HP_ZEPHYR] = hp_zephyr_pin_configs, }; static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { [STAC_92HD83XXX_AUTO] = "auto", [STAC_92HD83XXX_REF] = "ref", [STAC_92HD83XXX_PWR_REF] = "mic-ref", [STAC_DELL_S14] = "dell-s14", [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500", [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", [STAC_HP_DV7_4000] = "hp-dv7-4000", [STAC_HP_ZEPHYR] = "hp-zephyr", }; static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_92HD83XXX_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_92HD83XXX_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, "unknown Dell", STAC_DELL_S14), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028, "Dell Vostro 3500", STAC_DELL_VOSTRO_3500), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355B, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355C, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355D, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355E, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355F, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3560, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358B, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358C, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358D, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3591, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3592, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561, "HP", STAC_HP_ZEPHYR), {} /* terminator */ }; static const struct snd_pci_quirk stac92hd83xxx_codec_id_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561, "HP", STAC_HP_ZEPHYR), {} /* terminator */ }; static const unsigned int ref92hd71bxx_pin_configs[STAC92HD71BXX_NUM_PINS] = { 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0, 0x90a000f0, 0x01452050, 0x01452050, 0x00000000, 0x00000000 }; static const unsigned int dell_m4_1_pin_configs[STAC92HD71BXX_NUM_PINS] = { 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, 0x40f000f0, 0x4f0000f0, 0x4f0000f0, 0x00000000, 0x00000000 }; static const unsigned int dell_m4_2_pin_configs[STAC92HD71BXX_NUM_PINS] = { 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, 0x00000000 }; static const unsigned int dell_m4_3_pin_configs[STAC92HD71BXX_NUM_PINS] = { 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0, 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, 0x00000000 }; static const unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs, [STAC_DELL_M4_1] = dell_m4_1_pin_configs, [STAC_DELL_M4_2] = dell_m4_2_pin_configs, [STAC_DELL_M4_3] = dell_m4_3_pin_configs, [STAC_HP_M4] = NULL, [STAC_HP_DV4] = NULL, [STAC_HP_DV5] = NULL, [STAC_HP_HDX] = NULL, [STAC_HP_DV4_1222NR] = NULL, }; static const char * const stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { [STAC_92HD71BXX_AUTO] = "auto", [STAC_92HD71BXX_REF] = "ref", [STAC_DELL_M4_1] = "dell-m4-1", [STAC_DELL_M4_2] = "dell-m4-2", [STAC_DELL_M4_3] = "dell-m4-3", [STAC_HP_M4] = "hp-m4", [STAC_HP_DV4] = "hp-dv4", [STAC_HP_DV5] = "hp-dv5", [STAC_HP_HDX] = "hp-hdx", [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr", }; static const struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_92HD71BXX_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_92HD71BXX_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fb, "HP dv4-1222nr", STAC_HP_DV4_1222NR), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720, "HP", STAC_HP_DV5), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, "HP", STAC_HP_DV5), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, "HP dv4-7", STAC_HP_DV4), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600, "HP dv4-7", STAC_HP_DV5), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610, "HP HDX", STAC_HP_HDX), /* HDX18 */ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, "HP mini 1000", STAC_HP_M4), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b, "HP HDX", STAC_HP_HDX), /* HDX16 */ SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620, "HP dv6", STAC_HP_DV5), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061, "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x363e, "HP DV6", STAC_HP_DV5), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010, "HP", STAC_HP_DV5), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, "unknown Dell", STAC_DELL_M4_1), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, "unknown Dell", STAC_DELL_M4_1), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0250, "unknown Dell", STAC_DELL_M4_1), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024f, "unknown Dell", STAC_DELL_M4_1), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024d, "unknown Dell", STAC_DELL_M4_1), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0251, "unknown Dell", STAC_DELL_M4_1), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0277, "unknown Dell", STAC_DELL_M4_1), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0263, "unknown Dell", STAC_DELL_M4_2), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0265, "unknown Dell", STAC_DELL_M4_2), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0262, "unknown Dell", STAC_DELL_M4_2), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264, "unknown Dell", STAC_DELL_M4_2), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02aa, "unknown Dell", STAC_DELL_M4_3), {} /* terminator */ }; static const unsigned int ref922x_pin_configs[10] = { 0x01014010, 0x01016011, 0x01012012, 0x0221401f, 0x01813122, 0x01011014, 0x01441030, 0x01c41030, 0x40000100, 0x40000100, }; /* STAC 922X pin configs for 102801A7 102801AB 102801A9 102801D1 102801D2 */ static const unsigned int dell_922x_d81_pin_configs[10] = { 0x02214030, 0x01a19021, 0x01111012, 0x01114010, 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1, 0x01813122, 0x400001f2, }; /* STAC 922X pin configs for 102801AC 102801D0 */ static const unsigned int dell_922x_d82_pin_configs[10] = { 0x02214030, 0x01a19021, 0x01111012, 0x01114010, 0x02a19020, 0x01117011, 0x01451140, 0x400001f0, 0x01813122, 0x400001f1, }; /* STAC 922X pin configs for 102801BF */ static const unsigned int dell_922x_m81_pin_configs[10] = { 0x0321101f, 0x01112024, 0x01111222, 0x91174220, 0x03a11050, 0x01116221, 0x90a70330, 0x01452340, 0x40C003f1, 0x405003f0, }; /* STAC 9221 A1 pin configs for 102801D7 (Dell XPS M1210) */ static const unsigned int dell_922x_m82_pin_configs[10] = { 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310, 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, 0x508003f3, 0x405003f4, }; static const unsigned int d945gtp3_pin_configs[10] = { 0x0221401f, 0x01a19022, 0x01813021, 0x01014010, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x02a19120, 0x40000100, }; static const unsigned int d945gtp5_pin_configs[10] = { 0x0221401f, 0x01011012, 0x01813024, 0x01014010, 0x01a19021, 0x01016011, 0x01452130, 0x40000100, 0x02a19320, 0x40000100, }; static const unsigned int intel_mac_v1_pin_configs[10] = { 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd, 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240, 0x400000fc, 0x400000fb, }; static const unsigned int intel_mac_v2_pin_configs[10] = { 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa, 0x400000fc, 0x400000fb, }; static const unsigned int intel_mac_v3_pin_configs[10] = { 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240, 0x400000fc, 0x400000fb, }; static const unsigned int intel_mac_v4_pin_configs[10] = { 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, 0x400000fc, 0x400000fb, }; static const unsigned int intel_mac_v5_pin_configs[10] = { 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, 0x400000fc, 0x400000fb, }; static const unsigned int ecs202_pin_configs[10] = { 0x0221401f, 0x02a19020, 0x01a19020, 0x01114010, 0x408000f0, 0x01813022, 0x074510a0, 0x40c400f1, 0x9037012e, 0x40e000f2, }; static const unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { [STAC_D945_REF] = ref922x_pin_configs, [STAC_D945GTP3] = d945gtp3_pin_configs, [STAC_D945GTP5] = d945gtp5_pin_configs, [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs, [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs, [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs, [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs, [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs, [STAC_INTEL_MAC_AUTO] = intel_mac_v3_pin_configs, /* for backward compatibility */ [STAC_MACMINI] = intel_mac_v3_pin_configs, [STAC_MACBOOK] = intel_mac_v5_pin_configs, [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs, [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs, [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs, [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs, [STAC_ECS_202] = ecs202_pin_configs, [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs, [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs, [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs, [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs, }; static const char * const stac922x_models[STAC_922X_MODELS] = { [STAC_922X_AUTO] = "auto", [STAC_D945_REF] = "ref", [STAC_D945GTP5] = "5stack", [STAC_D945GTP3] = "3stack", [STAC_INTEL_MAC_V1] = "intel-mac-v1", [STAC_INTEL_MAC_V2] = "intel-mac-v2", [STAC_INTEL_MAC_V3] = "intel-mac-v3", [STAC_INTEL_MAC_V4] = "intel-mac-v4", [STAC_INTEL_MAC_V5] = "intel-mac-v5", [STAC_INTEL_MAC_AUTO] = "intel-mac-auto", /* for backward compatibility */ [STAC_MACMINI] = "macmini", [STAC_MACBOOK] = "macbook", [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1", [STAC_MACBOOK_PRO_V2] = "macbook-pro", [STAC_IMAC_INTEL] = "imac-intel", [STAC_IMAC_INTEL_20] = "imac-intel-20", [STAC_ECS_202] = "ecs202", [STAC_922X_DELL_D81] = "dell-d81", [STAC_922X_DELL_D82] = "dell-d82", [STAC_922X_DELL_M81] = "dell-m81", [STAC_922X_DELL_M82] = "dell-m82", }; static const struct snd_pci_quirk stac922x_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_D945_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_D945_REF), /* Intel 945G based systems */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101, "Intel D945G", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202, "Intel D945G", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606, "Intel D945G", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601, "Intel D945G", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111, "Intel D945G", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115, "Intel D945G", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116, "Intel D945G", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117, "Intel D945G", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118, "Intel D945G", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119, "Intel D945G", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826, "Intel D945G", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049, "Intel D945G", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055, "Intel D945G", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048, "Intel D945G", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110, "Intel D945G", STAC_D945GTP3), /* Intel D945G 5-stack systems */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404, "Intel D945G", STAC_D945GTP5), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303, "Intel D945G", STAC_D945GTP5), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013, "Intel D945G", STAC_D945GTP5), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417, "Intel D945G", STAC_D945GTP5), /* Intel 945P based systems */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b, "Intel D945P", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112, "Intel D945P", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d, "Intel D945P", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909, "Intel D945P", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505, "Intel D945P", STAC_D945GTP3), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707, "Intel D945P", STAC_D945GTP5), /* other intel */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0204, "Intel D945", STAC_D945_REF), /* other systems */ /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */ SND_PCI_QUIRK(0x8384, 0x7680, "Mac", STAC_INTEL_MAC_AUTO), /* Dell systems */ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7, "unknown Dell", STAC_922X_DELL_D81), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9, "unknown Dell", STAC_922X_DELL_D81), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab, "unknown Dell", STAC_922X_DELL_D81), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac, "unknown Dell", STAC_922X_DELL_D82), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf, "unknown Dell", STAC_922X_DELL_M81), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0, "unknown Dell", STAC_922X_DELL_D82), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1, "unknown Dell", STAC_922X_DELL_D81), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2, "unknown Dell", STAC_922X_DELL_D81), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7, "Dell XPS M1210", STAC_922X_DELL_M82), /* ECS/PC Chips boards */ SND_PCI_QUIRK_MASK(0x1019, 0xf000, 0x2000, "ECS/PC chips", STAC_ECS_202), {} /* terminator */ }; static const unsigned int ref927x_pin_configs[14] = { 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, 0x01a19040, 0x01011012, 0x01016011, 0x0101201f, 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070, 0x01c42190, 0x40000100, }; static const unsigned int d965_3st_pin_configs[14] = { 0x0221401f, 0x02a19120, 0x40000100, 0x01014011, 0x01a19021, 0x01813024, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x40000100 }; static const unsigned int d965_5st_pin_configs[14] = { 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, 0x01a19040, 0x01011012, 0x01016011, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x01442070, 0x40000100, 0x40000100 }; static const unsigned int d965_5st_no_fp_pin_configs[14] = { 0x40000100, 0x40000100, 0x0181304e, 0x01014010, 0x01a19040, 0x01011012, 0x01016011, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x01442070, 0x40000100, 0x40000100 }; static const unsigned int dell_3st_pin_configs[14] = { 0x02211230, 0x02a11220, 0x01a19040, 0x01114210, 0x01111212, 0x01116211, 0x01813050, 0x01112214, 0x403003fa, 0x90a60040, 0x90a60040, 0x404003fb, 0x40c003fc, 0x40000100 }; static const unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { [STAC_D965_REF_NO_JD] = ref927x_pin_configs, [STAC_D965_REF] = ref927x_pin_configs, [STAC_D965_3ST] = d965_3st_pin_configs, [STAC_D965_5ST] = d965_5st_pin_configs, [STAC_D965_5ST_NO_FP] = d965_5st_no_fp_pin_configs, [STAC_DELL_3ST] = dell_3st_pin_configs, [STAC_DELL_BIOS] = NULL, [STAC_927X_VOLKNOB] = NULL, }; static const char * const stac927x_models[STAC_927X_MODELS] = { [STAC_927X_AUTO] = "auto", [STAC_D965_REF_NO_JD] = "ref-no-jd", [STAC_D965_REF] = "ref", [STAC_D965_3ST] = "3stack", [STAC_D965_5ST] = "5stack", [STAC_D965_5ST_NO_FP] = "5stack-no-fp", [STAC_DELL_3ST] = "dell-3stack", [STAC_DELL_BIOS] = "dell-bios", [STAC_927X_VOLKNOB] = "volknob", }; static const struct snd_pci_quirk stac927x_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_D965_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_D965_REF), /* Intel 946 based systems */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST), /* 965 based 3 stack systems */ SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2100, "Intel D965", STAC_D965_3ST), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000, "Intel D965", STAC_D965_3ST), /* Dell 3 stack systems */ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST), /* Dell 3 stack systems with verb table in BIOS */ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS), /* 965 based 5 stack systems */ SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2300, "Intel D965", STAC_D965_5ST), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500, "Intel D965", STAC_D965_5ST), /* volume-knob fixes */ SND_PCI_QUIRK_VENDOR(0x10cf, "FSC", STAC_927X_VOLKNOB), {}