#define nid_has_volume(codec, nid, dir) \
        check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS)
 
+static struct nid_path *
+get_nid_path(struct hda_codec *codec, hda_nid_t from_nid, hda_nid_t to_nid);
+static void activate_path(struct hda_codec *codec, struct nid_path *path,
+                         bool enable, bool add_aamix);
+
 /*
  * input MUX handling
  */
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        struct alc_spec *spec = codec->spec;
-       unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
-       if (mux_idx >= spec->num_mux_defs)
-               mux_idx = 0;
-       if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
-               mux_idx = 0;
-       return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
+       return snd_hda_input_mux_info(&spec->input_mux[0], uinfo);
 }
 
 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
+static hda_nid_t get_adc_nid(struct hda_codec *codec, int adc_idx, int imux_idx)
+{
+       struct alc_spec *spec = codec->spec;
+       if (spec->dyn_adc_switch)
+               adc_idx = spec->dyn_adc_idx[imux_idx];
+       return spec->adc_nids[adc_idx];
+}
+
 static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur)
 {
        struct alc_spec *spec = codec->spec;
        return false;
 }
 
-static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx)
-{
-       return spec->capsrc_nids ?
-               spec->capsrc_nids[idx] : spec->adc_nids[idx];
-}
-
 static void call_update_outputs(struct hda_codec *codec);
 static void alc_inv_dmic_sync(struct hda_codec *codec, bool force);
+static void alc_inv_dmic_sync_adc(struct hda_codec *codec, int adc_idx);
 
 /* for shared I/O, change the pin-control accordingly */
 static void update_shared_mic_hp(struct hda_codec *codec, bool set_as_mic)
 {
        struct alc_spec *spec = codec->spec;
        const struct hda_input_mux *imux;
-       unsigned int mux_idx;
-       int i, type, num_conns;
-       hda_nid_t nid;
-
-       if (!spec->input_mux)
-               return 0;
+       struct nid_path *path;
 
-       mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
-       imux = &spec->input_mux[mux_idx];
-       if (!imux->num_items && mux_idx > 0)
-               imux = &spec->input_mux[0];
-       if (!imux->num_items)
+       imux = spec->input_mux;
+       if (!imux || !imux->num_items)
                return 0;
 
        if (idx >= imux->num_items)
                idx = imux->num_items - 1;
        if (spec->cur_mux[adc_idx] == idx && !force)
                return 0;
+
+       path = get_nid_path(codec, spec->imux_pins[spec->cur_mux[adc_idx]],
+                           spec->adc_nids[adc_idx]);
+       if (!path)
+               return 0;
+       if (path->active)
+               activate_path(codec, path, false, false);
+
        spec->cur_mux[adc_idx] = idx;
 
        if (spec->shared_mic_hp)
                update_shared_mic_hp(codec, spec->cur_mux[adc_idx]);
 
-       if (spec->dyn_adc_switch) {
+       if (spec->dyn_adc_switch)
                alc_dyn_adc_pcm_resetup(codec, idx);
-               adc_idx = spec->dyn_adc_idx[idx];
-       }
-
-       nid = get_capsrc(spec, adc_idx);
 
-       /* no selection? */
-       num_conns = snd_hda_get_num_conns(codec, nid);
-       if (num_conns <= 1)
-               return 1;
-
-       type = get_wcaps_type(get_wcaps(codec, nid));
-       if (type == AC_WID_AUD_MIX) {
-               /* Matrix-mixer style (e.g. ALC882) */
-               int active = imux->items[idx].index;
-               for (i = 0; i < num_conns; i++) {
-                       unsigned int v = (i == active) ? 0 : HDA_AMP_MUTE;
-                       snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, i,
-                                                HDA_AMP_MUTE, v);
-               }
-       } else {
-               /* MUX style (e.g. ALC880) */
-               snd_hda_codec_write_cache(codec, nid, 0,
-                                         AC_VERB_SET_CONNECT_SEL,
-                                         imux->items[idx].index);
-       }
+       path = get_nid_path(codec, spec->imux_pins[idx],
+                           get_adc_nid(codec, adc_idx, idx));
+       if (!path)
+               return 0;
+       if (path->active)
+               return 0;
+       activate_path(codec, path, true, false);
        alc_inv_dmic_sync(codec, true);
        return 1;
 }
        return -1;
 }
 
-/* check whether dynamic ADC-switching is available */
-static bool alc_check_dyn_adc_switch(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       struct hda_input_mux *imux = &spec->private_imux[0];
-       int i, n, idx;
-       hda_nid_t cap, pin;
-
-       if (imux != spec->input_mux) /* no dynamic imux? */
-               return false;
-
-       for (n = 0; n < spec->num_adc_nids; n++) {
-               cap = spec->private_capsrc_nids[n];
-               for (i = 0; i < imux->num_items; i++) {
-                       pin = spec->imux_pins[i];
-                       if (!pin)
-                               return false;
-                       if (get_connection_index(codec, cap, pin) < 0)
-                               break;
-               }
-               if (i >= imux->num_items)
-                       return true; /* no ADC-switch is needed */
-       }
-
-       for (i = 0; i < imux->num_items; i++) {
-               pin = spec->imux_pins[i];
-               for (n = 0; n < spec->num_adc_nids; n++) {
-                       cap = spec->private_capsrc_nids[n];
-                       idx = get_connection_index(codec, cap, pin);
-                       if (idx >= 0) {
-                               imux->items[i].index = idx;
-                               spec->dyn_adc_idx[i] = n;
-                               break;
-                       }
-               }
-       }
-
-       snd_printdd("realtek: enabling ADC switching\n");
-       spec->dyn_adc_switch = 1;
-       return true;
-}
-
 /* check whether all auto-mic pins are valid; setup indices if OK */
 static bool alc_auto_mic_check_imux(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
        const struct hda_input_mux *imux;
 
-       if (!spec->auto_mic)
-               return false;
-       if (spec->auto_mic_valid_imux)
-               return true; /* already checked */
-
-       /* fill up imux indices */
-       if (!alc_check_dyn_adc_switch(codec)) {
-               spec->auto_mic = 0;
-               return false;
-       }
-
        imux = spec->input_mux;
        spec->ext_mic_idx = find_idx_in_nid_list(spec->ext_mic_pin,
                                        spec->imux_pins, imux->num_items);
                                        spec->imux_pins, imux->num_items);
        spec->dock_mic_idx = find_idx_in_nid_list(spec->dock_mic_pin,
                                        spec->imux_pins, imux->num_items);
-       if (spec->ext_mic_idx < 0 || spec->int_mic_idx < 0) {
-               spec->auto_mic = 0;
+       if (spec->ext_mic_idx < 0 || spec->int_mic_idx < 0)
                return false; /* no corresponding imux */
-       }
 
        snd_hda_jack_detect_enable_callback(codec, spec->ext_mic_pin,
                                            ALC_MIC_EVENT, alc_mic_automute);
                                                    alc_mic_automute);
 
        spec->auto_mic_valid_imux = 1;
-       spec->auto_mic = 1;
        return true;
 }
 
        hda_nid_t fixed, ext, dock;
        int i;
 
-       if (spec->shared_mic_hp)
-               return 0; /* no auto-mic for the shared I/O */
-
        spec->ext_mic_idx = spec->int_mic_idx = spec->dock_mic_idx = -1;
 
        fixed = ext = dock = 0;
        spec->int_mic_pin = fixed;
        spec->dock_mic_pin = dock;
 
-       spec->auto_mic = 1;
        if (!alc_auto_mic_check_imux(codec))
                return 0;
 
+       spec->auto_mic = 1;
+       spec->num_adc_nids = 1;
+       spec->cur_mux[0] = spec->int_mic_idx;
        snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
                    ext, fixed, dock);
 
        return 0;
 }
 
-/* check the availabilities of auto-mute and auto-mic switches */
-static int alc_auto_check_switches(struct hda_codec *codec)
-{
-       int err;
-
-       err = alc_init_automute(codec);
-       if (err < 0)
-               return err;
-       err = alc_init_auto_mic(codec);
-       if (err < 0)
-               return err;
-       return 0;
-}
-
 /*
  * Realtek SSID verification
  */
 /*
  * capture mixer elements
  */
-static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
-                           struct snd_ctl_elem_info *uinfo)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       struct alc_spec *spec = codec->spec;
-       unsigned long val;
-       int err;
-
-       mutex_lock(&codec->control_mutex);
-       if (spec->vol_in_capsrc)
-               val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
-       else
-               val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
-       kcontrol->private_value = val;
-       err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
-       mutex_unlock(&codec->control_mutex);
-       return err;
-}
-
-static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
-                          unsigned int size, unsigned int __user *tlv)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       struct alc_spec *spec = codec->spec;
-       unsigned long val;
-       int err;
-
-       mutex_lock(&codec->control_mutex);
-       if (spec->vol_in_capsrc)
-               val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
-       else
-               val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
-       kcontrol->private_value = val;
-       err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
-       mutex_unlock(&codec->control_mutex);
-       return err;
-}
+#define alc_cap_vol_info       snd_hda_mixer_amp_volume_info
+#define alc_cap_vol_get                snd_hda_mixer_amp_volume_get
+#define alc_cap_vol_tlv                snd_hda_mixer_amp_tlv
 
-typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
-                            struct snd_ctl_elem_value *ucontrol);
+typedef int (*put_call_t)(struct snd_kcontrol *kcontrol,
+                         struct snd_ctl_elem_value *ucontrol);
 
-static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
-                                struct snd_ctl_elem_value *ucontrol,
-                                getput_call_t func, bool is_put)
+static int alc_cap_put_caller(struct snd_kcontrol *kcontrol,
+                             struct snd_ctl_elem_value *ucontrol,
+                             put_call_t func, int type)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        struct alc_spec *spec = codec->spec;
-       int i, err = 0;
+       const struct hda_input_mux *imux;
+       struct nid_path *path;
+       int i, adc_idx, err = 0;
 
+       imux = spec->input_mux;
+       adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
        mutex_lock(&codec->control_mutex);
-       if (is_put && spec->dyn_adc_switch) {
-               for (i = 0; i < spec->num_adc_nids; i++) {
-                       kcontrol->private_value =
-                               HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
-                                                   3, 0, HDA_INPUT);
-                       err = func(kcontrol, ucontrol);
-                       if (err < 0)
-                               goto error;
-               }
-       } else {
-               i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-               if (spec->vol_in_capsrc)
-                       kcontrol->private_value =
-                               HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[i],
-                                                   3, 0, HDA_OUTPUT);
-               else
-                       kcontrol->private_value =
-                               HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
-                                                   3, 0, HDA_INPUT);
+       codec->cached_write = 1;
+       for (i = 0; i < imux->num_items; i++) {
+               path = get_nid_path(codec, spec->imux_pins[i],
+                                   get_adc_nid(codec, adc_idx, i));
+               if (!path->ctls[type])
+                       continue;
+               kcontrol->private_value = path->ctls[type];
                err = func(kcontrol, ucontrol);
+               if (err < 0)
+                       goto error;
        }
-       if (err >= 0 && is_put)
-               alc_inv_dmic_sync(codec, false);
  error:
+       codec->cached_write = 0;
        mutex_unlock(&codec->control_mutex);
+       snd_hda_codec_resume_amp(codec);
+       if (err >= 0 && type == NID_PATH_MUTE_CTL &&
+           spec->inv_dmic_fixup && spec->inv_dmic_muted)
+               alc_inv_dmic_sync_adc(codec, adc_idx);
        return err;
 }
 
-static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
-                          struct snd_ctl_elem_value *ucontrol)
-{
-       return alc_cap_getput_caller(kcontrol, ucontrol,
-                                    snd_hda_mixer_amp_volume_get, false);
-}
-
 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
                           struct snd_ctl_elem_value *ucontrol)
 {
-       return alc_cap_getput_caller(kcontrol, ucontrol,
-                                    snd_hda_mixer_amp_volume_put, true);
+       return alc_cap_put_caller(kcontrol, ucontrol,
+                                 snd_hda_mixer_amp_volume_put,
+                                 NID_PATH_VOL_CTL);
 }
 
 /* capture mixer elements */
 #define alc_cap_sw_info                snd_ctl_boolean_stereo_info
+#define alc_cap_sw_get         snd_hda_mixer_amp_switch_get
 
-static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
+static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
                          struct snd_ctl_elem_value *ucontrol)
 {
-       return alc_cap_getput_caller(kcontrol, ucontrol,
-                                    snd_hda_mixer_amp_switch_get, false);
+       return alc_cap_put_caller(kcontrol, ucontrol,
+                                 snd_hda_mixer_amp_switch_put,
+                                 NID_PATH_MUTE_CTL);
 }
 
-static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
-                         struct snd_ctl_elem_value *ucontrol)
+static void alc_inv_dmic_sync_adc(struct hda_codec *codec, int adc_idx)
 {
-       return alc_cap_getput_caller(kcontrol, ucontrol,
-                                    snd_hda_mixer_amp_switch_put, true);
-}
-
-#define _DEFINE_CAPMIX(num) \
-       { \
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-               .name = "Capture Switch", \
-               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
-               .count = num, \
-               .info = alc_cap_sw_info, \
-               .get = alc_cap_sw_get, \
-               .put = alc_cap_sw_put, \
-       }, \
-       { \
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-               .name = "Capture Volume", \
-               .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
-                          SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
-                          SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
-               .count = num, \
-               .info = alc_cap_vol_info, \
-               .get = alc_cap_vol_get, \
-               .put = alc_cap_vol_put, \
-               .tlv = { .c = alc_cap_vol_tlv }, \
-       }
-
-#define _DEFINE_CAPSRC(num) \
-       { \
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-               /* .name = "Capture Source", */ \
-               .name = "Input Source", \
-               .count = num, \
-               .info = alc_mux_enum_info, \
-               .get = alc_mux_enum_get, \
-               .put = alc_mux_enum_put, \
-       }
-
-#define DEFINE_CAPMIX(num) \
-static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
-       _DEFINE_CAPMIX(num),                                  \
-       _DEFINE_CAPSRC(num),                                  \
-       { } /* end */                                         \
-}
-
-#define DEFINE_CAPMIX_NOSRC(num) \
-static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
-       _DEFINE_CAPMIX(num),                                        \
-       { } /* end */                                               \
-}
-
-/* up to three ADCs */
-DEFINE_CAPMIX(1);
-DEFINE_CAPMIX(2);
-DEFINE_CAPMIX(3);
-DEFINE_CAPMIX_NOSRC(1);
-DEFINE_CAPMIX_NOSRC(2);
-DEFINE_CAPMIX_NOSRC(3);
+       struct alc_spec *spec = codec->spec;
+       struct hda_input_mux *imux = &spec->private_imux[0];
+       struct nid_path *path;
+       hda_nid_t nid;
+       int i, dir, parm;
+       unsigned int val;
+
+       for (i = 0; i < imux->num_items; i++) {
+               if (spec->imux_pins[i] == spec->inv_dmic_pin)
+                       break;
+       }
+       if (i >= imux->num_items)
+               return;
+
+       path = get_nid_path(codec, spec->inv_dmic_pin,
+                           get_adc_nid(codec, adc_idx, i));
+       val = path->ctls[NID_PATH_MUTE_CTL];
+       if (!val)
+               return;
+       nid = get_amp_nid_(val);
+       dir = get_amp_direction_(val);
+       parm = AC_AMP_SET_RIGHT |
+               (dir == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT);
+
+       /* we care only right channel */
+       val = snd_hda_codec_amp_read(codec, nid, 1, dir, 0);
+       if (val & 0x80) /* if already muted, we don't need to touch */
+               return;
+       val |= 0x80;
+       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+                           parm | val);
+}
 
 /*
  * Inverted digital-mic handling
 static void alc_inv_dmic_sync(struct hda_codec *codec, bool force)
 {
        struct alc_spec *spec = codec->spec;
-       int i;
+       int src, nums;
 
        if (!spec->inv_dmic_fixup)
                return;
        if (!spec->inv_dmic_muted && !force)
                return;
-       for (i = 0; i < spec->num_adc_nids; i++) {
-               int src = spec->dyn_adc_switch ? 0 : i;
+       nums = spec->dyn_adc_switch ? 1 : spec->num_adc_nids;
+       for (src = 0; src < nums; src++) {
                bool dmic_fixup = false;
-               hda_nid_t nid;
-               int parm, dir, v;
 
                if (spec->inv_dmic_muted &&
                    spec->imux_pins[spec->cur_mux[src]] == spec->inv_dmic_pin)
                        dmic_fixup = true;
                if (!dmic_fixup && !force)
                        continue;
-               if (spec->vol_in_capsrc) {
-                       nid = spec->capsrc_nids[i];
-                       parm = AC_AMP_SET_RIGHT | AC_AMP_SET_OUTPUT;
-                       dir = HDA_OUTPUT;
-               } else {
-                       nid = spec->adc_nids[i];
-                       parm = AC_AMP_SET_RIGHT | AC_AMP_SET_INPUT;
-                       dir = HDA_INPUT;
-               }
-               /* we care only right channel */
-               v = snd_hda_codec_amp_read(codec, nid, 1, dir, 0);
-               if (v & 0x80) /* if already muted, we don't need to touch */
-                       continue;
-               if (dmic_fixup) /* add mute for d-mic */
-                       v |= 0x80;
-               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
-                                   parm | v);
+               alc_inv_dmic_sync_adc(codec, src);
        }
 }
 
 
 #define NID_MAPPING            (-1)
 
-#define SUBDEV_SPEAKER_                (0 << 6)
-#define SUBDEV_HP_             (1 << 6)
-#define SUBDEV_LINE_           (2 << 6)
-#define SUBDEV_SPEAKER(x)      (SUBDEV_SPEAKER_ | ((x) & 0x3f))
-#define SUBDEV_HP(x)           (SUBDEV_HP_ | ((x) & 0x3f))
-#define SUBDEV_LINE(x)         (SUBDEV_LINE_ | ((x) & 0x3f))
-
 static void alc_free_kctls(struct hda_codec *codec);
 
 #ifdef CONFIG_SND_HDA_INPUT_BEEP
 static int __alc_build_controls(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
-       struct snd_kcontrol *kctl = NULL;
-       const struct snd_kcontrol_new *knew;
-       int i, j, err;
-       unsigned int u;
-       hda_nid_t nid;
+       int i, err;
 
        for (i = 0; i < spec->num_mixers; i++) {
                err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
                        return err;
        }
 
-       /* assign Capture Source enums to NID */
-       if (spec->capsrc_nids || spec->adc_nids) {
-               kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
-               if (!kctl)
-                       kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
-               for (i = 0; kctl && i < kctl->count; i++) {
-                       err = snd_hda_add_nid(codec, kctl, i,
-                                             get_capsrc(spec, i));
-                       if (err < 0)
-                               return err;
-               }
-       }
-       if (spec->cap_mixer && spec->adc_nids) {
-               const char *kname = kctl ? kctl->id.name : NULL;
-               for (knew = spec->cap_mixer; knew->name; knew++) {
-                       if (kname && strcmp(knew->name, kname) == 0)
-                               continue;
-                       kctl = snd_hda_find_mixer_ctl(codec, knew->name);
-                       for (i = 0; kctl && i < kctl->count; i++) {
-                               err = snd_hda_add_nid(codec, kctl, i,
-                                                     spec->adc_nids[i]);
-                               if (err < 0)
-                                       return err;
-                       }
-               }
-       }
-
-       /* other nid->control mapping */
-       for (i = 0; i < spec->num_mixers; i++) {
-               for (knew = spec->mixers[i]; knew->name; knew++) {
-                       if (knew->iface != NID_MAPPING)
-                               continue;
-                       kctl = snd_hda_find_mixer_ctl(codec, knew->name);
-                       if (kctl == NULL)
-                               continue;
-                       u = knew->subdevice;
-                       for (j = 0; j < 4; j++, u >>= 8) {
-                               nid = u & 0x3f;
-                               if (nid == 0)
-                                       continue;
-                               switch (u & 0xc0) {
-                               case SUBDEV_SPEAKER_:
-                                       nid = spec->autocfg.speaker_pins[nid];
-                                       break;
-                               case SUBDEV_LINE_:
-                                       nid = spec->autocfg.line_out_pins[nid];
-                                       break;
-                               case SUBDEV_HP_:
-                                       nid = spec->autocfg.hp_pins[nid];
-                                       break;
-                               default:
-                                       continue;
-                               }
-                               err = snd_hda_add_nid(codec, kctl, 0, nid);
-                               if (err < 0)
-                                       return err;
-                       }
-                       u = knew->private_value;
-                       for (j = 0; j < 4; j++, u >>= 8) {
-                               nid = u & 0xff;
-                               if (nid == 0)
-                                       continue;
-                               err = snd_hda_add_nid(codec, kctl, 0, nid);
-                               if (err < 0)
-                                       return err;
-                       }
-               }
-       }
-
        alc_free_kctls(codec); /* no longer needed */
 
        return 0;
  * Common callbacks
  */
 
-static void alc_init_special_input_src(struct hda_codec *codec);
 static void alc_auto_init_std(struct hda_codec *codec);
 
 static int alc_init(struct hda_codec *codec)
        alc_auto_init_amp(codec, spec->init_amp);
 
        snd_hda_gen_apply_verbs(codec);
-       alc_init_special_input_src(codec);
        alc_auto_init_std(codec);
 
        alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
        return 0;
 }
 
-static int new_capture_source(struct hda_codec *codec, int adc_idx,
-                             hda_nid_t pin, int idx, const char *label)
-{
-       struct alc_spec *spec = codec->spec;
-       struct hda_input_mux *imux = &spec->private_imux[0];
-       struct nid_path *path;
-
-       path = snd_array_new(&spec->paths);
-       if (!path)
-               return -ENOMEM;
-       memset(path, 0, sizeof(*path));
-       if (!parse_nid_path(codec, pin, spec->adc_nids[adc_idx], 2, path)) {
-               snd_printd(KERN_ERR "invalid input path 0x%x -> 0x%x\n",
-                          pin, spec->adc_nids[adc_idx]);
-               return -EINVAL;
-       }
-
-       spec->imux_pins[imux->num_items] = pin;
-       snd_hda_add_imux_item(imux, label, idx, NULL);
-       return 0;
-}
-
 static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
 {
        unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
        return snd_hda_get_conn_index(codec, to_nid, from_nid, true) >= 0;
 }
 
-/* Parse the codec tree and retrieve ADCs and corresponding capsrc MUXs */
-static int alc_auto_fill_adc_caps(struct hda_codec *codec)
+/* Parse the codec tree and retrieve ADCs */
+static int alc_auto_fill_adc_nids(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
        hda_nid_t nid;
        hda_nid_t *adc_nids = spec->private_adc_nids;
-       hda_nid_t *cap_nids = spec->private_capsrc_nids;
        int max_nums = ARRAY_SIZE(spec->private_adc_nids);
        int i, nums = 0;
 
        nid = codec->start_nid;
        for (i = 0; i < codec->num_nodes; i++, nid++) {
-               hda_nid_t src;
                unsigned int caps = get_wcaps(codec, nid);
                int type = get_wcaps_type(caps);
 
                if (type != AC_WID_AUD_IN || (caps & AC_WCAP_DIGITAL))
                        continue;
                adc_nids[nums] = nid;
-               cap_nids[nums] = nid;
-               src = nid;
-               for (;;) {
-                       int n;
-                       type = get_wcaps_type(get_wcaps(codec, src));
-                       if (type == AC_WID_PIN)
-                               break;
-                       if (type == AC_WID_AUD_SEL) {
-                               cap_nids[nums] = src;
-                               break;
-                       }
-                       n = snd_hda_get_num_conns(codec, src);
-                       if (n > 1) {
-                               cap_nids[nums] = src;
-                               break;
-                       } else if (n != 1)
-                               break;
-                       if (snd_hda_get_connections(codec, src, &src, 1) != 1)
-                               break;
-               }
                if (++nums >= max_nums)
                        break;
        }
        spec->adc_nids = spec->private_adc_nids;
-       spec->capsrc_nids = spec->private_capsrc_nids;
        spec->num_adc_nids = nums;
        return nums;
 }
 
+/* filter out invalid adc_nids that don't give all active input pins;
+ * if needed, check whether dynamic ADC-switching is available
+ */
+static int check_dyn_adc_switch(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       struct hda_input_mux *imux = &spec->private_imux[0];
+       hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)];
+       int i, n, nums;
+       hda_nid_t pin, adc;
+
+ again:
+       nums = 0;
+       for (n = 0; n < spec->num_adc_nids; n++) {
+               adc = spec->adc_nids[n];
+               for (i = 0; i < imux->num_items; i++) {
+                       pin = spec->imux_pins[i];
+                       if (!is_reachable_path(codec, pin, adc))
+                               break;
+               }
+               if (i >= imux->num_items)
+                       adc_nids[nums++] = adc;
+       }
+
+       if (!nums) {
+               if (spec->shared_mic_hp) {
+                       spec->shared_mic_hp = 0;
+                       spec->private_imux[0].num_items = 1;
+                       goto again;
+               }
+
+               /* check whether ADC-switch is possible */
+               for (i = 0; i < imux->num_items; i++) {
+                       pin = spec->imux_pins[i];
+                       for (n = 0; n < spec->num_adc_nids; n++) {
+                               adc = spec->adc_nids[n];
+                               if (is_reachable_path(codec, pin, adc)) {
+                                       spec->dyn_adc_idx[i] = n;
+                                       break;
+                               }
+                       }
+               }
+
+               snd_printdd("realtek: enabling ADC switching\n");
+               spec->dyn_adc_switch = 1;
+       } else if (nums != spec->num_adc_nids) {
+               memcpy(spec->private_adc_nids, adc_nids,
+                      nums * sizeof(hda_nid_t));
+               spec->num_adc_nids = nums;
+       }
+
+       if (spec->input_mux->num_items == 1 || spec->shared_mic_hp) {
+               snd_printdd("realtek: reducing to a single ADC\n");
+               spec->num_adc_nids = 1; /* reduce to a single ADC */
+       }
+
+       return 0;
+}
+
+/* templates for capture controls */
+static const struct snd_kcontrol_new cap_src_temp = {
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+       .name = "Input Source",
+       .info = alc_mux_enum_info,
+       .get = alc_mux_enum_get,
+       .put = alc_mux_enum_put,
+};
+
+static const struct snd_kcontrol_new cap_vol_temp = {
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+       .name = "Capture Volume",
+       .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
+                  SNDRV_CTL_ELEM_ACCESS_TLV_READ |
+                  SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK),
+       .info = alc_cap_vol_info,
+       .get = alc_cap_vol_get,
+       .put = alc_cap_vol_put,
+       .tlv = { .c = alc_cap_vol_tlv },
+};
+
+static const struct snd_kcontrol_new cap_sw_temp = {
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+       .name = "Capture Switch",
+       .info = alc_cap_sw_info,
+       .get = alc_cap_sw_get,
+       .put = alc_cap_sw_put,
+};
+
+static int parse_capvol_in_path(struct hda_codec *codec, struct nid_path *path)
+{
+       hda_nid_t nid;
+       int i, depth;
+
+       path->ctls[NID_PATH_VOL_CTL] = path->ctls[NID_PATH_MUTE_CTL] = 0;
+       for (depth = 0; depth < 3; depth++) {
+               if (depth >= path->depth)
+                       return -EINVAL;
+               i = path->depth - depth - 1;
+               nid = path->path[i];
+               if (!path->ctls[NID_PATH_VOL_CTL]) {
+                       if (nid_has_volume(codec, nid, HDA_OUTPUT))
+                               path->ctls[NID_PATH_VOL_CTL] =
+                                       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
+                       else if (nid_has_volume(codec, nid, HDA_INPUT)) {
+                               int idx = path->idx[i];
+                               if (!depth && codec->single_adc_amp)
+                                       idx = 0;
+                               path->ctls[NID_PATH_VOL_CTL] =
+                                       HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_INPUT);
+                       }
+               }
+               if (!path->ctls[NID_PATH_MUTE_CTL]) {
+                       if (nid_has_mute(codec, nid, HDA_OUTPUT))
+                               path->ctls[NID_PATH_MUTE_CTL] =
+                                       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
+                       else if (nid_has_mute(codec, nid, HDA_INPUT)) {
+                               int idx = path->idx[i];
+                               if (!depth && codec->single_adc_amp)
+                                       idx = 0;
+                               path->ctls[NID_PATH_MUTE_CTL] =
+                                       HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_INPUT);
+                       }
+               }
+       }
+       return 0;
+}
+
+static int create_capture_mixers(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       struct hda_input_mux *imux = &spec->private_imux[0];
+       struct snd_kcontrol_new *knew;
+       int i, n, nums;
+
+       if (spec->dyn_adc_switch)
+               nums = 1;
+       else
+               nums = spec->num_adc_nids;
+
+       if (!spec->auto_mic && imux->num_items > 1) {
+               knew = alc_kcontrol_new(spec, "Input Source", &cap_src_temp);
+               if (!knew)
+                       return -ENOMEM;
+               knew->count = nums;
+       }
+
+       for (n = 0; n < nums; n++) {
+               int vol, sw;
+
+               vol = sw = 0;
+               for (i = 0; i < imux->num_items; i++) {
+                       struct nid_path *path;
+                       path = get_nid_path(codec, spec->imux_pins[i],
+                                           get_adc_nid(codec, n, i));
+                       if (!path)
+                               continue;
+                       parse_capvol_in_path(codec, path);
+                       if (!vol)
+                               vol = path->ctls[NID_PATH_VOL_CTL];
+                       if (!sw)
+                               sw = path->ctls[NID_PATH_MUTE_CTL];
+               }
+
+               if (vol) {
+                       knew = alc_kcontrol_new(spec, "Capture Volume",
+                                               &cap_vol_temp);
+                       if (!knew)
+                               return -ENOMEM;
+                       knew->index = n;
+                       knew->private_value = vol;
+                       knew->subdevice = HDA_SUBDEV_AMP_FLAG;
+               }
+               if (sw) {
+                       knew = alc_kcontrol_new(spec, "Capture Switch",
+                                               &cap_sw_temp);
+                       if (!knew)
+                               return -ENOMEM;
+                       knew->index = n;
+                       knew->private_value = sw;
+                       knew->subdevice = HDA_SUBDEV_AMP_FLAG;
+               }
+       }
+
+       return 0;
+}
+
 /* create playback/capture controls for input pins */
 static int alc_auto_create_input_ctls(struct hda_codec *codec)
 {
        hda_nid_t mixer = spec->mixer_nid;
        struct hda_input_mux *imux = &spec->private_imux[0];
        int num_adcs;
-       int i, c, err, idx, type_idx = 0;
+       int i, c, err, type_idx = 0;
        const char *prev_label = NULL;
 
-       num_adcs = alc_auto_fill_adc_caps(codec);
+       num_adcs = alc_auto_fill_adc_nids(codec);
        if (num_adcs < 0)
                return 0;
 
        for (i = 0; i < cfg->num_inputs; i++) {
                hda_nid_t pin;
                const char *label;
+               bool imux_added;
 
                pin = cfg->inputs[i].pin;
                if (!alc_is_input_pin(codec, pin))
                        }
                }
 
+               imux_added = false;
                for (c = 0; c < num_adcs; c++) {
-                       hda_nid_t cap = get_capsrc(spec, c);
-                       idx = get_connection_index(codec, cap, pin);
-                       if (idx >= 0) {
-                               err = new_capture_source(codec, c, pin, idx, label);
-                               if (err < 0)
-                                       return err;
-                               break;
+                       struct nid_path *path;
+                       hda_nid_t adc = spec->adc_nids[c];
+
+                       if (!is_reachable_path(codec, pin, adc))
+                               continue;
+                       path = snd_array_new(&spec->paths);
+                       if (!path)
+                               return -ENOMEM;
+                       memset(path, 0, sizeof(*path));
+                       if (!parse_nid_path(codec, pin, adc, 2, path)) {
+                               snd_printd(KERN_ERR
+                                          "invalid input path 0x%x -> 0x%x\n",
+                                          pin, adc);
+                               spec->paths.used--;
+                               continue;
+                       }
+
+                       if (!imux_added) {
+                               spec->imux_pins[imux->num_items] = pin;
+                               snd_hda_add_imux_item(imux, label,
+                                                     imux->num_items, NULL);
+                               imux_added = true;
                        }
                }
        }
 
-       spec->num_mux_defs = 1;
        spec->input_mux = imux;
-
        return 0;
 }
 
        return 0;
 }
 
-static struct nid_path *
-get_nid_path(struct hda_codec *codec, hda_nid_t from_nid, hda_nid_t to_nid);
-static void activate_path(struct hda_codec *codec, struct nid_path *path,
-                         bool enable);
-
 static int get_pin_type(int line_out_type)
 {
        if (line_out_type == AUTO_PIN_HP_OUT)
                        struct nid_path *path;
                        path = get_nid_path(codec, nid, spec->mixer_nid);
                        if (path)
-                               activate_path(codec, path, path->active);
+                               activate_path(codec, path, path->active, false);
                }
        }
 }
 }
 
 static void activate_amp_in(struct hda_codec *codec, struct nid_path *path,
-                           int i, bool enable)
+                           int i, bool enable, bool add_aamix)
 {
        struct alc_spec *spec = codec->spec;
        hda_nid_t conn[16];
        int n, nums, idx;
+       int type;
        hda_nid_t nid = path->path[i];
 
        nums = snd_hda_get_connections(codec, nid, conn, ARRAY_SIZE(conn));
-       if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_PIN) {
+       type = get_wcaps_type(get_wcaps(codec, nid));
+       if (type == AC_WID_PIN ||
+           (type == AC_WID_AUD_IN && codec->single_adc_amp)) {
                nums = 1;
                idx = 0;
        } else
         * when aa-mixer is available, we need to enable the path as well
         */
        for (n = 0; n < nums; n++) {
-               if (n != idx && conn[n] != spec->mixer_nid)
+               if (n != idx && (!add_aamix || conn[n] != spec->mixer_nid))
                        continue;
                activate_amp(codec, nid, HDA_INPUT, n, enable);
        }
 }
 
 static void activate_path(struct hda_codec *codec, struct nid_path *path,
-                         bool enable)
+                         bool enable, bool add_aamix)
 {
        int i;
 
                                            AC_VERB_SET_CONNECT_SEL,
                                            path->idx[i]);
                if (has_amp_in(codec, path, i))
-                       activate_amp_in(codec, path, i, enable);
+                       activate_amp_in(codec, path, i, enable, add_aamix);
                if (has_amp_out(codec, path, i))
                        activate_amp_out(codec, path, i, enable);
        }
                return;
        if (path->active)
                return;
-       activate_path(codec, path, true);
+       activate_path(codec, path, true, true);
 }
 
 static void alc_auto_init_multi_out(struct hda_codec *codec)
 
        if (output) {
                snd_hda_set_pin_ctl_cache(codec, nid, PIN_OUT);
-               activate_path(codec, path, true);
+               activate_path(codec, path, true, true);
        } else {
-               activate_path(codec, path, false);
+               activate_path(codec, path, false, true);
                snd_hda_set_pin_ctl_cache(codec, nid,
                                          spec->multi_io[idx].ctl_in);
        }
                        spec->multi_io[i].ctl_in =
                                snd_hda_codec_update_cache(codec, pin, 0,
                                           AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-               activate_path(codec, path, path->active);
-       }
-}
-
-/* filter out invalid adc_nids (and capsrc_nids) that don't give all
- * active input pins
- */
-static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       const struct hda_input_mux *imux;
-       hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)];
-       hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)];
-       int i, n, nums;
-
-       imux = spec->input_mux;
-       if (!imux)
-               return;
-       if (spec->dyn_adc_switch)
-               return;
-
- again:
-       nums = 0;
-       for (n = 0; n < spec->num_adc_nids; n++) {
-               hda_nid_t cap = spec->private_capsrc_nids[n];
-               int num_conns = snd_hda_get_num_conns(codec, cap);
-               for (i = 0; i < imux->num_items; i++) {
-                       hda_nid_t pin = spec->imux_pins[i];
-                       if (pin) {
-                               if (get_connection_index(codec, cap, pin) < 0)
-                                       break;
-                       } else if (num_conns <= imux->items[i].index)
-                               break;
-               }
-               if (i >= imux->num_items) {
-                       adc_nids[nums] = spec->private_adc_nids[n];
-                       capsrc_nids[nums++] = cap;
-               }
+               activate_path(codec, path, path->active, true);
        }
-       if (!nums) {
-               /* check whether ADC-switch is possible */
-               if (!alc_check_dyn_adc_switch(codec)) {
-                       if (spec->shared_mic_hp) {
-                               spec->shared_mic_hp = 0;
-                               spec->private_imux[0].num_items = 1;
-                               goto again;
-                       }
-                       printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
-                              " using fallback 0x%x\n",
-                              codec->chip_name, spec->private_adc_nids[0]);
-                       spec->num_adc_nids = 1;
-                       spec->auto_mic = 0;
-                       return;
-               }
-       } else if (nums != spec->num_adc_nids) {
-               memcpy(spec->private_adc_nids, adc_nids,
-                      nums * sizeof(hda_nid_t));
-               memcpy(spec->private_capsrc_nids, capsrc_nids,
-                      nums * sizeof(hda_nid_t));
-               spec->num_adc_nids = nums;
-       }
-
-       if (spec->auto_mic)
-               alc_auto_mic_check_imux(codec); /* check auto-mic setups */
-       else if (spec->input_mux->num_items == 1 || spec->shared_mic_hp)
-               spec->num_adc_nids = 1; /* reduce to a single ADC */
 }
 
 /*
  * initialize ADC paths
  */
-static void alc_auto_init_adc(struct hda_codec *codec, int adc_idx)
-{
-       struct alc_spec *spec = codec->spec;
-       hda_nid_t nid;
-
-       nid = spec->adc_nids[adc_idx];
-       /* mute ADC */
-       if (nid_has_mute(codec, nid, HDA_INPUT)) {
-               snd_hda_codec_write(codec, nid, 0,
-                                   AC_VERB_SET_AMP_GAIN_MUTE,
-                                   AMP_IN_MUTE(0));
-               return;
-       }
-       if (!spec->capsrc_nids)
-               return;
-       nid = spec->capsrc_nids[adc_idx];
-       if (nid_has_mute(codec, nid, HDA_OUTPUT))
-               snd_hda_codec_write(codec, nid, 0,
-                                   AC_VERB_SET_AMP_GAIN_MUTE,
-                                   AMP_OUT_MUTE);
-}
-
 static void alc_auto_init_input_src(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
-       int c, nums;
+       struct hda_input_mux *imux = &spec->private_imux[0];
+       struct nid_path *path;
+       int i, c, nums;
 
-       for (c = 0; c < spec->num_adc_nids; c++)
-               alc_auto_init_adc(codec, c);
        if (spec->dyn_adc_switch)
                nums = 1;
        else
                nums = spec->num_adc_nids;
-       for (c = 0; c < nums; c++)
-               alc_mux_select(codec, c, spec->cur_mux[c], true);
+
+       for (c = 0; c < nums; c++) {
+               for (i = 0; i < imux->num_items; i++) {
+                       path = get_nid_path(codec, spec->imux_pins[i],
+                                           get_adc_nid(codec, c, i));
+                       if (path) {
+                               bool active = path->active;
+                               if (i == spec->cur_mux[c])
+                                       active = true;
+                               activate_path(codec, path, active, false);
+                       }
+               }
+       }
+
+       alc_inv_dmic_sync(codec, true);
+       if (spec->shared_mic_hp)
+               update_shared_mic_hp(codec, spec->cur_mux[0]);
 }
 
 /* add mic boosts if needed */
        return 0;
 }
 
-/* select or unmute the given capsrc route */
-static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
-                                   int idx)
-{
-       if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
-               snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
-                                        HDA_AMP_MUTE, 0);
-       } else if (snd_hda_get_num_conns(codec, cap) > 1) {
-               snd_hda_codec_write_cache(codec, cap, 0,
-                                         AC_VERB_SET_CONNECT_SEL, idx);
-       }
-}
-
-/* set the default connection to that pin */
-static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
-{
-       struct alc_spec *spec = codec->spec;
-       int i;
-
-       if (!pin)
-               return 0;
-       for (i = 0; i < spec->num_adc_nids; i++) {
-               hda_nid_t cap = get_capsrc(spec, i);
-               int idx;
-
-               idx = get_connection_index(codec, cap, pin);
-               if (idx < 0)
-                       continue;
-               select_or_unmute_capsrc(codec, cap, idx);
-               return i; /* return the found index */
-       }
-       return -1; /* not found */
-}
-
-/* initialize some special cases for input sources */
-static void alc_init_special_input_src(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       int i;
-
-       for (i = 0; i < spec->autocfg.num_inputs; i++)
-               init_capsrc_for_pin(codec, spec->autocfg.inputs[i].pin);
-}
-
-/* assign appropriate capture mixers */
-static void set_capture_mixer(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       static const struct snd_kcontrol_new *caps[2][3] = {
-               { alc_capture_mixer_nosrc1,
-                 alc_capture_mixer_nosrc2,
-                 alc_capture_mixer_nosrc3 },
-               { alc_capture_mixer1,
-                 alc_capture_mixer2,
-                 alc_capture_mixer3 },
-       };
-
-       /* check whether either of ADC or MUX has a volume control */
-       if (!nid_has_volume(codec, spec->adc_nids[0], HDA_INPUT)) {
-               if (!spec->capsrc_nids)
-                       return; /* no volume */
-               if (!nid_has_volume(codec, spec->capsrc_nids[0], HDA_OUTPUT))
-                       return; /* no volume in capsrc, too */
-               spec->vol_in_capsrc = 1;
-       }
-
-       if (spec->num_adc_nids > 0) {
-               int mux = 0;
-               int num_adcs = 0;
-
-               if (spec->input_mux && spec->input_mux->num_items > 1)
-                       mux = 1;
-               if (spec->auto_mic) {
-                       num_adcs = 1;
-                       mux = 0;
-               } else if (spec->dyn_adc_switch)
-                       num_adcs = 1;
-               if (!num_adcs) {
-                       if (spec->num_adc_nids > 3)
-                               spec->num_adc_nids = 3;
-                       else if (!spec->num_adc_nids)
-                               return;
-                       num_adcs = spec->num_adc_nids;
-               }
-               spec->cap_mixer = caps[mux][num_adcs - 1];
-       }
-}
-
 /*
  * standard auto-parser initializations
  */
  dig_only:
        alc_auto_parse_digital(codec);
 
-       if (!spec->no_analog)
-               alc_remove_invalid_adc_nids(codec);
-
        if (ssid_nids)
                alc_ssid_check(codec, ssid_nids);
 
        if (!spec->no_analog) {
-               err = alc_auto_check_switches(codec);
+               err = alc_init_automute(codec);
                if (err < 0)
                        return err;
+
+               err = check_dyn_adc_switch(codec);
+               if (err < 0)
+                       return err;
+
+               if (!spec->shared_mic_hp) {
+                       err = alc_init_auto_mic(codec);
+                       if (err < 0)
+                       return err;
+               }
+
+               err = create_capture_mixers(codec);
+               if (err < 0)
+                       return err;
+
                err = alc_auto_add_mic_boost(codec);
                if (err < 0)
                        return err;
        if (spec->kctls.list)
                add_mixer(spec, spec->kctls.list);
 
-       if (!spec->no_analog && !spec->cap_mixer)
-               set_capture_mixer(codec);
-
        return 1;
 }