Merge branch 'fix/hda' into topic/hda
authorTakashi Iwai <tiwai@suse.de>
Sun, 19 Jul 2009 11:52:31 +0000 (13:52 +0200)
committerTakashi Iwai <tiwai@suse.de>
Sun, 19 Jul 2009 11:52:31 +0000 (13:52 +0200)
1  2 
sound/pci/hda/hda_codec.c
sound/pci/hda/patch_realtek.c

@@@ -150,14 -150,7 +150,14 @@@ make_codec_cmd(struct hda_codec *codec
  {
        u32 val;
  
 -      val = (u32)(codec->addr & 0x0f) << 28;
 +      if ((codec->addr & ~0xf) || (direct & ~1) || (nid & ~0x7f) ||
 +          (verb & ~0xfff) || (parm & ~0xffff)) {
 +              printk(KERN_ERR "hda-codec: out of range cmd %x:%x:%x:%x:%x\n",
 +                     codec->addr, direct, nid, verb, parm);
 +              return ~0;
 +      }
 +
 +      val = (u32)codec->addr << 28;
        val |= (u32)direct << 27;
        val |= (u32)nid << 20;
        val |= verb << 8;
@@@ -174,9 -167,6 +174,9 @@@ static int codec_exec_verb(struct hda_c
        struct hda_bus *bus = codec->bus;
        int err;
  
 +      if (cmd == ~0)
 +              return -1;
 +
        if (res)
                *res = -1;
   again:
@@@ -326,8 -316,6 +326,8 @@@ int snd_hda_get_connections(struct hda_
                /* single connection */
                parm = snd_hda_codec_read(codec, nid, 0,
                                          AC_VERB_GET_CONNECT_LIST, 0);
 +              if (parm == -1 && codec->bus->rirb_error)
 +                      return -EIO;
                conn_list[0] = parm & mask;
                return 1;
        }
                int range_val;
                hda_nid_t val, n;
  
 -              if (i % num_elems == 0)
 +              if (i % num_elems == 0) {
                        parm = snd_hda_codec_read(codec, nid, 0,
                                                  AC_VERB_GET_CONNECT_LIST, i);
 +                      if (parm == -1 && codec->bus->rirb_error)
 +                              return -EIO;
 +              }
                range_val = !!(parm & (1 << (shift-1))); /* ranges */
                val = parm & mask;
+               if (val == 0) {
+                       snd_printk(KERN_WARNING "hda_codec: "
+                                  "invalid CONNECT_LIST verb %x[%i]:%x\n",
+                                   nid, i, parm);
+                       return 0;
+               }
                parm >>= shift;
                if (range_val) {
                        /* ranges between the previous and this one */
@@@ -900,7 -891,7 +906,7 @@@ static void hda_set_power_state(struct 
   * Returns 0 if successful, or a negative error code.
   */
  int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
 -                                  int do_init, struct hda_codec **codecp)
 +                                  struct hda_codec **codecp)
  {
        struct hda_codec *codec;
        char component[31];
                            codec->afg ? codec->afg : codec->mfg,
                            AC_PWRST_D0);
  
 -      if (do_init) {
 -              err = snd_hda_codec_configure(codec);
 -              if (err < 0)
 -                      goto error;
 -      }
        snd_hda_codec_proc_new(codec);
  
        snd_hda_create_hwdep(codec);
@@@ -1046,7 -1042,6 +1052,7 @@@ int snd_hda_codec_configure(struct hda_
                err = init_unsol_queue(codec->bus);
        return err;
  }
 +EXPORT_SYMBOL_HDA(snd_hda_codec_configure);
  
  /**
   * snd_hda_codec_setup_stream - set up the codec for streaming
@@@ -2578,7 -2573,7 +2584,7 @@@ unsigned int snd_hda_calc_stream_format
        case 20:
        case 24:
        case 32:
 -              if (maxbps >= 32)
 +              if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE)
                        val |= 0x40;
                else if (maxbps >= 24)
                        val |= 0x30;
@@@ -2705,12 -2700,11 +2711,12 @@@ static int snd_hda_query_supported_pcm(
                                        bps = 20;
                        }
                }
 -              else if (streams == AC_SUPFMT_FLOAT32) {
 -                      /* should be exclusive */
 +              if (streams & AC_SUPFMT_FLOAT32) {
                        formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
 -                      bps = 32;
 -              } else if (streams == AC_SUPFMT_AC3) {
 +                      if (!bps)
 +                              bps = 32;
 +              }
 +              if (streams == AC_SUPFMT_AC3) {
                        /* should be exclusive */
                        /* temporary hack: we have still no proper support
                         * for the direct AC3 stream...
@@@ -208,6 -208,12 +208,6 @@@ enum 
        ALC885_MBP3,
        ALC885_MB5,
        ALC885_IMAC24,
 -      ALC882_AUTO,
 -      ALC882_MODEL_LAST,
 -};
 -
 -/* ALC883 models */
 -enum {
        ALC883_3ST_2ch_DIG,
        ALC883_3ST_6ch_DIG,
        ALC883_3ST_6ch,
        ALC889A_MB31,
        ALC1200_ASUS_P5Q,
        ALC883_SONY_VAIO_TT,
 -      ALC883_AUTO,
 -      ALC883_MODEL_LAST,
 +      ALC882_AUTO,
 +      ALC882_MODEL_LAST,
  };
  
  /* for GPIO Poll */
@@@ -314,8 -320,6 +314,8 @@@ struct alc_spec 
        struct snd_array kctls;
        struct hda_input_mux private_imux[3];
        hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
 +      hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
 +      hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
  
        /* hooks */
        void (*init_hook)(struct hda_codec *codec);
@@@ -4501,6 -4505,12 +4501,12 @@@ static int alc880_parse_auto_config(str
                                              &dig_nid, 1);
                if (err < 0)
                        continue;
+               if (dig_nid > 0x7f) {
+                       printk(KERN_ERR "alc880_auto: invalid dig_nid "
+                               "connection 0x%x for NID 0x%x\n", dig_nid,
+                               spec->autocfg.dig_out_pins[i]);
+                       continue;
+               }
                if (!i)
                        spec->multiout.dig_out_nid = dig_nid;
                else {
@@@ -6291,7 -6301,7 +6297,7 @@@ static int patch_alc260(struct hda_code
  
  
  /*
 - * ALC882 support
 + * ALC882/883/885/888/889 support
   *
   * ALC882 is almost identical with ALC880 but has cleaner and more flexible
   * configuration.  Each pin widget can choose any input DACs and a mixer.
   */
  #define ALC882_DIGOUT_NID     0x06
  #define ALC882_DIGIN_NID      0x0a
 +#define ALC883_DIGOUT_NID     ALC882_DIGOUT_NID
 +#define ALC883_DIGIN_NID      ALC882_DIGIN_NID
 +#define ALC1200_DIGOUT_NID    0x10
 +
  
  static struct hda_channel_mode alc882_ch_modes[1] = {
        { 8, NULL }
  };
  
 +/* DACs */
  static hda_nid_t alc882_dac_nids[4] = {
        /* front, rear, clfe, rear_surr */
        0x02, 0x03, 0x04, 0x05
  };
 +#define alc883_dac_nids               alc882_dac_nids
  
 -/* identical with ALC880 */
 +/* ADCs */
  #define alc882_adc_nids               alc880_adc_nids
  #define alc882_adc_nids_alt   alc880_adc_nids_alt
 +#define alc883_adc_nids               alc882_adc_nids_alt
 +static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
 +static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
 +#define alc889_adc_nids               alc880_adc_nids
  
  static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
  static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
 +#define alc883_capsrc_nids    alc882_capsrc_nids_alt
 +static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
 +#define alc889_capsrc_nids    alc882_capsrc_nids
  
  /* input MUX */
  /* FIXME: should be a matrix-type input source selection */
@@@ -6346,8 -6343,6 +6352,8 @@@ static struct hda_input_mux alc882_capt
        },
  };
  
 +#define alc883_capture_source alc882_capture_source
 +
  static struct hda_input_mux mb5_capture_source = {
        .num_items = 3,
        .items = {
        },
  };
  
 +static struct hda_input_mux alc883_3stack_6ch_intel = {
 +      .num_items = 4,
 +      .items = {
 +              { "Mic", 0x1 },
 +              { "Front Mic", 0x0 },
 +              { "Line", 0x2 },
 +              { "CD", 0x4 },
 +      },
 +};
 +
 +static struct hda_input_mux alc883_lenovo_101e_capture_source = {
 +      .num_items = 2,
 +      .items = {
 +              { "Mic", 0x1 },
 +              { "Line", 0x2 },
 +      },
 +};
 +
 +static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
 +      .num_items = 4,
 +      .items = {
 +              { "Mic", 0x0 },
 +              { "iMic", 0x1 },
 +              { "Line", 0x2 },
 +              { "CD", 0x4 },
 +      },
 +};
 +
 +static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
 +      .num_items = 2,
 +      .items = {
 +              { "Mic", 0x0 },
 +              { "Int Mic", 0x1 },
 +      },
 +};
 +
 +static struct hda_input_mux alc883_lenovo_sky_capture_source = {
 +      .num_items = 3,
 +      .items = {
 +              { "Mic", 0x0 },
 +              { "Front Mic", 0x1 },
 +              { "Line", 0x4 },
 +      },
 +};
 +
 +static struct hda_input_mux alc883_asus_eee1601_capture_source = {
 +      .num_items = 2,
 +      .items = {
 +              { "Mic", 0x0 },
 +              { "Line", 0x2 },
 +      },
 +};
 +
 +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
 + */
 +static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
 +      { 2, NULL }
 +};
 +
  /*
   * 2ch mode
   */
@@@ -6439,18 -6363,6 +6445,18 @@@ static struct hda_verb alc882_3ST_ch2_i
        { } /* end */
  };
  
 +/*
 + * 4ch mode
 + */
 +static struct hda_verb alc882_3ST_ch4_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_OUT },
 +      { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
 +      { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
 +      { } /* end */
 +};
 +
  /*
   * 6ch mode
   */
@@@ -6464,14 -6376,11 +6470,14 @@@ static struct hda_verb alc882_3ST_ch6_i
        { } /* end */
  };
  
 -static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
 +static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
        { 2, alc882_3ST_ch2_init },
 +      { 4, alc882_3ST_ch4_init },
        { 6, alc882_3ST_ch6_init },
  };
  
 +#define alc883_3ST_6ch_modes  alc882_3ST_6ch_modes
 +
  /*
   * 6ch mode
   */
@@@ -6559,143 -6468,6 +6565,143 @@@ static struct hda_channel_mode alc885_m
        { 6, alc885_mb5_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
 + */
 +static struct hda_verb alc883_3ST_ch2_intel_init[] = {
 +      { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 +      { 0x19, 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_3ST_ch4_intel_init[] = {
 +      { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 +      { 0x19, 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_3ST_ch6_intel_init[] = {
 +      { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 +      { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
 +      { 0x19, 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_3ST_6ch_intel_modes[3] = {
 +      { 2, alc883_3ST_ch2_intel_init },
 +      { 4, alc883_3ST_ch4_intel_init },
 +      { 6, alc883_3ST_ch6_intel_init },
 +};
 +
 +/*
 + * 6ch mode
 + */
 +static struct hda_verb alc883_sixstack_ch6_init[] = {
 +      { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
 +      { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 +      { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 +      { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 +      { } /* end */
 +};
 +
 +/*
 + * 8ch mode
 + */
 +static struct hda_verb alc883_sixstack_ch8_init[] = {
 +      { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 +      { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 +      { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 +      { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 +      { } /* end */
 +};
 +
 +static struct hda_channel_mode alc883_sixstack_modes[2] = {
 +      { 6, alc883_sixstack_ch6_init },
 +      { 8, alc883_sixstack_ch8_init },
 +};
 +
 +
  /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
   *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
   */
@@@ -6831,7 -6603,7 +6837,7 @@@ static struct snd_kcontrol_new alc882_c
        { } /* end */
  };
  
 -static struct hda_verb alc882_init_verbs[] = {
 +static struct hda_verb alc882_base_init_verbs[] = {
        /* Front mixer: unmute input/output amp left and right (volume = 0) */
        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  
 +      /* mute analog input loopbacks */
 +      {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 +      {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 +      {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 +      {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 +      {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 +
        /* Front Pin: output 0 (0x0c) */
        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  
        /* 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 */
 -      {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 -      {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 -      {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 -      {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
        /* Input mixer2 */
        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
        {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)},
 -      /* ADC1: mute amp left and right */
 -      {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 -      {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
        /* ADC2: mute amp left and right */
        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
        { }
  };
  
 -static struct hda_verb alc882_eapd_verbs[] = {
 -      /* change to EAPD mode */
 -      {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
 -      {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
 -      { }
 -};
 -
 -/* Mac Pro test */
 +static struct hda_verb alc882_adc1_init_verbs[] = {
 +      /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
 +      {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 +      {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 +      {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 +      {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 +      /* ADC1: mute amp left and right */
 +      {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 +      {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
 +      { }
 +};
 +
 +static struct hda_verb alc882_eapd_verbs[] = {
 +      /* change to EAPD mode */
 +      {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
 +      {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
 +      { }
 +};
 +
 +#define alc883_init_verbs     alc882_base_init_verbs
 +
 +/* Mac Pro test */
  static struct snd_kcontrol_new alc882_macpro_mixer[] = {
        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@@ -7278,10 -7037,12 +7284,10 @@@ static void alc885_imac24_init_hook(str
  /*
   * generic initialization of ADC, input mixers and output mixers
   */
 -static struct hda_verb alc882_auto_init_verbs[] = {
 +static struct hda_verb alc883_auto_init_verbs[] = {
        /*
         * Unmute ADC0-2 and set the default input to mic-in
         */
 -      {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
 -      {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  
        /* 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 */
 -      {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 -      {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
 -      {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
 -      {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
        /* Input mixer2 */
        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
        { }
  };
  
 -#ifdef CONFIG_SND_HDA_POWER_SAVE
 -#define alc882_loopbacks      alc880_loopbacks
 -#endif
 -
 -/* pcm configuration: identical with ALC880 */
 -#define alc882_pcm_analog_playback    alc880_pcm_analog_playback
 -#define alc882_pcm_analog_capture     alc880_pcm_analog_capture
 -#define alc882_pcm_digital_playback   alc880_pcm_digital_playback
 -#define alc882_pcm_digital_capture    alc880_pcm_digital_capture
 -
 -/*
 - * configuration and preset
 - */
 -static const char *alc882_models[ALC882_MODEL_LAST] = {
 -      [ALC882_3ST_DIG]        = "3stack-dig",
 -      [ALC882_6ST_DIG]        = "6stack-dig",
 -      [ALC882_ARIMA]          = "arima",
 -      [ALC882_W2JC]           = "w2jc",
 -      [ALC882_TARGA]          = "targa",
 -      [ALC882_ASUS_A7J]       = "asus-a7j",
 -      [ALC882_ASUS_A7M]       = "asus-a7m",
 -      [ALC885_MACPRO]         = "macpro",
 -      [ALC885_MB5]            = "mb5",
 -      [ALC885_MBP3]           = "mbp3",
 -      [ALC885_IMAC24]         = "imac24",
 -      [ALC882_AUTO]           = "auto",
 +/* 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 */
  };
  
 -static struct snd_pci_quirk alc882_cfg_tbl[] = {
 -      SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
 -      SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
 -      SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
 -      SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
 -      SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
 -      SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
 -      SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
 -      SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
 -      SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
 -      SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
 -      SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
 -      SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
 -      {}
 +/* 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 */
  };
  
 -static struct alc_config_preset alc882_presets[] = {
 -      [ALC882_3ST_DIG] = {
 -              .mixers = { alc882_base_mixer },
 -              .init_verbs = { alc882_init_verbs },
 -              .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 -              .dac_nids = alc882_dac_nids,
 -              .dig_out_nid = ALC882_DIGOUT_NID,
 -              .dig_in_nid = ALC882_DIGIN_NID,
 -              .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
 -              .channel_mode = alc882_ch_modes,
 -              .need_dac_fix = 1,
 -              .input_mux = &alc882_capture_source,
 -      },
 -      [ALC882_6ST_DIG] = {
 -              .mixers = { alc882_base_mixer, alc882_chmode_mixer },
 -              .init_verbs = { alc882_init_verbs },
 -              .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 -              .dac_nids = alc882_dac_nids,
 -              .dig_out_nid = ALC882_DIGOUT_NID,
 -              .dig_in_nid = ALC882_DIGIN_NID,
 -              .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
 -              .channel_mode = alc882_sixstack_modes,
 -              .input_mux = &alc882_capture_source,
 -      },
 -      [ALC882_ARIMA] = {
 -              .mixers = { alc882_base_mixer, alc882_chmode_mixer },
 -              .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
 -              .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 -              .dac_nids = alc882_dac_nids,
 -              .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
 -              .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_MBP3] = {
 -              .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
 -              .init_verbs = { alc885_mbp3_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),
 -              .input_mux = &alc882_capture_source,
 -              .dig_out_nid = ALC882_DIGOUT_NID,
 -              .dig_in_nid = ALC882_DIGIN_NID,
 -              .unsol_event = alc_automute_amp_unsol_event,
 -              .init_hook = alc885_mbp3_init_hook,
 -      },
 -      [ALC885_MB5] = {
 -              .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_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,
 -      },
 -      [ALC885_MACPRO] = {
 -              .mixers = { alc882_macpro_mixer },
 -              .init_verbs = { alc882_macpro_init_verbs },
 -              .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 -              .dac_nids = alc882_dac_nids,
 -              .dig_out_nid = ALC882_DIGOUT_NID,
 -              .dig_in_nid = ALC882_DIGIN_NID,
 -              .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
 -              .channel_mode = alc882_ch_modes,
 -              .input_mux = &alc882_capture_source,
 -              .init_hook = alc885_macpro_init_hook,
 -      },
 -      [ALC885_IMAC24] = {
 -              .mixers = { alc885_imac24_mixer },
 -              .init_verbs = { alc885_imac24_init_verbs },
 -              .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 -              .dac_nids = alc882_dac_nids,
 -              .dig_out_nid = ALC882_DIGOUT_NID,
 -              .dig_in_nid = ALC882_DIGIN_NID,
 -              .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
 -              .channel_mode = alc882_ch_modes,
 -              .input_mux = &alc882_capture_source,
 -              .unsol_event = alc_automute_amp_unsol_event,
 -              .init_hook = alc885_imac24_init_hook,
 -      },
 -      [ALC882_TARGA] = {
 -              .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
 -              .init_verbs = { alc882_init_verbs, alc880_gpio3_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,
 -              .capsrc_nids = alc882_capsrc_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_init_hook,
 -      },
 -      [ALC882_ASUS_A7J] = {
 -              .mixers = { alc882_asus_a7j_mixer, alc882_chmode_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,
 -              .capsrc_nids = alc882_capsrc_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,
 -      },
 -      [ALC882_ASUS_A7M] = {
 -              .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
 -              .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
 -                              alc880_gpio1_init_verbs,
 -                              alc882_asus_a7m_verbs },
 -              .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 -              .dac_nids = alc882_dac_nids,
 -              .dig_out_nid = ALC882_DIGOUT_NID,
 -              .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
 -              .channel_mode = alc880_threestack_modes,
 -              .need_dac_fix = 1,
 -              .input_mux = &alc882_capture_source,
 -      },
 +/* 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 */
  };
  
 -
 -/*
 - * Pin config fixes
 - */
 -enum {
 -      PINFIX_ABIT_AW9D_MAX
 +/* 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 alc_pincfg alc882_abit_aw9d_pinfix[] = {
 -      { 0x15, 0x01080104 }, /* side */
 -      { 0x16, 0x01011012 }, /* rear */
 -      { 0x17, 0x01016011 }, /* clfe */
 -      { }
 +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 const struct alc_pincfg *alc882_pin_fixes[] = {
 -      [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
 +static struct hda_verb alc883_medion_eapd_verbs[] = {
 +        /* eanable EAPD on medion laptop */
 +      {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
 +      {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
 +      { }
  };
  
 -static struct snd_pci_quirk alc882_pinfix_tbl[] = {
 -      SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
 -      {}
 -};
 -
 -/*
 - * BIOS auto configuration
 - */
 -static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
 -                                            hda_nid_t nid, int pin_type,
 -                                            int dac_idx)
 -{
 -      /* set as output */
 -      struct alc_spec *spec = codec->spec;
 -      int idx;
 -
 -      alc_set_pin_output(codec, nid, pin_type);
 -      if (spec->multiout.dac_nids[dac_idx] == 0x25)
 -              idx = 4;
 -      else
 -              idx = spec->multiout.dac_nids[dac_idx] - 2;
 -      snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
 -
 -}
 -
 -static void alc882_auto_init_multi_out(struct hda_codec *codec)
 -{
 -      struct alc_spec *spec = codec->spec;
 -      int i;
 -
 -      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_type,
 -                                                        i);
 -      }
 -}
 -
 -static void alc882_auto_init_hp_out(struct hda_codec *codec)
 -{
 -      struct alc_spec *spec = codec->spec;
 -      hda_nid_t pin;
 -
 -      pin = spec->autocfg.hp_pins[0];
 -      if (pin) /* connect to front */
 -              /* use dac 0 */
 -              alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
 -      pin = spec->autocfg.speaker_pins[0];
 -      if (pin)
 -              alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
 -}
 -
 -#define alc882_is_input_pin(nid)      alc880_is_input_pin(nid)
 -#define ALC882_PIN_CD_NID             ALC880_PIN_CD_NID
 -
 -static void alc882_auto_init_analog_input(struct hda_codec *codec)
 -{
 -      struct alc_spec *spec = codec->spec;
 -      int i;
 -
 -      for (i = 0; i < AUTO_PIN_LAST; i++) {
 -              hda_nid_t nid = spec->autocfg.input_pins[i];
 -              if (!nid)
 -                      continue;
 -              alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
 -              if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
 -                      snd_hda_codec_write(codec, nid, 0,
 -                                          AC_VERB_SET_AMP_GAIN_MUTE,
 -                                          AMP_OUT_MUTE);
 -      }
 -}
 -
 -static void alc882_auto_init_input_src(struct hda_codec *codec)
 -{
 -      struct alc_spec *spec = codec->spec;
 -      int c;
 -
 -      for (c = 0; c < spec->num_adc_nids; c++) {
 -              hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
 -              hda_nid_t nid = spec->capsrc_nids[c];
 -              unsigned int mux_idx;
 -              const struct hda_input_mux *imux;
 -              int conns, mute, idx, item;
 -
 -              conns = snd_hda_get_connections(codec, nid, conn_list,
 -                                              ARRAY_SIZE(conn_list));
 -              if (conns < 0)
 -                      continue;
 -              mux_idx = c >= spec->num_mux_defs ? 0 : c;
 -              imux = &spec->input_mux[mux_idx];
 -              for (idx = 0; idx < conns; idx++) {
 -                      /* if the current connection is the selected one,
 -                       * unmute it as default - otherwise mute it
 -                       */
 -                      mute = AMP_IN_MUTE(idx);
 -                      for (item = 0; item < imux->num_items; item++) {
 -                              if (imux->items[item].index == idx) {
 -                                      if (spec->cur_mux[c] == item)
 -                                              mute = AMP_IN_UNMUTE(idx);
 -                                      break;
 -                              }
 -                      }
 -                      /* check if we have a selector or mixer
 -                       * we could check for the widget type instead, but
 -                       * just check for Amp-In presence (in case of mixer
 -                       * without amp-in there is something wrong, this
 -                       * function shouldn't be used or capsrc nid is wrong)
 -                       */
 -                      if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
 -                              snd_hda_codec_write(codec, nid, 0,
 -                                                  AC_VERB_SET_AMP_GAIN_MUTE,
 -                                                  mute);
 -                      else if (mute != AMP_IN_MUTE(idx))
 -                              snd_hda_codec_write(codec, nid, 0,
 -                                                  AC_VERB_SET_CONNECT_SEL,
 -                                                  idx);
 -              }
 -      }
 -}
 -
 -/* add mic boosts if needed */
 -static int alc_auto_add_mic_boost(struct hda_codec *codec)
 -{
 -      struct alc_spec *spec = codec->spec;
 -      int err;
 -      hda_nid_t nid;
 -
 -      nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
 -      if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
 -              err = add_control(spec, ALC_CTL_WIDGET_VOL,
 -                                "Mic Boost",
 -                                HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
 -              if (err < 0)
 -                      return err;
 -      }
 -      nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
 -      if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
 -              err = add_control(spec, ALC_CTL_WIDGET_VOL,
 -                                "Front Mic Boost",
 -                                HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
 -              if (err < 0)
 -                      return err;
 -      }
 -      return 0;
 -}
 -
 -/* almost identical with ALC880 parser... */
 -static int alc882_parse_auto_config(struct hda_codec *codec)
 -{
 -      struct alc_spec *spec = codec->spec;
 -      int err = alc880_parse_auto_config(codec);
 -
 -      if (err < 0)
 -              return err;
 -      else if (!err)
 -              return 0; /* no config found */
 -
 -      err = alc_auto_add_mic_boost(codec);
 -      if (err < 0)
 -              return err;
 -
 -      /* hack - override the init verbs */
 -      spec->init_verbs[0] = alc882_auto_init_verbs;
 -
 -      return 1; /* config found */
 -}
 -
 -/* additional initialization for auto-configuration model */
 -static void alc882_auto_init(struct hda_codec *codec)
 -{
 -      struct alc_spec *spec = codec->spec;
 -      alc882_auto_init_multi_out(codec);
 -      alc882_auto_init_hp_out(codec);
 -      alc882_auto_init_analog_input(codec);
 -      alc882_auto_init_input_src(codec);
 -      if (spec->unsol_event)
 -              alc_inithook(codec);
 -}
 -
 -static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
 -
 -static int patch_alc882(struct hda_codec *codec)
 -{
 -      struct alc_spec *spec;
 -      int err, board_config;
 -
 -      spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 -      if (spec == NULL)
 -              return -ENOMEM;
 -
 -      codec->spec = spec;
 -
 -      board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
 -                                                alc882_models,
 -                                                alc882_cfg_tbl);
 -
 -      if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
 -              /* Pick up systems that don't supply PCI SSID */
 -              switch (codec->subsystem_id) {
 -              case 0x106b0c00: /* Mac Pro */
 -                      board_config = ALC885_MACPRO;
 -                      break;
 -              case 0x106b1000: /* iMac 24 */
 -              case 0x106b2800: /* AppleTV */
 -              case 0x106b3e00: /* iMac 24 Aluminium */
 -                      board_config = ALC885_IMAC24;
 -                      break;
 -              case 0x106b00a0: /* MacBookPro3,1 - Another revision */
 -              case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
 -              case 0x106b00a4: /* MacbookPro4,1 */
 -              case 0x106b2c00: /* Macbook Pro rev3 */
 -              /* Macbook 3.1 (0x106b3600) is handled by patch_alc883() */
 -              case 0x106b3800: /* MacbookPro4,1 - latter revision */
 -                      board_config = ALC885_MBP3;
 -                      break;
 -              case 0x106b3f00: /* Macbook 5,1 */
 -              case 0x106b4000: /* Macbook Pro 5,1 - FIXME: HP jack sense
 -                                *   seems not working, so apparently
 -                                *   no perfect solution yet
 -                                */
 -                      board_config = ALC885_MB5;
 -                      break;
 -              default:
 -                      /* ALC889A is handled better as ALC888-compatible */
 -                      if (codec->revision_id == 0x100101 ||
 -                          codec->revision_id == 0x100103) {
 -                              alc_free(codec);
 -                              return patch_alc883(codec);
 -                      }
 -                      printk(KERN_INFO "hda_codec: Unknown model for %s, "
 -                             "trying auto-probe from BIOS...\n",
 -                             codec->chip_name);
 -                      board_config = ALC882_AUTO;
 -              }
 -      }
 -
 -      alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
 -
 -      if (board_config == ALC882_AUTO) {
 -              /* automatic parse from the BIOS config */
 -              err = alc882_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 = ALC882_3ST_DIG;
 -              }
 -      }
 -
 -      err = snd_hda_attach_beep_device(codec, 0x1);
 -      if (err < 0) {
 -              alc_free(codec);
 -              return err;
 -      }
 -
 -      if (board_config != ALC882_AUTO)
 -              setup_preset(spec, &alc882_presets[board_config]);
 -
 -      spec->stream_analog_playback = &alc882_pcm_analog_playback;
 -      spec->stream_analog_capture = &alc882_pcm_analog_capture;
 -      /* FIXME: setup DAC5 */
 -      /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
 -      spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
 -
 -      spec->stream_digital_playback = &alc882_pcm_digital_playback;
 -      spec->stream_digital_capture = &alc882_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 = alc882_adc_nids_alt;
 -                      spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
 -                      spec->capsrc_nids = alc882_capsrc_nids_alt;
 -              } else {
 -                      spec->adc_nids = alc882_adc_nids;
 -                      spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
 -                      spec->capsrc_nids = alc882_capsrc_nids;
 -              }
 -      }
 -      set_capture_mixer(spec);
 -      set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
 -
 -      spec->vmaster_nid = 0x0c;
 -
 -      codec->patch_ops = alc_patch_ops;
 -      if (board_config == ALC882_AUTO)
 -              spec->init_hook = alc882_auto_init;
 -#ifdef CONFIG_SND_HDA_POWER_SAVE
 -      if (!spec->loopback.amplist)
 -              spec->loopback.amplist = alc882_loopbacks;
 -#endif
 -      codec->proc_widget_hook = print_realtek_coef;
 -
 -      return 0;
 -}
 -
 -/*
 - * ALC883 support
 - *
 - * ALC883 is almost identical with ALC880 but has cleaner and more flexible
 - * configuration.  Each pin widget can choose any input DACs and a mixer.
 - * Each ADC is connected from a mixer of all inputs.  This makes possible
 - * 6-channel independent captures.
 - *
 - * In addition, an independent DAC for the multi-playback (not used in this
 - * driver yet).
 - */
 -#define ALC883_DIGOUT_NID     0x06
 -#define ALC883_DIGIN_NID      0x0a
 -
 -#define ALC1200_DIGOUT_NID    0x10
 -
 -static hda_nid_t alc883_dac_nids[4] = {
 -      /* front, rear, clfe, rear_surr */
 -      0x02, 0x03, 0x04, 0x05
 -};
 -
 -static hda_nid_t alc883_adc_nids[2] = {
 -      /* ADC1-2 */
 -      0x08, 0x09,
 -};
 -
 -static hda_nid_t alc883_adc_nids_alt[1] = {
 -      /* ADC1 */
 -      0x08,
 -};
 -
 -static hda_nid_t alc883_adc_nids_rev[2] = {
 -      /* ADC2-1 */
 -      0x09, 0x08
 -};
 -
 -#define alc889_adc_nids               alc880_adc_nids
 -
 -static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
 -
 -static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
 -
 -#define alc889_capsrc_nids    alc882_capsrc_nids
 -
 -/* input MUX */
 -/* FIXME: should be a matrix-type input source selection */
 -
 -static struct hda_input_mux alc883_capture_source = {
 -      .num_items = 4,
 -      .items = {
 -              { "Mic", 0x0 },
 -              { "Front Mic", 0x1 },
 -              { "Line", 0x2 },
 -              { "CD", 0x4 },
 -      },
 -};
 -
 -static struct hda_input_mux alc883_3stack_6ch_intel = {
 -      .num_items = 4,
 -      .items = {
 -              { "Mic", 0x1 },
 -              { "Front Mic", 0x0 },
 -              { "Line", 0x2 },
 -              { "CD", 0x4 },
 -      },
 -};
 -
 -static struct hda_input_mux alc883_lenovo_101e_capture_source = {
 -      .num_items = 2,
 -      .items = {
 -              { "Mic", 0x1 },
 -              { "Line", 0x2 },
 -      },
 -};
 -
 -static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
 -      .num_items = 4,
 -      .items = {
 -              { "Mic", 0x0 },
 -              { "iMic", 0x1 },
 -              { "Line", 0x2 },
 -              { "CD", 0x4 },
 -      },
 -};
 -
 -static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
 -      .num_items = 2,
 -      .items = {
 -              { "Mic", 0x0 },
 -              { "Int Mic", 0x1 },
 -      },
 -};
 -
 -static struct hda_input_mux alc883_lenovo_sky_capture_source = {
 -      .num_items = 3,
 -      .items = {
 -              { "Mic", 0x0 },
 -              { "Front Mic", 0x1 },
 -              { "Line", 0x4 },
 -      },
 -};
 -
 -static struct hda_input_mux alc883_asus_eee1601_capture_source = {
 -      .num_items = 2,
 -      .items = {
 -              { "Mic", 0x0 },
 -              { "Line", 0x2 },
 -      },
 -};
 -
 -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
 - */
 -static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
 -      { 2, NULL }
 -};
 -
 -/*
 - * 2ch mode
 - */
 -static struct hda_verb alc883_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 */
 -};
 -
 -/*
 - * 4ch mode
 - */
 -static struct hda_verb alc883_3ST_ch4_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_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_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 alc883_3ST_6ch_modes[3] = {
 -      { 2, alc883_3ST_ch2_init },
 -      { 4, alc883_3ST_ch4_init },
 -      { 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
 - */
 -static struct hda_verb alc883_3ST_ch2_intel_init[] = {
 -      { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 -      { 0x19, 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_3ST_ch4_intel_init[] = {
 -      { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 -      { 0x19, 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_3ST_ch6_intel_init[] = {
 -      { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 -      { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
 -      { 0x19, 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_3ST_6ch_intel_modes[3] = {
 -      { 2, alc883_3ST_ch2_intel_init },
 -      { 4, alc883_3ST_ch4_intel_init },
 -      { 6, alc883_3ST_ch6_intel_init },
 -};
 -
 -/*
 - * 6ch mode
 - */
 -static struct hda_verb alc883_sixstack_ch6_init[] = {
 -      { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
 -      { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 -      { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 -      { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 -      { } /* end */
 -};
 -
 -/*
 - * 8ch mode
 - */
 -static struct hda_verb alc883_sixstack_ch8_init[] = {
 -      { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 -      { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 -      { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 -      { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 -      { } /* end */
 -};
 -
 -static struct hda_channel_mode alc883_sixstack_modes[2] = {
 -      { 6, alc883_sixstack_ch6_init },
 -      { 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},
 -      {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
 -      { }
 -};
 -
 -/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
 - *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
 - */
 -
 -static struct snd_kcontrol_new alc883_base_mixer[] = {
 -      HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 -      HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 -      HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 -      HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 -      HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 -      HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
 -      HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
 -      HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 -      HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
 -      HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
 -      HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 -      HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 -      HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 -      HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 -      HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 -      HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 -      HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 -      HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 -      HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 -      HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
 -      HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 -      { } /* end */
 -};
 +#define alc883_base_mixer     alc882_base_mixer
  
  static struct snd_kcontrol_new alc883_mitac_mixer[] = {
        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@@ -7696,45 -8303,123 +7702,45 @@@ static struct hda_bind_ctls alc883_bind
                HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
                HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
                0
 -      },
 -};
 -
 -static struct snd_kcontrol_new alc883_asus_eee1601_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", 0x14, 0x0, HDA_OUTPUT),
 -      HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 -      HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 -      HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 -      HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 -      HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 -      { } /* end */
 -};
 -
 -static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
 -      HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
 -      HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
 -      {
 -              .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 -              /* .name = "Capture Source", */
 -              .name = "Input Source",
 -              .count = 1,
 -              .info = alc_mux_enum_info,
 -              .get = alc_mux_enum_get,
 -              .put = alc_mux_enum_put,
 -      },
 -      { } /* end */
 -};
 -
 -static struct snd_kcontrol_new alc883_chmode_mixer[] = {
 -      {
 -              .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 -              .name = "Channel Mode",
 -              .info = alc_ch_mode_info,
 -              .get = alc_ch_mode_get,
 -              .put = alc_ch_mode_put,
 -      },
 -      { } /* end */
 -};
 -
 -static struct hda_verb alc883_init_verbs[] = {
 -      /* ADC1: mute amp left and right */
 -      {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 -      {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
 -      /* ADC2: mute amp left and right */
 -      {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 -      {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
 -      /* Front mixer: unmute input/output amp left and right (volume = 0) */
 -      {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)},
 -      /* Rear 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)},
 -      /* CLFE 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)},
 -      /* Side 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)},
 -
 -      /* mute analog input loopbacks */
 -      {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 -      {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 -      {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 -      {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 -      {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 -
 -      /* Front Pin: output 0 (0x0c) */
 -      {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},
 -      /* Rear Pin: output 1 (0x0d) */
 -      {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},
 -      /* CLFE Pin: output 2 (0x0e) */
 -      {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},
 -      /* Side Pin: output 3 (0x0f) */
 -      {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},
 -      /* Mic (rear) pin: input vref at 80% */
 -      {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 -      {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 -      /* 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},
 -      /* Line In pin: input */
 -      {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 -      {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 -      /* Line-2 In: Headphone output (output 0 - 0x0c) */
 -      {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 -      {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 -      {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
 -      /* CD pin widget for input */
 -      {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 +      },
 +};
  
 -      /* FIXME: use matrix-type input source selection */
 -      /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
 -      /* Input mixer2 */
 -      {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 -      {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 -      {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 -      {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 -      /* Input mixer3 */
 -      {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 -      {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 -      {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 -      {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 -      { }
 +static struct snd_kcontrol_new alc883_asus_eee1601_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", 0x14, 0x0, HDA_OUTPUT),
 +      HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 +      HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 +      HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 +      HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 +      HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 +      { } /* end */
 +};
 +
 +static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
 +      HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
 +      HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
 +      {
 +              .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 +              /* .name = "Capture Source", */
 +              .name = "Input Source",
 +              .count = 1,
 +              .info = alc_mux_enum_info,
 +              .get = alc_mux_enum_get,
 +              .put = alc_mux_enum_put,
 +      },
 +      { } /* end */
 +};
 +
 +static struct snd_kcontrol_new alc883_chmode_mixer[] = {
 +      {
 +              .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 +              .name = "Channel Mode",
 +              .info = alc_ch_mode_info,
 +              .get = alc_ch_mode_get,
 +              .put = alc_ch_mode_put,
 +      },
 +      { } /* end */
  };
  
  /* toggle speaker-output according to the hp-jack state */
@@@ -8169,6 -8854,69 +8175,6 @@@ static void alc883_vaiott_init_hook(str
        alc_automute_amp(codec);
  }
  
 -/*
 - * generic initialization of ADC, input mixers and output mixers
 - */
 -static struct hda_verb alc883_auto_init_verbs[] = {
 -      /*
 -       * Unmute ADC0-2 and set the default input to mic-in
 -       */
 -      {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
 -      {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 -      {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
 -      {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 -
 -      /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
 -       * mixer widget
 -       * Note: PASD motherboards uses the Line In 2 as the input for
 -       * front panel mic (mic 2)
 -       */
 -      /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
 -      {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 -      {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 -      {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 -      {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 -      {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 -
 -      /*
 -       * Set up output mixers (0x0c - 0x0f)
 -       */
 -      /* set vol=0 to output mixers */
 -      {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 -      {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 -      {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 -      {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 -      /* set up input amps for analog loopback */
 -      /* Amp Indices: DAC = 0, mixer = 1 */
 -      {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_UNMUTE(0)},
 -      {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 -      {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)},
 -      {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 -      {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 -      {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 -
 -      /* FIXME: use matrix-type input source selection */
 -      /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
 -      /* Input mixer1 */
 -      {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 -      {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 -      {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
 -      /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
 -      {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
 -      /* Input mixer2 */
 -      {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(3)}, */
 -      {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
 -
 -      { }
 -};
 -
  static struct hda_verb alc888_asus_m90v_verbs[] = {
        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@@ -8279,44 -9027,25 +8285,44 @@@ static void alc889A_mb31_unsol_event(st
                alc889A_mb31_automute(codec);
  }
  
 +
  #ifdef CONFIG_SND_HDA_POWER_SAVE
 -#define alc883_loopbacks      alc880_loopbacks
 +#define alc882_loopbacks      alc880_loopbacks
  #endif
  
  /* pcm configuration: identical with ALC880 */
 -#define alc883_pcm_analog_playback    alc880_pcm_analog_playback
 -#define alc883_pcm_analog_capture     alc880_pcm_analog_capture
 -#define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
 -#define alc883_pcm_digital_playback   alc880_pcm_digital_playback
 -#define alc883_pcm_digital_capture    alc880_pcm_digital_capture
 +#define alc882_pcm_analog_playback    alc880_pcm_analog_playback
 +#define alc882_pcm_analog_capture     alc880_pcm_analog_capture
 +#define alc882_pcm_digital_playback   alc880_pcm_digital_playback
 +#define alc882_pcm_digital_capture    alc880_pcm_digital_capture
 +
 +static hda_nid_t alc883_slave_dig_outs[] = {
 +      ALC1200_DIGOUT_NID, 0,
 +};
 +
 +static hda_nid_t alc1200_slave_dig_outs[] = {
 +      ALC883_DIGOUT_NID, 0,
 +};
  
  /*
   * configuration and preset
   */
 -static const char *alc883_models[ALC883_MODEL_LAST] = {
 -      [ALC883_3ST_2ch_DIG]    = "3stack-dig",
 +static const char *alc882_models[ALC882_MODEL_LAST] = {
 +      [ALC882_3ST_DIG]        = "3stack-dig",
 +      [ALC882_6ST_DIG]        = "6stack-dig",
 +      [ALC882_ARIMA]          = "arima",
 +      [ALC882_W2JC]           = "w2jc",
 +      [ALC882_TARGA]          = "targa",
 +      [ALC882_ASUS_A7J]       = "asus-a7j",
 +      [ALC882_ASUS_A7M]       = "asus-a7m",
 +      [ALC885_MACPRO]         = "macpro",
 +      [ALC885_MB5]            = "mb5",
 +      [ALC885_MBP3]           = "mbp3",
 +      [ALC885_IMAC24]         = "imac24",
 +      [ALC883_3ST_2ch_DIG]    = "3stack-2ch-dig",
        [ALC883_3ST_6ch_DIG]    = "3stack-6ch-dig",
        [ALC883_3ST_6ch]        = "3stack-6ch",
 -      [ALC883_6ST_DIG]        = "6stack-dig",
 +      [ALC883_6ST_DIG]        = "alc883-6stack-dig",
        [ALC883_TARGA_DIG]      = "targa-dig",
        [ALC883_TARGA_2ch_DIG]  = "targa-2ch-dig",
        [ALC883_TARGA_8ch_DIG]  = "targa-8ch-dig",
        [ALC1200_ASUS_P5Q]      = "asus-p5q",
        [ALC889A_MB31]          = "mb31",
        [ALC883_SONY_VAIO_TT]   = "sony-vaio-tt",
 -      [ALC883_AUTO]           = "auto",
 +      [ALC882_AUTO]           = "auto",
  };
  
 -static struct snd_pci_quirk alc883_cfg_tbl[] = {
 -      SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
 +static struct snd_pci_quirk alc882_cfg_tbl[] = {
 +      SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
 +
        SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
        SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
        SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
                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, 0x0157, "Acer X3200", ALC882_AUTO),
 +      SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
        SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
                ALC888_ACER_ASPIRE_6530G),
        SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
         *    model=auto should work fine now
         */
        /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
 +
        SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
 +
        SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
        SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
        SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
        SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
 +
 +      SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
 +      SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
 +      SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
        SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
 +      SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
 +      SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
 +      SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
        SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
        SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
        SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
 +
 +      SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
        SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
 -      SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
 +      SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
        SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
        SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
        SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
        SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
        SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
 -      SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
 +      SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
 +
        SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
        SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
        SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
 +      SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
        SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
 +      SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
        SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
 +      SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
        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, 0x7327, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
 +      SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
 +
        SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
        SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
        SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
        SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
 +      /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
        SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
        SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
                      ALC883_FUJITSU_PI2515),
        SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
        SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
 +
        SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
        SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
        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),
 -      {}
 -};
  
 -static hda_nid_t alc883_slave_dig_outs[] = {
 -      ALC1200_DIGOUT_NID, 0,
 +      {}
  };
  
 -static hda_nid_t alc1200_slave_dig_outs[] = {
 -      ALC883_DIGOUT_NID, 0,
 +/* codec SSID table for Intel Mac */
 +static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
 +      SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
 +      SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
 +      SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
 +      SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
 +      SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
 +      SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
 +      SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
 +      SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
 +      SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
 +      SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
 +      SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
 +      /* FIXME: HP jack sense seems not working for MBP 5,1, so apparently
 +       * no perfect solution yet
 +       */
 +      SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
 +      {} /* terminator */
  };
  
 -static struct alc_config_preset alc883_presets[] = {
 +static struct alc_config_preset alc882_presets[] = {
 +      [ALC882_3ST_DIG] = {
 +              .mixers = { alc882_base_mixer },
 +              .init_verbs = { alc882_base_init_verbs,
 +                              alc882_adc1_init_verbs },
 +              .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 +              .dac_nids = alc882_dac_nids,
 +              .dig_out_nid = ALC882_DIGOUT_NID,
 +              .dig_in_nid = ALC882_DIGIN_NID,
 +              .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
 +              .channel_mode = alc882_ch_modes,
 +              .need_dac_fix = 1,
 +              .input_mux = &alc882_capture_source,
 +      },
 +      [ALC882_6ST_DIG] = {
 +              .mixers = { alc882_base_mixer, alc882_chmode_mixer },
 +              .init_verbs = { alc882_base_init_verbs,
 +                              alc882_adc1_init_verbs },
 +              .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 +              .dac_nids = alc882_dac_nids,
 +              .dig_out_nid = ALC882_DIGOUT_NID,
 +              .dig_in_nid = ALC882_DIGIN_NID,
 +              .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
 +              .channel_mode = alc882_sixstack_modes,
 +              .input_mux = &alc882_capture_source,
 +      },
 +      [ALC882_ARIMA] = {
 +              .mixers = { alc882_base_mixer, alc882_chmode_mixer },
 +              .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
 +                              alc882_eapd_verbs },
 +              .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 +              .dac_nids = alc882_dac_nids,
 +              .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
 +              .channel_mode = alc882_sixstack_modes,
 +              .input_mux = &alc882_capture_source,
 +      },
 +      [ALC882_W2JC] = {
 +              .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
 +              .init_verbs = { alc882_base_init_verbs, alc882_adc1_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_MBP3] = {
 +              .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
 +              .init_verbs = { alc885_mbp3_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),
 +              .input_mux = &alc882_capture_source,
 +              .dig_out_nid = ALC882_DIGOUT_NID,
 +              .dig_in_nid = ALC882_DIGIN_NID,
 +              .unsol_event = alc_automute_amp_unsol_event,
 +              .init_hook = alc885_mbp3_init_hook,
 +      },
 +      [ALC885_MB5] = {
 +              .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_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,
 +      },
 +      [ALC885_MACPRO] = {
 +              .mixers = { alc882_macpro_mixer },
 +              .init_verbs = { alc882_macpro_init_verbs },
 +              .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 +              .dac_nids = alc882_dac_nids,
 +              .dig_out_nid = ALC882_DIGOUT_NID,
 +              .dig_in_nid = ALC882_DIGIN_NID,
 +              .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
 +              .channel_mode = alc882_ch_modes,
 +              .input_mux = &alc882_capture_source,
 +              .init_hook = alc885_macpro_init_hook,
 +      },
 +      [ALC885_IMAC24] = {
 +              .mixers = { alc885_imac24_mixer },
 +              .init_verbs = { alc885_imac24_init_verbs },
 +              .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 +              .dac_nids = alc882_dac_nids,
 +              .dig_out_nid = ALC882_DIGOUT_NID,
 +              .dig_in_nid = ALC882_DIGIN_NID,
 +              .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
 +              .channel_mode = alc882_ch_modes,
 +              .input_mux = &alc882_capture_source,
 +              .unsol_event = alc_automute_amp_unsol_event,
 +              .init_hook = alc885_imac24_init_hook,
 +      },
 +      [ALC882_TARGA] = {
 +              .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
 +              .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
 +                              alc880_gpio3_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,
 +              .capsrc_nids = alc882_capsrc_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_init_hook,
 +      },
 +      [ALC882_ASUS_A7J] = {
 +              .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
 +              .init_verbs = { alc882_base_init_verbs, alc882_adc1_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,
 +              .capsrc_nids = alc882_capsrc_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,
 +      },
 +      [ALC882_ASUS_A7M] = {
 +              .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
 +              .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
 +                              alc882_eapd_verbs, alc880_gpio1_init_verbs,
 +                              alc882_asus_a7m_verbs },
 +              .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 +              .dac_nids = alc882_dac_nids,
 +              .dig_out_nid = ALC882_DIGOUT_NID,
 +              .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
 +              .channel_mode = alc880_threestack_modes,
 +              .need_dac_fix = 1,
 +              .input_mux = &alc882_capture_source,
 +      },
        [ALC883_3ST_2ch_DIG] = {
                .mixers = { alc883_3ST_2ch_mixer },
                .init_verbs = { alc883_init_verbs },
  };
  
  
 +/*
 + * Pin config fixes
 + */
 +enum {
 +      PINFIX_ABIT_AW9D_MAX
 +};
 +
 +static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
 +      { 0x15, 0x01080104 }, /* side */
 +      { 0x16, 0x01011012 }, /* rear */
 +      { 0x17, 0x01016011 }, /* clfe */
 +      { }
 +};
 +
 +static const struct alc_pincfg *alc882_pin_fixes[] = {
 +      [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
 +};
 +
 +static struct snd_pci_quirk alc882_pinfix_tbl[] = {
 +      SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
 +      {}
 +};
 +
  /*
   * BIOS auto configuration
   */
 -static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
 +static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
                                              hda_nid_t nid, int pin_type,
                                              int dac_idx)
  {
  
  }
  
 -static void alc883_auto_init_multi_out(struct hda_codec *codec)
 +static void alc882_auto_init_multi_out(struct hda_codec *codec)
  {
        struct alc_spec *spec = codec->spec;
        int 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_type,
 +                      alc882_auto_set_output_and_unmute(codec, nid, pin_type,
                                                          i);
        }
  }
  
 -static void alc883_auto_init_hp_out(struct hda_codec *codec)
 +static void alc882_auto_init_hp_out(struct hda_codec *codec)
  {
        struct alc_spec *spec = codec->spec;
        hda_nid_t pin;
        pin = spec->autocfg.hp_pins[0];
        if (pin) /* connect to front */
                /* use dac 0 */
 -              alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
 +              alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
        pin = spec->autocfg.speaker_pins[0];
        if (pin)
 -              alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
 +              alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
  }
  
 -#define alc883_is_input_pin(nid)      alc880_is_input_pin(nid)
 -#define ALC883_PIN_CD_NID             ALC880_PIN_CD_NID
 -
 -static void alc883_auto_init_analog_input(struct hda_codec *codec)
 +static void alc882_auto_init_analog_input(struct hda_codec *codec)
  {
        struct alc_spec *spec = codec->spec;
        int i;
  
        for (i = 0; i < AUTO_PIN_LAST; i++) {
                hda_nid_t nid = spec->autocfg.input_pins[i];
 -              if (alc883_is_input_pin(nid)) {
 -                      alc_set_input_pin(codec, nid, i);
 -                      if (nid != ALC883_PIN_CD_NID &&
 -                          (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
 +              if (!nid)
 +                      continue;
 +              alc_set_input_pin(codec, nid, i);
 +              if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
 +                      snd_hda_codec_write(codec, nid, 0,
 +                                          AC_VERB_SET_AMP_GAIN_MUTE,
 +                                          AMP_OUT_MUTE);
 +      }
 +}
 +
 +static void alc882_auto_init_input_src(struct hda_codec *codec)
 +{
 +      struct alc_spec *spec = codec->spec;
 +      int c;
 +
 +      for (c = 0; c < spec->num_adc_nids; c++) {
 +              hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
 +              hda_nid_t nid = spec->capsrc_nids[c];
 +              unsigned int mux_idx;
 +              const struct hda_input_mux *imux;
 +              int conns, mute, idx, item;
 +
 +              conns = snd_hda_get_connections(codec, nid, conn_list,
 +                                              ARRAY_SIZE(conn_list));
 +              if (conns < 0)
 +                      continue;
 +              mux_idx = c >= spec->num_mux_defs ? 0 : c;
 +              imux = &spec->input_mux[mux_idx];
 +              for (idx = 0; idx < conns; idx++) {
 +                      /* if the current connection is the selected one,
 +                       * unmute it as default - otherwise mute it
 +                       */
 +                      mute = AMP_IN_MUTE(idx);
 +                      for (item = 0; item < imux->num_items; item++) {
 +                              if (imux->items[item].index == idx) {
 +                                      if (spec->cur_mux[c] == item)
 +                                              mute = AMP_IN_UNMUTE(idx);
 +                                      break;
 +                              }
 +                      }
 +                      /* check if we have a selector or mixer
 +                       * we could check for the widget type instead, but
 +                       * just check for Amp-In presence (in case of mixer
 +                       * without amp-in there is something wrong, this
 +                       * function shouldn't be used or capsrc nid is wrong)
 +                       */
 +                      if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
                                snd_hda_codec_write(codec, nid, 0,
                                                    AC_VERB_SET_AMP_GAIN_MUTE,
 -                                                  AMP_OUT_MUTE);
 +                                                  mute);
 +                      else if (mute != AMP_IN_MUTE(idx))
 +                              snd_hda_codec_write(codec, nid, 0,
 +                                                  AC_VERB_SET_CONNECT_SEL,
 +                                                  idx);
                }
        }
  }
  
 -#define alc883_auto_init_input_src    alc882_auto_init_input_src
 +/* add mic boosts if needed */
 +static int alc_auto_add_mic_boost(struct hda_codec *codec)
 +{
 +      struct alc_spec *spec = codec->spec;
 +      int err;
 +      hda_nid_t nid;
 +
 +      nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
 +      if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
 +              err = add_control(spec, ALC_CTL_WIDGET_VOL,
 +                                "Mic Boost",
 +                                HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
 +              if (err < 0)
 +                      return err;
 +      }
 +      nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
 +      if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
 +              err = add_control(spec, ALC_CTL_WIDGET_VOL,
 +                                "Front Mic Boost",
 +                                HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
 +              if (err < 0)
 +                      return err;
 +      }
 +      return 0;
 +}
  
  /* almost identical with ALC880 parser... */
 -static int alc883_parse_auto_config(struct hda_codec *codec)
 +static int alc882_parse_auto_config(struct hda_codec *codec)
  {
        struct alc_spec *spec = codec->spec;
 -      int err = alc880_parse_auto_config(codec);
 -      struct auto_pin_cfg *cfg = &spec->autocfg;
 +      struct auto_pin_cfg *autocfg = &spec->autocfg;
 +      unsigned int wcap;
        int i;
 +      int err = alc880_parse_auto_config(codec);
  
        if (err < 0)
                return err;
  
        /* hack - override the init verbs */
        spec->init_verbs[0] = alc883_auto_init_verbs;
 +      /* if ADC 0x07 is available, initialize it, too */
 +      wcap = get_wcaps(codec, 0x07);
 +      wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
 +      if (wcap == AC_WID_AUD_IN)
 +              add_verb(spec, alc882_adc1_init_verbs);
  
 -      /* setup input_mux for ALC889 */
 -      if (codec->vendor_id == 0x10ec0889) {
 -              /* digital-mic input pin is excluded in alc880_auto_create..()
 -               * because it's under 0x18
 -               */
 -              if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
 -                  cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
 -                      struct hda_input_mux *imux = &spec->private_imux[0];
 -                      for (i = 1; i < 3; i++)
 -                              memcpy(&spec->private_imux[i],
 -                                     &spec->private_imux[0],
 -                                     sizeof(spec->private_imux[0]));
 -                      imux->items[imux->num_items].label = "Int DMic";
 -                      imux->items[imux->num_items].index = 0x0b;
 -                      imux->num_items++;
 -                      spec->num_mux_defs = 3;
 -                      spec->input_mux = spec->private_imux;
 -              }
 +      /* digital-mic input pin is excluded in alc880_auto_create..()
 +       * because it's under 0x18
 +       */
 +      if (autocfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
 +          autocfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
 +              struct hda_input_mux *imux = &spec->private_imux[0];
 +              for (i = 1; i < 3; i++)
 +                      memcpy(&spec->private_imux[i],
 +                             &spec->private_imux[0],
 +                             sizeof(spec->private_imux[0]));
 +              imux->items[imux->num_items].label = "Int DMic";
 +              imux->items[imux->num_items].index = 0x0b;
 +              imux->num_items++;
 +              spec->num_mux_defs = 3;
 +              spec->input_mux = spec->private_imux;
        }
  
        return 1; /* config found */
  }
  
  /* additional initialization for auto-configuration model */
 -static void alc883_auto_init(struct hda_codec *codec)
 +static void alc882_auto_init(struct hda_codec *codec)
  {
        struct alc_spec *spec = codec->spec;
 -      alc883_auto_init_multi_out(codec);
 -      alc883_auto_init_hp_out(codec);
 -      alc883_auto_init_analog_input(codec);
 -      alc883_auto_init_input_src(codec);
 +      alc882_auto_init_multi_out(codec);
 +      alc882_auto_init_hp_out(codec);
 +      alc882_auto_init_analog_input(codec);
 +      alc882_auto_init_input_src(codec);
        if (spec->unsol_event)
                alc_inithook(codec);
  }
  
 -static int patch_alc883(struct hda_codec *codec)
 +static int patch_alc882(struct hda_codec *codec)
  {
        struct alc_spec *spec;
        int err, board_config;
  
        codec->spec = spec;
  
 -      alc_fix_pll_init(codec, 0x20, 0x0a, 10);
 +      switch (codec->vendor_id) {
 +      case 0x10ec0882:
 +      case 0x10ec0885:
 +              break;
 +      default:
 +              /* ALC883 and variants */
 +              alc_fix_pll_init(codec, 0x20, 0x0a, 10);
 +              break;
 +      }
  
 -      board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
 -                                                alc883_models,
 -                                                alc883_cfg_tbl);
 -      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;
 -              }
 +      board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
 +                                                alc882_models,
 +                                                alc882_cfg_tbl);
 +
 +      if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
 +              board_config = snd_hda_check_board_codec_sid_config(codec,
 +                      ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
 +
 +      if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
 +              printk(KERN_INFO "hda_codec: Unknown model for %s, "
 +                     "trying auto-probe from BIOS...\n",
 +                     codec->chip_name);
 +              board_config = ALC882_AUTO;
        }
  
 -      if (board_config == ALC883_AUTO) {
 +      alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
 +
 +      if (board_config == ALC882_AUTO) {
                /* automatic parse from the BIOS config */
 -              err = alc883_parse_auto_config(codec);
 +              err = alc882_parse_auto_config(codec);
                if (err < 0) {
                        alc_free(codec);
                        return err;
                        printk(KERN_INFO
                               "hda_codec: Cannot set up configuration "
                               "from BIOS.  Using base mode...\n");
 -                      board_config = ALC883_3ST_2ch_DIG;
 +                      board_config = ALC882_3ST_DIG;
                }
        }
  
                return err;
        }
  
 -      if (board_config != ALC883_AUTO)
 -              setup_preset(spec, &alc883_presets[board_config]);
 +      if (board_config != ALC882_AUTO)
 +              setup_preset(spec, &alc882_presets[board_config]);
  
 -      switch (codec->vendor_id) {
 -      case 0x10ec0888:
 -              if (!spec->num_adc_nids) {
 -                      spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
 -                      spec->adc_nids = alc883_adc_nids;
 -              }
 -              if (!spec->capsrc_nids)
 -                      spec->capsrc_nids = alc883_capsrc_nids;
 +      spec->stream_analog_playback = &alc882_pcm_analog_playback;
 +      spec->stream_analog_capture = &alc882_pcm_analog_capture;
 +      /* FIXME: setup DAC5 */
 +      /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
 +      spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
 +
 +      spec->stream_digital_playback = &alc882_pcm_digital_playback;
 +      spec->stream_digital_capture = &alc882_pcm_digital_capture;
 +
 +      if (codec->vendor_id == 0x10ec0888)
                spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
 -              break;
 -      case 0x10ec0889:
 -              if (!spec->num_adc_nids) {
 -                      spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
 -                      spec->adc_nids = alc889_adc_nids;
 -              }
 -              if (!spec->capsrc_nids)
 -                      spec->capsrc_nids = alc889_capsrc_nids;
 -              break;
 -      default:
 -              if (!spec->num_adc_nids) {
 -                      spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
 -                      spec->adc_nids = alc883_adc_nids;
 +
 +      if (!spec->adc_nids && spec->input_mux) {
 +              int i;
 +              spec->num_adc_nids = 0;
 +              for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
 +                      hda_nid_t cap;
 +                      hda_nid_t nid = alc882_adc_nids[i];
 +                      unsigned int wcap = get_wcaps(codec, nid);
 +                      /* get type */
 +                      wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
 +                      if (wcap != AC_WID_AUD_IN)
 +                              continue;
 +                      spec->private_adc_nids[spec->num_adc_nids] = nid;
 +                      err = snd_hda_get_connections(codec, nid, &cap, 1);
 +                      if (err < 0)
 +                              continue;
 +                      spec->private_capsrc_nids[spec->num_adc_nids] = cap;
 +                      spec->num_adc_nids++;
                }
 -              if (!spec->capsrc_nids)
 -                      spec->capsrc_nids = alc883_capsrc_nids;
 -              break;
 +              spec->adc_nids = spec->private_adc_nids;
 +              spec->capsrc_nids = spec->private_capsrc_nids;
        }
  
 -      spec->stream_analog_playback = &alc883_pcm_analog_playback;
 -      spec->stream_analog_capture = &alc883_pcm_analog_capture;
 -      spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
 -
 -      spec->stream_digital_playback = &alc883_pcm_digital_playback;
 -      spec->stream_digital_capture = &alc883_pcm_digital_capture;
 -
 -      if (!spec->cap_mixer)
 -              set_capture_mixer(spec);
 +      set_capture_mixer(spec);
        set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
  
        spec->vmaster_nid = 0x0c;
  
        codec->patch_ops = alc_patch_ops;
 -      if (board_config == ALC883_AUTO)
 -              spec->init_hook = alc883_auto_init;
 -
 +      if (board_config == ALC882_AUTO)
 +              spec->init_hook = alc882_auto_init;
  #ifdef CONFIG_SND_HDA_POWER_SAVE
        if (!spec->loopback.amplist)
 -              spec->loopback.amplist = alc883_loopbacks;
 +              spec->loopback.amplist = alc882_loopbacks;
  #endif
        codec->proc_widget_hook = print_realtek_coef;
  
        return 0;
  }
  
 +
  /*
   * ALC262 support
   */
@@@ -11816,38 -12270,26 +11822,38 @@@ static int alc268_new_analog_output(str
                                    const char *ctlname, int idx)
  {
        char name[32];
 +      hda_nid_t dac;
        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) {
 +      switch (nid) {
 +      case 0x14:
 +      case 0x16:
 +              dac = 0x02;
 +              break;
 +      case 0x15:
 +              dac = 0x03;
 +              break;
 +      default:
 +              return 0;
 +      }
 +      if (spec->multiout.dac_nids[0] != dac &&
 +          spec->multiout.dac_nids[1] != dac) {
                err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
 -                                HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
 +                                HDA_COMPOSE_AMP_VAL(dac, 3, idx,
                                                      HDA_OUTPUT));
                if (err < 0)
                        return err;
 -      } else
 -              return -1;
 +              spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
 +      }
 +
        sprintf(name, "%s Playback Switch", ctlname);
 -      err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
 +      if (nid != 0x16)
 +              err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
                          HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
 +      else /* mono */
 +              err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
 +                        HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
        if (err < 0)
                return err;
        return 0;
@@@ -11860,19 -12302,14 +11866,19 @@@ static int alc268_auto_create_multi_out
        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);
 +      if (nid) {
 +              const char *name;
 +              if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
 +                      name = "Speaker";
 +              else
 +                      name = "Front";
 +              err = alc268_new_analog_output(spec, nid, name, 0);
 +              if (err < 0)
 +                      return err;
 +      }
  
        nid = cfg->speaker_pins[0];
        if (nid == 0x1d) {
                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
                if (err < 0)
                        return err;
 +      } else {
 +              err = alc268_new_analog_output(spec, nid, "Speaker", 0);
 +              if (err < 0)
 +                      return err;
        }
        nid = cfg->hp_pins[0];
 -      if (nid)
 -              alc268_new_analog_output(spec, nid, "Headphone", 0);
 +      if (nid) {
 +              err = alc268_new_analog_output(spec, nid, "Headphone", 0);
 +              if (err < 0)
 +                      return err;
 +      }
  
        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));
 +                                HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
                if (err < 0)
                        return err;
        }
@@@ -17108,23 -17538,23 +17114,23 @@@ static struct hda_codec_preset snd_hda_
        { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
        { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
        { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
 -        .patch = patch_alc883 },
 +        .patch = patch_alc882 },
        { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
          .patch = patch_alc662 },
        { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
        { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
        { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
 -      { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
 +      { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
        { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
 -        .patch = patch_alc882 }, /* should be patch_alc883() in future */
 +        .patch = patch_alc882 },
        { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
 -        .patch = patch_alc882 }, /* should be patch_alc883() in future */
 +        .patch = patch_alc882 },
        { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
 -      { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
 +      { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
        { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
 -        .patch = patch_alc883 },
 -      { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
 -      { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
 +        .patch = patch_alc882 },
 +      { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
 +      { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
        {} /* terminator */
  };