return false;
 }
 
-static void clear_vol_marks(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       int i;
-
-       for (i = 0; i < spec->out_path.used; i++) {
-               struct nid_path *path = snd_array_elem(&spec->out_path, i);
-               path->ctls[0] = path->ctls[1] = 0;
-       }
-}
-
 /* badness definition */
 enum {
        /* No primary DAC is found for the main output */
        return NULL;
 }
 
-static int eval_shared_vol_badness(struct hda_codec *codec, hda_nid_t pin,
-                                  hda_nid_t dac)
+/* look for widgets in the path between the given NIDs appropriate for
+ * volume and mute controls, and assign the values to ctls[].
+ *
+ * When no appropriate widget is found in the path, the badness value
+ * is incremented depending on the situation.  The function returns the
+ * total badness for both volume and mute controls.
+ */
+static int assign_out_path_ctls(struct hda_codec *codec, hda_nid_t pin,
+                               hda_nid_t dac)
 {
        struct nid_path *path = get_out_path(codec, pin, dac);
        hda_nid_t nid;
        nid = alc_look_for_out_mute_nid(codec, path);
        if (nid) {
                unsigned int wid_type = get_wcaps_type(get_wcaps(codec, nid));
-               if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT)
+               if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT ||
+                   nid_has_mute(codec, nid, HDA_OUTPUT))
                        val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
                else
                        val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT);
                if (!add_new_out_path(codec, pin, dac))
                        dac = dacs[i] = 0;
                if (dac)
-                       badness += eval_shared_vol_badness(codec, pin, dac);
+                       badness += assign_out_path_ctls(codec, pin, dac);
        }
 
        return badness;
                        spec->vmaster_nid = alc_look_for_out_vol_nid(codec, path);
        }
 
-       /* clear the bitmap flags for creating controls */
-       clear_vol_marks(codec);
        kfree(best_cfg);
        return 0;
 }
 
+/* replace the channels in the composed amp value with the given number */
+static unsigned int amp_val_replace_channels(unsigned int val, unsigned int chs)
+{
+       val &= ~(0x3U << 16);
+       val |= chs << 16;
+       return val;
+}
+
 static int alc_auto_add_vol_ctl(struct hda_codec *codec,
                                const char *pfx, int cidx,
-                               hda_nid_t nid, unsigned int chs,
+                               unsigned int chs,
                                struct nid_path *path)
 {
        unsigned int val;
-       if (!nid || !path)
+       if (!path)
                return 0;
-       val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
-       if (is_ctl_used(codec, val, NID_PATH_VOL_CTL) && chs != 2) /* exclude LFE */
+       val = path->ctls[NID_PATH_VOL_CTL];
+       if (!val)
                return 0;
-       path->ctls[NID_PATH_VOL_CTL] = val;
-       return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
-                                val);
+       val = amp_val_replace_channels(val, chs);
+       return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx, val);
+}
+
+/* return the channel bits suitable for the given path->ctls[] */
+static int get_default_ch_nums(struct hda_codec *codec, struct nid_path *path,
+                              int type)
+{
+       int chs = 1; /* mono (left only) */
+       if (path) {
+               hda_nid_t nid = get_amp_nid_(path->ctls[type]);
+               if (nid && (get_wcaps(codec, nid) & AC_WCAP_STEREO))
+                       chs = 3; /* stereo */
+       }
+       return chs;
 }
 
 static int alc_auto_add_stereo_vol(struct hda_codec *codec,
                                   const char *pfx, int cidx,
-                                  hda_nid_t nid, struct nid_path *path)
+                                  struct nid_path *path)
 {
-       int chs = 1;
-       if (get_wcaps(codec, nid) & AC_WCAP_STEREO)
-               chs = 3;
-       return alc_auto_add_vol_ctl(codec, pfx, cidx, nid, chs, path);
+       int chs = get_default_ch_nums(codec, path, NID_PATH_VOL_CTL);
+       return alc_auto_add_vol_ctl(codec, pfx, cidx, chs, path);
 }
 
 /* create a mute-switch for the given mixer widget;
  */
 static int alc_auto_add_sw_ctl(struct hda_codec *codec,
                               const char *pfx, int cidx,
-                              hda_nid_t nid, unsigned int chs,
+                              unsigned int chs,
                               struct nid_path *path)
 {
-       int wid_type;
-       int type;
-       unsigned long val;
-       if (!nid || !path)
+       unsigned int val;
+       int type = ALC_CTL_WIDGET_MUTE;
+
+       if (!path)
                return 0;
-       wid_type = get_wcaps_type(get_wcaps(codec, nid));
-       if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT) {
-               type = ALC_CTL_WIDGET_MUTE;
-               val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
-       } else if (snd_hda_get_num_conns(codec, nid) == 1) {
-               type = ALC_CTL_WIDGET_MUTE;
-               val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT);
-       } else {
-               type = ALC_CTL_BIND_MUTE;
-               val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
-       }
-       if (is_ctl_used(codec, val, NID_PATH_MUTE_CTL) && chs != 2) /* exclude LFE */
+       val = path->ctls[NID_PATH_MUTE_CTL];
+       if (!val)
                return 0;
-       path->ctls[NID_PATH_MUTE_CTL] = val;
+       val = amp_val_replace_channels(val, chs);
+       if (get_amp_direction_(val) == HDA_INPUT) {
+               hda_nid_t nid = get_amp_nid_(val);
+               if (snd_hda_get_num_conns(codec, nid) > 1) {
+                       type = ALC_CTL_BIND_MUTE;
+                       val |= 2 << 19; /* FIXME: fixed two widgets, so far */
+               }
+       }
        return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
 }
 
 static int alc_auto_add_stereo_sw(struct hda_codec *codec, const char *pfx,
-                                 int cidx, hda_nid_t nid,
-                                 struct nid_path *path)
+                                 int cidx, struct nid_path *path)
 {
-       int chs = 1;
-       if (get_wcaps(codec, nid) & AC_WCAP_STEREO)
-               chs = 3;
-       return alc_auto_add_sw_ctl(codec, pfx, cidx, nid, chs, path);
+       int chs = get_default_ch_nums(codec, path, NID_PATH_MUTE_CTL);
+       return alc_auto_add_sw_ctl(codec, pfx, cidx, chs, path);
 }
 
 static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec,
                const char *name;
                int index;
                hda_nid_t dac, pin;
-               hda_nid_t sw, vol;
                struct nid_path *path;
 
                dac = spec->multiout.dac_nids[i];
                path = get_out_path(codec, pin, dac);
                if (!path)
                        continue;
-               sw = alc_look_for_out_mute_nid(codec, path);
-               vol = alc_look_for_out_vol_nid(codec, path);
                if (!name || !strcmp(name, "CLFE")) {
                        /* Center/LFE */
-                       err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1,
-                                                  path);
+                       err = alc_auto_add_vol_ctl(codec, "Center", 0, 1, path);
                        if (err < 0)
                                return err;
-                       err = alc_auto_add_vol_ctl(codec, "LFE", 0, vol, 2,
-                                                  path);
+                       err = alc_auto_add_vol_ctl(codec, "LFE", 0, 2, path);
                        if (err < 0)
                                return err;
-                       err = alc_auto_add_sw_ctl(codec, "Center", 0, sw, 1,
-                                                 path);
+                       err = alc_auto_add_sw_ctl(codec, "Center", 0, 1, path);
                        if (err < 0)
                                return err;
-                       err = alc_auto_add_sw_ctl(codec, "LFE", 0, sw, 2,
-                                                 path);
+                       err = alc_auto_add_sw_ctl(codec, "LFE", 0, 2, path);
                        if (err < 0)
                                return err;
                } else {
-                       err = alc_auto_add_stereo_vol(codec, name, index, vol,
-                                                     path);
+                       err = alc_auto_add_stereo_vol(codec, name, index, path);
                        if (err < 0)
                                return err;
-                       err = alc_auto_add_stereo_sw(codec, name, index, sw,
-                                                    path);
+                       err = alc_auto_add_stereo_sw(codec, name, index, path);
                        if (err < 0)
                                return err;
                }
                                     hda_nid_t dac, const char *pfx,
                                     int cidx)
 {
-       struct alc_spec *spec = codec->spec;
        struct nid_path *path;
-       hda_nid_t sw, vol;
        int err;
 
        path = get_out_path(codec, pin, dac);
        if (!path)
                return 0;
-
-       if (!dac) {
-               unsigned int val;
-               /* the corresponding DAC is already occupied */
-               if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
-                       return 0; /* no way */
-               /* create a switch only */
-               val = HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT);
-               if (is_ctl_used(codec, val, NID_PATH_MUTE_CTL))
-                       return 0; /* already created */
-               path->ctls[NID_PATH_MUTE_CTL] = val;
-               return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val);
+       /* bind volume control will be created in the case of dac = 0 */
+       if (dac) {
+               err = alc_auto_add_stereo_vol(codec, pfx, cidx, path);
+               if (err < 0)
+                       return err;
        }
-
-       sw = alc_look_for_out_mute_nid(codec, path);
-       vol = alc_look_for_out_vol_nid(codec, path);
-       err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol, path);
-       if (err < 0)
-               return err;
-       err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw, path);
+       err = alc_auto_add_stereo_sw(codec, pfx, cidx, path);
        if (err < 0)
                return err;
        return 0;
                return badness;
        }
 
-       return 0;
+       /* assign volume and mute controls */
+       for (i = old_pins; i < spec->multi_ios; i++)
+               badness += assign_out_path_ctls(codec, spec->multi_io[i].pin,
+                                               spec->multi_io[i].dac);
+
+       return badness;
 }
 
 static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,