]> err.no Git - linux-2.6/blobdiff - sound/pci/hda/patch_realtek.c
[ALSA] hda-intel - Fix PCM device number assignment
[linux-2.6] / sound / pci / hda / patch_realtek.c
index 1b2ad52bc908314363218c9ddeafe8f5b527030b..85ea3f82de1925e217d67ce967f8e277843467ef 100644 (file)
@@ -23,7 +23,6 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
@@ -93,6 +92,7 @@ enum {
        ALC262_HP_BPC_D7000_WL,
        ALC262_HP_BPC_D7000_WF,
        ALC262_HP_TC_T5735,
+       ALC262_HP_RP5700,
        ALC262_BENQ_ED8,
        ALC262_SONY_ASSAMD,
        ALC262_BENQ_T31,
@@ -106,6 +106,8 @@ enum {
        ALC268_3ST,
        ALC268_TOSHIBA,
        ALC268_ACER,
+       ALC268_DELL,
+       ALC268_ZEPTO,
 #ifdef CONFIG_SND_DEBUG
        ALC268_TEST,
 #endif
@@ -156,6 +158,7 @@ enum {
        ALC662_5ST_DIG,
        ALC662_LENOVO_101E,
        ALC662_ASUS_EEEPC_P701,
+       ALC662_ASUS_EEEPC_EP20,
        ALC662_AUTO,
        ALC662_MODEL_LAST,
 };
@@ -195,6 +198,7 @@ enum {
        ALC883_HAIER_W66,               
        ALC888_6ST_HP,
        ALC888_3ST_HP,
+       ALC888_6ST_DELL,
        ALC883_MITAC,
        ALC883_AUTO,
        ALC883_MODEL_LAST,
@@ -217,6 +221,8 @@ struct alc_spec {
        char *stream_name_analog;       /* analog PCM stream */
        struct hda_pcm_stream *stream_analog_playback;
        struct hda_pcm_stream *stream_analog_capture;
+       struct hda_pcm_stream *stream_analog_alt_playback;
+       struct hda_pcm_stream *stream_analog_alt_capture;
 
        char *stream_name_digital;      /* digital PCM stream */
        struct hda_pcm_stream *stream_digital_playback;
@@ -227,6 +233,7 @@ struct alc_spec {
                                         * max_channels, dacs must be set
                                         * dig_out_nid and hp_nid are optional
                                         */
+       hda_nid_t alt_dac_nid;
 
        /* capture */
        unsigned int num_adc_nids;
@@ -260,7 +267,11 @@ struct alc_spec {
        /* for pin sensing */
        unsigned int sense_updated: 1;
        unsigned int jack_present: 1;
+       unsigned int master_sw: 1;
 
+       /* for virtual master */
+       hda_nid_t vmaster_nid;
+       u32 vmaster_tlv[4];
 #ifdef CONFIG_SND_HDA_POWER_SAVE
        struct hda_loopback_check loopback;
 #endif
@@ -805,7 +816,7 @@ static void alc_subsystem_id(struct hda_codec *codec,
        /* check sum */
        tmp = 0;
        for (i = 1; i < 16; i++) {
-               if ((ass >> i) && 1)
+               if ((ass >> i) & 1)
                        tmp++;
        }
        if (((ass >> 16) & 0xf) != tmp)
@@ -894,10 +905,10 @@ do_sku:
                break;
        }
        
-       /* is laptop and enable the function "Mute internal speaker
+       /* is laptop or Desktop and enable the function "Mute internal speaker
         * when the external headphone out jack is plugged"
         */
-       if (!(ass & 0x4) || !(ass & 0x8000))
+       if (!(ass & 0x8000))
                return;
        /*
         * 10~8 : Jack location
@@ -907,9 +918,9 @@ do_sku:
         *              when the external headphone out jack is plugged"
         */
        if (!spec->autocfg.speaker_pins[0]) {
-               if (spec->multiout.dac_nids[0])
+               if (spec->autocfg.line_out_pins[0])
                        spec->autocfg.speaker_pins[0] =
-                               spec->multiout.dac_nids[0];
+                               spec->autocfg.line_out_pins[0];
                else
                        return;
        }
@@ -1075,7 +1086,6 @@ static struct snd_kcontrol_new alc880_capture_mixer[] = {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                /* The multiple "Capture Source" controls confuse alsamixer
                 * So call somewhat different..
-                * FIXME: the controls appear in the "playback" view!
                 */
                /* .name = "Capture Source", */
                .name = "Input Source",
@@ -1097,7 +1107,6 @@ static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                /* The multiple "Capture Source" controls confuse alsamixer
                 * So call somewhat different..
-                * FIXME: the controls appear in the "playback" view!
                 */
                /* .name = "Capture Source", */
                .name = "Input Source",
@@ -1292,7 +1301,6 @@ static struct snd_kcontrol_new alc880_z71v_mixer[] = {
 };
 
 
-/* FIXME! */
 /*
  * ALC880 F1734 model
  *
@@ -1308,8 +1316,8 @@ static hda_nid_t alc880_f1734_dac_nids[1] = {
 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -1318,7 +1326,6 @@ static struct snd_kcontrol_new alc880_f1734_mixer[] = {
 };
 
 
-/* FIXME! */
 /*
  * ALC880 ASUS model
  *
@@ -1355,7 +1362,6 @@ static struct snd_kcontrol_new alc880_asus_mixer[] = {
        { } /* end */
 };
 
-/* FIXME! */
 /*
  * ALC880 ASUS W1V model
  *
@@ -1393,7 +1399,6 @@ static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                /* The multiple "Capture Source" controls confuse alsamixer
                 * So call somewhat different..
-                * FIXME: the controls appear in the "playback" view!
                 */
                /* .name = "Capture Source", */
                .name = "Input Source",
@@ -1407,10 +1412,10 @@ static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
 
 /* Uniwill */
 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
-       HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
@@ -1450,15 +1455,48 @@ static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
 };
 
 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
-       HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
        { } /* end */
 };
 
+/*
+ * virtual master controls
+ */
+
+/*
+ * slave controls for virtual master
+ */
+static const char *alc_slave_vols[] = {
+       "Front Playback Volume",
+       "Surround Playback Volume",
+       "Center Playback Volume",
+       "LFE Playback Volume",
+       "Side Playback Volume",
+       "Headphone Playback Volume",
+       "Speaker Playback Volume",
+       "Mono Playback Volume",
+       "Line-Out Playback Volume",
+       NULL,
+};
+
+static const char *alc_slave_sws[] = {
+       "Front Playback Switch",
+       "Surround Playback Switch",
+       "Center Playback Switch",
+       "LFE Playback Switch",
+       "Side Playback Switch",
+       "Headphone Playback Switch",
+       "Speaker Playback Switch",
+       "Mono Playback Switch",
+       "IEC958 Playback Switch",
+       NULL,
+};
+
 /*
  * build control elements
  */
@@ -1485,6 +1523,23 @@ static int alc_build_controls(struct hda_codec *codec)
                if (err < 0)
                        return err;
        }
+
+       /* if we have no master control, let's create it */
+       if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
+               snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
+                                       HDA_OUTPUT, spec->vmaster_tlv);
+               err = snd_hda_add_vmaster(codec, "Master Playback Volume",
+                                         spec->vmaster_tlv, alc_slave_vols);
+               if (err < 0)
+                       return err;
+       }
+       if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
+               err = snd_hda_add_vmaster(codec, "Master Playback Switch",
+                                         NULL, alc_slave_sws);
+               if (err < 0)
+                       return err;
+       }
+
        return 0;
 }
 
@@ -1856,7 +1911,6 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
                alc880_uniwill_p53_dcvol_automute(codec);
 }
 
-/* FIXME! */
 /*
  * F1734 pin configuration:
  * HP = 0x14, speaker-out = 0x15, mic = 0x18
@@ -1885,7 +1939,6 @@ static struct hda_verb alc880_pin_f1734_init_verbs[] = {
        { }
 };
 
-/* FIXME! */
 /*
  * ASUS pin configuration:
  * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
@@ -2032,9 +2085,8 @@ static struct hda_channel_mode alc880_lg_ch_modes[3] = {
 };
 
 static struct snd_kcontrol_new alc880_lg_mixer[] = {
-       /* FIXME: it's not really "master" but front channels */
-       HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
        HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
@@ -2322,7 +2374,7 @@ static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
 /*
  * Analog capture
  */
-static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
+static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
                                      struct hda_codec *codec,
                                      unsigned int stream_tag,
                                      unsigned int format,
@@ -2330,18 +2382,18 @@ static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
 {
        struct alc_spec *spec = codec->spec;
 
-       snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
+       snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
                                   stream_tag, 0, format);
        return 0;
 }
 
-static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
+static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
                                      struct hda_codec *codec,
                                      struct snd_pcm_substream *substream)
 {
        struct alc_spec *spec = codec->spec;
 
-       snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
+       snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
                                   0, 0, 0);
        return 0;
 }
@@ -2362,13 +2414,27 @@ static struct hda_pcm_stream alc880_pcm_analog_playback = {
 };
 
 static struct hda_pcm_stream alc880_pcm_analog_capture = {
-       .substreams = 2,
+       .substreams = 1,
+       .channels_min = 2,
+       .channels_max = 2,
+       /* NID is set in alc_build_pcms */
+};
+
+static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
+       .substreams = 1,
+       .channels_min = 2,
+       .channels_max = 2,
+       /* NID is set in alc_build_pcms */
+};
+
+static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
+       .substreams = 2, /* can be overridden */
        .channels_min = 2,
        .channels_max = 2,
        /* NID is set in alc_build_pcms */
        .ops = {
-               .prepare = alc880_capture_pcm_prepare,
-               .cleanup = alc880_capture_pcm_cleanup
+               .prepare = alc880_alt_capture_pcm_prepare,
+               .cleanup = alc880_alt_capture_pcm_cleanup
        },
 };
 
@@ -2392,7 +2458,7 @@ static struct hda_pcm_stream alc880_pcm_digital_capture = {
 };
 
 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
-static struct hda_pcm_stream alc_pcm_null_playback = {
+static struct hda_pcm_stream alc_pcm_null_stream = {
        .substreams = 0,
        .channels_min = 0,
        .channels_max = 0,
@@ -2433,6 +2499,7 @@ static int alc_build_pcms(struct hda_codec *codec)
                codec->num_pcms = 2;
                info = spec->pcm_rec + 1;
                info->name = spec->stream_name_digital;
+               info->pcm_type = HDA_PCM_TYPE_SPDIF;
                if (spec->multiout.dig_out_nid &&
                    spec->stream_digital_playback) {
                        info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
@@ -2449,17 +2516,32 @@ static int alc_build_pcms(struct hda_codec *codec)
         * model, configure a second analog capture-only PCM.
         */
        /* Additional Analaog capture for index #2 */
-       if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
-           spec->adc_nids) {
+       if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
+           (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
                codec->num_pcms = 3;
                info = spec->pcm_rec + 2;
                info->name = spec->stream_name_analog;
-               /* No playback stream for second PCM */
-               info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
-               info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
-               if (spec->stream_analog_capture) {
-                       info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
-                       info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
+               if (spec->alt_dac_nid) {
+                       info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
+                               *spec->stream_analog_alt_playback;
+                       info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
+                               spec->alt_dac_nid;
+               } else {
+                       info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
+                               alc_pcm_null_stream;
+                       info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
+               }
+               if (spec->num_adc_nids > 1) {
+                       info->stream[SNDRV_PCM_STREAM_CAPTURE] =
+                               *spec->stream_analog_alt_capture;
+                       info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
+                               spec->adc_nids[1];
+                       info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
+                               spec->num_adc_nids - 1;
+               } else {
+                       info->stream[SNDRV_PCM_STREAM_CAPTURE] =
+                               alc_pcm_null_stream;
+                       info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
                }
        }
 
@@ -3567,6 +3649,7 @@ static int patch_alc880(struct hda_codec *codec)
        spec->stream_name_analog = "ALC880 Analog";
        spec->stream_analog_playback = &alc880_pcm_analog_playback;
        spec->stream_analog_capture = &alc880_pcm_analog_capture;
+       spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
 
        spec->stream_name_digital = "ALC880 Digital";
        spec->stream_digital_playback = &alc880_pcm_digital_playback;
@@ -3591,6 +3674,8 @@ static int patch_alc880(struct hda_codec *codec)
                }
        }
 
+       spec->vmaster_nid = 0x0c;
+
        codec->patch_ops = alc_patch_ops;
        if (board_config == ALC880_AUTO)
                spec->init_hook = alc880_auto_init;
@@ -3747,18 +3832,135 @@ static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
        { } /* end */
 };
 
+/* update HP, line and mono out pins according to the master switch */
+static void alc260_hp_master_update(struct hda_codec *codec,
+                                   hda_nid_t hp, hda_nid_t line,
+                                   hda_nid_t mono)
+{
+       struct alc_spec *spec = codec->spec;
+       unsigned int val = spec->master_sw ? PIN_HP : 0;
+       /* change HP and line-out pins */
+       snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+                           val);
+       snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+                           val);
+       /* mono (speaker) depending on the HP jack sense */
+       val = (val && !spec->jack_present) ? PIN_OUT : 0;
+       snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+                           val);
+}
+
+static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
+                                  struct snd_ctl_elem_value *ucontrol)
+{
+       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct alc_spec *spec = codec->spec;
+       *ucontrol->value.integer.value = spec->master_sw;
+       return 0;
+}
+
+static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
+                                  struct snd_ctl_elem_value *ucontrol)
+{
+       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct alc_spec *spec = codec->spec;
+       int val = !!*ucontrol->value.integer.value;
+       hda_nid_t hp, line, mono;
+
+       if (val == spec->master_sw)
+               return 0;
+       spec->master_sw = val;
+       hp = (kcontrol->private_value >> 16) & 0xff;
+       line = (kcontrol->private_value >> 8) & 0xff;
+       mono = kcontrol->private_value & 0xff;
+       alc260_hp_master_update(codec, hp, line, mono);
+       return 1;
+}
+
+static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name = "Master Playback Switch",
+               .info = snd_ctl_boolean_mono_info,
+               .get = alc260_hp_master_sw_get,
+               .put = alc260_hp_master_sw_put,
+               .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
+       },
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
+                             HDA_OUTPUT),
+       HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
+       { } /* end */
+};
+
+static struct hda_verb alc260_hp_unsol_verbs[] = {
+       {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+       {},
+};
+
+static void alc260_hp_automute(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       unsigned int present;
+
+       present = snd_hda_codec_read(codec, 0x10, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0);
+       spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
+       alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
+}
+
+static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+       if ((res >> 26) == ALC880_HP_EVENT)
+               alc260_hp_automute(codec);
+}
+
 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name = "Master Playback Switch",
+               .info = snd_ctl_boolean_mono_info,
+               .get = alc260_hp_master_sw_get,
+               .put = alc260_hp_master_sw_put,
+               .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
+       },
        HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
        HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
        { } /* end */
 };
 
+static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
+       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+       {},
+};
+
+static void alc260_hp_3013_automute(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       unsigned int present;
+
+       present = snd_hda_codec_read(codec, 0x15, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0);
+       spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
+       alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
+}
+
+static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
+                                      unsigned int res)
+{
+       if ((res >> 26) == ALC880_HP_EVENT)
+               alc260_hp_3013_automute(codec);
+}
+
 /* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12, 
  * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
  */
@@ -3773,8 +3975,8 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
        ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
        HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
        HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
        { } /* end */
 };
 
@@ -3805,9 +4007,9 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = {
        HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
        HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
        ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
-       HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
+       HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
                              HDA_OUTPUT),
-       HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
+       HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
                           HDA_INPUT),
        HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
        HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
@@ -3868,7 +4070,6 @@ static struct snd_kcontrol_new alc260_capture_mixer[] = {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                /* The multiple "Capture Source" controls confuse alsamixer
                 * So call somewhat different..
-                * FIXME: the controls appear in the "playback" view!
                 */
                /* .name = "Capture Source", */
                .name = "Input Source",
@@ -3887,7 +4088,6 @@ static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                /* The multiple "Capture Source" controls confuse alsamixer
                 * So call somewhat different..
-                * FIXME: the controls appear in the "playback" view!
                 */
                /* .name = "Capture Source", */
                .name = "Input Source",
@@ -4479,17 +4679,8 @@ static struct hda_verb alc260_test_init_verbs[] = {
 };
 #endif
 
-static struct hda_pcm_stream alc260_pcm_analog_playback = {
-       .substreams = 1,
-       .channels_min = 2,
-       .channels_max = 2,
-};
-
-static struct hda_pcm_stream alc260_pcm_analog_capture = {
-       .substreams = 1,
-       .channels_min = 2,
-       .channels_max = 2,
-};
+#define alc260_pcm_analog_playback     alc880_pcm_analog_alt_playback
+#define alc260_pcm_analog_capture      alc880_pcm_analog_capture
 
 #define alc260_pcm_digital_playback    alc880_pcm_digital_playback
 #define alc260_pcm_digital_capture     alc880_pcm_digital_capture
@@ -4827,10 +5018,11 @@ static struct alc_config_preset alc260_presets[] = {
                .input_mux = &alc260_capture_source,
        },
        [ALC260_HP] = {
-               .mixers = { alc260_base_output_mixer,
+               .mixers = { alc260_hp_output_mixer,
                            alc260_input_mixer,
                            alc260_capture_alt_mixer },
-               .init_verbs = { alc260_init_verbs },
+               .init_verbs = { alc260_init_verbs,
+                               alc260_hp_unsol_verbs },
                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
                .dac_nids = alc260_dac_nids,
                .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
@@ -4838,12 +5030,15 @@ static struct alc_config_preset alc260_presets[] = {
                .num_channel_mode = ARRAY_SIZE(alc260_modes),
                .channel_mode = alc260_modes,
                .input_mux = &alc260_capture_source,
+               .unsol_event = alc260_hp_unsol_event,
+               .init_hook = alc260_hp_automute,
        },
        [ALC260_HP_3013] = {
                .mixers = { alc260_hp_3013_mixer,
                            alc260_input_mixer,
                            alc260_capture_alt_mixer },
-               .init_verbs = { alc260_hp_3013_init_verbs },
+               .init_verbs = { alc260_hp_3013_init_verbs,
+                               alc260_hp_3013_unsol_verbs },
                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
                .dac_nids = alc260_dac_nids,
                .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
@@ -4851,6 +5046,8 @@ static struct alc_config_preset alc260_presets[] = {
                .num_channel_mode = ARRAY_SIZE(alc260_modes),
                .channel_mode = alc260_modes,
                .input_mux = &alc260_capture_source,
+               .unsol_event = alc260_hp_3013_unsol_event,
+               .init_hook = alc260_hp_3013_automute,
        },
        [ALC260_FUJITSU_S702X] = {
                .mixers = { alc260_fujitsu_mixer,
@@ -4968,6 +5165,8 @@ static int patch_alc260(struct hda_codec *codec)
        spec->stream_digital_playback = &alc260_pcm_digital_playback;
        spec->stream_digital_capture = &alc260_pcm_digital_capture;
 
+       spec->vmaster_nid = 0x08;
+
        codec->patch_ops = alc_patch_ops;
        if (board_config == ALC260_AUTO)
                spec->init_hook = alc260_auto_init;
@@ -5030,10 +5229,14 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
        const struct hda_input_mux *imux = spec->input_mux;
        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
        static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
-       hda_nid_t nid = capture_mixers[adc_idx];
+       hda_nid_t nid;
        unsigned int *cur_val = &spec->cur_mux[adc_idx];
        unsigned int i, idx;
 
+       if (spec->num_adc_nids < 3)
+               nid = capture_mixers[adc_idx + 1];
+       else
+               nid = capture_mixers[adc_idx];
        idx = ucontrol->value.enumerated.item[0];
        if (idx >= imux->num_items)
                idx = imux->num_items - 1;
@@ -5168,15 +5371,15 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
 };
 
 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
-       HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE   ("Master Switch", 0x0c, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE  ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE  ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
+       HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
+       HDA_CODEC_MUTE  ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
        HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT),
+       HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
        { } /* end */
 };
@@ -5741,7 +5944,6 @@ static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                /* The multiple "Capture Source" controls confuse alsamixer
                 * So call somewhat different..
-                * FIXME: the controls appear in the "playback" view!
                 */
                /* .name = "Capture Source", */
                .name = "Input Source",
@@ -5764,7 +5966,6 @@ static struct snd_kcontrol_new alc882_capture_mixer[] = {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                /* The multiple "Capture Source" controls confuse alsamixer
                 * So call somewhat different..
-                * FIXME: the controls appear in the "playback" view!
                 */
                /* .name = "Capture Source", */
                .name = "Input Source",
@@ -5812,6 +6013,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
        SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
        SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
+       SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
        SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
        SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
@@ -6052,7 +6254,7 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec)
        hda_nid_t nid;
 
        nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
-       if (nid) {
+       if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
                err = add_control(spec, ALC_CTL_WIDGET_VOL,
                                  "Mic Boost",
                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
@@ -6060,7 +6262,7 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec)
                        return err;
        }
        nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
-       if (nid) {
+       if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
                err = add_control(spec, ALC_CTL_WIDGET_VOL,
                                  "Front Mic Boost",
                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
@@ -6123,6 +6325,7 @@ static int patch_alc882(struct hda_codec *codec)
                case 0x106b1000: /* iMac 24 */
                        board_config = ALC885_IMAC24;
                        break;
+               case 0x106b00a1: /* Macbook */
                case 0x106b2c00: /* Macbook Pro rev3 */
                        board_config = ALC885_MBP3;
                        break;
@@ -6155,6 +6358,9 @@ static int patch_alc882(struct hda_codec *codec)
        spec->stream_name_analog = "ALC882 Analog";
        spec->stream_analog_playback = &alc882_pcm_analog_playback;
        spec->stream_analog_capture = &alc882_pcm_analog_capture;
+       /* FIXME: setup DAC5 */
+       /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
+       spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
 
        spec->stream_name_digital = "ALC882 Digital";
        spec->stream_digital_playback = &alc882_pcm_digital_playback;
@@ -6179,6 +6385,8 @@ static int patch_alc882(struct hda_codec *codec)
                }
        }
 
+       spec->vmaster_nid = 0x0c;
+
        codec->patch_ops = alc_patch_ops;
        if (board_config == ALC882_AUTO)
                spec->init_hook = alc882_auto_init;
@@ -6255,7 +6463,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
        struct alc_spec *spec = codec->spec;
        const struct hda_input_mux *imux = spec->input_mux;
        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-       static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
+       static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
        hda_nid_t nid = capture_mixers[adc_idx];
        unsigned int *cur_val = &spec->cur_mux[adc_idx];
        unsigned int i, idx;
@@ -6600,8 +6808,8 @@ static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
@@ -6750,6 +6958,46 @@ static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
        { } /* end */
 };
 
+static struct snd_kcontrol_new alc888_6st_dell_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
+       HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
+       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
+       HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
+       HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               /* .name = "Capture Source", */
+               .name = "Input Source",
+               .count = 2,
+               .info = alc883_mux_enum_info,
+               .get = alc883_mux_enum_get,
+               .put = alc883_mux_enum_put,
+       },
+       { } /* end */
+};
+
 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -6996,6 +7244,15 @@ static struct hda_verb alc888_3st_hp_verbs[] = {
        { }
 };
 
+static struct hda_verb alc888_6st_dell_verbs[] = {
+       {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},  /* Rear : output 1 (0x0e) */
+       {0x16, AC_VERB_SET_CONNECT_SEL, 0x01},  /* CLFE : output 2 (0x0d) */
+       {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},  /* Side : output 3 (0x0f) */
+       {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+       { }
+};
+
 static struct hda_verb alc888_3st_hp_2ch_init[] = {
        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
@@ -7191,6 +7448,33 @@ static struct hda_verb alc883_acer_eapd_verbs[] = {
        { }
 };
 
+static void alc888_6st_dell_front_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+       present = snd_hda_codec_read(codec, 0x1b, 0,
+                               AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
+                               HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+       snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+                               HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+       snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
+                               HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+       snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
+                               HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+}
+
+static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
+                                            unsigned int res)
+{
+       switch (res >> 26) {
+       case ALC880_HP_EVENT:
+               printk("hp_event\n");
+               alc888_6st_dell_front_automute(codec);
+               break;
+       }
+}
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -7264,7 +7548,6 @@ static struct snd_kcontrol_new alc883_capture_mixer[] = {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                /* The multiple "Capture Source" controls confuse alsamixer
                 * So call somewhat different..
-                * FIXME: the controls appear in the "playback" view!
                 */
                /* .name = "Capture Source", */
                .name = "Input Source",
@@ -7283,6 +7566,7 @@ static struct snd_kcontrol_new alc883_capture_mixer[] = {
 /* pcm configuration: identiacal with ALC880 */
 #define alc883_pcm_analog_playback     alc880_pcm_analog_playback
 #define alc883_pcm_analog_capture      alc880_pcm_analog_capture
+#define alc883_pcm_analog_alt_capture  alc880_pcm_analog_alt_capture
 #define alc883_pcm_digital_playback    alc880_pcm_digital_playback
 #define alc883_pcm_digital_capture     alc880_pcm_digital_capture
 
@@ -7307,6 +7591,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
        [ALC883_HAIER_W66]      = "haier-w66",
        [ALC888_6ST_HP]         = "6stack-hp",
        [ALC888_3ST_HP]         = "3stack-hp",
+       [ALC888_6ST_DELL]       = "6stack-dell",
        [ALC883_MITAC]          = "mitac",
        [ALC883_AUTO]           = "auto",
 };
@@ -7317,6 +7602,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
        SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
        SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
+       SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
        SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
        SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
@@ -7355,6 +7641,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
        SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
        SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
+       SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
        SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
        {}
@@ -7591,6 +7878,21 @@ static struct alc_config_preset alc883_presets[] = {
                .need_dac_fix = 1,
                .input_mux = &alc883_capture_source,
        },
+       [ALC888_6ST_DELL] = {
+               .mixers = { alc888_6st_dell_mixer, alc883_chmode_mixer },
+               .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
+               .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+               .dac_nids = alc883_dac_nids,
+               .dig_out_nid = ALC883_DIGOUT_NID,
+               .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+               .adc_nids = alc883_adc_nids,
+               .dig_in_nid = ALC883_DIGIN_NID,
+               .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
+               .channel_mode = alc883_sixstack_modes,
+               .input_mux = &alc883_capture_source,
+               .unsol_event = alc888_6st_dell_unsol_event,
+               .init_hook = alc888_6st_dell_front_automute,
+       },
        [ALC883_MITAC] = {
                .mixers = { alc883_mitac_mixer },
                .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
@@ -7751,6 +8053,7 @@ static int patch_alc883(struct hda_codec *codec)
        spec->stream_name_analog = "ALC883 Analog";
        spec->stream_analog_playback = &alc883_pcm_analog_playback;
        spec->stream_analog_capture = &alc883_pcm_analog_capture;
+       spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
 
        spec->stream_name_digital = "ALC883 Digital";
        spec->stream_digital_playback = &alc883_pcm_digital_playback;
@@ -7761,6 +8064,8 @@ static int patch_alc883(struct hda_codec *codec)
                spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
        }
 
+       spec->vmaster_nid = 0x0c;
+
        codec->patch_ops = alc_patch_ops;
        if (board_config == ALC883_AUTO)
                spec->init_hook = alc883_auto_init;
@@ -7800,7 +8105,7 @@ static struct snd_kcontrol_new alc262_base_mixer[] = {
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
        /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
-          HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
+          HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
@@ -7822,19 +8127,105 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
        /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
-          HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
+          HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
        /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
        { } /* end */
 };
 
+/* update HP, line and mono-out pins according to the master switch */
+static void alc262_hp_master_update(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       int val = spec->master_sw;
+
+       /* HP & line-out */
+       snd_hda_codec_write_cache(codec, 0x1b, 0,
+                                 AC_VERB_SET_PIN_WIDGET_CONTROL,
+                                 val ? PIN_HP : 0);
+       snd_hda_codec_write_cache(codec, 0x15, 0,
+                                 AC_VERB_SET_PIN_WIDGET_CONTROL,
+                                 val ? PIN_HP : 0);
+       /* mono (speaker) depending on the HP jack sense */
+       val = val && !spec->jack_present;
+       snd_hda_codec_write_cache(codec, 0x16, 0,
+                                 AC_VERB_SET_PIN_WIDGET_CONTROL,
+                                 val ? PIN_OUT : 0);
+}
+
+static void alc262_hp_bpc_automute(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       unsigned int presence;
+       presence = snd_hda_codec_read(codec, 0x1b, 0,
+                                     AC_VERB_GET_PIN_SENSE, 0);
+       spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
+       alc262_hp_master_update(codec);
+}
+
+static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+       if ((res >> 26) != ALC880_HP_EVENT)
+               return;
+       alc262_hp_bpc_automute(codec);
+}
+
+static void alc262_hp_wildwest_automute(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       unsigned int presence;
+       presence = snd_hda_codec_read(codec, 0x15, 0,
+                                     AC_VERB_GET_PIN_SENSE, 0);
+       spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
+       alc262_hp_master_update(codec);
+}
+
+static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
+                                          unsigned int res)
+{
+       if ((res >> 26) != ALC880_HP_EVENT)
+               return;
+       alc262_hp_wildwest_automute(codec);
+}
+
+static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
+                                  struct snd_ctl_elem_value *ucontrol)
+{
+       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct alc_spec *spec = codec->spec;
+       *ucontrol->value.integer.value = spec->master_sw;
+       return 0;
+}
+
+static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
+                                  struct snd_ctl_elem_value *ucontrol)
+{
+       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct alc_spec *spec = codec->spec;
+       int val = !!*ucontrol->value.integer.value;
+
+       if (val == spec->master_sw)
+               return 0;
+       spec->master_sw = val;
+       alc262_hp_master_update(codec);
+       return 1;
+}
+
 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name = "Master Playback Switch",
+               .info = snd_ctl_boolean_mono_info,
+               .get = alc262_hp_master_sw_get,
+               .put = alc262_hp_master_sw_put,
+       },
        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
-
+       HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
+                             HDA_OUTPUT),
+       HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
+                           HDA_OUTPUT),
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
@@ -7853,12 +8244,21 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
 };
 
 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name = "Master Playback Switch",
+               .info = snd_ctl_boolean_mono_info,
+               .get = alc262_hp_master_sw_get,
+               .put = alc262_hp_master_sw_put,
+       },
        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
+                             HDA_OUTPUT),
+       HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
+                           HDA_OUTPUT),
        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
        HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
@@ -7878,43 +8278,20 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
        { } /* end */
 };
 
-static struct hda_bind_ctls alc262_hp_t5735_bind_front_vol = {
-       .ops = &snd_hda_bind_vol,
-       .values = {
-               HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
-               HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
-               0
-       },
-};
-
-static struct hda_bind_ctls alc262_hp_t5735_bind_front_sw = {
-       .ops = &snd_hda_bind_sw,
-       .values = {
-               HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
-               HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
-               0
-       },
-};
-
 /* mute/unmute internal speaker according to the hp jack and mute state */
 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
 {
        struct alc_spec *spec = codec->spec;
-       unsigned int mute;
 
        if (force || !spec->sense_updated) {
                unsigned int present;
                present = snd_hda_codec_read(codec, 0x15, 0,
                                             AC_VERB_GET_PIN_SENSE, 0);
-               spec->jack_present = (present & 0x80000000) != 0;
+               spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
                spec->sense_updated = 1;
        }
-       if (spec->jack_present)
-               mute = (0x7080 | ((0)<<8));  /* mute internal speaker */
-       else    /* unmute internal speaker if necessary */
-               mute = (0x7000 | ((0)<<8));
-               snd_hda_codec_write(codec, 0x0c, 0,
-                           AC_VERB_SET_AMP_GAIN_MUTE, mute );
+       snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
+                                spec->jack_present ? HDA_AMP_MUTE : 0);
 }
 
 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
@@ -7931,12 +8308,8 @@ static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
 }
 
 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
-       HDA_BIND_VOL("PCM Playback Volume", &alc262_hp_t5735_bind_front_vol),
-       HDA_BIND_SW("PCM Playback Switch",&alc262_hp_t5735_bind_front_sw),
-       HDA_CODEC_VOLUME("LineOut Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("LineOut Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -7953,6 +8326,37 @@ static struct hda_verb alc262_hp_t5735_verbs[] = {
        { }
 };
 
+static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
+       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
+       { } /* end */
+};
+
+static struct hda_verb alc262_hp_rp5700_verbs[] = {
+       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+       {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
+       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
+       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
+       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
+       {}
+};
+
+static struct hda_input_mux alc262_hp_rp5700_capture_source = {
+       .num_items = 1,
+       .items = {
+               { "Line", 0x1 },
+       },
+};
+
 /* bind hp and internal speaker mute (with plug check) */
 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
                                     struct snd_ctl_elem_value *ucontrol)
@@ -8579,7 +8983,7 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = {
        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
+       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 
@@ -8621,6 +9025,8 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = {
        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
 
+       {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+
        { }
 };
 
@@ -8715,6 +9121,8 @@ static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
 
+       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+
        { }
 };
 
@@ -8795,6 +9203,7 @@ static const char *alc262_models[ALC262_MODEL_LAST] = {
        [ALC262_HP_BPC]         = "hp-bpc",
        [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
        [ALC262_HP_TC_T5735]    = "hp-tc-t5735",
+       [ALC262_HP_RP5700]      = "hp-rp5700",
        [ALC262_BENQ_ED8]       = "benq",
        [ALC262_BENQ_T31]       = "benq-t31",
        [ALC262_SONY_ASSAMD]    = "sony-assamd",
@@ -8825,12 +9234,14 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
        SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
                      ALC262_HP_TC_T5735),
+       SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
        SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
        SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
        SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
        SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
        SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
        SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
+       SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
        SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
        SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
        SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
@@ -8897,6 +9308,8 @@ static struct alc_config_preset alc262_presets[] = {
                .num_channel_mode = ARRAY_SIZE(alc262_modes),
                .channel_mode = alc262_modes,
                .input_mux = &alc262_HP_capture_source,
+               .unsol_event = alc262_hp_bpc_unsol_event,
+               .init_hook = alc262_hp_bpc_automute,
        },
        [ALC262_HP_BPC_D7000_WF] = {
                .mixers = { alc262_HP_BPC_WildWest_mixer },
@@ -8907,6 +9320,8 @@ static struct alc_config_preset alc262_presets[] = {
                .num_channel_mode = ARRAY_SIZE(alc262_modes),
                .channel_mode = alc262_modes,
                .input_mux = &alc262_HP_D7000_capture_source,
+               .unsol_event = alc262_hp_wildwest_unsol_event,
+               .init_hook = alc262_hp_wildwest_automute,
        },
        [ALC262_HP_BPC_D7000_WL] = {
                .mixers = { alc262_HP_BPC_WildWest_mixer,
@@ -8918,6 +9333,8 @@ static struct alc_config_preset alc262_presets[] = {
                .num_channel_mode = ARRAY_SIZE(alc262_modes),
                .channel_mode = alc262_modes,
                .input_mux = &alc262_HP_D7000_capture_source,
+               .unsol_event = alc262_hp_wildwest_unsol_event,
+               .init_hook = alc262_hp_wildwest_automute,
        },
        [ALC262_HP_TC_T5735] = {
                .mixers = { alc262_hp_t5735_mixer },
@@ -8930,6 +9347,15 @@ static struct alc_config_preset alc262_presets[] = {
                .input_mux = &alc262_capture_source,
                .unsol_event = alc262_hp_t5735_unsol_event,
                .init_hook = alc262_hp_t5735_init_hook,
+       },
+       [ALC262_HP_RP5700] = {
+               .mixers = { alc262_hp_rp5700_mixer },
+               .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
+               .num_dacs = ARRAY_SIZE(alc262_dac_nids),
+               .dac_nids = alc262_dac_nids,
+               .num_channel_mode = ARRAY_SIZE(alc262_modes),
+               .channel_mode = alc262_modes,
+               .input_mux = &alc262_hp_rp5700_capture_source,
         },
        [ALC262_BENQ_ED8] = {
                .mixers = { alc262_base_mixer },
@@ -9059,6 +9485,8 @@ static int patch_alc262(struct hda_codec *codec)
                }
        }
 
+       spec->vmaster_nid = 0x0c;
+
        codec->patch_ops = alc_patch_ops;
        if (board_config == ALC262_AUTO)
                spec->init_hook = alc262_auto_init;
@@ -9216,6 +9644,49 @@ static void alc268_acer_init_hook(struct hda_codec *codec)
        alc268_acer_automute(codec, 1);
 }
 
+static struct snd_kcontrol_new alc268_dell_mixer[] = {
+       /* output mixer control */
+       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
+       { }
+};
+
+static struct hda_verb alc268_dell_verbs[] = {
+       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+       { }
+};
+
+/* mute/unmute internal speaker according to the hp jack and mute state */
+static void alc268_dell_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+       unsigned int mute;
+
+       present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
+       if (present & 0x80000000)
+               mute = HDA_AMP_MUTE;
+       else
+               mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
+       snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
+                                HDA_AMP_MUTE, mute);
+}
+
+static void alc268_dell_unsol_event(struct hda_codec *codec,
+                                   unsigned int res)
+{
+       if ((res >> 26) != ALC880_HP_EVENT)
+               return;
+       alc268_dell_automute(codec);
+}
+
+#define alc268_dell_init_hook  alc268_dell_automute
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -9326,7 +9797,6 @@ static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                /* The multiple "Capture Source" controls confuse alsamixer
                 * So call somewhat different..
-                * FIXME: the controls appear in the "playback" view!
                 */
                /* .name = "Capture Source", */
                .name = "Input Source",
@@ -9347,7 +9817,6 @@ static struct snd_kcontrol_new alc268_capture_mixer[] = {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                /* The multiple "Capture Source" controls confuse alsamixer
                 * So call somewhat different..
-                * FIXME: the controls appear in the "playback" view!
                 */
                /* .name = "Capture Source", */
                .name = "Input Source",
@@ -9390,7 +9859,8 @@ static struct snd_kcontrol_new alc268_test_mixer[] = {
        HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
        HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),
+       /* The below appears problematic on some hardwares */
+       /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
        HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
        HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
        HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
@@ -9570,6 +10040,7 @@ static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
 /* pcm configuration: identiacal with ALC880 */
 #define alc268_pcm_analog_playback     alc880_pcm_analog_playback
 #define alc268_pcm_analog_capture      alc880_pcm_analog_capture
+#define alc268_pcm_analog_alt_capture  alc880_pcm_analog_alt_capture
 #define alc268_pcm_digital_playback    alc880_pcm_digital_playback
 
 /*
@@ -9635,6 +10106,8 @@ static const char *alc268_models[ALC268_MODEL_LAST] = {
        [ALC268_3ST]            = "3stack",
        [ALC268_TOSHIBA]        = "toshiba",
        [ALC268_ACER]           = "acer",
+       [ALC268_DELL]           = "dell",
+       [ALC268_ZEPTO]          = "zepto",
 #ifdef CONFIG_SND_DEBUG
        [ALC268_TEST]           = "test",
 #endif
@@ -9643,12 +10116,16 @@ static const char *alc268_models[ALC268_MODEL_LAST] = {
 
 static struct snd_pci_quirk alc268_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
+       SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
        SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
+       SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
+       SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
        SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
        SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
        SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
        SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
        SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
+       SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
        {}
 };
 
@@ -9696,6 +10173,35 @@ static struct alc_config_preset alc268_presets[] = {
                .unsol_event = alc268_acer_unsol_event,
                .init_hook = alc268_acer_init_hook,
        },
+       [ALC268_DELL] = {
+               .mixers = { alc268_dell_mixer },
+               .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
+                               alc268_dell_verbs },
+               .num_dacs = ARRAY_SIZE(alc268_dac_nids),
+               .dac_nids = alc268_dac_nids,
+               .hp_nid = 0x02,
+               .num_channel_mode = ARRAY_SIZE(alc268_modes),
+               .channel_mode = alc268_modes,
+               .unsol_event = alc268_dell_unsol_event,
+               .init_hook = alc268_dell_init_hook,
+               .input_mux = &alc268_capture_source,
+       },
+       [ALC268_ZEPTO] = {
+               .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
+               .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
+                               alc268_toshiba_verbs },
+               .num_dacs = ARRAY_SIZE(alc268_dac_nids),
+               .dac_nids = alc268_dac_nids,
+               .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
+               .adc_nids = alc268_adc_nids_alt,
+               .hp_nid = 0x03,
+               .dig_out_nid = ALC268_DIGOUT_NID,
+               .num_channel_mode = ARRAY_SIZE(alc268_modes),
+               .channel_mode = alc268_modes,
+               .input_mux = &alc268_capture_source,
+               .unsol_event = alc268_toshiba_unsol_event,
+               .init_hook = alc268_toshiba_automute
+       },
 #ifdef CONFIG_SND_DEBUG
        [ALC268_TEST] = {
                .mixers = { alc268_test_mixer, alc268_capture_mixer },
@@ -9756,34 +10262,34 @@ static int patch_alc268(struct hda_codec *codec)
        spec->stream_name_analog = "ALC268 Analog";
        spec->stream_analog_playback = &alc268_pcm_analog_playback;
        spec->stream_analog_capture = &alc268_pcm_analog_capture;
+       spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
 
        spec->stream_name_digital = "ALC268 Digital";
        spec->stream_digital_playback = &alc268_pcm_digital_playback;
 
-       if (board_config == ALC268_AUTO) {
-               if (!spec->adc_nids && spec->input_mux) {
-                       /* check whether NID 0x07 is valid */
-                       unsigned int wcap = get_wcaps(codec, 0x07);
-
-                       /* get type */
-                       wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
-                       if (wcap != AC_WID_AUD_IN) {
-                               spec->adc_nids = alc268_adc_nids_alt;
-                               spec->num_adc_nids =
-                                       ARRAY_SIZE(alc268_adc_nids_alt);
-                               spec->mixers[spec->num_mixers] =
+       if (!spec->adc_nids && spec->input_mux) {
+               /* check whether NID 0x07 is valid */
+               unsigned int wcap = get_wcaps(codec, 0x07);
+
+               /* get type */
+               wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+               if (wcap != AC_WID_AUD_IN) {
+                       spec->adc_nids = alc268_adc_nids_alt;
+                       spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
+                       spec->mixers[spec->num_mixers] =
                                        alc268_capture_alt_mixer;
-                               spec->num_mixers++;
-                       } else {
-                               spec->adc_nids = alc268_adc_nids;
-                               spec->num_adc_nids =
-                                       ARRAY_SIZE(alc268_adc_nids);
-                               spec->mixers[spec->num_mixers] =
-                                       alc268_capture_mixer;
-                               spec->num_mixers++;
-                       }
+                       spec->num_mixers++;
+               } else {
+                       spec->adc_nids = alc268_adc_nids;
+                       spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
+                       spec->mixers[spec->num_mixers] =
+                               alc268_capture_mixer;
+                       spec->num_mixers++;
                }
        }
+
+       spec->vmaster_nid = 0x02;
+
        codec->patch_ops = alc_patch_ops;
        if (board_config == ALC268_AUTO)
                spec->init_hook = alc268_auto_init;
@@ -9830,7 +10336,6 @@ static struct snd_kcontrol_new alc269_capture_mixer[] = {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                /* The multiple "Capture Source" controls confuse alsamixer
                 * So call somewhat different..
-                * FIXME: the controls appear in the "playback" view!
                 */
                /* .name = "Capture Source", */
                .name = "Input Source",
@@ -10963,7 +11468,6 @@ static struct snd_kcontrol_new alc861_capture_mixer[] = {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                /* The multiple "Capture Source" controls confuse alsamixer
                 * So call somewhat different..
-                *FIXME: the controls appear in the "playback" view!
                 */
                /* .name = "Capture Source", */
                .name = "Input Source",
@@ -11294,6 +11798,8 @@ static int patch_alc861(struct hda_codec *codec)
        spec->stream_digital_playback = &alc861_pcm_digital_playback;
        spec->stream_digital_capture = &alc861_pcm_digital_capture;
 
+       spec->vmaster_nid = 0x03;
+
        codec->patch_ops = alc_patch_ops;
        if (board_config == ALC861_AUTO)
                spec->init_hook = alc861_auto_init;
@@ -11448,7 +11954,6 @@ static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                /* The multiple "Capture Source" controls confuse alsamixer
                 * So call somewhat different..
-                *FIXME: the controls appear in the "playback" view!
                 */
                /* .name = "Capture Source", */
                .name = "Input Source",
@@ -12270,6 +12775,8 @@ static int patch_alc861vd(struct hda_codec *codec)
        spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
        spec->num_mixers++;
 
+       spec->vmaster_nid = 0x02;
+
        codec->patch_ops = alc_patch_ops;
 
        if (board_config == ALC861VD_AUTO)
@@ -12495,8 +13002,8 @@ static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
        HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
@@ -12506,10 +13013,10 @@ static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
 };
 
 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
-       HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
 
-       HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 
        HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
        HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -12521,6 +13028,24 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
        { } /* end */
 };
 
+static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
+       HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
+       HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
+       HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+       { } /* end */
+};
+
 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -12606,6 +13131,13 @@ static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
        {}
 };
 
+/* Set Unsolicited Event*/
+static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
+       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+       {}
+};
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -12662,7 +13194,6 @@ static struct snd_kcontrol_new alc662_capture_mixer[] = {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                /* The multiple "Capture Source" controls confuse alsamixer
                 * So call somewhat different..
-                * FIXME: the controls appear in the "playback" view!
                 */
                /* .name = "Capture Source", */
                .name = "Input Source",
@@ -12742,6 +13273,40 @@ static void alc662_eeepc_inithook(struct hda_codec *codec)
        alc662_eeepc_mic_automute(codec);
 }
 
+static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
+{
+       unsigned int mute;
+       unsigned int present;
+
+       snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
+       present = snd_hda_codec_read(codec, 0x14, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0);
+       present = (present & 0x80000000) != 0;
+       if (present) {
+               /* mute internal speaker */
+               snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
+                                        HDA_AMP_MUTE, HDA_AMP_MUTE);
+       } else {
+               /* unmute internal speaker if necessary */
+               mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
+               snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
+                                        HDA_AMP_MUTE, mute);
+       }
+}
+
+/* unsolicited event for HP jack sensing */
+static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
+                                         unsigned int res)
+{
+       if ((res >> 26) == ALC880_HP_EVENT)
+               alc662_eeepc_ep20_automute(codec);
+}
+
+static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
+{
+       alc662_eeepc_ep20_automute(codec);
+}
+
 #ifdef CONFIG_SND_HDA_POWER_SAVE
 #define alc662_loopbacks       alc880_loopbacks
 #endif
@@ -12763,11 +13328,13 @@ static const char *alc662_models[ALC662_MODEL_LAST] = {
        [ALC662_5ST_DIG]        = "6stack-dig",
        [ALC662_LENOVO_101E]    = "lenovo-101e",
        [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
+       [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
        [ALC662_AUTO]           = "auto",
 };
 
 static struct snd_pci_quirk alc662_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
+       SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
        SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
        {}
 };
@@ -12855,6 +13422,21 @@ static struct alc_config_preset alc662_presets[] = {
                .unsol_event = alc662_eeepc_unsol_event,
                .init_hook = alc662_eeepc_inithook,
        },
+       [ALC662_ASUS_EEEPC_EP20] = {
+               .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
+                           alc662_chmode_mixer },
+               .init_verbs = { alc662_init_verbs,
+                               alc662_eeepc_ep20_sue_init_verbs },
+               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+               .dac_nids = alc662_dac_nids,
+               .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
+               .adc_nids = alc662_adc_nids,
+               .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
+               .channel_mode = alc662_3ST_6ch_modes,
+               .input_mux = &alc662_lenovo_101e_capture_source,
+               .unsol_event = alc662_eeepc_ep20_unsol_event,
+               .init_hook = alc662_eeepc_ep20_inithook,
+       },
 
 };
 
@@ -13014,6 +13596,7 @@ static void alc662_auto_init_multi_out(struct hda_codec *codec)
        struct alc_spec *spec = codec->spec;
        int i;
 
+       alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
        for (i = 0; i <= HDA_SIDE; i++) {
                hda_nid_t nid = spec->autocfg.line_out_pins[i];
                int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -13164,6 +13747,8 @@ static int patch_alc662(struct hda_codec *codec)
                spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
        }
 
+       spec->vmaster_nid = 0x02;
+
        codec->patch_ops = alc_patch_ops;
        if (board_config == ALC662_AUTO)
                spec->init_hook = alc662_auto_init;