[ALSA] hda-codec - Add quirk for another MSI laptop to alc883_cfg_tbl[]
[safe/jmp/linux-2.6] / sound / pci / hda / patch_realtek.c
index 61dffb8..a31735d 100644 (file)
@@ -93,10 +93,18 @@ enum {
        ALC262_HP_BPC_D7000_WL,
        ALC262_HP_BPC_D7000_WF,
        ALC262_BENQ_ED8,
+       ALC262_SONY_ASSAMD,
        ALC262_AUTO,
        ALC262_MODEL_LAST /* last tag */
 };
 
+/* ALC268 models */
+enum {
+       ALC268_3ST,
+       ALC268_AUTO,
+       ALC268_MODEL_LAST /* last tag */
+};
+
 /* ALC861 models */
 enum {
        ALC861_3ST,
@@ -117,6 +125,8 @@ enum {
        ALC861VD_3ST,
        ALC861VD_3ST_DIG,
        ALC861VD_6ST_DIG,
+       ALC861VD_LENOVO,
+       ALC861VD_DALLAS,
        ALC861VD_AUTO,
        ALC861VD_MODEL_LAST,
 };
@@ -137,8 +147,11 @@ enum {
        ALC882_3ST_DIG,
        ALC882_6ST_DIG,
        ALC882_ARIMA,
-       ALC882_AUTO,
+       ALC882_W2JC,
+       ALC882_TARGA,
+       ALC882_ASUS_A7J,
        ALC885_MACPRO,
+       ALC882_AUTO,
        ALC882_MODEL_LAST,
 };
 
@@ -150,11 +163,13 @@ enum {
        ALC883_6ST_DIG,
        ALC883_TARGA_DIG,
        ALC883_TARGA_2ch_DIG,
-       ALC888_DEMO_BOARD,
        ALC883_ACER,
        ALC883_MEDION,
+       ALC883_MEDION_MD2,      
        ALC883_LAPTOP_EAPD,
        ALC883_LENOVO_101E_2ch,
+       ALC883_LENOVO_NB0763,
+       ALC888_LENOVO_MS7195_DIG,               
        ALC883_AUTO,
        ALC883_MODEL_LAST,
 };
@@ -635,6 +650,13 @@ static struct hda_verb alc_gpio2_init_verbs[] = {
        { }
 };
 
+static struct hda_verb alc_gpio3_init_verbs[] = {
+       {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
+       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
+       {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
+       { }
+};
+
 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
  *     31 ~ 16 :       Manufacture ID
  *     15 ~ 8  :       SKU ID
@@ -660,7 +682,22 @@ static void alc_subsystem_id(struct hda_codec *codec,
        case 3:
                snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
                break;
+       case 7:
+               snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
+               break;
        case 5:
+               switch (codec->vendor_id) {
+               case 0x10ec0862:
+               case 0x10ec0660:
+               case 0x10ec0662:        
+               case 0x10ec0267:
+               case 0x10ec0268:
+                       snd_hda_codec_write(codec, 0x14, 0,
+                                           AC_VERB_SET_EAPD_BTLENABLE, 2);
+                       snd_hda_codec_write(codec, 0x15, 0,
+                                           AC_VERB_SET_EAPD_BTLENABLE, 2);
+                       return;
+               }
        case 6:
                if (ass & 4) {  /* bit 2 : 0 = Desktop, 1 = Laptop */
                        hda_nid_t port = 0;
@@ -1487,7 +1524,7 @@ static struct hda_verb alc880_beep_init_verbs[] = {
 };
 
 /* toggle speaker-output according to the hp-jack state */
-static void alc880_uniwill_automute(struct hda_codec *codec)
+static void alc880_uniwill_hp_automute(struct hda_codec *codec)
 {
        unsigned int present;
        unsigned char bits;
@@ -1503,11 +1540,27 @@ static void alc880_uniwill_automute(struct hda_codec *codec)
                                 0x80, bits);
        snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0,
                                 0x80, bits);
+}
+
+/* auto-toggle front mic */
+static void alc880_uniwill_mic_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+       unsigned char bits;
 
        present = snd_hda_codec_read(codec, 0x18, 0,
                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
-       snd_hda_codec_write(codec, 0x0b, 0, AC_VERB_SET_AMP_GAIN_MUTE,
-                           0x7000 | (0x01 << 8) | bits);
+       bits = present ? 0x80 : 0;
+       snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
+                                0x80, bits);
+       snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
+                                0x80, bits);
+}
+
+static void alc880_uniwill_automute(struct hda_codec *codec)
+{
+       alc880_uniwill_hp_automute(codec);
+       alc880_uniwill_mic_automute(codec);
 }
 
 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
@@ -1516,9 +1569,14 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec,
        /* Looks like the unsol event is incompatible with the standard
         * definition.  4bit tag is placed at 28 bit!
         */
-       if ((res >> 28) == ALC880_HP_EVENT ||
-           (res >> 28) == ALC880_MIC_EVENT)
-               alc880_uniwill_automute(codec);
+       switch (res >> 28) {
+       case ALC880_HP_EVENT:
+               alc880_uniwill_hp_automute(codec);
+               break;
+       case ALC880_MIC_EVENT:
+               alc880_uniwill_mic_automute(codec);
+               break;
+       }
 }
 
 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
@@ -3095,6 +3153,14 @@ static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
        }
 }
 
+static int get_pin_type(int line_out_type)
+{
+       if (line_out_type == AUTO_PIN_HP_OUT)
+               return PIN_HP;
+       else
+               return PIN_OUT;
+}
+
 static void alc880_auto_init_multi_out(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
@@ -3103,7 +3169,8 @@ static void alc880_auto_init_multi_out(struct hda_codec *codec)
        alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
        for (i = 0; i < spec->autocfg.line_outs; i++) {
                hda_nid_t nid = spec->autocfg.line_out_pins[i];
-               alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
+               int pin_type = get_pin_type(spec->autocfg.line_out_type);
+               alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
        }
 }
 
@@ -4292,8 +4359,10 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec)
 
        alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
        nid = spec->autocfg.line_out_pins[0];
-       if (nid)
-               alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
+       if (nid) {
+               int pin_type = get_pin_type(spec->autocfg.line_out_type);
+               alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
+       }
        
        nid = spec->autocfg.speaker_pins[0];
        if (nid)
@@ -4301,7 +4370,7 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec)
 
        nid = spec->autocfg.hp_pins[0];
        if (nid)
-               alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
+               alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
 }
 
 #define ALC260_PIN_CD_NID              0x16
@@ -4697,6 +4766,35 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
 }
 
 /*
+ * 2ch mode
+ */
+static struct hda_verb alc882_3ST_ch2_init[] = {
+       { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
+       { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+       { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+       { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+       { } /* end */
+};
+
+/*
+ * 6ch mode
+ */
+static struct hda_verb alc882_3ST_ch6_init[] = {
+       { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+       { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+       { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
+       { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+       { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+       { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
+       { } /* end */
+};
+
+static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
+       { 2, alc882_3ST_ch2_init },
+       { 6, alc882_3ST_ch6_init },
+};
+
+/*
  * 6ch mode
  */
 static struct hda_verb alc882_sixstack_ch6_init[] = {
@@ -4753,6 +4851,55 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
        { } /* end */
 };
 
+static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 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("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("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
+       HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
+       { } /* end */
+};
+
+static struct snd_kcontrol_new alc882_targa_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 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_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+       { } /* end */
+};
+
+/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
+ *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
+ */
+static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 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("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
+       HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, 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 alc882_chmode_mixer[] = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -4914,6 +5061,66 @@ static struct hda_verb alc882_macpro_init_verbs[] = {
        { }
 };
 
+static struct hda_verb alc882_targa_verbs[] = {
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       
+       {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
+       {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
+       {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
+
+       {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+       {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
+       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
+       {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
+       { } /* end */
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc882_targa_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+       present = snd_hda_codec_read(codec, 0x14, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
+                                0x80, present ? 0x80 : 0);
+       snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
+                                0x80, present ? 0x80 : 0);
+       snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
+}
+
+static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+       /* Looks like the unsol event is incompatible with the standard
+        * definition.  4bit tag is placed at 26 bit!
+        */
+       if (((res >> 26) == ALC880_HP_EVENT)) {
+               alc882_targa_automute(codec);
+       }
+}
+
+static struct hda_verb alc882_asus_a7j_verbs[] = {
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       
+       {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
+       {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
+
+       {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
+       {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
+       {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
+       { } /* end */
+};
+
 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
 {
        unsigned int gpiostate, gpiomask, gpiodir;
@@ -5072,6 +5279,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
        [ALC882_3ST_DIG]        = "3stack-dig",
        [ALC882_6ST_DIG]        = "6stack-dig",
        [ALC882_ARIMA]          = "arima",
+       [ALC882_W2JC]           = "w2jc",
        [ALC885_MACPRO]         = "macpro",
        [ALC882_AUTO]           = "auto",
 };
@@ -5080,8 +5288,11 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
        SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
+       SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
        SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
+       SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
        SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
+       SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
        {}
 };
 
@@ -5118,6 +5329,18 @@ static struct alc_config_preset alc882_presets[] = {
                .channel_mode = alc882_sixstack_modes,
                .input_mux = &alc882_capture_source,
        },
+       [ALC882_W2JC] = {
+               .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
+               .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
+                               alc880_gpio1_init_verbs },
+               .num_dacs = ARRAY_SIZE(alc882_dac_nids),
+               .dac_nids = alc882_dac_nids,
+               .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
+               .channel_mode = alc880_threestack_modes,
+               .need_dac_fix = 1,
+               .input_mux = &alc882_capture_source,
+               .dig_out_nid = ALC882_DIGOUT_NID,
+       },
        [ALC885_MACPRO] = {
                .mixers = { alc882_macpro_mixer },
                .init_verbs = { alc882_macpro_init_verbs },
@@ -5129,6 +5352,36 @@ static struct alc_config_preset alc882_presets[] = {
                .channel_mode = alc882_ch_modes,
                .input_mux = &alc882_capture_source,
        },
+       [ALC882_TARGA] = {
+               .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
+                           alc882_capture_mixer },
+               .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
+               .num_dacs = ARRAY_SIZE(alc882_dac_nids),
+               .dac_nids = alc882_dac_nids,
+               .dig_out_nid = ALC882_DIGOUT_NID,
+               .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
+               .adc_nids = alc882_adc_nids,
+               .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
+               .channel_mode = alc882_3ST_6ch_modes,
+               .need_dac_fix = 1,
+               .input_mux = &alc882_capture_source,
+               .unsol_event = alc882_targa_unsol_event,
+               .init_hook = alc882_targa_automute,
+       },
+       [ALC882_ASUS_A7J] = {
+               .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
+                           alc882_capture_mixer },
+               .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
+               .num_dacs = ARRAY_SIZE(alc882_dac_nids),
+               .dac_nids = alc882_dac_nids,
+               .dig_out_nid = ALC882_DIGOUT_NID,
+               .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
+               .adc_nids = alc882_adc_nids,
+               .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
+               .channel_mode = alc882_3ST_6ch_modes,
+               .need_dac_fix = 1,
+               .input_mux = &alc882_capture_source,
+       },      
 };
 
 
@@ -5164,8 +5417,9 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec)
        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);
                if (nid)
-                       alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT,
+                       alc882_auto_set_output_and_unmute(codec, nid, pin_type,
                                                          i);
        }
 }
@@ -5355,6 +5609,16 @@ static struct hda_input_mux alc883_lenovo_101e_capture_source = {
        },
 };
 
+static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
+       .num_items = 4,
+       .items = {
+               { "Mic", 0x0 },
+               { "iMic", 0x1 },
+               { "Line", 0x2 },
+               { "CD", 0x4 },
+       },
+};
+
 #define alc883_mux_enum_info alc_mux_enum_info
 #define alc883_mux_enum_get alc_mux_enum_get
 
@@ -5686,6 +5950,58 @@ static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
        { } /* end */
 };
 
+static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
+       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 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("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, 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_medion_md2_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Front Playback Switch", 0x15, 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("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, 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("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_chmode_mixer[] = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -5800,21 +6116,108 @@ static struct hda_verb alc883_lenovo_101e_verbs[] = {
        { } /* end */
 };
 
-/* toggle speaker-output according to the hp-jack state */
-static void alc883_tagra_automute(struct hda_codec *codec)
+static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
+        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       { } /* end */
+};
+
+static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
+       {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
+       { } /* end */
+};
+
+/* toggle front-jack and RCA according to the hp-jack state */
+static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
 {
        unsigned int present;
-       unsigned char bits;
-
-       present = snd_hda_codec_read(codec, 0x14, 0,
+       present = snd_hda_codec_read(codec, 0x1b, 0,
                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
-       bits = present ? 0x80 : 0;
-       snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
-                                0x80, bits);
-       snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
-                                0x80, bits);
-       snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
-                           present ? 1 : 3);
+       snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+                                0x80, present ? 0x80 : 0);
+       snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+                                0x80, present ? 0x80 : 0);
+       snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+                                0x80, present ? 0x80 : 0);
+       snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+                                0x80, present ? 0x80 : 0);
+       
+}
+
+/* toggle RCA according to the front-jack state */
+static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+       present = snd_hda_codec_read(codec, 0x14, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+                                0x80, present ? 0x80 : 0);
+       snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+                                0x80, present ? 0x80 : 0);
+       
+}
+static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
+                                            unsigned int res)
+{
+       if ((res >> 26) == ALC880_HP_EVENT)
+               alc888_lenovo_ms7195_front_automute(codec);
+       if ((res >> 26) == ALC880_FRONT_EVENT)
+               alc888_lenovo_ms7195_rca_automute(codec);
+}
+
+static struct hda_verb alc883_medion_md2_verbs[] = {
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+
+       {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+       { } /* end */
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc883_medion_md2_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+       present = snd_hda_codec_read(codec, 0x14, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+                                0x80, present ? 0x80 : 0);
+       snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+                                0x80, present ? 0x80 : 0);
+}
+
+static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
+                                         unsigned int res)
+{
+       if ((res >> 26) == ALC880_HP_EVENT)
+               alc883_medion_md2_automute(codec);
+}
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc883_tagra_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+       unsigned char bits;
+
+       present = snd_hda_codec_read(codec, 0x14, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       bits = present ? 0x80 : 0;
+       snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
+                                0x80, bits);
+       snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
+                                0x80, bits);
+       snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
+                           present ? 1 : 3);
 }
 
 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -5965,11 +6368,13 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
        [ALC883_6ST_DIG]        = "6stack-dig",
        [ALC883_TARGA_DIG]      = "targa-dig",
        [ALC883_TARGA_2ch_DIG]  = "targa-2ch-dig",
-       [ALC888_DEMO_BOARD]     = "6stack-dig-demo",
        [ALC883_ACER]           = "acer",
        [ALC883_MEDION]         = "medion",
+       [ALC883_MEDION_MD2]     = "medion-md2",
        [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
        [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
+       [ALC883_LENOVO_NB0763]  = "lenovo-nb0763",
+       [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
        [ALC883_AUTO]           = "auto",
 };
 
@@ -5981,8 +6386,11 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
+       SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
+       SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
        SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
+       SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
        SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
@@ -5993,10 +6401,14 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
        SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
+       SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
        SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
        SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
        SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
-       SND_PCI_QUIRK(0x17aa, 0x101e, "lenovo 101e", ALC883_LENOVO_101E_2ch),
+       SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
+       SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
+       SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
+       SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
        {}
 };
 
@@ -6082,19 +6494,6 @@ static struct alc_config_preset alc883_presets[] = {
                .unsol_event = alc883_tagra_unsol_event,
                .init_hook = alc883_tagra_automute,
        },
-       [ALC888_DEMO_BOARD] = {
-               .mixers = { alc883_base_mixer, alc883_chmode_mixer },
-               .init_verbs = { alc883_init_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,
-       },
        [ALC883_ACER] = {
                .mixers = { alc883_base_mixer,
                            alc883_chmode_mixer },
@@ -6125,6 +6524,20 @@ static struct alc_config_preset alc883_presets[] = {
                .channel_mode = alc883_sixstack_modes,
                .input_mux = &alc883_capture_source,
        },
+       [ALC883_MEDION_MD2] = {
+               .mixers = { alc883_medion_md2_mixer},
+               .init_verbs = { alc883_init_verbs, alc883_medion_md2_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,
+               .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
+               .channel_mode = alc883_3ST_2ch_modes,
+               .input_mux = &alc883_capture_source,
+               .unsol_event = alc883_medion_md2_unsol_event,
+               .init_hook = alc883_medion_md2_automute,
+       },      
        [ALC883_LAPTOP_EAPD] = {
                .mixers = { alc883_base_mixer,
                            alc883_chmode_mixer },
@@ -6150,6 +6563,35 @@ static struct alc_config_preset alc883_presets[] = {
                .unsol_event = alc883_lenovo_101e_unsol_event,
                .init_hook = alc883_lenovo_101e_all_automute,
        },
+       [ALC883_LENOVO_NB0763] = {
+               .mixers = { alc883_lenovo_nb0763_mixer },
+               .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
+               .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+               .dac_nids = alc883_dac_nids,
+               .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+               .adc_nids = alc883_adc_nids,
+               .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
+               .channel_mode = alc883_3ST_2ch_modes,
+               .need_dac_fix = 1,
+               .input_mux = &alc883_lenovo_nb0763_capture_source,
+               .unsol_event = alc883_medion_md2_unsol_event,
+               .init_hook = alc883_medion_md2_automute,
+       },
+       [ALC888_LENOVO_MS7195_DIG] = {
+               .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
+               .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_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,
+               .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
+               .channel_mode = alc883_3ST_6ch_modes,
+               .need_dac_fix = 1,
+               .input_mux = &alc883_capture_source,
+               .unsol_event = alc883_lenovo_ms7195_unsol_event,
+               .init_hook = alc888_lenovo_ms7195_front_automute,
+       },      
 };
 
 
@@ -6185,8 +6627,9 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec)
        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);
                if (nid)
-                       alc883_auto_set_output_and_unmute(codec, nid, PIN_OUT,
+                       alc883_auto_set_output_and_unmute(codec, nid, pin_type,
                                                          i);
        }
 }
@@ -6412,6 +6855,18 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
        { } /* end */
 };
 
+static struct snd_kcontrol_new alc262_sony_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Front Playback Switch", 0x15, 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("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
+       HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
+       { } /* end */
+};
+
+
+
 #define alc262_capture_mixer           alc882_capture_mixer
 #define alc262_capture_alt_mixer       alc882_capture_alt_mixer
 
@@ -6510,6 +6965,15 @@ static struct hda_verb alc262_hippo1_unsol_verbs[] = {
        {}
 };
 
+static struct hda_verb alc262_sony_unsol_verbs[] = {
+       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},   // Front Mic
+
+       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+};
+
 /* mute/unmute internal speaker according to the hp jack and mute state */
 static void alc262_hippo_automute(struct hda_codec *codec, int force)
 {
@@ -7128,6 +7592,7 @@ static const char *alc262_models[ALC262_MODEL_LAST] = {
        [ALC262_HP_BPC]         = "hp-bpc",
        [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
        [ALC262_BENQ_ED8]       = "benq",
+       [ALC262_BENQ_ED8]       = "sony-assamd",
        [ALC262_AUTO]           = "auto",
 };
 
@@ -7135,8 +7600,12 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
        SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
        SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
+       SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
+       SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
        SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
+       SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
        SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
+       SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
        SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
        SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
        SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
@@ -7149,6 +7618,9 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
        SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
        SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
        SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
+       SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
+       SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
+       SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
        {}
 };
 
@@ -7236,49 +7708,566 @@ static struct alc_config_preset alc262_presets[] = {
                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
                .dac_nids = alc262_dac_nids,
                .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc262_modes),
-               .channel_mode = alc262_modes,
-               .input_mux = &alc262_capture_source,
+               .num_channel_mode = ARRAY_SIZE(alc262_modes),
+               .channel_mode = alc262_modes,
+               .input_mux = &alc262_capture_source,
+       },
+       [ALC262_SONY_ASSAMD] = {
+               .mixers = { alc262_sony_mixer },
+               .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
+               .num_dacs = ARRAY_SIZE(alc262_dac_nids),
+               .dac_nids = alc262_dac_nids,
+               .hp_nid = 0x02,
+               .num_channel_mode = ARRAY_SIZE(alc262_modes),
+               .channel_mode = alc262_modes,
+               .input_mux = &alc262_capture_source,
+               .unsol_event = alc262_hippo_unsol_event,
+       },      
+};
+
+static int patch_alc262(struct hda_codec *codec)
+{
+       struct alc_spec *spec;
+       int board_config;
+       int err;
+
+       spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+       if (spec == NULL)
+               return -ENOMEM;
+
+       codec->spec = spec;
+#if 0
+       /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
+        * under-run
+        */
+       {
+       int tmp;
+       snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
+       tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
+       snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
+       snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
+       }
+#endif
+
+       board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
+                                                 alc262_models,
+                                                 alc262_cfg_tbl);
+
+       if (board_config < 0) {
+               printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
+                      "trying auto-probe from BIOS...\n");
+               board_config = ALC262_AUTO;
+       }
+
+       if (board_config == ALC262_AUTO) {
+               /* automatic parse from the BIOS config */
+               err = alc262_parse_auto_config(codec);
+               if (err < 0) {
+                       alc_free(codec);
+                       return err;
+               } else if (!err) {
+                       printk(KERN_INFO
+                              "hda_codec: Cannot set up configuration "
+                              "from BIOS.  Using base mode...\n");
+                       board_config = ALC262_BASIC;
+               }
+       }
+
+       if (board_config != ALC262_AUTO)
+               setup_preset(spec, &alc262_presets[board_config]);
+
+       spec->stream_name_analog = "ALC262 Analog";
+       spec->stream_analog_playback = &alc262_pcm_analog_playback;
+       spec->stream_analog_capture = &alc262_pcm_analog_capture;
+               
+       spec->stream_name_digital = "ALC262 Digital";
+       spec->stream_digital_playback = &alc262_pcm_digital_playback;
+       spec->stream_digital_capture = &alc262_pcm_digital_capture;
+
+       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 = alc262_adc_nids_alt;
+                       spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
+                       spec->mixers[spec->num_mixers] =
+                               alc262_capture_alt_mixer;
+                       spec->num_mixers++;
+               } else {
+                       spec->adc_nids = alc262_adc_nids;
+                       spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
+                       spec->mixers[spec->num_mixers] = alc262_capture_mixer;
+                       spec->num_mixers++;
+               }
+       }
+
+       codec->patch_ops = alc_patch_ops;
+       if (board_config == ALC262_AUTO)
+               spec->init_hook = alc262_auto_init;
+               
+       return 0;
+}
+
+/*
+ *  ALC268 channel source setting (2 channel)
+ */
+#define ALC268_DIGOUT_NID      ALC880_DIGOUT_NID
+#define alc268_modes           alc260_modes
+       
+static hda_nid_t alc268_dac_nids[2] = {
+       /* front, hp */
+       0x02, 0x03
+};
+
+static hda_nid_t alc268_adc_nids[2] = {
+       /* ADC0-1 */
+       0x08, 0x07
+};
+
+static hda_nid_t alc268_adc_nids_alt[1] = {
+       /* ADC0 */
+       0x08
+};
+
+static struct snd_kcontrol_new alc268_base_mixer[] = {
+       /* output mixer control */
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+       { }
+};
+
+/*
+ * generic initialization of ADC, input mixers and output mixers
+ */
+static struct hda_verb alc268_base_init_verbs[] = {
+       /* Unmute DAC0-1 and set vol = 0 */
+       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+       /*
+        * Set up output mixers (0x0c - 0x0e)
+        */
+       /* set vol=0 to output mixers */
+       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+
+       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
+       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
+       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
+       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
+       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
+       {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
+
+       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+
+       /* FIXME: use matrix-type input source selection */
+       /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
+       /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
+       /* Input mixer2 */
+       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
+       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
+       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
+
+       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
+       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
+       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
+       { }
+};
+
+/*
+ * generic initialization of ADC, input mixers and output mixers
+ */
+static struct hda_verb alc268_volume_init_verbs[] = {
+       /* set output DAC */
+       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
+       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
+       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
+       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
+       {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
+
+       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+
+       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+
+       /* set PCBEEP vol = 0 */
+       {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
+
+       { }
+};
+
+#define alc268_mux_enum_info alc_mux_enum_info
+#define alc268_mux_enum_get alc_mux_enum_get
+
+static int alc268_mux_enum_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;
+       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] = { 0x23, 0x24 };
+       hda_nid_t nid = capture_mixers[adc_idx];
+       unsigned int *cur_val = &spec->cur_mux[adc_idx];
+       unsigned int i, idx;
+
+       idx = ucontrol->value.enumerated.item[0];
+       if (idx >= imux->num_items)
+               idx = imux->num_items - 1;
+       if (*cur_val == idx && !codec->in_resume)
+               return 0;
+       for (i = 0; i < imux->num_items; i++) {
+               unsigned int v = (i == idx) ? 0x7000 : 0x7080;
+               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+                                   v | (imux->items[i].index << 8));
+                snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
+                                   idx );
+       }
+       *cur_val = idx;
+       return 1;
+}
+
+static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
+       HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
+       {
+               .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",
+               .count = 1,
+               .info = alc268_mux_enum_info,
+               .get = alc268_mux_enum_get,
+               .put = alc268_mux_enum_put,
+       },
+       { } /* end */
+};
+
+static struct snd_kcontrol_new alc268_capture_mixer[] = {
+       HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
+       {
+               .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",
+               .count = 2,
+               .info = alc268_mux_enum_info,
+               .get = alc268_mux_enum_get,
+               .put = alc268_mux_enum_put,
+       },
+       { } /* end */
+};
+
+static struct hda_input_mux alc268_capture_source = {
+       .num_items = 4,
+       .items = {
+               { "Mic", 0x0 },
+               { "Front Mic", 0x1 },
+               { "Line", 0x2 },
+               { "CD", 0x3 },
+       },
+};
+
+/* create input playback/capture controls for the given pin */
+static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
+                                   const char *ctlname, int idx)
+{
+       char name[32];
+       int err;
+
+       sprintf(name, "%s Playback Volume", ctlname);
+       if (nid == 0x14) {
+               err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+                                 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
+                                                     HDA_OUTPUT));
+               if (err < 0)
+                       return err;
+       } else if (nid == 0x15) {
+               err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+                                 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
+                                                     HDA_OUTPUT));
+               if (err < 0)
+                       return err;
+       } else
+               return -1;
+       sprintf(name, "%s Playback Switch", ctlname);
+       err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+                         HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
+       if (err < 0)
+               return err;
+       return 0;
+}
+
+/* add playback controls from the parsed DAC table */
+static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
+                                            const struct auto_pin_cfg *cfg)
+{
+       hda_nid_t nid;
+       int err;
+
+       spec->multiout.num_dacs = 2;    /* only use one dac */
+       spec->multiout.dac_nids = spec->private_dac_nids;
+       spec->multiout.dac_nids[0] = 2;
+       spec->multiout.dac_nids[1] = 3;
+
+       nid = cfg->line_out_pins[0];
+       if (nid)
+               alc268_new_analog_output(spec, nid, "Front", 0);        
+
+       nid = cfg->speaker_pins[0];
+       if (nid == 0x1d) {
+               err = add_control(spec, ALC_CTL_WIDGET_VOL,
+                                 "Speaker Playback Volume",
+                                 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
+               if (err < 0)
+                       return err;
+       }
+       nid = cfg->hp_pins[0];
+       if (nid)
+               alc268_new_analog_output(spec, nid, "Headphone", 0);
+
+       nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
+       if (nid == 0x16) {
+               err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+                                 "Mono Playback Switch",
+                                 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
+               if (err < 0)
+                       return err;
+       }
+       return 0;       
+}
+
+/* create playback/capture controls for input pins */
+static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
+                                               const struct auto_pin_cfg *cfg)
+{
+       struct hda_input_mux *imux = &spec->private_imux;
+       int i, idx1;
+
+       for (i = 0; i < AUTO_PIN_LAST; i++) {
+               switch(cfg->input_pins[i]) {
+               case 0x18:
+                       idx1 = 0;       /* Mic 1 */
+                       break;
+               case 0x19:
+                       idx1 = 1;       /* Mic 2 */
+                       break;
+               case 0x1a:
+                       idx1 = 2;       /* Line In */
+                       break;
+               case 0x1c:      
+                       idx1 = 3;       /* CD */
+                       break;
+               default:
+                       continue;
+               }
+               imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
+               imux->items[imux->num_items].index = idx1;
+               imux->num_items++;      
+       }
+       return 0;
+}
+
+static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
+       hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
+       hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
+       unsigned int    dac_vol1, dac_vol2;
+
+       if (speaker_nid) {
+               snd_hda_codec_write(codec, speaker_nid, 0,
+                                   AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+               snd_hda_codec_write(codec, 0x0f, 0,
+                                   AC_VERB_SET_AMP_GAIN_MUTE,
+                                   AMP_IN_UNMUTE(1));
+               snd_hda_codec_write(codec, 0x10, 0,
+                                   AC_VERB_SET_AMP_GAIN_MUTE,
+                                   AMP_IN_UNMUTE(1));
+       } else {
+               snd_hda_codec_write(codec, 0x0f, 0,
+                                   AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
+               snd_hda_codec_write(codec, 0x10, 0,
+                                   AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
+       }
+
+       dac_vol1 = dac_vol2 = 0xb000 | 0x40;    /* set max volume  */
+       if (line_nid == 0x14)   
+               dac_vol2 = AMP_OUT_ZERO;
+       else if (line_nid == 0x15)
+               dac_vol1 = AMP_OUT_ZERO;
+       if (hp_nid == 0x14)     
+               dac_vol2 = AMP_OUT_ZERO;
+       else if (hp_nid == 0x15)
+               dac_vol1 = AMP_OUT_ZERO;
+       if (line_nid != 0x16 || hp_nid != 0x16 ||
+           spec->autocfg.line_out_pins[1] != 0x16 ||
+           spec->autocfg.line_out_pins[2] != 0x16)
+               dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
+
+       snd_hda_codec_write(codec, 0x02, 0,
+                           AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
+       snd_hda_codec_write(codec, 0x03, 0,
+                           AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
+}
+
+/* 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_digital_playback    alc880_pcm_digital_playback
+
+/*
+ * BIOS auto configuration
+ */
+static int alc268_parse_auto_config(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       int err;
+       static hda_nid_t alc268_ignore[] = { 0 };
+
+       err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+                                          alc268_ignore);
+       if (err < 0)
+               return err;
+       if (!spec->autocfg.line_outs)
+               return 0; /* can't find valid BIOS pin config */
+
+       err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
+       if (err < 0)
+               return err;
+       err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
+       if (err < 0)
+               return err;
+
+       spec->multiout.max_channels = 2;
+
+       /* digital only support output */
+       if (spec->autocfg.dig_out_pin)
+               spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
+
+       if (spec->kctl_alloc)
+               spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
+
+       spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
+       spec->num_mux_defs = 1;
+       spec->input_mux = &spec->private_imux;
+
+       return 1;
+}
+
+#define alc268_auto_init_multi_out     alc882_auto_init_multi_out
+#define alc268_auto_init_hp_out                alc882_auto_init_hp_out
+#define alc268_auto_init_analog_input  alc882_auto_init_analog_input
+
+/* init callback for auto-configuration model -- overriding the default init */
+static void alc268_auto_init(struct hda_codec *codec)
+{
+       alc268_auto_init_multi_out(codec);
+       alc268_auto_init_hp_out(codec);
+       alc268_auto_init_mono_speaker_out(codec);
+       alc268_auto_init_analog_input(codec);
+}
+
+/*
+ * configuration and preset
+ */
+static const char *alc268_models[ALC268_MODEL_LAST] = {
+       [ALC268_3ST]            = "3stack",
+       [ALC268_AUTO]           = "auto",
+};
+
+static struct snd_pci_quirk alc268_cfg_tbl[] = {
+       SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
+       {}
+};
+
+static struct alc_config_preset alc268_presets[] = {
+       [ALC268_3ST] = {
+               .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
+               .init_verbs = { alc268_base_init_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,
        },
 };
 
-static int patch_alc262(struct hda_codec *codec)
+static int patch_alc268(struct hda_codec *codec)
 {
        struct alc_spec *spec;
        int board_config;
        int err;
 
-       spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+       spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
                return -ENOMEM;
 
        codec->spec = spec;
-#if 0
-       /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
-        * under-run
-        */
-       {
-       int tmp;
-       snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
-       tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
-       snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
-       snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
-       }
-#endif
 
-       board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
-                                                 alc262_models,
-                                                 alc262_cfg_tbl);
+       board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
+                                                 alc268_models,
+                                                 alc268_cfg_tbl);
 
-       if (board_config < 0) {
-               printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
+       if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
+               printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
                       "trying auto-probe from BIOS...\n");
-               board_config = ALC262_AUTO;
+               board_config = ALC268_AUTO;
        }
 
-       if (board_config == ALC262_AUTO) {
+       if (board_config == ALC268_AUTO) {
                /* automatic parse from the BIOS config */
-               err = alc262_parse_auto_config(codec);
+               err = alc268_parse_auto_config(codec);
                if (err < 0) {
                        alc_free(codec);
                        return err;
@@ -7286,44 +8275,47 @@ static int patch_alc262(struct hda_codec *codec)
                        printk(KERN_INFO
                               "hda_codec: Cannot set up configuration "
                               "from BIOS.  Using base mode...\n");
-                       board_config = ALC262_BASIC;
+                       board_config = ALC268_3ST;
                }
        }
 
-       if (board_config != ALC262_AUTO)
-               setup_preset(spec, &alc262_presets[board_config]);
-
-       spec->stream_name_analog = "ALC262 Analog";
-       spec->stream_analog_playback = &alc262_pcm_analog_playback;
-       spec->stream_analog_capture = &alc262_pcm_analog_capture;
-               
-       spec->stream_name_digital = "ALC262 Digital";
-       spec->stream_digital_playback = &alc262_pcm_digital_playback;
-       spec->stream_digital_capture = &alc262_pcm_digital_capture;
-
-       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 = alc262_adc_nids_alt;
-                       spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
-                       spec->mixers[spec->num_mixers] =
-                               alc262_capture_alt_mixer;
-                       spec->num_mixers++;
-               } else {
-                       spec->adc_nids = alc262_adc_nids;
-                       spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
-                       spec->mixers[spec->num_mixers] = alc262_capture_mixer;
-                       spec->num_mixers++;
+       if (board_config != ALC268_AUTO)
+               setup_preset(spec, &alc268_presets[board_config]);
+
+       spec->stream_name_analog = "ALC268 Analog";
+       spec->stream_analog_playback = &alc268_pcm_analog_playback;
+       spec->stream_analog_capture = &alc268_pcm_analog_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] =
+                                       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++;
+                       }
                }
        }
-
        codec->patch_ops = alc_patch_ops;
-       if (board_config == ALC262_AUTO)
-               spec->init_hook = alc262_auto_init;
+       if (board_config == ALC268_AUTO)
+               spec->init_hook = alc268_auto_init;
                
        return 0;
 }
@@ -8182,8 +9174,9 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec)
        alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
        for (i = 0; i < spec->autocfg.line_outs; i++) {
                hda_nid_t nid = spec->autocfg.line_out_pins[i];
+               int pin_type = get_pin_type(spec->autocfg.line_out_type);
                if (nid)
-                       alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT,
+                       alc861_auto_set_output_and_unmute(codec, nid, pin_type,
                                                          spec->multiout.dac_nids[i]);
        }
 }
@@ -8294,11 +9287,12 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
        SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
        SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
+       SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
        SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
-       SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660_3ST),
        SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
        SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA),
        SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
+       SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
        SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
        SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
        SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
@@ -8510,6 +9504,15 @@ static struct hda_input_mux alc861vd_capture_source = {
        },
 };
 
+static struct hda_input_mux alc861vd_dallas_capture_source = {
+       .num_items = 3,
+       .items = {
+               { "Front Mic", 0x0 },
+               { "ATAPI Mic", 0x1 },
+               { "Line In", 0x5 },
+       },
+};
+
 #define alc861vd_mux_enum_info alc_mux_enum_info
 #define alc861vd_mux_enum_get alc_mux_enum_get
 
@@ -8672,6 +9675,55 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
        { } /* end */
 };
 
+static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+       /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
+       HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+
+       HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+
+       HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+
+       HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+
+       { } /* end */
+};
+
+/* Pin assignment: Front=0x14, HP = 0x15,
+ *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
+ */
+static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
+       HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               /* .name = "Capture Source", */
+               .name = "Input Source",
+               .count = 1,
+               .info = alc882_mux_enum_info,
+               .get = alc882_mux_enum_get,
+               .put = alc882_mux_enum_put,
+       },
+       { } /* end */
+};
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -8693,10 +9745,10 @@ static struct hda_verb alc861vd_volume_init_verbs[] = {
        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
 
        /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(8)},
 
        /*
         * Set up output mixers (0x02 - 0x05)
@@ -8797,6 +9849,132 @@ static struct hda_verb alc861vd_6stack_init_verbs[] = {
        { }
 };
 
+static struct hda_verb alc861vd_eapd_verbs[] = {
+       {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
+       { }
+};
+
+static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
+       {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 
+       {}
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+       unsigned char bits;
+
+       present = snd_hda_codec_read(codec, 0x1b, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       bits = present ? 0x80 : 0;
+       snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+                                0x80, bits);
+       snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+                                0x80, bits);
+}
+
+static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+       unsigned char bits;
+
+       present = snd_hda_codec_read(codec, 0x18, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       bits = present ? 0x80 : 0;
+       snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
+                                0x80, bits);
+       snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
+                                0x80, bits);
+}
+
+static void alc861vd_lenovo_automute(struct hda_codec *codec)
+{
+       alc861vd_lenovo_hp_automute(codec);
+       alc861vd_lenovo_mic_automute(codec);
+}
+
+static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
+                                       unsigned int res)
+{
+       switch (res >> 26) {
+       case ALC880_HP_EVENT:
+               alc861vd_lenovo_hp_automute(codec);
+               break;
+       case ALC880_MIC_EVENT:
+               alc861vd_lenovo_mic_automute(codec);
+               break;
+       }
+}
+
+static struct hda_verb alc861vd_dallas_verbs[] = {
+       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+       {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+       
+       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
+       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
+       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+       {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+
+       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+       {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},  
+       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+
+       { } /* end */
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc861vd_dallas_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+
+       present = snd_hda_codec_read(codec, 0x15, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+                                0x80, present ? 0x80 : 0);
+       snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+                                0x80, present ? 0x80 : 0);
+}
+
+static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+       if ((res >> 26) == ALC880_HP_EVENT)
+               alc861vd_dallas_automute(codec);
+}
+
 /* pcm configuration: identiacal with ALC880 */
 #define alc861vd_pcm_analog_playback   alc880_pcm_analog_playback
 #define alc861vd_pcm_analog_capture    alc880_pcm_analog_capture
@@ -8811,16 +9989,22 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
        [ALC861VD_3ST]          = "3stack",
        [ALC861VD_3ST_DIG]      = "3stack-digout",
        [ALC861VD_6ST_DIG]      = "6stack-digout",
+       [ALC861VD_LENOVO]       = "lenovo",
+       [ALC861VD_DALLAS]       = "dallas",
        [ALC861VD_AUTO]         = "auto",
 };
 
 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
        SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
+       SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST),
        SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
        SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
 
-       SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_3ST),
+       SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),
+       SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
+       SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
+       SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
        {}
 };
 
@@ -8869,6 +10053,35 @@ static struct alc_config_preset alc861vd_presets[] = {
                .channel_mode = alc861vd_6stack_modes,
                .input_mux = &alc861vd_capture_source,
        },
+       [ALC861VD_LENOVO] = {
+               .mixers = { alc861vd_lenovo_mixer },
+               .init_verbs = { alc861vd_volume_init_verbs,
+                               alc861vd_3stack_init_verbs,
+                               alc861vd_eapd_verbs,
+                               alc861vd_lenovo_unsol_verbs },
+               .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
+               .dac_nids = alc660vd_dac_nids,
+               .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
+               .adc_nids = alc861vd_adc_nids,
+               .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
+               .channel_mode = alc861vd_3stack_2ch_modes,
+               .input_mux = &alc861vd_capture_source,
+               .unsol_event = alc861vd_lenovo_unsol_event,
+               .init_hook = alc861vd_lenovo_automute,
+       },
+       [ALC861VD_DALLAS] = {
+               .mixers = { alc861vd_dallas_mixer },
+               .init_verbs = { alc861vd_dallas_verbs },
+               .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
+               .dac_nids = alc861vd_dac_nids,
+               .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
+               .adc_nids = alc861vd_adc_nids,
+               .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
+               .channel_mode = alc861vd_3stack_2ch_modes,
+               .input_mux = &alc861vd_dallas_capture_source,
+               .unsol_event = alc861vd_dallas_unsol_event,
+               .init_hook = alc861vd_dallas_automute,
+       },      
 };
 
 /*
@@ -8892,9 +10105,10 @@ static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
        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);
                if (nid)
                        alc861vd_auto_set_output_and_unmute(codec, nid,
-                                                               PIN_OUT, i);
+                                                           pin_type, i);
        }
 }
 
@@ -8991,7 +10205,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
                                return err;
                        sprintf(name, "%s Playback Switch", chname[i]);
                        err = add_control(spec, ALC_CTL_BIND_MUTE, name,
-                                         HDA_COMPOSE_AMP_VAL(nid_v, 3, 2,
+                                         HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
                                                              HDA_INPUT));
                        if (err < 0)
                                return err;
@@ -9867,8 +11081,9 @@ static void alc662_auto_init_multi_out(struct hda_codec *codec)
 
        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);
                if (nid)
-                       alc662_auto_set_output_and_unmute(codec, nid, PIN_OUT,
+                       alc662_auto_set_output_and_unmute(codec, nid, pin_type,
                                                          i);
        }
 }
@@ -10031,6 +11246,7 @@ static int patch_alc662(struct hda_codec *codec)
 struct hda_codec_preset snd_hda_preset_realtek[] = {
        { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
        { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
+       { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
        { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
          .patch = patch_alc861 },
        { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },