ALSA: hda - Add quirk for Acer Aspire 6935G
[pandora-kernel.git] / sound / pci / hda / patch_realtek.c
index 1bf9d05..d22b260 100644 (file)
@@ -220,9 +220,11 @@ enum {
        ALC883_6ST_DIG,
        ALC883_TARGA_DIG,
        ALC883_TARGA_2ch_DIG,
+       ALC883_TARGA_8ch_DIG,
        ALC883_ACER,
        ALC883_ACER_ASPIRE,
        ALC888_ACER_ASPIRE_4930G,
+       ALC888_ACER_ASPIRE_8930G,
        ALC883_MEDION,
        ALC883_MEDION_MD2,
        ALC883_LAPTOP_EAPD,
@@ -240,7 +242,9 @@ enum {
        ALC883_3ST_6ch_INTEL,
        ALC888_ASUS_M90V,
        ALC888_ASUS_EEE1601,
+       ALC889A_MB31,
        ALC1200_ASUS_P5Q,
+       ALC883_SONY_VAIO_TT,
        ALC883_AUTO,
        ALC883_MODEL_LAST,
 };
@@ -277,13 +281,13 @@ struct alc_spec {
                                                 */
        unsigned int num_init_verbs;
 
-       char *stream_name_analog;       /* analog PCM stream */
+       char stream_name_analog[16];    /* 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 */
+       char stream_name_digital[16];   /* digital PCM stream */
        struct hda_pcm_stream *stream_digital_playback;
        struct hda_pcm_stream *stream_digital_capture;
 
@@ -312,6 +316,8 @@ struct alc_spec {
        const struct hda_channel_mode *channel_mode;
        int num_channel_mode;
        int need_dac_fix;
+       int const_channel_count;
+       int ext_channel_count;
 
        /* PCM information */
        struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
@@ -367,6 +373,7 @@ struct alc_config_preset {
        unsigned int num_channel_mode;
        const struct hda_channel_mode *channel_mode;
        int need_dac_fix;
+       int const_channel_count;
        unsigned int num_mux_defs;
        const struct hda_input_mux *input_mux;
        void (*unsol_event)(struct hda_codec *, unsigned int);
@@ -461,7 +468,7 @@ static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
        struct alc_spec *spec = codec->spec;
        return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
                                   spec->num_channel_mode,
-                                  spec->multiout.max_channels);
+                                  spec->ext_channel_count);
 }
 
 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
@@ -471,9 +478,12 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
        struct alc_spec *spec = codec->spec;
        int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
                                      spec->num_channel_mode,
-                                     &spec->multiout.max_channels);
-       if (err >= 0 && spec->need_dac_fix)
-               spec->multiout.num_dacs = spec->multiout.max_channels / 2;
+                                     &spec->ext_channel_count);
+       if (err >= 0 && !spec->const_channel_count) {
+               spec->multiout.max_channels = spec->ext_channel_count;
+               if (spec->need_dac_fix)
+                       spec->multiout.num_dacs = spec->multiout.max_channels / 2;
+       }
        return err;
 }
 
@@ -788,6 +798,12 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
                pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
                if (pincap & AC_PINCAP_VREF_80)
                        val = PIN_VREF80;
+               else if (pincap & AC_PINCAP_VREF_50)
+                       val = PIN_VREF50;
+               else if (pincap & AC_PINCAP_VREF_100)
+                       val = PIN_VREF100;
+               else if (pincap & AC_PINCAP_VREF_GRD)
+                       val = PIN_VREFGRD;
        }
        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
 }
@@ -847,8 +863,13 @@ static void setup_preset(struct alc_spec *spec,
        spec->channel_mode = preset->channel_mode;
        spec->num_channel_mode = preset->num_channel_mode;
        spec->need_dac_fix = preset->need_dac_fix;
+       spec->const_channel_count = preset->const_channel_count;
 
-       spec->multiout.max_channels = spec->channel_mode[0].channels;
+       if (preset->const_channel_count)
+               spec->multiout.max_channels = preset->const_channel_count;
+       else
+               spec->multiout.max_channels = spec->channel_mode[0].channels;
+       spec->ext_channel_count = spec->channel_mode[0].channels;
 
        spec->multiout.num_dacs = preset->num_dacs;
        spec->multiout.dac_nids = preset->dac_nids;
@@ -1449,6 +1470,59 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
        { }
 };
 
+/*
+ * ALC889 Acer Aspire 8930G model
+ */
+
+static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
+/* Front Mic: set to PIN_IN (empty by default) */
+       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+/* Unselect Front Mic by default in input mixer 3 */
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
+/* Enable unsolicited event for HP jack */
+       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+/* Connect Internal Front to Front */
+       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
+/* Connect Internal Rear to Rear */
+       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
+/* Connect Internal CLFE to CLFE */
+       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
+/* Connect HP out to Front */
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
+       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+/* Enable all DACs */
+/*  DAC DISABLE/MUTE 1? */
+/*  setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
+       {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
+       {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
+/*  DAC DISABLE/MUTE 2? */
+/*  some bit here disables the other DACs. Init=0x4900 */
+       {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
+       {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
+/* Enable amplifiers */
+       {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
+       {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
+/* DMIC fix
+ * This laptop has a stereo digital microphone. The mics are only 1cm apart
+ * which makes the stereo useless. However, either the mic or the ALC889
+ * makes the signal become a difference/sum signal instead of standard
+ * stereo, which is annoying. So instead we flip this bit which makes the
+ * codec replicate the sum signal to both channels, turning it into a
+ * normal mono mic.
+ */
+/*  DMIC_CONTROL? Init value = 0x0001 */
+       {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
+       {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
+       { }
+};
+
 static struct hda_input_mux alc888_2_capture_sources[2] = {
        /* Front mic only available on one ADC */
        {
@@ -1470,6 +1544,38 @@ static struct hda_input_mux alc888_2_capture_sources[2] = {
        }
 };
 
+static struct hda_input_mux alc889_capture_sources[3] = {
+       /* Digital mic only available on first "ADC" */
+       {
+               .num_items = 5,
+               .items = {
+                       { "Mic", 0x0 },
+                       { "Line", 0x2 },
+                       { "CD", 0x4 },
+                       { "Front Mic", 0xb },
+                       { "Input Mix", 0xa },
+               },
+       },
+       {
+               .num_items = 4,
+               .items = {
+                       { "Mic", 0x0 },
+                       { "Line", 0x2 },
+                       { "CD", 0x4 },
+                       { "Input Mix", 0xa },
+               },
+       },
+       {
+               .num_items = 4,
+               .items = {
+                       { "Mic", 0x0 },
+                       { "Line", 0x2 },
+                       { "CD", 0x4 },
+                       { "Input Mix", 0xa },
+               },
+       }
+};
+
 static struct snd_kcontrol_new alc888_base_mixer[] = {
        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -1501,6 +1607,17 @@ static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec)
        alc_automute_amp(codec);
 }
 
+static void alc889_acer_aspire_8930g_init_hook(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+
+       spec->autocfg.hp_pins[0] = 0x15;
+       spec->autocfg.speaker_pins[0] = 0x14;
+       spec->autocfg.speaker_pins[1] = 0x16;
+       spec->autocfg.speaker_pins[2] = 0x1b;
+       alc_automute_amp(codec);
+}
+
 /*
  * ALC880 3-stack model
  *
@@ -2606,6 +2723,7 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = {
 /* Enable GPIO mask and set output */
 #define alc880_gpio1_init_verbs        alc_gpio1_init_verbs
 #define alc880_gpio2_init_verbs        alc_gpio2_init_verbs
+#define alc880_gpio3_init_verbs        alc_gpio3_init_verbs
 
 /* Clevo m520g init */
 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
@@ -3169,7 +3287,10 @@ static int alc_build_pcms(struct hda_codec *codec)
        if (spec->no_analog)
                goto skip_analog;
 
+       snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
+                "%s Analog", codec->chip_name);
        info->name = spec->stream_name_analog;
+       
        if (spec->stream_analog_playback) {
                if (snd_BUG_ON(!spec->multiout.dac_nids))
                        return -EINVAL;
@@ -3195,6 +3316,9 @@ static int alc_build_pcms(struct hda_codec *codec)
  skip_analog:
        /* SPDIF for stream index #1 */
        if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
+               snprintf(spec->stream_name_digital,
+                        sizeof(spec->stream_name_digital),
+                        "%s Digital", codec->chip_name);
                codec->num_pcms = 2;
                codec->slave_dig_outs = spec->multiout.slave_dig_outs;
                info = spec->pcm_rec + 1;
@@ -4404,8 +4528,8 @@ static int patch_alc880(struct hda_codec *codec)
                                                  alc880_models,
                                                  alc880_cfg_tbl);
        if (board_config < 0) {
-               printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
-                      "trying auto-probe from BIOS...\n");
+               printk(KERN_INFO "hda_codec: Unknown model for %s, "
+                      "trying auto-probe from BIOS...\n", codec->chip_name);
                board_config = ALC880_AUTO;
        }
 
@@ -4432,12 +4556,10 @@ static int patch_alc880(struct hda_codec *codec)
        if (board_config != ALC880_AUTO)
                setup_preset(spec, &alc880_presets[board_config]);
 
-       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;
        spec->stream_digital_capture = &alc880_pcm_digital_capture;
 
@@ -6050,8 +6172,9 @@ static int patch_alc260(struct hda_codec *codec)
                                                  alc260_models,
                                                  alc260_cfg_tbl);
        if (board_config < 0) {
-               snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
-                          "trying auto-probe from BIOS...\n");
+               snd_printd(KERN_INFO "hda_codec: Unknown model for %s, "
+                          "trying auto-probe from BIOS...\n",
+                          codec->chip_name);
                board_config = ALC260_AUTO;
        }
 
@@ -6078,11 +6201,9 @@ static int patch_alc260(struct hda_codec *codec)
        if (board_config != ALC260_AUTO)
                setup_preset(spec, &alc260_presets[board_config]);
 
-       spec->stream_name_analog = "ALC260 Analog";
        spec->stream_analog_playback = &alc260_pcm_analog_playback;
        spec->stream_analog_capture = &alc260_pcm_analog_capture;
 
-       spec->stream_name_digital = "ALC260 Digital";
        spec->stream_digital_playback = &alc260_pcm_digital_playback;
        spec->stream_digital_capture = &alc260_pcm_digital_capture;
 
@@ -6256,6 +6377,34 @@ static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
        { 6, alc885_mbp_ch6_init },
 };
 
+/*
+ * 2ch
+ * Speakers/Woofer/HP = Front
+ * LineIn = Input
+ */
+static struct hda_verb alc885_mb5_ch2_init[] = {
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       { } /* end */
+};
+
+/*
+ * 6ch mode
+ * Speakers/HP = Front
+ * Woofer = LFE
+ * LineIn = Surround
+ */
+static struct hda_verb alc885_mb5_ch6_init[] = {
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
+       { } /* end */
+};
+
+static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
+       { 2, alc885_mb5_ch2_init },
+       { 6, alc885_mb5_ch6_init },
+};
 
 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
@@ -6300,10 +6449,14 @@ static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
 };
 
 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE   ("Front Playback Switch", 0x0d, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE   ("Line-Out Playback Switch", 0x0c, 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_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
+       HDA_BIND_MUTE   ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
+       HDA_BIND_MUTE   ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
+       HDA_BIND_MUTE   ("HP Playback Switch", 0x0f, 0x02, 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, 0x01, HDA_INPUT),
@@ -6312,6 +6465,7 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {
        HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
        { } /* 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),
@@ -6541,22 +6695,39 @@ static struct hda_verb alc882_macpro_init_verbs[] = {
 
 /* Macbook 5,1 */
 static struct hda_verb alc885_mb5_init_verbs[] = {
+       /* DACs */
+       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
        /* Front mixer */
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       /* LineOut mixer */
        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       /* Front Pin: output 0 (0x0d) */
+       /* Surround mixer */
+       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+       /* LFE mixer */
+       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+       /* HP mixer */
+       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+       /* Front Pin (0x0c) */
        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x18, AC_VERB_SET_CONNECT_SEL, 0x01},
-       /* HP Pin: output 0 (0x0c) */
+       {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
+       /* LFE Pin (0x0e) */
+       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
+       /* HP Pin (0x0f) */
        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
        /* Front Mic pin: input vref at 80% */
        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
@@ -6976,13 +7147,13 @@ static struct alc_config_preset alc882_presets[] = {
                .init_hook = alc885_mbp3_init_hook,
        },
        [ALC885_MB5] = {
-               .mixers = { alc885_mb5_mixer },
+               .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
                .init_verbs = { alc885_mb5_init_verbs,
                                alc880_gpio1_init_verbs },
                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
                .dac_nids = alc882_dac_nids,
-               .channel_mode = alc885_mbp_6ch_modes,
-               .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
+               .channel_mode = alc885_mb5_6ch_modes,
+               .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
                .input_mux = &mb5_capture_source,
                .dig_out_nid = ALC882_DIGOUT_NID,
                .dig_in_nid = ALC882_DIGIN_NID,
@@ -7288,7 +7459,7 @@ static int patch_alc882(struct hda_codec *codec)
                case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
                case 0x106b00a4: /* MacbookPro4,1 */
                case 0x106b2c00: /* Macbook Pro rev3 */
-               case 0x106b3600: /* Macbook 3.1 */
+               /* Macbook 3.1 (0x106b3600) is handled by patch_alc883() */
                case 0x106b3800: /* MacbookPro4,1 - latter revision */
                        board_config = ALC885_MBP3;
                        break;
@@ -7306,8 +7477,9 @@ static int patch_alc882(struct hda_codec *codec)
                                alc_free(codec);
                                return patch_alc883(codec);
                        }
-                       printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
-                                        "trying auto-probe from BIOS...\n");
+                       printk(KERN_INFO "hda_codec: Unknown model for %s, "
+                              "trying auto-probe from BIOS...\n",
+                              codec->chip_name);
                        board_config = ALC882_AUTO;
                }
        }
@@ -7337,14 +7509,6 @@ static int patch_alc882(struct hda_codec *codec)
        if (board_config != ALC882_AUTO)
                setup_preset(spec, &alc882_presets[board_config]);
 
-       if (codec->vendor_id == 0x10ec0885) {
-               spec->stream_name_analog = "ALC885 Analog";
-               spec->stream_name_digital = "ALC885 Digital";
-       } else {
-               spec->stream_name_analog = "ALC882 Analog";
-               spec->stream_name_digital = "ALC882 Digital";
-       }
-
        spec->stream_analog_playback = &alc882_pcm_analog_playback;
        spec->stream_analog_capture = &alc882_pcm_analog_capture;
        /* FIXME: setup DAC5 */
@@ -7497,6 +7661,17 @@ static struct hda_input_mux alc883_asus_eee1601_capture_source = {
        },
 };
 
+static struct hda_input_mux alc889A_mb31_capture_source = {
+       .num_items = 2,
+       .items = {
+               { "Mic", 0x0 },
+               /* Front Mic (0x01) unused */
+               { "Line", 0x2 },
+               /* Line 2 (0x03) unused */
+               /* CD (0x04) unsused? */
+       },
+};
+
 /*
  * 2ch mode
  */
@@ -7546,6 +7721,73 @@ static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
        { 6, alc883_3ST_ch6_init },
 };
 
+
+/*
+ * 2ch mode
+ */
+static struct hda_verb alc883_4ST_ch2_init[] = {
+       { 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_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 */
+};
+
+/*
+ * 4ch mode
+ */
+static struct hda_verb alc883_4ST_ch4_init[] = {
+       { 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_VREF80 },
+       { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+       { 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 */
+};
+
+/*
+ * 6ch mode
+ */
+static struct hda_verb alc883_4ST_ch6_init[] = {
+       { 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_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 */
+};
+
+/*
+ * 8ch mode
+ */
+static struct hda_verb alc883_4ST_ch8_init[] = {
+       { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+       { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+       { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
+       { 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 alc883_4ST_8ch_modes[4] = {
+       { 2, alc883_4ST_ch2_init },
+       { 4, alc883_4ST_ch4_init },
+       { 6, alc883_4ST_ch6_init },
+       { 8, alc883_4ST_ch8_init },
+};
+
+
 /*
  * 2ch mode
  */
@@ -7615,6 +7857,49 @@ static struct hda_channel_mode alc883_sixstack_modes[2] = {
        { 8, alc883_sixstack_ch8_init },
 };
 
+/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
+static struct hda_verb alc889A_mb31_ch2_init[] = {
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},             /* HP as front */
+       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
+       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},    /* Line as input */
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Line off */
+       { } /* end */
+};
+
+/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
+static struct hda_verb alc889A_mb31_ch4_init[] = {
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},             /* HP as front */
+       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
+       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},   /* Line as output */
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
+       { } /* end */
+};
+
+/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
+static struct hda_verb alc889A_mb31_ch5_init[] = {
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},             /* HP as rear */
+       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
+       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},    /* Line as input */
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Line off */
+       { } /* end */
+};
+
+/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
+static struct hda_verb alc889A_mb31_ch6_init[] = {
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},             /* HP as front */
+       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Subwoofer off */
+       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},   /* Line as output */
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
+       { } /* end */
+};
+
+static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
+       { 2, alc889A_mb31_ch2_init },
+       { 4, alc889A_mb31_ch4_init },
+       { 5, alc889A_mb31_ch5_init },
+       { 6, alc889A_mb31_ch6_init },
+};
+
 static struct hda_verb alc883_medion_eapd_verbs[] = {
         /* eanable EAPD on medion laptop */
        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
@@ -7893,6 +8178,42 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
        { } /* end */
 };
 
+static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
+       /* Output mixers */
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
+       HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
+               HDA_OUTPUT),
+       HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
+       HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
+       /* Output switches */
+       HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
+       HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
+       /* Boost mixers */
+       HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
+       HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
+       /* Input mixers */
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+       { } /* end */
+};
+
+static struct snd_kcontrol_new alc883_vaiott_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", 0x15, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+       { } /* end */
+};
+
 static struct hda_bind_ctls alc883_bind_cap_vol = {
        .ops = &snd_hda_bind_vol,
        .values = {
@@ -8103,14 +8424,24 @@ static struct hda_verb alc883_tagra_verbs[] = {
        {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 */
+/* Connect Line-Out side jack (SPDIF) to Side */
+       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
+/* Connect Mic jack to CLFE */
+       {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},
+/* Connect Line-in jack to Surround */
+       {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},
+/* Connect HP out jack to Front */
+       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
 
        {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 */
 };
@@ -8169,6 +8500,17 @@ static struct hda_verb alc888_6st_dell_verbs[] = {
        { }
 };
 
+static struct hda_verb alc883_vaiott_verbs[] = {
+       /* HP */
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+
+       /* enable unsolicited event */
+       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+
+       { } /* end */
+};
+
 static void alc888_3st_hp_init_hook(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
@@ -8344,8 +8686,8 @@ static void alc883_lenovo_101e_ispeaker_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;
+       present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
+               & AC_PINSENSE_PRESENCE;
        bits = present ? HDA_AMP_MUTE : 0;
        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
                                 HDA_AMP_MUTE, bits);
@@ -8428,6 +8770,16 @@ static void alc888_lenovo_sky_init_hook(struct hda_codec *codec)
        alc_automute_amp(codec);
 }
 
+static void alc883_vaiott_init_hook(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+
+       spec->autocfg.hp_pins[0] = 0x15;
+       spec->autocfg.speaker_pins[0] = 0x14;
+       spec->autocfg.speaker_pins[1] = 0x17;
+       alc_automute_amp(codec);
+}
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -8565,6 +8917,42 @@ static void alc883_eee1601_inithook(struct hda_codec *codec)
        alc_automute_pin(codec);
 }
 
+static struct hda_verb alc889A_mb31_verbs[] = {
+       /* Init rear pin (used as headphone output) */
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},    /* Apple Headphones */
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},           /* Connect to front */
+       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+       /* Init line pin (used as output in 4ch and 6ch mode) */
+       {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},           /* Connect to CLFE */
+       /* Init line 2 pin (used as headphone out by default) */
+       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  /* Use as input */
+       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
+       { } /* end */
+};
+
+/* Mute speakers according to the headphone jack state */
+static void alc889A_mb31_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+
+       /* Mute only in 2ch or 4ch mode */
+       if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
+           == 0x00) {
+               present = snd_hda_codec_read(codec, 0x15, 0,
+                       AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
+               snd_hda_codec_amp_stereo(codec, 0x14,  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);
+       }
+}
+
+static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+       if ((res >> 26) == ALC880_HP_EVENT)
+               alc889A_mb31_automute(codec);
+}
+
 #ifdef CONFIG_SND_HDA_POWER_SAVE
 #define alc883_loopbacks       alc880_loopbacks
 #endif
@@ -8586,9 +8974,11 @@ 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",
+       [ALC883_TARGA_8ch_DIG]  = "targa-8ch-dig",
        [ALC883_ACER]           = "acer",
        [ALC883_ACER_ASPIRE]    = "acer-aspire",
        [ALC888_ACER_ASPIRE_4930G]      = "acer-aspire-4930g",
+       [ALC888_ACER_ASPIRE_8930G]      = "acer-aspire-8930g",
        [ALC883_MEDION]         = "medion",
        [ALC883_MEDION_MD2]     = "medion-md2",
        [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
@@ -8605,6 +8995,8 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
        [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
        [ALC883_3ST_6ch_INTEL]  = "3stack-6ch-intel",
        [ALC1200_ASUS_P5Q]      = "asus-p5q",
+       [ALC889A_MB31]          = "mb31",
+       [ALC883_SONY_VAIO_TT]   = "sony-vaio-tt",
        [ALC883_AUTO]           = "auto",
 };
 
@@ -8620,6 +9012,10 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
                ALC888_ACER_ASPIRE_4930G),
        SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
                ALC888_ACER_ASPIRE_4930G),
+       SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
+               ALC888_ACER_ASPIRE_8930G),
+       SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
+               ALC888_ACER_ASPIRE_8930G),
        SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO),
        SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO),
        SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
@@ -8665,6 +9061,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
+       SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_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),
@@ -8697,6 +9094,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
        SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
        SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
        SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
+       SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
        {}
 };
 
@@ -8793,6 +9191,24 @@ static struct alc_config_preset alc883_presets[] = {
                .unsol_event = alc883_tagra_unsol_event,
                .init_hook = alc883_tagra_init_hook,
        },
+       [ALC883_TARGA_8ch_DIG] = {
+               .mixers = { alc883_base_mixer, alc883_chmode_mixer },
+               .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
+                               alc883_tagra_verbs },
+               .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+               .dac_nids = alc883_dac_nids,
+               .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
+               .adc_nids = alc883_adc_nids_rev,
+               .capsrc_nids = alc883_capsrc_nids_rev,
+               .dig_out_nid = ALC883_DIGOUT_NID,
+               .dig_in_nid = ALC883_DIGIN_NID,
+               .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
+               .channel_mode = alc883_4ST_8ch_modes,
+               .need_dac_fix = 1,
+               .input_mux = &alc883_capture_source,
+               .unsol_event = alc883_tagra_unsol_event,
+               .init_hook = alc883_tagra_init_hook,
+       },
        [ALC883_ACER] = {
                .mixers = { alc883_base_mixer },
                /* On TravelMate laptops, GPIO 0 enables the internal speaker
@@ -8839,6 +9255,27 @@ static struct alc_config_preset alc883_presets[] = {
                .unsol_event = alc_automute_amp_unsol_event,
                .init_hook = alc888_acer_aspire_4930g_init_hook,
        },
+       [ALC888_ACER_ASPIRE_8930G] = {
+               .mixers = { alc888_base_mixer,
+                               alc883_chmode_mixer },
+               .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
+                               alc889_acer_aspire_8930g_verbs },
+               .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+               .dac_nids = alc883_dac_nids,
+               .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
+               .adc_nids = alc889_adc_nids,
+               .capsrc_nids = alc889_capsrc_nids,
+               .dig_out_nid = ALC883_DIGOUT_NID,
+               .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
+               .channel_mode = alc883_3ST_6ch_modes,
+               .need_dac_fix = 1,
+               .const_channel_count = 6,
+               .num_mux_defs =
+                       ARRAY_SIZE(alc889_capture_sources),
+               .input_mux = alc889_capture_sources,
+               .unsol_event = alc_automute_amp_unsol_event,
+               .init_hook = alc889_acer_aspire_8930g_init_hook,
+       },
        [ALC883_MEDION] = {
                .mixers = { alc883_fivestack_mixer,
                            alc883_chmode_mixer },
@@ -9056,6 +9493,32 @@ static struct alc_config_preset alc883_presets[] = {
                .channel_mode = alc883_sixstack_modes,
                .input_mux = &alc883_capture_source,
        },
+       [ALC889A_MB31] = {
+               .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
+               .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
+                       alc880_gpio1_init_verbs },
+               .adc_nids = alc883_adc_nids,
+               .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+               .dac_nids = alc883_dac_nids,
+               .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+               .channel_mode = alc889A_mb31_6ch_modes,
+               .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
+               .input_mux = &alc889A_mb31_capture_source,
+               .dig_out_nid = ALC883_DIGOUT_NID,
+               .unsol_event = alc889A_mb31_unsol_event,
+               .init_hook = alc889A_mb31_automute,
+       },
+       [ALC883_SONY_VAIO_TT] = {
+               .mixers = { alc883_vaiott_mixer },
+               .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
+               .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+               .dac_nids = alc883_dac_nids,
+               .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
+               .channel_mode = alc883_3ST_2ch_modes,
+               .input_mux = &alc883_capture_source,
+               .unsol_event = alc_automute_amp_unsol_event,
+               .init_hook = alc883_vaiott_init_hook,
+       },
 };
 
 
@@ -9201,10 +9664,18 @@ static int patch_alc883(struct hda_codec *codec)
        board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
                                                  alc883_models,
                                                  alc883_cfg_tbl);
-       if (board_config < 0) {
-               printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
-                      "trying auto-probe from BIOS...\n");
-               board_config = ALC883_AUTO;
+       if (board_config < 0 || board_config >= ALC883_MODEL_LAST) {
+               /* Pick up systems that don't supply PCI SSID */
+               switch (codec->subsystem_id) {
+               case 0x106b3600: /* Macbook 3.1 */
+                       board_config = ALC889A_MB31;
+                       break;
+               default:
+                       printk(KERN_INFO
+                               "hda_codec: Unknown model for %s, trying "
+                               "auto-probe from BIOS...\n", codec->chip_name);
+                       board_config = ALC883_AUTO;
+               }
        }
 
        if (board_config == ALC883_AUTO) {
@@ -9232,13 +9703,6 @@ static int patch_alc883(struct hda_codec *codec)
 
        switch (codec->vendor_id) {
        case 0x10ec0888:
-               if (codec->revision_id == 0x100101) {
-                       spec->stream_name_analog = "ALC1200 Analog";
-                       spec->stream_name_digital = "ALC1200 Digital";
-               } else {
-                       spec->stream_name_analog = "ALC888 Analog";
-                       spec->stream_name_digital = "ALC888 Digital";
-               }
                if (!spec->num_adc_nids) {
                        spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
                        spec->adc_nids = alc883_adc_nids;
@@ -9249,8 +9713,6 @@ static int patch_alc883(struct hda_codec *codec)
                spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
                break;
        case 0x10ec0889:
-               spec->stream_name_analog = "ALC889 Analog";
-               spec->stream_name_digital = "ALC889 Digital";
                if (!spec->num_adc_nids) {
                        spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
                        spec->adc_nids = alc889_adc_nids;
@@ -9261,8 +9723,6 @@ static int patch_alc883(struct hda_codec *codec)
                                                        capture */
                break;
        default:
-               spec->stream_name_analog = "ALC883 Analog";
-               spec->stream_name_digital = "ALC883 Digital";
                if (!spec->num_adc_nids) {
                        spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
                        spec->adc_nids = alc883_adc_nids;
@@ -10507,31 +10967,46 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = {
        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
 
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
+       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
 
 
        /* FIXME: use matrix-type input source selection */
-       /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
-       /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
+       /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
+       /* Input mixer1: only unmute Mic */
        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
+       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
+       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
+       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
+       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
+       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
+       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
+       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
+       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
        /* Input mixer2 */
        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
+       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
+       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
+       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
+       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
+       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
+       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
+       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
+       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
        /* Input mixer3 */
        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
 
        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 
@@ -11057,8 +11532,8 @@ static int patch_alc262(struct hda_codec *codec)
                                                  alc262_cfg_tbl);
 
        if (board_config < 0) {
-               printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
-                      "trying auto-probe from BIOS...\n");
+               printk(KERN_INFO "hda_codec: Unknown model for %s, "
+                      "trying auto-probe from BIOS...\n", codec->chip_name);
                board_config = ALC262_AUTO;
        }
 
@@ -11087,11 +11562,9 @@ static int patch_alc262(struct hda_codec *codec)
        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;
 
@@ -11916,15 +12389,16 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
                                                ALC268_ACER_ASPIRE_ONE),
        SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
        SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
-       SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
+       SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
+                          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(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
+       SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
+       SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
+                          ALC268_TOSHIBA),
        SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
        SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
        SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
-       SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
+       SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
        {}
 };
 
@@ -12095,8 +12569,8 @@ static int patch_alc268(struct hda_codec *codec)
                                                  alc268_cfg_tbl);
 
        if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
-               printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
-                      "trying auto-probe from BIOS...\n");
+               printk(KERN_INFO "hda_codec: Unknown model for %s, "
+                      "trying auto-probe from BIOS...\n", codec->chip_name);
                board_config = ALC268_AUTO;
        }
 
@@ -12117,14 +12591,6 @@ static int patch_alc268(struct hda_codec *codec)
        if (board_config != ALC268_AUTO)
                setup_preset(spec, &alc268_presets[board_config]);
 
-       if (codec->vendor_id == 0x10ec0267) {
-               spec->stream_name_analog = "ALC267 Analog";
-               spec->stream_name_digital = "ALC267 Digital";
-       } else {
-               spec->stream_name_analog = "ALC268 Analog";
-               spec->stream_name_digital = "ALC268 Digital";
-       }
-
        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;
@@ -12951,8 +13417,8 @@ static int patch_alc269(struct hda_codec *codec)
                                                  alc269_cfg_tbl);
 
        if (board_config < 0) {
-               printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
-                      "trying auto-probe from BIOS...\n");
+               printk(KERN_INFO "hda_codec: Unknown model for %s, "
+                      "trying auto-probe from BIOS...\n", codec->chip_name);
                board_config = ALC269_AUTO;
        }
 
@@ -12979,7 +13445,6 @@ static int patch_alc269(struct hda_codec *codec)
        if (board_config != ALC269_AUTO)
                setup_preset(spec, &alc269_presets[board_config]);
 
-       spec->stream_name_analog = "ALC269 Analog";
        if (codec->subsystem_id == 0x17aa3bf8) {
                /* Due to a hardware problem on Lenovo Ideadpad, we need to
                 * fix the sample rate of analog I/O to 44.1kHz
@@ -12990,7 +13455,6 @@ static int patch_alc269(struct hda_codec *codec)
                spec->stream_analog_playback = &alc269_pcm_analog_playback;
                spec->stream_analog_capture = &alc269_pcm_analog_capture;
        }
-       spec->stream_name_digital = "ALC269 Digital";
        spec->stream_digital_playback = &alc269_pcm_digital_playback;
        spec->stream_digital_capture = &alc269_pcm_digital_capture;
 
@@ -14052,8 +14516,8 @@ static int patch_alc861(struct hda_codec *codec)
                                                  alc861_cfg_tbl);
 
        if (board_config < 0) {
-               printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
-                      "trying auto-probe from BIOS...\n");
+               printk(KERN_INFO "hda_codec: Unknown model for %s, "
+                      "trying auto-probe from BIOS...\n", codec->chip_name);
                board_config = ALC861_AUTO;
        }
 
@@ -14080,11 +14544,9 @@ static int patch_alc861(struct hda_codec *codec)
        if (board_config != ALC861_AUTO)
                setup_preset(spec, &alc861_presets[board_config]);
 
-       spec->stream_name_analog = "ALC861 Analog";
        spec->stream_analog_playback = &alc861_pcm_analog_playback;
        spec->stream_analog_capture = &alc861_pcm_analog_capture;
 
-       spec->stream_name_digital = "ALC861 Digital";
        spec->stream_digital_playback = &alc861_pcm_digital_playback;
        spec->stream_digital_capture = &alc861_pcm_digital_capture;
 
@@ -14978,8 +15440,8 @@ static int patch_alc861vd(struct hda_codec *codec)
                                                  alc861vd_cfg_tbl);
 
        if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
-               printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
-                       "ALC861VD, trying auto-probe from BIOS...\n");
+               printk(KERN_INFO "hda_codec: Unknown model for %s, "
+                      "trying auto-probe from BIOS...\n", codec->chip_name);
                board_config = ALC861VD_AUTO;
        }
 
@@ -15007,13 +15469,8 @@ static int patch_alc861vd(struct hda_codec *codec)
                setup_preset(spec, &alc861vd_presets[board_config]);
 
        if (codec->vendor_id == 0x10ec0660) {
-               spec->stream_name_analog = "ALC660-VD Analog";
-               spec->stream_name_digital = "ALC660-VD Digital";
                /* always turn on EAPD */
                add_verb(spec, alc660vd_eapd_verbs);
-       } else {
-               spec->stream_name_analog = "ALC861VD Analog";
-               spec->stream_name_digital = "ALC861VD Digital";
        }
 
        spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
@@ -16908,8 +17365,8 @@ static int patch_alc662(struct hda_codec *codec)
                                                  alc662_models,
                                                  alc662_cfg_tbl);
        if (board_config < 0) {
-               printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
-                      "trying auto-probe from BIOS...\n");
+               printk(KERN_INFO "hda_codec: Unknown model for %s, "
+                      "trying auto-probe from BIOS...\n", codec->chip_name);
                board_config = ALC662_AUTO;
        }
 
@@ -16936,17 +17393,6 @@ static int patch_alc662(struct hda_codec *codec)
        if (board_config != ALC662_AUTO)
                setup_preset(spec, &alc662_presets[board_config]);
 
-       if (codec->vendor_id == 0x10ec0663) {
-               spec->stream_name_analog = "ALC663 Analog";
-               spec->stream_name_digital = "ALC663 Digital";
-       } else if (codec->vendor_id == 0x10ec0272) {
-               spec->stream_name_analog = "ALC272 Analog";
-               spec->stream_name_digital = "ALC272 Digital";
-       } else {
-               spec->stream_name_analog = "ALC662 Analog";
-               spec->stream_name_digital = "ALC662 Digital";
-       }
-
        spec->stream_analog_playback = &alc662_pcm_analog_playback;
        spec->stream_analog_capture = &alc662_pcm_analog_capture;