diff options
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 1499 |
1 files changed, 809 insertions, 690 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6990cfcb6a3..6b0bc040c3b 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -28,6 +28,7 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/pci.h> +#include <linux/dmi.h> #include <sound/core.h> #include <sound/asoundef.h> #include <sound/jack.h> @@ -40,6 +41,8 @@ enum { STAC_INSERT_EVENT, STAC_PWR_EVENT, STAC_HP_EVENT, + STAC_LO_EVENT, + STAC_MIC_EVENT, }; enum { @@ -81,6 +84,7 @@ enum { STAC_DELL_M6_DMIC, STAC_DELL_M6_BOTH, STAC_DELL_EQ, + STAC_ALIENWARE_M17X, STAC_92HD73XX_MODELS }; @@ -89,6 +93,7 @@ enum { STAC_92HD83XXX_REF, STAC_92HD83XXX_PWR_REF, STAC_DELL_S14, + STAC_92HD83XXX_HP, STAC_92HD83XXX_MODELS }; @@ -155,6 +160,7 @@ enum { STAC_D965_5ST_NO_FP, STAC_DELL_3ST, STAC_DELL_BIOS, + STAC_927X_VOLKNOB, STAC_927X_MODELS }; @@ -177,6 +183,12 @@ struct sigmatel_jack { struct snd_jack *jack; }; +struct sigmatel_mic_route { + hda_nid_t pin; + signed char mux_idx; + signed char dmux_idx; +}; + struct sigmatel_spec { struct snd_kcontrol_new *mixers[4]; unsigned int num_mixers; @@ -188,6 +200,7 @@ struct sigmatel_spec { unsigned int hp_detect: 1; unsigned int spdif_mute: 1; unsigned int check_volume_offset:1; + unsigned int auto_mic:1; /* gpio lines */ unsigned int eapd_mask; @@ -219,7 +232,6 @@ struct sigmatel_spec { /* playback */ struct hda_input_mux *mono_mux; - struct hda_input_mux *amp_mux; unsigned int cur_mmux; struct hda_multi_out multiout; hda_nid_t dac_nids[5]; @@ -239,6 +251,15 @@ struct sigmatel_spec { unsigned int num_dmuxes; hda_nid_t *smux_nids; unsigned int num_smuxes; + unsigned int num_analog_muxes; + + unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */ + 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; + const char **spdif_labels; hda_nid_t dig_in_nid; @@ -263,7 +284,6 @@ struct sigmatel_spec { unsigned int cur_smux[2]; unsigned int cur_amux; hda_nid_t *amp_nids; - unsigned int num_amps; unsigned int powerdown_adcs; /* i/o switches */ @@ -282,7 +302,6 @@ struct sigmatel_spec { struct hda_input_mux private_dimux; struct hda_input_mux private_imux; struct hda_input_mux private_smux; - struct hda_input_mux private_amp_mux; struct hda_input_mux private_mono_mux; }; @@ -311,11 +330,6 @@ static hda_nid_t stac92hd73xx_adc_nids[2] = { 0x1a, 0x1b }; -#define DELL_M6_AMP 2 -static hda_nid_t stac92hd73xx_amp_nids[3] = { - 0x0b, 0x0c, 0x0e -}; - #define STAC92HD73XX_NUM_DMICS 2 static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { 0x13, 0x14, 0 @@ -323,8 +337,8 @@ static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { #define STAC92HD73_DAC_COUNT 5 -static hda_nid_t stac92hd73xx_mux_nids[4] = { - 0x28, 0x29, 0x2a, 0x2b, +static hda_nid_t stac92hd73xx_mux_nids[2] = { + 0x20, 0x21, }; static hda_nid_t stac92hd73xx_dmux_nids[2] = { @@ -335,14 +349,16 @@ static hda_nid_t stac92hd73xx_smux_nids[2] = { 0x22, 0x23, }; -#define STAC92HD83XXX_NUM_DMICS 2 -static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { - 0x11, 0x12, 0 +#define STAC92HD73XX_NUM_CAPS 2 +static 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 hda_nid_t stac92hd83xxx_dmux_nids[2] = { +static hda_nid_t stac92hd83xxx_mux_nids[2] = { 0x17, 0x18, }; @@ -362,9 +378,12 @@ static unsigned int stac92hd83xxx_pwr_mapping[4] = { 0x03, 0x0c, 0x20, 0x40, }; -static hda_nid_t stac92hd83xxx_amp_nids[1] = { - 0xc, +#define STAC92HD83XXX_NUM_CAPS 2 +static unsigned long stac92hd83xxx_capvols[] = { + HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_OUTPUT), }; +#define stac92hd83xxx_capsws stac92hd83xxx_capvols static hda_nid_t stac92hd71bxx_pwr_nids[3] = { 0x0a, 0x0d, 0x0f @@ -395,6 +414,13 @@ static hda_nid_t stac92hd71bxx_slave_dig_outs[2] = { 0x22, 0 }; +#define STAC92HD71BXX_NUM_CAPS 2 +static 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 hda_nid_t stac925x_adc_nids[1] = { 0x03, }; @@ -416,6 +442,13 @@ static hda_nid_t stac925x_dmux_nids[1] = { 0x14, }; +static unsigned long stac925x_capvols[] = { + HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), +}; +static unsigned long stac925x_capsws[] = { + HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), +}; + static hda_nid_t stac922x_adc_nids[2] = { 0x06, 0x07, }; @@ -424,6 +457,13 @@ static hda_nid_t stac922x_mux_nids[2] = { 0x12, 0x13, }; +#define STAC922X_NUM_CAPS 2 +static 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 hda_nid_t stac927x_slave_dig_outs[2] = { 0x1f, 0, }; @@ -453,6 +493,18 @@ static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = { 0x13, 0x14, 0 }; +#define STAC927X_NUM_CAPS 3 +static 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 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 *stac927x_spdif_labels[5] = { "Digital Playback", "ADAT", "Analog Mux 1", "Analog Mux 2", "Analog Mux 3" @@ -479,6 +531,16 @@ static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { 0x17, 0x18, 0 }; +#define STAC9205_NUM_CAPS 2 +static unsigned long stac9205_capvols[] = { + HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT), + HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT), +}; +static unsigned long stac9205_capsws[] = { + HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT), +}; + static hda_nid_t stac9200_pin_nids[8] = { 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, @@ -529,34 +591,6 @@ static hda_nid_t stac9205_pin_nids[12] = { 0x21, 0x22, }; -#define stac92xx_amp_volume_info snd_hda_mixer_amp_volume_info - -static int stac92xx_amp_volume_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; - hda_nid_t nid = spec->amp_nids[spec->cur_amux]; - - kcontrol->private_value ^= get_amp_nid(kcontrol); - kcontrol->private_value |= nid; - - return snd_hda_mixer_amp_volume_get(kcontrol, ucontrol); -} - -static int stac92xx_amp_volume_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; - hda_nid_t nid = spec->amp_nids[spec->cur_amux]; - - kcontrol->private_value ^= get_amp_nid(kcontrol); - kcontrol->private_value |= nid; - - return snd_hda_mixer_amp_volume_put(kcontrol, ucontrol); -} - static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -693,9 +727,35 @@ static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e 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); - - return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, - spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]); + const struct hda_input_mux *imux = spec->input_mux; + unsigned int idx, prev_idx; + + 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) { + 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; + snd_hda_codec_write_cache(codec, spec->dmux_nids[adc_idx], 0, + AC_VERB_SET_CONNECT_SEL, + imux->items[idx - 1].index); + } + spec->cur_mux[adc_idx] = idx; + return 1; } static int stac92xx_mono_mux_enum_info(struct snd_kcontrol *kcontrol, @@ -726,41 +786,6 @@ static int stac92xx_mono_mux_enum_put(struct snd_kcontrol *kcontrol, spec->mono_nid, &spec->cur_mmux); } -static int stac92xx_amp_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->amp_mux, uinfo); -} - -static int stac92xx_amp_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_amux; - return 0; -} - -static int stac92xx_amp_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; - struct snd_kcontrol *ctl = - snd_hda_find_mixer_ctl(codec, "Amp Capture Volume"); - if (!ctl) - return -EINVAL; - - snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE | - SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); - - return snd_hda_input_mux_put(codec, spec->amp_mux, ucontrol, - 0, &spec->cur_amux); -} - #define stac92xx_aloopback_info snd_ctl_boolean_mono_info static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol, @@ -828,92 +853,20 @@ static struct hda_verb stac9200_eapd_init[] = { {} }; -static struct hda_verb stac92hd73xx_6ch_core_init[] = { - /* set master volume and direct control */ - { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, - /* setup adcs to point to mixer */ - { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, - { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, - { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - /* setup import muxs */ - { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01}, - { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01}, - { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01}, - { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00}, - {} -}; - static 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}, - /* setup adcs to point to mixer */ - { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, - { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, - /* setup import muxs */ - { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01}, - { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01}, - { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01}, - { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00}, {} }; -static struct hda_verb dell_m6_core_init[] = { - { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, - /* setup adcs to point to mixer */ - { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, - { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, - /* setup import muxs */ - { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01}, - { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01}, - { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01}, - { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00}, - {} -}; - -static struct hda_verb stac92hd73xx_8ch_core_init[] = { - /* set master volume and direct control */ - { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, - /* setup adcs to point to mixer */ - { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, - { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, - { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - /* setup import muxs */ - { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01}, - { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01}, - { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01}, - { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x03}, - {} -}; - -static struct hda_verb stac92hd73xx_10ch_core_init[] = { +static struct hda_verb stac92hd73xx_core_init[] = { /* set master volume and direct control */ { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, - /* dac3 is connected to import3 mux */ - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f}, - /* setup adcs to point to mixer */ - { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, - { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, - { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - /* setup import muxs */ - { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01}, - { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01}, - { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01}, - { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x03}, {} }; static struct hda_verb stac92hd83xxx_core_init[] = { - { 0xa, AC_VERB_SET_CONNECT_SEL, 0x1}, - { 0xb, AC_VERB_SET_CONNECT_SEL, 0x1}, - { 0xd, AC_VERB_SET_CONNECT_SEL, 0x0}, - /* power state controls amps */ { 0x01, AC_VERB_SET_EAPD, 1 << 2}, {} @@ -925,19 +878,6 @@ static struct hda_verb stac92hd71bxx_core_init[] = { {} }; -#define HD_DISABLE_PORTF 1 -static struct hda_verb stac92hd71bxx_analog_core_init[] = { - /* start of config #1 */ - - /* connect port 0f to audio mixer */ - { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, - /* start of config #2 */ - - /* set master volume and direct control */ - { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, - {} -}; - static 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)}, @@ -970,6 +910,16 @@ static struct hda_verb d965_core_init[] = { {} }; +static 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 struct hda_verb stac927x_core_init[] = { /* set master volume and direct control */ { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, @@ -978,6 +928,14 @@ static struct hda_verb stac927x_core_init[] = { {} }; +static 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 struct hda_verb stac9205_core_init[] = { /* set master volume and direct control */ { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, @@ -996,31 +954,6 @@ static struct hda_verb stac9205_core_init[] = { .put = stac92xx_mono_mux_enum_put, \ } -#define STAC_AMP_MUX \ - { \ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = "Amp Selector Capture Switch", \ - .count = 1, \ - .info = stac92xx_amp_mux_enum_info, \ - .get = stac92xx_amp_mux_enum_get, \ - .put = stac92xx_amp_mux_enum_put, \ - } - -#define STAC_AMP_VOL(xname, nid, chs, idx, dir) \ - { \ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = 0, \ - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ - SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ - SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \ - .info = stac92xx_amp_volume_info, \ - .get = stac92xx_amp_volume_get, \ - .put = stac92xx_amp_volume_put, \ - .tlv = { .c = snd_hda_mixer_amp_tlv }, \ - .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \ - } - #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \ { \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ @@ -1051,34 +984,6 @@ static struct snd_kcontrol_new stac9200_mixer[] = { { } /* end */ }; -#define DELL_M6_MIXER 6 -static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = { - /* start of config #1 */ - HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), - - HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT), - HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT), - - HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT), - HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT), - - /* start of config #2 */ - HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT), - - HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), - HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), - - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), - - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), - - { } /* end */ -}; - static struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = { STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), {} @@ -1094,134 +999,14 @@ static struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = { {} }; -static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = { - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), - - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), - - HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), - - HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT), - - HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT), - HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT), - - HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), - HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), - - HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT), - HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT), - { } /* end */ -}; - -static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), - - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), - - HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), - - HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT), - - HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT), - HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT), - - HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), - HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), - - HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT), - HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT), - { } /* end */ -}; - - -static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_OUTPUT), - - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT), - - HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0x3, HDA_INPUT), - HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0x3, HDA_INPUT), - - HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x4, HDA_INPUT), - HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x4, HDA_INPUT), - - HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x0, HDA_INPUT), - - HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x2, HDA_INPUT), - HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x2, HDA_INPUT), - - /* - HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x1, HDA_INPUT), - */ - { } /* end */ -}; - -static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), - - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), - /* analog pc-beep replaced with digital beep support */ - /* - HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT), - HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT), - */ - - HDA_CODEC_MUTE("Import0 Mux Capture Switch", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Import0 Mux Capture Volume", 0x17, 0x0, HDA_INPUT), - - HDA_CODEC_MUTE("Import1 Mux Capture Switch", 0x17, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Import1 Mux Capture Volume", 0x17, 0x1, HDA_INPUT), - - HDA_CODEC_MUTE("DAC0 Capture Switch", 0x17, 0x3, HDA_INPUT), - HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x17, 0x3, HDA_INPUT), - - HDA_CODEC_MUTE("DAC1 Capture Switch", 0x17, 0x4, HDA_INPUT), - HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x17, 0x4, HDA_INPUT), - { } /* end */ -}; static struct snd_kcontrol_new stac92hd71bxx_loopback[] = { STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) }; -static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), - - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), - { } /* end */ -}; - static struct snd_kcontrol_new stac925x_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), - { } /* end */ -}; - -static struct snd_kcontrol_new stac9205_mixer[] = { - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT), - - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT), { } /* end */ }; @@ -1230,29 +1015,6 @@ static struct snd_kcontrol_new stac9205_loopback[] = { {} }; -/* This needs to be generated dynamically based on sequence */ -static struct snd_kcontrol_new stac922x_mixer[] = { - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), - - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT), - { } /* end */ -}; - - -static struct snd_kcontrol_new stac927x_mixer[] = { - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT), - - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT), - - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT), - { } /* end */ -}; - static struct snd_kcontrol_new stac927x_loopback[] = { STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), {} @@ -1310,18 +1072,21 @@ static int stac92xx_build_controls(struct hda_codec *codec) int err; int i; - err = snd_hda_add_new_ctls(codec, spec->mixer); - if (err < 0) - return err; + 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->num_dmuxes > 0) { + 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, + err = snd_hda_ctl_add(codec, 0, snd_ctl_new1(&stac_dmux_mixer, codec)); if (err < 0) return err; @@ -1337,7 +1102,7 @@ static int stac92xx_build_controls(struct hda_codec *codec) spec->spdif_mute = 1; } stac_smux_mixer.count = spec->num_smuxes; - err = snd_hda_ctl_add(codec, + err = snd_hda_ctl_add(codec, 0, snd_ctl_new1(&stac_smux_mixer, codec)); if (err < 0) return err; @@ -1766,12 +1531,20 @@ static unsigned int dell_m6_pin_configs[13] = { 0x4f0000f0, }; +static unsigned int alienware_m17x_pin_configs[13] = { + 0x0321101f, 0x0321101f, 0x03a11020, 0x03014020, + 0x90170110, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0, + 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0, + 0x904601b0, +}; + static 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, }; static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { @@ -1783,6 +1556,7 @@ static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { [STAC_DELL_M6_DMIC] = "dell-m6-dmic", [STAC_DELL_M6_BOTH] = "dell-m6", [STAC_DELL_EQ] = "dell-eq", + [STAC_ALIENWARE_M17X] = "alienware", }; static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { @@ -1817,6 +1591,14 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { "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), + {} /* terminator */ +}; + +static struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1, + "Alienware M17x", STAC_ALIENWARE_M17X), {} /* terminator */ }; @@ -1827,8 +1609,8 @@ static unsigned int ref92hd83xxx_pin_configs[10] = { }; static unsigned int dell_s14_pin_configs[10] = { - 0x02214030, 0x02211010, 0x02a19020, 0x01014050, - 0x40f000f0, 0x01819040, 0x40f000f0, 0x90a60160, + 0x0221403f, 0x0221101f, 0x02a19020, 0x90170110, + 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a60160, 0x40f000f0, 0x40f000f0, }; @@ -1843,6 +1625,7 @@ static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { [STAC_92HD83XXX_REF] = "ref", [STAC_92HD83XXX_PWR_REF] = "mic-ref", [STAC_DELL_S14] = "dell-s14", + [STAC_92HD83XXX_HP] = "hp", }; static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { @@ -1853,6 +1636,8 @@ static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { "DFI LanParty", STAC_92HD83XXX_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, "unknown Dell", STAC_DELL_S14), + SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600, + "HP", STAC_92HD83XXX_HP), {} /* terminator */ }; @@ -1915,6 +1700,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { "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, @@ -1927,6 +1714,10 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { "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_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, @@ -2236,6 +2027,7 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { [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 *stac927x_models[STAC_927X_MODELS] = { @@ -2247,6 +2039,7 @@ static const char *stac927x_models[STAC_927X_MODELS] = { [STAC_D965_5ST_NO_FP] = "5stack-no-fp", [STAC_DELL_3ST] = "dell-3stack", [STAC_DELL_BIOS] = "dell-bios", + [STAC_927X_VOLKNOB] = "volknob", }; static struct snd_pci_quirk stac927x_cfg_tbl[] = { @@ -2282,6 +2075,8 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { "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), {} /* terminator */ }; @@ -2642,8 +2437,7 @@ static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol, return 0; } -static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid, - unsigned char type); +static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid); static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2657,7 +2451,7 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, /* check to be sure that the ports are upto date with * switch changes */ - stac_issue_unsol_event(codec, nid, STAC_HP_EVENT); + stac_issue_unsol_event(codec, nid); return 1; } @@ -2790,7 +2584,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ * appropriately according to the pin direction */ if (spec->hp_detect) - stac_issue_unsol_event(codec, nid, STAC_HP_EVENT); + stac_issue_unsol_event(codec, nid); return 1; } @@ -2858,9 +2652,8 @@ static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol, enum { STAC_CTL_WIDGET_VOL, STAC_CTL_WIDGET_MUTE, + STAC_CTL_WIDGET_MUTE_BEEP, STAC_CTL_WIDGET_MONO_MUX, - STAC_CTL_WIDGET_AMP_MUX, - STAC_CTL_WIDGET_AMP_VOL, STAC_CTL_WIDGET_HP_SWITCH, STAC_CTL_WIDGET_IO_SWITCH, STAC_CTL_WIDGET_CLFE_SWITCH, @@ -2870,9 +2663,8 @@ enum { static struct snd_kcontrol_new stac92xx_control_templates[] = { HDA_CODEC_VOLUME(NULL, 0, 0, 0), HDA_CODEC_MUTE(NULL, 0, 0, 0), + HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0), STAC_MONO_MUX, - STAC_AMP_MUX, - STAC_AMP_VOL(NULL, 0, 0, 0, 0), STAC_CODEC_HP_SWITCH(NULL), STAC_CODEC_IO_SWITCH(NULL, 0), STAC_CODEC_CLFE_SWITCH(NULL, 0), @@ -2883,7 +2675,8 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = { static struct snd_kcontrol_new * stac_control_new(struct sigmatel_spec *spec, struct snd_kcontrol_new *ktemp, - const char *name) + const char *name, + hda_nid_t nid) { struct snd_kcontrol_new *knew; @@ -2899,6 +2692,8 @@ stac_control_new(struct sigmatel_spec *spec, spec->kctls.alloced--; return NULL; } + if (nid) + knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; return knew; } @@ -2907,7 +2702,8 @@ static int stac92xx_add_control_temp(struct sigmatel_spec *spec, int idx, const char *name, unsigned long val) { - struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name); + struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name, + get_amp_nid_(val)); if (!knew) return -ENOMEM; knew->index = idx; @@ -2973,10 +2769,12 @@ static int stac92xx_add_input_source(struct sigmatel_spec *spec) struct snd_kcontrol_new *knew; struct hda_input_mux *imux = &spec->private_imux; + if (spec->auto_mic) + return 0; /* no need for input source */ if (!spec->num_adcs || imux->num_items <= 1) return 0; /* no need for input source control */ knew = stac_control_new(spec, &stac_input_src_temp, - stac_input_src_temp.name); + stac_input_src_temp.name, 0); if (!knew) return -ENOMEM; knew->count = spec->num_adcs; @@ -3066,7 +2864,7 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) HDA_MAX_CONNECTIONS); for (j = 0; j < conn_len; j++) { wcaps = get_wcaps(codec, conn[j]); - wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + wtype = get_wcaps_type(wcaps); /* we check only analog outputs */ if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL)) continue; @@ -3325,6 +3123,21 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, return 0; } +static int stac92xx_add_capvol_ctls(struct hda_codec *codec, unsigned long vol, + unsigned long sw, int idx) +{ + int err; + err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx, + "Capture Volume", vol); + if (err < 0) + return err; + err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_MUTE, idx, + "Capture Switch", sw); + if (err < 0) + return err; + return 0; +} + /* add playback controls from the parsed DAC table */ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) @@ -3398,7 +3211,7 @@ static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec) spec->mono_nid, con_lst, HDA_MAX_NUM_INPUTS); - if (!num_cons || num_cons > ARRAY_SIZE(stac92xx_mono_labels)) + if (num_cons <= 0 || num_cons > ARRAY_SIZE(stac92xx_mono_labels)) return -EINVAL; for (i = 0; i < num_cons; i++) { @@ -3412,49 +3225,21 @@ static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec) "Mono Mux", spec->mono_nid); } -/* labels for amp mux outputs */ -static const char *stac92xx_amp_labels[3] = { - "Front Microphone", "Microphone", "Line In", -}; - -/* create amp out controls mux on capable codecs */ -static int stac92xx_auto_create_amp_output_ctls(struct hda_codec *codec) -{ - struct sigmatel_spec *spec = codec->spec; - struct hda_input_mux *amp_mux = &spec->private_amp_mux; - int i, err; - - for (i = 0; i < spec->num_amps; i++) { - amp_mux->items[amp_mux->num_items].label = - stac92xx_amp_labels[i]; - amp_mux->items[amp_mux->num_items].index = i; - amp_mux->num_items++; - } - - if (spec->num_amps > 1) { - err = stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_MUX, - "Amp Selector Capture Switch", 0); - if (err < 0) - return err; - } - return stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_VOL, - "Amp Capture Volume", - HDA_COMPOSE_AMP_VAL(spec->amp_nids[0], 3, 0, HDA_INPUT)); -} - - /* create PC beep volume controls */ static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec, hda_nid_t nid) { struct sigmatel_spec *spec = codec->spec; u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT); - int err; + int err, type |