Merge branch 'fix/hda' into topic/hda
authorTakashi Iwai <tiwai@suse.de>
Thu, 9 Jul 2009 16:48:38 +0000 (18:48 +0200)
committerTakashi Iwai <tiwai@suse.de>
Thu, 9 Jul 2009 16:48:38 +0000 (18:48 +0200)
Conflicts:
sound/pci/hda/patch_realtek.c

Signed-off-by: Takashi Iwai <tiwai@suse.de>
1  2 
sound/pci/hda/hda_beep.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_realtek.c

diff --combined sound/pci/hda/hda_beep.c
@@@ -24,7 -24,6 +24,7 @@@
  #include <linux/workqueue.h>
  #include <sound/core.h>
  #include "hda_beep.h"
 +#include "hda_local.h"
  
  enum {
        DIGBEEP_HZ_STEP = 46875,        /* 46.875 Hz */
@@@ -51,19 -50,22 +51,22 @@@ static void snd_hda_generate_beep(struc
   * The tone frequency of beep generator on IDT/STAC codecs is
   * defined from the 8bit tone parameter, in Hz,
   *    freq = 48000 * (257 - tone) / 1024
-  * that is from 12kHz to 93.75kHz in step of 46.875 hz
+  * that is from 12kHz to 93.75Hz in steps of 46.875 Hz
   */
  static int beep_linear_tone(struct hda_beep *beep, int hz)
  {
+       if (hz <= 0)
+               return 0;
        hz *= 1000; /* fixed point */
-       hz = hz - DIGBEEP_HZ_MIN;
+       hz = hz - DIGBEEP_HZ_MIN
+               + DIGBEEP_HZ_STEP / 2; /* round to nearest step */
        if (hz < 0)
                hz = 0; /* turn off PC beep*/
        else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN))
-               hz = 0xff;
+               hz = 1; /* max frequency */
        else {
                hz /= DIGBEEP_HZ_STEP;
-               hz++;
+               hz = 255 - hz;
        }
        return hz;
  }
@@@ -116,9 -118,6 +119,9 @@@ int snd_hda_attach_beep_device(struct h
        struct hda_beep *beep;
        int err;
  
 +      if (!snd_hda_get_bool_hint(codec, "beep"))
 +              return 0; /* disabled explicitly */
 +
        beep = kzalloc(sizeof(*beep), GFP_KERNEL);
        if (beep == NULL)
                return -ENOMEM;
@@@ -61,9 -61,6 +61,9 @@@ static int probe_mask[SNDRV_CARDS] = {[
  static int probe_only[SNDRV_CARDS];
  static int single_cmd;
  static int enable_msi;
 +#ifdef CONFIG_SND_HDA_PATCH_LOADER
 +static char *patch[SNDRV_CARDS];
 +#endif
  
  module_param_array(index, int, NULL, 0444);
  MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
@@@ -87,10 -84,6 +87,10 @@@ MODULE_PARM_DESC(single_cmd, "Use singl
                 "(for debugging only).");
  module_param(enable_msi, int, 0444);
  MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
 +#ifdef CONFIG_SND_HDA_PATCH_LOADER
 +module_param_array(patch, charp, NULL, 0444);
 +MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface.");
 +#endif
  
  #ifdef CONFIG_SND_HDA_POWER_SAVE
  static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
@@@ -1293,7 -1286,8 +1293,7 @@@ static unsigned int azx_max_codecs[AZX_
        [AZX_DRIVER_TERA] = 1,
  };
  
 -static int __devinit azx_codec_create(struct azx *chip, const char *model,
 -                                    int no_init)
 +static int __devinit azx_codec_create(struct azx *chip, const char *model)
  {
        struct hda_bus_template bus_temp;
        int c, codecs, err;
        for (c = 0; c < max_slots; c++) {
                if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
                        struct hda_codec *codec;
 -                      err = snd_hda_codec_new(chip->bus, c, !no_init, &codec);
 +                      err = snd_hda_codec_new(chip->bus, c, &codec);
                        if (err < 0)
                                continue;
                        codecs++;
                snd_printk(KERN_ERR SFX "no codecs initialized\n");
                return -ENXIO;
        }
 +      return 0;
 +}
  
 +/* configure each codec instance */
 +static int __devinit azx_codec_configure(struct azx *chip)
 +{
 +      struct hda_codec *codec;
 +      list_for_each_entry(codec, &chip->bus->codec_list, list) {
 +              snd_hda_codec_configure(codec);
 +      }
        return 0;
  }
  
@@@ -1470,6 -1455,17 +1470,17 @@@ static int azx_pcm_open(struct snd_pcm_
                return err;
        }
        snd_pcm_limit_hw_rates(runtime);
+       /* sanity check */
+       if (snd_BUG_ON(!runtime->hw.channels_min) ||
+           snd_BUG_ON(!runtime->hw.channels_max) ||
+           snd_BUG_ON(!runtime->hw.formats) ||
+           snd_BUG_ON(!runtime->hw.rates)) {
+               azx_release_device(azx_dev);
+               hinfo->ops.close(hinfo, apcm->codec, substream);
+               snd_hda_power_down(apcm->codec);
+               mutex_unlock(&chip->open_mutex);
+               return -EINVAL;
+       }
        spin_lock_irqsave(&chip->reg_lock, flags);
        azx_dev->substream = substream;
        azx_dev->running = 0;
        runtime->private_data = azx_dev;
        snd_pcm_set_sync(substream);
        mutex_unlock(&chip->open_mutex);
-       if (snd_BUG_ON(!runtime->hw.channels_min || !runtime->hw.channels_max))
-               return -EINVAL;
-       if (snd_BUG_ON(!runtime->hw.formats))
-               return -EINVAL;
-       if (snd_BUG_ON(!runtime->hw.rates))
-               return -EINVAL;
        return 0;
  }
  
@@@ -2344,9 -2333,19 +2348,19 @@@ static int __devinit azx_create(struct 
        gcap = azx_readw(chip, GCAP);
        snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap);
  
-       /* ATI chips seems buggy about 64bit DMA addresses */
-       if (chip->driver_type == AZX_DRIVER_ATI)
-               gcap &= ~ICH6_GCAP_64OK;
+       /* disable SB600 64bit support for safety */
+       if ((chip->driver_type == AZX_DRIVER_ATI) ||
+           (chip->driver_type == AZX_DRIVER_ATIHDMI)) {
+               struct pci_dev *p_smbus;
+               p_smbus = pci_get_device(PCI_VENDOR_ID_ATI,
+                                        PCI_DEVICE_ID_ATI_SBX00_SMBUS,
+                                        NULL);
+               if (p_smbus) {
+                       if (p_smbus->revision < 0x30)
+                               gcap &= ~ICH6_GCAP_64OK;
+                       pci_dev_put(p_smbus);
+               }
+       }
  
        /* allow 64bit DMA address if supported by H/W */
        if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
@@@ -2482,32 -2481,15 +2496,32 @@@ static int __devinit azx_probe(struct p
                return err;
        }
  
 +      /* set this here since it's referred in snd_hda_load_patch() */
 +      snd_card_set_dev(card, &pci->dev);
 +
        err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
        if (err < 0)
                goto out_free;
        card->private_data = chip;
  
        /* create codec instances */
 -      err = azx_codec_create(chip, model[dev], probe_only[dev]);
 +      err = azx_codec_create(chip, model[dev]);
        if (err < 0)
                goto out_free;
 +#ifdef CONFIG_SND_HDA_PATCH_LOADER
 +      if (patch[dev]) {
 +              snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n",
 +                         patch[dev]);
 +              err = snd_hda_load_patch(chip->bus, patch[dev]);
 +              if (err < 0)
 +                      goto out_free;
 +      }
 +#endif
 +      if (!probe_only[dev]) {
 +              err = azx_codec_configure(chip);
 +              if (err < 0)
 +                      goto out_free;
 +      }
  
        /* create PCM streams */
        err = snd_hda_build_pcms(chip->bus);
        if (err < 0)
                goto out_free;
  
 -      snd_card_set_dev(card, &pci->dev);
 -
        err = snd_card_register(card);
        if (err < 0)
                goto out_free;
@@@ -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);
@@@ -6291,7 -6295,7 +6291,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 -6337,6 +6346,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 -6357,6 +6439,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 -6370,11 +6464,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 -6462,6 +6559,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 -6597,7 +6831,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),
@@@ -7166,9 -6919,6 +7166,6 @@@ static struct hda_verb alc882_targa_ver
        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  
        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
-       {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
-       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
-       {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
        { } /* end */
  };
  
@@@ -7281,10 -7031,12 +7278,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",
 -};
 -
 -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),
 -      {}
 -};
 -
 -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,
 -      },
 +/* 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 */
  };
  
 -
 -/*
 - * Pin config fixes
 - */
 -enum {
 -      PINFIX_ABIT_AW9D_MAX
 +/* 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_pincfg alc882_abit_aw9d_pinfix[] = {
 -      { 0x15, 0x01080104 }, /* side */
 -      { 0x16, 0x01011012 }, /* rear */
 -      { 0x17, 0x01016011 }, /* clfe */
 -      { }
 +/* 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 */
  };
  
 -static const struct alc_pincfg *alc882_pin_fixes[] = {
 -      [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
 +/* 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 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_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 */
 +      {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
 +      {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
 +      { }
  };
  
 +#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),
        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@@ -7740,6 -8338,84 +7737,6 @@@ static struct snd_kcontrol_new alc883_c
        { } /* 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)},
 -      { }
 -};
 -
  /* toggle speaker-output according to the hp-jack state */
  static void alc883_mitac_init_hook(struct hda_codec *codec)
  {
@@@ -8172,6 -8848,69 +8169,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)},
@@@ -8282,44 -9021,25 +8279,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,
 +                              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 },
        },
        [ALC883_TARGA_DIG] = {
                .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
-               .init_verbs = { alc883_init_verbs, alc883_targa_verbs},
+               .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
+                               alc883_targa_verbs},
                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
                .dac_nids = alc883_dac_nids,
                .dig_out_nid = ALC883_DIGOUT_NID,
        },
        [ALC883_TARGA_2ch_DIG] = {
                .mixers = { alc883_targa_2ch_mixer},
-               .init_verbs = { alc883_init_verbs, alc883_targa_verbs},
+               .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
+                               alc883_targa_verbs},
                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
                .dac_nids = alc883_dac_nids,
                .adc_nids = alc883_adc_nids_alt,
  };
  
  
 +/*
 + * 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
   */
@@@ -12431,9 -12878,9 +12430,9 @@@ static struct snd_kcontrol_new alc269_l
  
  static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
        { } /* end */
  };
  
@@@ -17085,23 -17532,23 +17084,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 */
  };