]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'topic/hda' into for-linus
authorTakashi Iwai <tiwai@suse.de>
Sun, 18 Mar 2012 17:22:30 +0000 (18:22 +0100)
committerTakashi Iwai <tiwai@suse.de>
Sun, 18 Mar 2012 17:22:30 +0000 (18:22 +0100)
21 files changed:
Documentation/sound/alsa/ALSA-Configuration.txt
Documentation/sound/alsa/HD-Audio-Models.txt
Documentation/sound/alsa/HD-Audio.txt
include/sound/control.h
sound/core/vmaster.c
sound/pci/hda/alc260_quirks.c [deleted file]
sound/pci/hda/alc880_quirks.c [deleted file]
sound/pci/hda/alc882_quirks.c [deleted file]
sound/pci/hda/alc_quirks.c [deleted file]
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_jack.c
sound/pci/hda/hda_jack.h
sound/pci/hda/hda_local.h
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_via.c

index 936699e4f04b0abdf74788b66ace8ab1a16f66ff..9af64c508ab44d87601ad4dae3db17e597ac7fc9 100644 (file)
@@ -860,7 +860,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 
     [Multiple options for each card instance]
     model      - force the model name
-    position_fix - Fix DMA pointer (0 = auto, 1 = use LPIB, 2 = POSBUF)
+    position_fix - Fix DMA pointer (0 = auto, 1 = use LPIB, 2 = POSBUF,
+                  3 = VIACOMBO, 4 = COMBO)
     probe_mask  - Bitmask to probe codecs (default = -1, meaning all slots)
                  When the bit 8 (0x100) is set, the lower 8 bits are used
                  as the "fixed" codec slots; i.e. the driver probes the
@@ -925,6 +926,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
            (Usually SD_LPIB register is more accurate than the
            position buffer.)
 
+           position_fix=3 is specific to VIA devices.  The position
+           of the capture stream is checked from both LPIB and POSBUF
+           values.  position_fix=4 is a combination mode, using LPIB
+           for playback and POSBUF for capture.
+
     NB: If you get many "azx_get_response timeout" messages at
     loading, it's likely a problem of interrupts (e.g. ACPI irq
     routing).  Try to boot with options like "pci=noacpi".  Also, you
index c8c54544abc5c757e27c32c322b812fabf598769..d97d992ced14f97a5d423f79f1ae9b9f230fc55e 100644 (file)
@@ -8,37 +8,10 @@ ALC880
   5stack-digout        5-jack in back, 2-jack in front, a SPDIF out
   6stack       6-jack in back, 2-jack in front
   6stack-digout        6-jack with a SPDIF out
-  w810         3-jack
-  z71v         3-jack (HP shared SPDIF)
-  asus         3-jack (ASUS Mobo)
-  asus-w1v     ASUS W1V
-  asus-dig     ASUS with SPDIF out
-  asus-dig2    ASUS with SPDIF out (using GPIO2)
-  uniwill      3-jack
-  fujitsu      Fujitsu Laptops (Pi1536)
-  F1734                2-jack
-  lg           LG laptop (m1 express dual)
-  lg-lw                LG LW20/LW25 laptop
-  tcl          TCL S700
-  clevo                Clevo laptops (m520G, m665n)
-  medion       Medion Rim 2150
-  test         for testing/debugging purpose, almost all controls can be
-               adjusted.  Appearing only when compiled with
-               $CONFIG_SND_DEBUG=y
-  auto         auto-config reading BIOS (default)
 
 ALC260
 ======
-  fujitsu      Fujitsu S7020
-  acer         Acer TravelMate
-  will         Will laptops (PB V7900)
-  replacer     Replacer 672V
-  favorit100   Maxdata Favorit 100XS
-  basic                fixed pin assignment (old default model)
-  test         for testing/debugging purpose, almost all controls can
-               adjusted.  Appearing only when compiled with
-               $CONFIG_SND_DEBUG=y
-  auto         auto-config reading BIOS (default)
+  N/A
 
 ALC262
 ======
@@ -70,55 +43,7 @@ ALC680
 
 ALC882/883/885/888/889
 ======================
-  3stack-dig   3-jack with SPDIF I/O
-  6stack-dig   6-jack digital with SPDIF I/O
-  arima                Arima W820Di1
-  targa                Targa T8, MSI-1049 T8
-  asus-a7j     ASUS A7J
-  asus-a7m     ASUS A7M
-  macpro       MacPro support
-  mb5          Macbook 5,1
-  macmini3     Macmini 3,1
-  mba21                Macbook Air 2,1
-  mbp3         Macbook Pro rev3
-  imac24       iMac 24'' with jack detection
-  imac91       iMac 9,1
-  w2jc         ASUS W2JC
-  3stack-2ch-dig       3-jack with SPDIF I/O (ALC883)
-  alc883-6stack-dig    6-jack digital with SPDIF I/O (ALC883)
-  3stack-6ch    3-jack 6-channel
-  3stack-6ch-dig 3-jack 6-channel with SPDIF I/O
-  6stack-dig-demo  6-jack digital for Intel demo board
-  acer         Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc)
-  acer-aspire  Acer Aspire 9810
-  acer-aspire-4930g Acer Aspire 4930G
-  acer-aspire-6530g Acer Aspire 6530G
-  acer-aspire-7730g Acer Aspire 7730G
-  acer-aspire-8930g Acer Aspire 8930G
-  medion       Medion Laptops
-  targa-dig    Targa/MSI
-  targa-2ch-dig        Targa/MSI with 2-channel
-  targa-8ch-dig Targa/MSI with 8-channel (MSI GX620)
-  laptop-eapd   3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE)
-  lenovo-101e  Lenovo 101E
-  lenovo-nb0763        Lenovo NB0763
-  lenovo-ms7195-dig Lenovo MS7195
-  lenovo-sky   Lenovo Sky
-  haier-w66    Haier W66
-  3stack-hp    HP machines with 3stack (Lucknow, Samba boards)
-  6stack-dell  Dell machines with 6stack (Inspiron 530)
-  mitac                Mitac 8252D
-  clevo-m540r  Clevo M540R (6ch + digital)
-  clevo-m720   Clevo M720 laptop series
-  fujitsu-pi2515 Fujitsu AMILO Pi2515
-  fujitsu-xa3530 Fujitsu AMILO XA3530
-  3stack-6ch-intel Intel DG33* boards
-  intel-alc889a        Intel IbexPeak with ALC889A
-  intel-x58    Intel DX58 with ALC889
-  asus-p5q     ASUS P5Q-EM boards
-  mb31         MacBook 3,1
-  sony-vaio-tt  Sony VAIO TT
-  auto         auto-config reading BIOS (default)
+  N/A
 
 ALC861/660
 ==========
index 91fee3b45fb80f75ac406dfbba093f1f49a418c1..7813c06a5c71d70a353862a6fec6713d3d73da3b 100644 (file)
@@ -59,7 +59,12 @@ a case, you can change the default method via `position_fix` option.
 `position_fix=1` means to use LPIB method explicitly.
 `position_fix=2` means to use the position-buffer.
 `position_fix=3` means to use a combination of both methods, needed
-for some VIA and ATI controllers.  0 is the default value for all other
+for some VIA controllers.  The capture stream position is corrected
+by comparing both LPIB and position-buffer values.
+`position_fix=4` is another combination available for all controllers,
+and uses LPIB for the playback and the position-buffer for the capture
+streams.
+0 is the default value for all other
 controllers, the automatic check and fallback to LPIB as described in
 the above.  If you get a problem of repeated sounds, this option might
 help.
index b2796e83c7acf3d1b4dd5bfacd76966a4c3eff4e..eff96dc7a2784fe90af94d47d47cd73d710d724a 100644 (file)
@@ -227,6 +227,11 @@ snd_ctl_add_slave_uncached(struct snd_kcontrol *master,
        return _snd_ctl_add_slave(master, slave, SND_CTL_SLAVE_NEED_UPDATE);
 }
 
+int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kctl,
+                            void (*hook)(void *private_data, int),
+                            void *private_data);
+void snd_ctl_sync_vmaster_hook(struct snd_kcontrol *kctl);
+
 /*
  * Helper functions for jack-detection controls
  */
index 130cfe677d60a1ef8bf996c0a61bc0dea35a9da6..14a286a7bf2b01686e450b2a3bc258df59f24e21 100644 (file)
@@ -37,6 +37,8 @@ struct link_master {
        struct link_ctl_info info;
        int val;                /* the master value */
        unsigned int tlv[4];
+       void (*hook)(void *private_data, int);
+       void *hook_private_data;
 };
 
 /*
@@ -126,7 +128,9 @@ static int master_init(struct link_master *master)
                master->info.count = 1; /* always mono */
                /* set full volume as default (= no attenuation) */
                master->val = master->info.max_val;
-               return 0;
+               if (master->hook)
+                       master->hook(master->hook_private_data, master->val);
+               return 1;
        }
        return -ENOENT;
 }
@@ -329,6 +333,8 @@ static int master_put(struct snd_kcontrol *kcontrol,
                slave_put_val(slave, uval);
        }
        kfree(uval);
+       if (master->hook && !err)
+               master->hook(master->hook_private_data, master->val);
        return 1;
 }
 
@@ -408,3 +414,41 @@ struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
        return kctl;
 }
 EXPORT_SYMBOL(snd_ctl_make_virtual_master);
+
+/**
+ * snd_ctl_add_vmaster_hook - Add a hook to a vmaster control
+ * @kcontrol: vmaster kctl element
+ * @hook: the hook function
+ *
+ * Adds the given hook to the vmaster control element so that it's called
+ * at each time when the value is changed.
+ */
+int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kcontrol,
+                            void (*hook)(void *private_data, int),
+                            void *private_data)
+{
+       struct link_master *master = snd_kcontrol_chip(kcontrol);
+       master->hook = hook;
+       master->hook_private_data = private_data;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(snd_ctl_add_vmaster_hook);
+
+/**
+ * snd_ctl_sync_vmaster_hook - Sync the vmaster hook
+ * @kcontrol: vmaster kctl element
+ *
+ * Call the hook function to synchronize with the current value of the given
+ * vmaster element.  NOP when NULL is passed to @kcontrol or the hook doesn't
+ * exist.
+ */
+void snd_ctl_sync_vmaster_hook(struct snd_kcontrol *kcontrol)
+{
+       struct link_master *master;
+       if (!kcontrol)
+               return;
+       master = snd_kcontrol_chip(kcontrol);
+       if (master->hook)
+               master->hook(master->hook_private_data, master->val);
+}
+EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster_hook);
diff --git a/sound/pci/hda/alc260_quirks.c b/sound/pci/hda/alc260_quirks.c
deleted file mode 100644 (file)
index 3b5170b..0000000
+++ /dev/null
@@ -1,968 +0,0 @@
-/*
- * ALC260 quirk models
- * included by patch_realtek.c
- */
-
-/* ALC260 models */
-enum {
-       ALC260_AUTO,
-       ALC260_BASIC,
-       ALC260_FUJITSU_S702X,
-       ALC260_ACER,
-       ALC260_WILL,
-       ALC260_REPLACER_672V,
-       ALC260_FAVORIT100,
-#ifdef CONFIG_SND_DEBUG
-       ALC260_TEST,
-#endif
-       ALC260_MODEL_LAST /* last tag */
-};
-
-static const hda_nid_t alc260_dac_nids[1] = {
-       /* front */
-       0x02,
-};
-
-static const hda_nid_t alc260_adc_nids[1] = {
-       /* ADC0 */
-       0x04,
-};
-
-static const hda_nid_t alc260_adc_nids_alt[1] = {
-       /* ADC1 */
-       0x05,
-};
-
-/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
- * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
- */
-static const hda_nid_t alc260_dual_adc_nids[2] = {
-       /* ADC0, ADC1 */
-       0x04, 0x05
-};
-
-#define ALC260_DIGOUT_NID      0x03
-#define ALC260_DIGIN_NID       0x06
-
-static const struct hda_input_mux alc260_capture_source = {
-       .num_items = 4,
-       .items = {
-               { "Mic", 0x0 },
-               { "Front Mic", 0x1 },
-               { "Line", 0x2 },
-               { "CD", 0x4 },
-       },
-};
-
-/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
- * headphone jack and the internal CD lines since these are the only pins at
- * which audio can appear.  For flexibility, also allow the option of
- * recording the mixer output on the second ADC (ADC0 doesn't have a
- * connection to the mixer output).
- */
-static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
-       {
-               .num_items = 3,
-               .items = {
-                       { "Mic/Line", 0x0 },
-                       { "CD", 0x4 },
-                       { "Headphone", 0x2 },
-               },
-       },
-       {
-               .num_items = 4,
-               .items = {
-                       { "Mic/Line", 0x0 },
-                       { "CD", 0x4 },
-                       { "Headphone", 0x2 },
-                       { "Mixer", 0x5 },
-               },
-       },
-
-};
-
-/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
- * the Fujitsu S702x, but jacks are marked differently.
- */
-static const struct hda_input_mux alc260_acer_capture_sources[2] = {
-       {
-               .num_items = 4,
-               .items = {
-                       { "Mic", 0x0 },
-                       { "Line", 0x2 },
-                       { "CD", 0x4 },
-                       { "Headphone", 0x5 },
-               },
-       },
-       {
-               .num_items = 5,
-               .items = {
-                       { "Mic", 0x0 },
-                       { "Line", 0x2 },
-                       { "CD", 0x4 },
-                       { "Headphone", 0x6 },
-                       { "Mixer", 0x5 },
-               },
-       },
-};
-
-/* Maxdata Favorit 100XS */
-static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
-       {
-               .num_items = 2,
-               .items = {
-                       { "Line/Mic", 0x0 },
-                       { "CD", 0x4 },
-               },
-       },
-       {
-               .num_items = 3,
-               .items = {
-                       { "Line/Mic", 0x0 },
-                       { "CD", 0x4 },
-                       { "Mixer", 0x5 },
-               },
-       },
-};
-
-/*
- * This is just place-holder, so there's something for alc_build_pcms to look
- * at when it calculates the maximum number of channels. ALC260 has no mixer
- * element which allows changing the channel mode, so the verb list is
- * never used.
- */
-static const struct hda_channel_mode alc260_modes[1] = {
-       { 2, NULL },
-};
-
-
-/* Mixer combinations
- *
- * basic: base_output + input + pc_beep + capture
- * fujitsu: fujitsu + capture
- * acer: acer + capture
- */
-
-static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc260_input_mixer[] = {
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
-       { } /* end */
-};
-
-/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
- * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
- */
-static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
-       ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
-       ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
-       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
-       { } /* end */
-};
-
-/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
- * versions of the ALC260 don't act on requests to enable mic bias from NID
- * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
- * datasheet doesn't mention this restriction.  At this stage it's not clear
- * whether this behaviour is intentional or is a hardware bug in chip
- * revisions available in early 2006.  Therefore for now allow the
- * "Headphone Jack Mode" control to span all choices, but if it turns out
- * that the lack of mic bias for this NID is intentional we could change the
- * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
- *
- * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
- * don't appear to make the mic bias available from the "line" jack, even
- * though the NID used for this jack (0x14) can supply it.  The theory is
- * that perhaps Acer have included blocking capacitors between the ALC260
- * and the output jack.  If this turns out to be the case for all such
- * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
- * to ALC_PIN_DIR_INOUT_NOMICBIAS.
- *
- * The C20x Tablet series have a mono internal speaker which is controlled
- * via the chip's Mono sum widget and pin complex, so include the necessary
- * controls for such models.  On models without a "mono speaker" the control
- * won't do anything.
- */
-static const struct snd_kcontrol_new alc260_acer_mixer[] = {
-       HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
-       ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
-       HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
-                             HDA_OUTPUT),
-       HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
-                          HDA_INPUT),
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
-       ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
-       ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
-       { } /* end */
-};
-
-/* Maxdata Favorit 100XS: one output and one input (0x12) jack
- */
-static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
-       HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
-       ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
-       HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
-       ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
-       { } /* end */
-};
-
-/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
- * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
- */
-static const struct snd_kcontrol_new alc260_will_mixer[] = {
-       HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
-       ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
-       ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
-       { } /* end */
-};
-
-/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
- * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
- */
-static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
-       HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
-       ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
-       HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
-       ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
-       { } /* end */
-};
-
-/*
- * initialization verbs
- */
-static const struct hda_verb alc260_init_verbs[] = {
-       /* Line In pin widget for input */
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       /* CD pin widget for input */
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       /* Mic1 (rear panel) pin widget for input and vref at 80% */
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       /* Mic2 (front panel) pin widget for input and vref at 80% */
-       {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       /* LINE-2 is used for line-out in rear */
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       /* select line-out */
-       {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
-       /* LINE-OUT pin */
-       {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       /* enable HP */
-       {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       /* enable Mono */
-       {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       /* mute capture amp left and right */
-       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       /* set connection select to line in (default select for this ADC) */
-       {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
-       /* mute capture amp left and right */
-       {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       /* set connection select to line in (default select for this ADC) */
-       {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
-       /* set vol=0 Line-Out mixer amp left and right */
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       /* unmute pin widget amp left and right (no gain on this amp) */
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* set vol=0 HP mixer amp left and right */
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       /* unmute pin widget amp left and right (no gain on this amp) */
-       {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* set vol=0 Mono mixer amp left and right */
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       /* unmute pin widget amp left and right (no gain on this amp) */
-       {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* unmute LINE-2 out pin */
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
-        * Line In 2 = 0x03
-        */
-       /* mute analog inputs */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-       /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
-       /* mute Front out path */
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       /* mute Headphone out path */
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       /* mute Mono out path */
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       { }
-};
-
-/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
- * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
- * audio = 0x16, internal speaker = 0x10.
- */
-static const struct hda_verb alc260_fujitsu_init_verbs[] = {
-       /* Disable all GPIOs */
-       {0x01, AC_VERB_SET_GPIO_MASK, 0},
-       /* Internal speaker is connected to headphone pin */
-       {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       /* Headphone/Line-out jack connects to Line1 pin; make it an output */
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       /* Ensure all other unused pins are disabled and muted. */
-       {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-       {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-       {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-
-       /* Disable digital (SPDIF) pins */
-       {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
-       {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
-
-       /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
-        * when acting as an output.
-        */
-       {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
-
-       /* Start with output sum widgets muted and their output gains at min */
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-
-       /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
-       {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Unmute Line1 pin widget output buffer since it starts as an output.
-        * If the pin mode is changed by the user the pin mode control will
-        * take care of enabling the pin's input/output buffers as needed.
-        * Therefore there's no need to enable the input buffer at this
-        * stage.
-        */
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Unmute input buffer of pin widget used for Line-in (no equiv
-        * mixer ctrl)
-        */
-       {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
-       /* Mute capture amp left and right */
-       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       /* Set ADC connection select to match default mixer setting - line
-        * in (on mic1 pin)
-        */
-       {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       /* Do the same for the second ADC: mute capture input amp and
-        * set ADC connection to line in (on mic1 pin)
-        */
-       {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       /* Mute all inputs to mixer widget (even unconnected ones) */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
-
-       { }
-};
-
-/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
- * similar laptops (adapted from Fujitsu init verbs).
- */
-static const struct hda_verb alc260_acer_init_verbs[] = {
-       /* On TravelMate laptops, GPIO 0 enables the internal speaker and
-        * the headphone jack.  Turn this on and rely on the standard mute
-        * methods whenever the user wants to turn these outputs off.
-        */
-       {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
-       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
-       {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
-       /* Internal speaker/Headphone jack is connected to Line-out pin */
-       {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       /* Internal microphone/Mic jack is connected to Mic1 pin */
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
-       /* Line In jack is connected to Line1 pin */
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
-       {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       /* Ensure all other unused pins are disabled and muted. */
-       {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-       {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-       {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       /* Disable digital (SPDIF) pins */
-       {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
-       {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
-
-       /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
-        * bus when acting as outputs.
-        */
-       {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
-       {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
-
-       /* Start with output sum widgets muted and their output gains at min */
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-
-       /* Unmute Line-out pin widget amp left and right
-        * (no equiv mixer ctrl)
-        */
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
-       {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Unmute Mic1 and Line1 pin widget input buffers since they start as
-        * inputs. If the pin mode is changed by the user the pin mode control
-        * will take care of enabling the pin's input/output buffers as needed.
-        * Therefore there's no need to enable the input buffer at this
-        * stage.
-        */
-       {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
-       /* Mute capture amp left and right */
-       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       /* Set ADC connection select to match default mixer setting - mic
-        * (on mic1 pin)
-        */
-       {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       /* Do similar with the second ADC: mute capture input amp and
-        * set ADC connection to mic to match ALSA's default state.
-        */
-       {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       /* Mute all inputs to mixer widget (even unconnected ones) */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
-
-       { }
-};
-
-/* Initialisation sequence for Maxdata Favorit 100XS
- * (adapted from Acer init verbs).
- */
-static const struct hda_verb alc260_favorit100_init_verbs[] = {
-       /* GPIO 0 enables the output jack.
-        * Turn this on and rely on the standard mute
-        * methods whenever the user wants to turn these outputs off.
-        */
-       {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
-       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
-       {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
-       /* Line/Mic input jack is connected to Mic1 pin */
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
-       /* Ensure all other unused pins are disabled and muted. */
-       {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-       {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-       {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-       {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       /* Disable digital (SPDIF) pins */
-       {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
-       {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
-
-       /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
-        * bus when acting as outputs.
-        */
-       {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
-       {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
-
-       /* Start with output sum widgets muted and their output gains at min */
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-
-       /* Unmute Line-out pin widget amp left and right
-        * (no equiv mixer ctrl)
-        */
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Unmute Mic1 and Line1 pin widget input buffers since they start as
-        * inputs. If the pin mode is changed by the user the pin mode control
-        * will take care of enabling the pin's input/output buffers as needed.
-        * Therefore there's no need to enable the input buffer at this
-        * stage.
-        */
-       {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
-       /* Mute capture amp left and right */
-       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       /* Set ADC connection select to match default mixer setting - mic
-        * (on mic1 pin)
-        */
-       {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       /* Do similar with the second ADC: mute capture input amp and
-        * set ADC connection to mic to match ALSA's default state.
-        */
-       {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       /* Mute all inputs to mixer widget (even unconnected ones) */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
-
-       { }
-};
-
-static const struct hda_verb alc260_will_verbs[] = {
-       {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
-       {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
-       {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
-       {}
-};
-
-static const struct hda_verb alc260_replacer_672v_verbs[] = {
-       {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
-       {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
-       {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
-
-       {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
-       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
-       {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
-
-       {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {}
-};
-
-/* toggle speaker-output according to the hp-jack state */
-static void alc260_replacer_672v_automute(struct hda_codec *codec)
-{
-        unsigned int present;
-
-       /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
-       present = snd_hda_jack_detect(codec, 0x0f);
-       if (present) {
-               snd_hda_codec_write_cache(codec, 0x01, 0,
-                                         AC_VERB_SET_GPIO_DATA, 1);
-               snd_hda_codec_write_cache(codec, 0x0f, 0,
-                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
-                                         PIN_HP);
-       } else {
-               snd_hda_codec_write_cache(codec, 0x01, 0,
-                                         AC_VERB_SET_GPIO_DATA, 0);
-               snd_hda_codec_write_cache(codec, 0x0f, 0,
-                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
-                                         PIN_OUT);
-       }
-}
-
-static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
-                                       unsigned int res)
-{
-        if ((res >> 26) == ALC_HP_EVENT)
-                alc260_replacer_672v_automute(codec);
-}
-
-static const struct hda_verb alc260_hp_dc7600_verbs[] = {
-       {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
-       {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {}
-};
-
-/* Test configuration for debugging, modelled after the ALC880 test
- * configuration.
- */
-#ifdef CONFIG_SND_DEBUG
-static const hda_nid_t alc260_test_dac_nids[1] = {
-       0x02,
-};
-static const hda_nid_t alc260_test_adc_nids[2] = {
-       0x04, 0x05,
-};
-/* For testing the ALC260, each input MUX needs its own definition since
- * the signal assignments are different.  This assumes that the first ADC
- * is NID 0x04.
- */
-static const struct hda_input_mux alc260_test_capture_sources[2] = {
-       {
-               .num_items = 7,
-               .items = {
-                       { "MIC1 pin", 0x0 },
-                       { "MIC2 pin", 0x1 },
-                       { "LINE1 pin", 0x2 },
-                       { "LINE2 pin", 0x3 },
-                       { "CD pin", 0x4 },
-                       { "LINE-OUT pin", 0x5 },
-                       { "HP-OUT pin", 0x6 },
-               },
-        },
-       {
-               .num_items = 8,
-               .items = {
-                       { "MIC1 pin", 0x0 },
-                       { "MIC2 pin", 0x1 },
-                       { "LINE1 pin", 0x2 },
-                       { "LINE2 pin", 0x3 },
-                       { "CD pin", 0x4 },
-                       { "Mixer", 0x5 },
-                       { "LINE-OUT pin", 0x6 },
-                       { "HP-OUT pin", 0x7 },
-               },
-        },
-};
-static const struct snd_kcontrol_new alc260_test_mixer[] = {
-       /* Output driver widgets */
-       HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
-
-       /* Modes for retasking pin widgets
-        * Note: the ALC260 doesn't seem to act on requests to enable mic
-         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
-         * mention this restriction.  At this stage it's not clear whether
-         * this behaviour is intentional or is a hardware bug in chip
-         * revisions available at least up until early 2006.  Therefore for
-         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
-         * choices, but if it turns out that the lack of mic bias for these
-         * NIDs is intentional we could change their modes from
-         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
-        */
-       ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
-       ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
-       ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
-       ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
-       ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
-       ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
-
-       /* Loopback mixer controls */
-       HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
-       HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
-       HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
-       HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
-       HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
-       HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
-       HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
-       HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
-       HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
-
-       /* Controls for GPIO pins, assuming they are configured as outputs */
-       ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
-       ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
-       ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
-       ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
-
-       /* Switches to allow the digital IO pins to be enabled.  The datasheet
-        * is ambigious as to which NID is which; testing on laptops which
-        * make this output available should provide clarification.
-        */
-       ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
-       ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
-
-       /* A switch allowing EAPD to be enabled.  Some laptops seem to use
-        * this output to turn on an external amplifier.
-        */
-       ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
-       ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
-
-       { } /* end */
-};
-static const struct hda_verb alc260_test_init_verbs[] = {
-       /* Enable all GPIOs as outputs with an initial value of 0 */
-       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
-       {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
-       {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
-
-       /* Enable retasking pins as output, initially without power amp */
-       {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x0f, 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},
-       {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
-       /* Disable digital (SPDIF) pins initially, but users can enable
-        * them via a mixer switch.  In the case of SPDIF-out, this initverb
-        * payload also sets the generation to 0, output to be in "consumer"
-        * PCM format, copyright asserted, no pre-emphasis and no validity
-        * control.
-        */
-       {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
-       {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
-
-       /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
-        * OUT1 sum bus when acting as an output.
-        */
-       {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
-       {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
-       {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
-       {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
-
-       /* Start with output sum widgets muted and their output gains at min */
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-
-       /* Unmute retasking pin widget output buffers since the default
-        * state appears to be output.  As the pin mode is changed by the
-        * user the pin mode control will take care of enabling the pin's
-        * input/output buffers as needed.
-        */
-       {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Also unmute the mono-out pin widget */
-       {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-       /* Mute capture amp left and right */
-       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       /* Set ADC connection select to match default mixer setting (mic1
-        * pin)
-        */
-       {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       /* Do the same for the second ADC: mute capture input amp and
-        * set ADC connection to mic1 pin
-        */
-       {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       /* Mute all inputs to mixer widget (even unconnected ones) */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
-
-       { }
-};
-#endif
-
-/*
- * ALC260 configurations
- */
-static const char * const alc260_models[ALC260_MODEL_LAST] = {
-       [ALC260_BASIC]          = "basic",
-       [ALC260_FUJITSU_S702X]  = "fujitsu",
-       [ALC260_ACER]           = "acer",
-       [ALC260_WILL]           = "will",
-       [ALC260_REPLACER_672V]  = "replacer",
-       [ALC260_FAVORIT100]     = "favorit100",
-#ifdef CONFIG_SND_DEBUG
-       [ALC260_TEST]           = "test",
-#endif
-       [ALC260_AUTO]           = "auto",
-};
-
-static const struct snd_pci_quirk alc260_cfg_tbl[] = {
-       SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
-       SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
-       SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
-       SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
-       SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
-       SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
-       SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
-       SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
-       SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
-       SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
-       SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
-       {}
-};
-
-static const struct alc_config_preset alc260_presets[] = {
-       [ALC260_BASIC] = {
-               .mixers = { alc260_base_output_mixer,
-                           alc260_input_mixer },
-               .init_verbs = { alc260_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc260_dac_nids),
-               .dac_nids = alc260_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
-               .adc_nids = alc260_dual_adc_nids,
-               .num_channel_mode = ARRAY_SIZE(alc260_modes),
-               .channel_mode = alc260_modes,
-               .input_mux = &alc260_capture_source,
-       },
-       [ALC260_FUJITSU_S702X] = {
-               .mixers = { alc260_fujitsu_mixer },
-               .init_verbs = { alc260_fujitsu_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc260_dac_nids),
-               .dac_nids = alc260_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
-               .adc_nids = alc260_dual_adc_nids,
-               .num_channel_mode = ARRAY_SIZE(alc260_modes),
-               .channel_mode = alc260_modes,
-               .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
-               .input_mux = alc260_fujitsu_capture_sources,
-       },
-       [ALC260_ACER] = {
-               .mixers = { alc260_acer_mixer },
-               .init_verbs = { alc260_acer_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc260_dac_nids),
-               .dac_nids = alc260_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
-               .adc_nids = alc260_dual_adc_nids,
-               .num_channel_mode = ARRAY_SIZE(alc260_modes),
-               .channel_mode = alc260_modes,
-               .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
-               .input_mux = alc260_acer_capture_sources,
-       },
-       [ALC260_FAVORIT100] = {
-               .mixers = { alc260_favorit100_mixer },
-               .init_verbs = { alc260_favorit100_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc260_dac_nids),
-               .dac_nids = alc260_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
-               .adc_nids = alc260_dual_adc_nids,
-               .num_channel_mode = ARRAY_SIZE(alc260_modes),
-               .channel_mode = alc260_modes,
-               .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
-               .input_mux = alc260_favorit100_capture_sources,
-       },
-       [ALC260_WILL] = {
-               .mixers = { alc260_will_mixer },
-               .init_verbs = { alc260_init_verbs, alc260_will_verbs },
-               .num_dacs = ARRAY_SIZE(alc260_dac_nids),
-               .dac_nids = alc260_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
-               .adc_nids = alc260_adc_nids,
-               .dig_out_nid = ALC260_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc260_modes),
-               .channel_mode = alc260_modes,
-               .input_mux = &alc260_capture_source,
-       },
-       [ALC260_REPLACER_672V] = {
-               .mixers = { alc260_replacer_672v_mixer },
-               .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
-               .num_dacs = ARRAY_SIZE(alc260_dac_nids),
-               .dac_nids = alc260_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
-               .adc_nids = alc260_adc_nids,
-               .dig_out_nid = ALC260_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc260_modes),
-               .channel_mode = alc260_modes,
-               .input_mux = &alc260_capture_source,
-               .unsol_event = alc260_replacer_672v_unsol_event,
-               .init_hook = alc260_replacer_672v_automute,
-       },
-#ifdef CONFIG_SND_DEBUG
-       [ALC260_TEST] = {
-               .mixers = { alc260_test_mixer },
-               .init_verbs = { alc260_test_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
-               .dac_nids = alc260_test_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
-               .adc_nids = alc260_test_adc_nids,
-               .num_channel_mode = ARRAY_SIZE(alc260_modes),
-               .channel_mode = alc260_modes,
-               .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
-               .input_mux = alc260_test_capture_sources,
-       },
-#endif
-};
-
diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c
deleted file mode 100644 (file)
index 501501e..0000000
+++ /dev/null
@@ -1,1707 +0,0 @@
-/*
- * ALC880 quirk models
- * included by patch_realtek.c
- */
-
-/* ALC880 board config type */
-enum {
-       ALC880_AUTO,
-       ALC880_3ST,
-       ALC880_3ST_DIG,
-       ALC880_5ST,
-       ALC880_5ST_DIG,
-       ALC880_W810,
-       ALC880_Z71V,
-       ALC880_6ST,
-       ALC880_6ST_DIG,
-       ALC880_F1734,
-       ALC880_ASUS,
-       ALC880_ASUS_DIG,
-       ALC880_ASUS_W1V,
-       ALC880_ASUS_DIG2,
-       ALC880_FUJITSU,
-       ALC880_UNIWILL_DIG,
-       ALC880_UNIWILL,
-       ALC880_UNIWILL_P53,
-       ALC880_CLEVO,
-       ALC880_TCL_S700,
-       ALC880_LG,
-#ifdef CONFIG_SND_DEBUG
-       ALC880_TEST,
-#endif
-       ALC880_MODEL_LAST /* last tag */
-};
-
-/*
- * ALC880 3-stack model
- *
- * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
- * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
- *                 F-Mic = 0x1b, HP = 0x19
- */
-
-static const hda_nid_t alc880_dac_nids[4] = {
-       /* front, rear, clfe, rear_surr */
-       0x02, 0x05, 0x04, 0x03
-};
-
-static const hda_nid_t alc880_adc_nids[3] = {
-       /* ADC0-2 */
-       0x07, 0x08, 0x09,
-};
-
-/* The datasheet says the node 0x07 is connected from inputs,
- * but it shows zero connection in the real implementation on some devices.
- * Note: this is a 915GAV bug, fixed on 915GLV
- */
-static const hda_nid_t alc880_adc_nids_alt[2] = {
-       /* ADC1-2 */
-       0x08, 0x09,
-};
-
-#define ALC880_DIGOUT_NID      0x06
-#define ALC880_DIGIN_NID       0x0a
-#define ALC880_PIN_CD_NID      0x1c
-
-static const struct hda_input_mux alc880_capture_source = {
-       .num_items = 4,
-       .items = {
-               { "Mic", 0x0 },
-               { "Front Mic", 0x3 },
-               { "Line", 0x2 },
-               { "CD", 0x4 },
-       },
-};
-
-/* channel source setting (2/6 channel selection for 3-stack) */
-/* 2ch mode */
-static const struct hda_verb alc880_threestack_ch2_init[] = {
-       /* set line-in to input, mute it */
-       { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
-       { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
-       /* set mic-in to input vref 80%, mute it */
-       { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
-       { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
-       { } /* end */
-};
-
-/* 6ch mode */
-static const struct hda_verb alc880_threestack_ch6_init[] = {
-       /* set line-in to output, unmute it */
-       { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-       { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
-       /* set mic-in to output, unmute it */
-       { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-       { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
-       { } /* end */
-};
-
-static const struct hda_channel_mode alc880_threestack_modes[2] = {
-       { 2, alc880_threestack_ch2_init },
-       { 6, alc880_threestack_ch6_init },
-};
-
-static const struct snd_kcontrol_new alc880_three_stack_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", 0x0f, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 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("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
-       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Channel Mode",
-               .info = alc_ch_mode_info,
-               .get = alc_ch_mode_get,
-               .put = alc_ch_mode_put,
-       },
-       { } /* end */
-};
-
-/*
- * ALC880 5-stack model
- *
- * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
- *      Side = 0x02 (0xd)
- * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
- *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
- */
-
-/* additional mixers to alc880_three_stack_mixer */
-static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
-       HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
-       { } /* end */
-};
-
-/* channel source setting (6/8 channel selection for 5-stack) */
-/* 6ch mode */
-static const struct hda_verb alc880_fivestack_ch6_init[] = {
-       /* set line-in to input, mute it */
-       { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
-       { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
-       { } /* end */
-};
-
-/* 8ch mode */
-static const struct hda_verb alc880_fivestack_ch8_init[] = {
-       /* set line-in to output, unmute it */
-       { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-       { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
-       { } /* end */
-};
-
-static const struct hda_channel_mode alc880_fivestack_modes[2] = {
-       { 6, alc880_fivestack_ch6_init },
-       { 8, alc880_fivestack_ch8_init },
-};
-
-
-/*
- * ALC880 6-stack model
- *
- * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
- *      Side = 0x05 (0x0f)
- * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
- *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
- */
-
-static const hda_nid_t alc880_6st_dac_nids[4] = {
-       /* front, rear, clfe, rear_surr */
-       0x02, 0x03, 0x04, 0x05
-};
-
-static const struct hda_input_mux alc880_6stack_capture_source = {
-       .num_items = 4,
-       .items = {
-               { "Mic", 0x0 },
-               { "Front Mic", 0x1 },
-               { "Line", 0x2 },
-               { "CD", 0x4 },
-       },
-};
-
-/* fixed 8-channels */
-static const struct hda_channel_mode alc880_sixstack_modes[1] = {
-       { 8, NULL },
-};
-
-static const struct snd_kcontrol_new alc880_six_stack_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_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Channel Mode",
-               .info = alc_ch_mode_info,
-               .get = alc_ch_mode_get,
-               .put = alc_ch_mode_put,
-       },
-       { } /* end */
-};
-
-
-/*
- * ALC880 W810 model
- *
- * W810 has rear IO for:
- * Front (DAC 02)
- * Surround (DAC 03)
- * Center/LFE (DAC 04)
- * Digital out (06)
- *
- * The system also has a pair of internal speakers, and a headphone jack.
- * These are both connected to Line2 on the codec, hence to DAC 02.
- *
- * There is a variable resistor to control the speaker or headphone
- * volume. This is a hardware-only device without a software API.
- *
- * Plugging headphones in will disable the internal speakers. This is
- * implemented in hardware, not via the driver using jack sense. In
- * a similar fashion, plugging into the rear socket marked "front" will
- * disable both the speakers and headphones.
- *
- * For input, there's a microphone jack, and an "audio in" jack.
- * These may not do anything useful with this driver yet, because I
- * haven't setup any initialization verbs for these yet...
- */
-
-static const hda_nid_t alc880_w810_dac_nids[3] = {
-       /* front, rear/surround, clfe */
-       0x02, 0x03, 0x04
-};
-
-/* fixed 6 channels */
-static const struct hda_channel_mode alc880_w810_modes[1] = {
-       { 6, NULL }
-};
-
-/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
-static const struct snd_kcontrol_new alc880_w810_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_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
-       { } /* end */
-};
-
-
-/*
- * Z710V model
- *
- * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
- * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
- *                 Line = 0x1a
- */
-
-static const hda_nid_t alc880_z71v_dac_nids[1] = {
-       0x02
-};
-#define ALC880_Z71V_HP_DAC     0x03
-
-/* fixed 2 channels */
-static const struct hda_channel_mode alc880_2_jack_modes[1] = {
-       { 2, NULL }
-};
-
-static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       { } /* end */
-};
-
-
-/*
- * ALC880 F1734 model
- *
- * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
- * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
- */
-
-static const hda_nid_t alc880_f1734_dac_nids[1] = {
-       0x03
-};
-#define ALC880_F1734_HP_DAC    0x02
-
-static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct hda_input_mux alc880_f1734_capture_source = {
-       .num_items = 2,
-       .items = {
-               { "Mic", 0x1 },
-               { "CD", 0x4 },
-       },
-};
-
-
-/*
- * ALC880 ASUS model
- *
- * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
- * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
- *  Mic = 0x18, Line = 0x1a
- */
-
-#define alc880_asus_dac_nids   alc880_w810_dac_nids    /* identical with w810 */
-#define alc880_asus_modes      alc880_threestack_modes /* 2/6 channel mode */
-
-static const struct snd_kcontrol_new alc880_asus_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("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Channel Mode",
-               .info = alc_ch_mode_info,
-               .get = alc_ch_mode_get,
-               .put = alc_ch_mode_put,
-       },
-       { } /* end */
-};
-
-/*
- * ALC880 ASUS W1V model
- *
- * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
- * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
- *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
- */
-
-/* additional mixers to alc880_asus_mixer */
-static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
-       HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
-       HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
-       { } /* end */
-};
-
-/* TCL S700 */
-static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
-       { } /* end */
-};
-
-/* Uniwill */
-static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-       HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Channel Mode",
-               .info = alc_ch_mode_info,
-               .get = alc_ch_mode_get,
-               .put = alc_ch_mode_put,
-       },
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       { } /* end */
-};
-
-/*
- * initialize the codec volumes, etc
- */
-
-/*
- * generic initialization of ADC, input mixers and output mixers
- */
-static const struct hda_verb alc880_volume_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},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
-       /* Unmute 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)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
-
-       /*
-        * 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_MUTE(0)},
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-
-       { }
-};
-
-/*
- * 3-stack pin configuration:
- * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
- */
-static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
-       /*
-        * preset connection lists of input pins
-        * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
-        */
-       {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
-       {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
-       {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
-
-       /*
-        * Set pin mode and muting
-        */
-       /* set front pin widgets 0x14 for output */
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Mic1 (rear panel) pin widget for input and vref at 80% */
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       /* Mic2 (as headphone out) for HP output */
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Line In pin widget for input */
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       /* Line2 (as front mic) pin widget for input and vref at 80% */
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       /* CD pin widget for input */
-       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-       { }
-};
-
-/*
- * 5-stack pin configuration:
- * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
- * line-in/side = 0x1a, f-mic = 0x1b
- */
-static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
-       /*
-        * preset connection lists of input pins
-        * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
-        */
-       {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
-       {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
-
-       /*
-        * Set pin mode and muting
-        */
-       /* set pin widgets 0x14-0x17 for output */
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       /* unmute pins for output (no gain on this amp) */
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-       /* Mic1 (rear panel) pin widget for input and vref at 80% */
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       /* Mic2 (as headphone out) for HP output */
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Line In pin widget for input */
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       /* Line2 (as front mic) pin widget for input and vref at 80% */
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       /* CD pin widget for input */
-       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-       { }
-};
-
-/*
- * W810 pin configuration:
- * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
- */
-static const struct hda_verb alc880_pin_w810_init_verbs[] = {
-       /* hphone/speaker input selector: front DAC */
-       {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
-
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-
-       { }
-};
-
-/*
- * Z71V pin configuration:
- * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
- */
-static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-       { }
-};
-
-/*
- * 6-stack pin configuration:
- * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
- * f-mic = 0x19, line = 0x1a, HP = 0x1b
- */
-static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
-       {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
-
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {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},
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-       { }
-};
-
-/*
- * Uniwill pin configuration:
- * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
- * line = 0x1a
- */
-static const struct hda_verb alc880_uniwill_init_verbs[] = {
-       {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
-
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {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},
-       /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
-       /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
-       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-       {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-
-       { }
-};
-
-/*
-* Uniwill P53
-* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
- */
-static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
-       {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
-
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {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},
-
-       {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_DCVOL_EVENT},
-
-       { }
-};
-
-static const struct hda_verb alc880_beep_init_verbs[] = {
-       { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
-       { }
-};
-
-static void alc880_uniwill_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-
-       spec->autocfg.hp_pins[0] = 0x14;
-       spec->autocfg.speaker_pins[0] = 0x15;
-       spec->autocfg.speaker_pins[0] = 0x16;
-       alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static void alc880_uniwill_init_hook(struct hda_codec *codec)
-{
-       alc_hp_automute(codec);
-       alc88x_simple_mic_automute(codec);
-}
-
-static void alc880_uniwill_unsol_event(struct hda_codec *codec,
-                                      unsigned int res)
-{
-       /* Looks like the unsol event is incompatible with the standard
-        * definition.  4bit tag is placed at 28 bit!
-        */
-       res >>= 28;
-       switch (res) {
-       case ALC_MIC_EVENT:
-               alc88x_simple_mic_automute(codec);
-               break;
-       default:
-               alc_exec_unsol_event(codec, res);
-               break;
-       }
-}
-
-static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
-{
-       alc_exec_unsol_event(codec, res >> 28);
-}
-
-static void alc880_uniwill_p53_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-
-       spec->autocfg.hp_pins[0] = 0x14;
-       spec->autocfg.speaker_pins[0] = 0x15;
-       alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
-{
-       unsigned int present;
-
-       present = snd_hda_codec_read(codec, 0x21, 0,
-                                    AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
-       present &= HDA_AMP_VOLMASK;
-       snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
-                                HDA_AMP_VOLMASK, present);
-       snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
-                                HDA_AMP_VOLMASK, present);
-}
-
-static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
-                                          unsigned int res)
-{
-       /* Looks like the unsol event is incompatible with the standard
-        * definition.  4bit tag is placed at 28 bit!
-        */
-       res >>= 28;
-       if (res == ALC_DCVOL_EVENT)
-               alc880_uniwill_p53_dcvol_automute(codec);
-       else
-               alc_exec_unsol_event(codec, res);
-}
-
-/*
- * F1734 pin configuration:
- * HP = 0x14, speaker-out = 0x15, mic = 0x18
- */
-static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
-       {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
-       {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
-       {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
-       {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-       {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
-       {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_DCVOL_EVENT},
-
-       { }
-};
-
-/*
- * ASUS pin configuration:
- * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
- */
-static const struct hda_verb alc880_pin_asus_init_verbs[] = {
-       {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
-       {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
-       {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-       { }
-};
-
-/* Enable GPIO mask and set output */
-#define alc880_gpio1_init_verbs        alc_gpio1_init_verbs
-#define alc880_gpio2_init_verbs        alc_gpio2_init_verbs
-#define alc880_gpio3_init_verbs        alc_gpio3_init_verbs
-
-/* Clevo m520g init */
-static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
-       /* headphone output */
-       {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
-       /* line-out */
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Line-in */
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* CD */
-       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Mic1 (rear panel) */
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Mic2 (front panel) */
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* headphone */
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-        /* change to EAPD mode */
-       {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
-       {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
-
-       { }
-};
-
-static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
-       /* change to EAPD mode */
-       {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
-       {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
-
-       /* Headphone output */
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       /* Front output*/
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       /* Line In pin widget for input */
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       /* CD pin widget for input */
-       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       /* Mic1 (rear panel) pin widget for input and vref at 80% */
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-
-       /* change to EAPD mode */
-       {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
-       {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
-
-       { }
-};
-
-/*
- * LG m1 express dual
- *
- * Pin assignment:
- *   Rear Line-In/Out (blue): 0x14
- *   Build-in Mic-In: 0x15
- *   Speaker-out: 0x17
- *   HP-Out (green): 0x1b
- *   Mic-In/Out (red): 0x19
- *   SPDIF-Out: 0x1e
- */
-
-/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
-static const hda_nid_t alc880_lg_dac_nids[3] = {
-       0x05, 0x02, 0x03
-};
-
-/* seems analog CD is not working */
-static const struct hda_input_mux alc880_lg_capture_source = {
-       .num_items = 3,
-       .items = {
-               { "Mic", 0x1 },
-               { "Line", 0x5 },
-               { "Internal Mic", 0x6 },
-       },
-};
-
-/* 2,4,6 channel modes */
-static const struct hda_verb alc880_lg_ch2_init[] = {
-       /* set line-in and mic-in to input */
-       { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
-       { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
-       { }
-};
-
-static const struct hda_verb alc880_lg_ch4_init[] = {
-       /* set line-in to out and mic-in to input */
-       { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
-       { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
-       { }
-};
-
-static const struct hda_verb alc880_lg_ch6_init[] = {
-       /* set line-in and mic-in to output */
-       { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
-       { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
-       { }
-};
-
-static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
-       { 2, alc880_lg_ch2_init },
-       { 4, alc880_lg_ch4_init },
-       { 6, alc880_lg_ch6_init },
-};
-
-static const struct snd_kcontrol_new alc880_lg_mixer[] = {
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
-       HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
-       HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Channel Mode",
-               .info = alc_ch_mode_info,
-               .get = alc_ch_mode_get,
-               .put = alc_ch_mode_put,
-       },
-       { } /* end */
-};
-
-static const struct hda_verb alc880_lg_init_verbs[] = {
-       /* set capture source to mic-in */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       /* mute all amp mixer inputs */
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
-       /* line-in to input */
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* built-in mic */
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* speaker-out */
-       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* mic-in to input */
-       {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* HP-out */
-       {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* jack sense */
-       {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       { }
-};
-
-/* toggle speaker-output according to the hp-jack state */
-static void alc880_lg_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-
-       spec->autocfg.hp_pins[0] = 0x1b;
-       spec->autocfg.speaker_pins[0] = 0x17;
-       alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static const struct hda_amp_list alc880_lg_loopbacks[] = {
-       { 0x0b, HDA_INPUT, 1 },
-       { 0x0b, HDA_INPUT, 6 },
-       { 0x0b, HDA_INPUT, 7 },
-       { } /* end */
-};
-#endif
-
-/*
- * Test configuration for debugging
- *
- * Almost all inputs/outputs are enabled.  I/O pins can be configured via
- * enum controls.
- */
-#ifdef CONFIG_SND_DEBUG
-static const hda_nid_t alc880_test_dac_nids[4] = {
-       0x02, 0x03, 0x04, 0x05
-};
-
-static const struct hda_input_mux alc880_test_capture_source = {
-       .num_items = 7,
-       .items = {
-               { "In-1", 0x0 },
-               { "In-2", 0x1 },
-               { "In-3", 0x2 },
-               { "In-4", 0x3 },
-               { "CD", 0x4 },
-               { "Front", 0x5 },
-               { "Surround", 0x6 },
-       },
-};
-
-static const struct hda_channel_mode alc880_test_modes[4] = {
-       { 2, NULL },
-       { 4, NULL },
-       { 6, NULL },
-       { 8, NULL },
-};
-
-static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
-                                struct snd_ctl_elem_info *uinfo)
-{
-       static const char * const texts[] = {
-               "N/A", "Line Out", "HP Out",
-               "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
-       };
-       uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-       uinfo->count = 1;
-       uinfo->value.enumerated.items = 8;
-       if (uinfo->value.enumerated.item >= 8)
-               uinfo->value.enumerated.item = 7;
-       strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
-       return 0;
-}
-
-static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
-                               struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
-       unsigned int pin_ctl, item = 0;
-
-       pin_ctl = snd_hda_codec_read(codec, nid, 0,
-                                    AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-       if (pin_ctl & AC_PINCTL_OUT_EN) {
-               if (pin_ctl & AC_PINCTL_HP_EN)
-                       item = 2;
-               else
-                       item = 1;
-       } else if (pin_ctl & AC_PINCTL_IN_EN) {
-               switch (pin_ctl & AC_PINCTL_VREFEN) {
-               case AC_PINCTL_VREF_HIZ: item = 3; break;
-               case AC_PINCTL_VREF_50:  item = 4; break;
-               case AC_PINCTL_VREF_GRD: item = 5; break;
-               case AC_PINCTL_VREF_80:  item = 6; break;
-               case AC_PINCTL_VREF_100: item = 7; break;
-               }
-       }
-       ucontrol->value.enumerated.item[0] = item;
-       return 0;
-}
-
-static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
-                               struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
-       static const unsigned int ctls[] = {
-               0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
-               AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
-               AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
-               AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
-               AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
-               AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
-       };
-       unsigned int old_ctl, new_ctl;
-
-       old_ctl = snd_hda_codec_read(codec, nid, 0,
-                                    AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-       new_ctl = ctls[ucontrol->value.enumerated.item[0]];
-       if (old_ctl != new_ctl) {
-               int val;
-               snd_hda_codec_write_cache(codec, nid, 0,
-                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
-                                         new_ctl);
-               val = ucontrol->value.enumerated.item[0] >= 3 ?
-                       HDA_AMP_MUTE : 0;
-               snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
-                                        HDA_AMP_MUTE, val);
-               return 1;
-       }
-       return 0;
-}
-
-static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
-                                struct snd_ctl_elem_info *uinfo)
-{
-       static const char * const texts[] = {
-               "Front", "Surround", "CLFE", "Side"
-       };
-       uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-       uinfo->count = 1;
-       uinfo->value.enumerated.items = 4;
-       if (uinfo->value.enumerated.item >= 4)
-               uinfo->value.enumerated.item = 3;
-       strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
-       return 0;
-}
-
-static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
-                               struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
-       unsigned int sel;
-
-       sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
-       ucontrol->value.enumerated.item[0] = sel & 3;
-       return 0;
-}
-
-static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
-                               struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
-       unsigned int sel;
-
-       sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
-       if (ucontrol->value.enumerated.item[0] != sel) {
-               sel = ucontrol->value.enumerated.item[0] & 3;
-               snd_hda_codec_write_cache(codec, nid, 0,
-                                         AC_VERB_SET_CONNECT_SEL, sel);
-               return 1;
-       }
-       return 0;
-}
-
-#define PIN_CTL_TEST(xname,nid) {                      \
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
-                       .name = xname,                 \
-                       .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
-                       .info = alc_test_pin_ctl_info, \
-                       .get = alc_test_pin_ctl_get,   \
-                       .put = alc_test_pin_ctl_put,   \
-                       .private_value = nid           \
-                       }
-
-#define PIN_SRC_TEST(xname,nid) {                      \
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
-                       .name = xname,                 \
-                       .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
-                       .info = alc_test_pin_src_info, \
-                       .get = alc_test_pin_src_get,   \
-                       .put = alc_test_pin_src_put,   \
-                       .private_value = nid           \
-                       }
-
-static const struct snd_kcontrol_new alc880_test_mixer[] = {
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
-       HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
-       HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
-       HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
-       PIN_CTL_TEST("Front Pin Mode", 0x14),
-       PIN_CTL_TEST("Surround Pin Mode", 0x15),
-       PIN_CTL_TEST("CLFE Pin Mode", 0x16),
-       PIN_CTL_TEST("Side Pin Mode", 0x17),
-       PIN_CTL_TEST("In-1 Pin Mode", 0x18),
-       PIN_CTL_TEST("In-2 Pin Mode", 0x19),
-       PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
-       PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
-       PIN_SRC_TEST("In-1 Pin Source", 0x18),
-       PIN_SRC_TEST("In-2 Pin Source", 0x19),
-       PIN_SRC_TEST("In-3 Pin Source", 0x1a),
-       PIN_SRC_TEST("In-4 Pin Source", 0x1b),
-       HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
-       HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
-       HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
-       HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Channel Mode",
-               .info = alc_ch_mode_info,
-               .get = alc_ch_mode_get,
-               .put = alc_ch_mode_put,
-       },
-       { } /* end */
-};
-
-static const struct hda_verb alc880_test_init_verbs[] = {
-       /* Unmute inputs of 0x0c - 0x0f */
-       {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)},
-       /* Vol output for 0x0c-0x0f */
-       {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 output pins 0x14-0x17 */
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       /* Unmute output pins 0x14-0x17 */
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Set input pins 0x18-0x1c */
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       /* Mute input pins 0x18-0x1b */
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       /* ADC set up */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
-       /* Analog input/passthru */
-       {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)},
-       { }
-};
-#endif
-
-/*
- */
-
-static const char * const alc880_models[ALC880_MODEL_LAST] = {
-       [ALC880_3ST]            = "3stack",
-       [ALC880_TCL_S700]       = "tcl",
-       [ALC880_3ST_DIG]        = "3stack-digout",
-       [ALC880_CLEVO]          = "clevo",
-       [ALC880_5ST]            = "5stack",
-       [ALC880_5ST_DIG]        = "5stack-digout",
-       [ALC880_W810]           = "w810",
-       [ALC880_Z71V]           = "z71v",
-       [ALC880_6ST]            = "6stack",
-       [ALC880_6ST_DIG]        = "6stack-digout",
-       [ALC880_ASUS]           = "asus",
-       [ALC880_ASUS_W1V]       = "asus-w1v",
-       [ALC880_ASUS_DIG]       = "asus-dig",
-       [ALC880_ASUS_DIG2]      = "asus-dig2",
-       [ALC880_UNIWILL_DIG]    = "uniwill",
-       [ALC880_UNIWILL_P53]    = "uniwill-p53",
-       [ALC880_FUJITSU]        = "fujitsu",
-       [ALC880_F1734]          = "F1734",
-       [ALC880_LG]             = "lg",
-#ifdef CONFIG_SND_DEBUG
-       [ALC880_TEST]           = "test",
-#endif
-       [ALC880_AUTO]           = "auto",
-};
-
-static const struct snd_pci_quirk alc880_cfg_tbl[] = {
-       SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
-       SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
-       SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
-       SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
-       SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
-       SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
-       SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
-       SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
-       SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
-       SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
-       SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
-       SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
-       SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
-       SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
-       SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
-       SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
-       SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
-       /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
-       SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
-       SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
-       SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
-       SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
-       SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
-       SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
-       SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
-       SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
-       SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
-       SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
-       SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
-       SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
-       SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
-       SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
-       SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
-       SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
-       SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
-       SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
-       SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
-       SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
-       SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
-       SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
-       SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
-       SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
-       SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
-       SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
-       SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
-       SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
-       SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
-       SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
-       SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
-       SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
-       SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
-       SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
-       SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
-       SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
-       SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
-       SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
-       SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
-       SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
-       SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
-       SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
-       SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
-       SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
-       SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
-       SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
-       SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
-       /* default Intel */
-       SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
-       SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
-       SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
-       {}
-};
-
-/*
- * ALC880 codec presets
- */
-static const struct alc_config_preset alc880_presets[] = {
-       [ALC880_3ST] = {
-               .mixers = { alc880_three_stack_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_pin_3stack_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_dac_nids),
-               .dac_nids = alc880_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
-               .channel_mode = alc880_threestack_modes,
-               .need_dac_fix = 1,
-               .input_mux = &alc880_capture_source,
-       },
-       [ALC880_3ST_DIG] = {
-               .mixers = { alc880_three_stack_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_pin_3stack_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_dac_nids),
-               .dac_nids = alc880_dac_nids,
-               .dig_out_nid = ALC880_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
-               .channel_mode = alc880_threestack_modes,
-               .need_dac_fix = 1,
-               .input_mux = &alc880_capture_source,
-       },
-       [ALC880_TCL_S700] = {
-               .mixers = { alc880_tcl_s700_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_pin_tcl_S700_init_verbs,
-                               alc880_gpio2_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_dac_nids),
-               .dac_nids = alc880_dac_nids,
-               .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
-               .num_adc_nids = 1, /* single ADC */
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
-               .channel_mode = alc880_2_jack_modes,
-               .input_mux = &alc880_capture_source,
-       },
-       [ALC880_5ST] = {
-               .mixers = { alc880_three_stack_mixer,
-                           alc880_five_stack_mixer},
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_pin_5stack_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_dac_nids),
-               .dac_nids = alc880_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
-               .channel_mode = alc880_fivestack_modes,
-               .input_mux = &alc880_capture_source,
-       },
-       [ALC880_5ST_DIG] = {
-               .mixers = { alc880_three_stack_mixer,
-                           alc880_five_stack_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_pin_5stack_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_dac_nids),
-               .dac_nids = alc880_dac_nids,
-               .dig_out_nid = ALC880_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
-               .channel_mode = alc880_fivestack_modes,
-               .input_mux = &alc880_capture_source,
-       },
-       [ALC880_6ST] = {
-               .mixers = { alc880_six_stack_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_pin_6stack_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
-               .dac_nids = alc880_6st_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
-               .channel_mode = alc880_sixstack_modes,
-               .input_mux = &alc880_6stack_capture_source,
-       },
-       [ALC880_6ST_DIG] = {
-               .mixers = { alc880_six_stack_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_pin_6stack_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
-               .dac_nids = alc880_6st_dac_nids,
-               .dig_out_nid = ALC880_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
-               .channel_mode = alc880_sixstack_modes,
-               .input_mux = &alc880_6stack_capture_source,
-       },
-       [ALC880_W810] = {
-               .mixers = { alc880_w810_base_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_pin_w810_init_verbs,
-                               alc880_gpio2_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
-               .dac_nids = alc880_w810_dac_nids,
-               .dig_out_nid = ALC880_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
-               .channel_mode = alc880_w810_modes,
-               .input_mux = &alc880_capture_source,
-       },
-       [ALC880_Z71V] = {
-               .mixers = { alc880_z71v_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_pin_z71v_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
-               .dac_nids = alc880_z71v_dac_nids,
-               .dig_out_nid = ALC880_DIGOUT_NID,
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
-               .channel_mode = alc880_2_jack_modes,
-               .input_mux = &alc880_capture_source,
-       },
-       [ALC880_F1734] = {
-               .mixers = { alc880_f1734_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_pin_f1734_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
-               .dac_nids = alc880_f1734_dac_nids,
-               .hp_nid = 0x02,
-               .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
-               .channel_mode = alc880_2_jack_modes,
-               .input_mux = &alc880_f1734_capture_source,
-               .unsol_event = alc880_uniwill_p53_unsol_event,
-               .setup = alc880_uniwill_p53_setup,
-               .init_hook = alc_hp_automute,
-       },
-       [ALC880_ASUS] = {
-               .mixers = { alc880_asus_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_pin_asus_init_verbs,
-                               alc880_gpio1_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
-               .dac_nids = alc880_asus_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
-               .channel_mode = alc880_asus_modes,
-               .need_dac_fix = 1,
-               .input_mux = &alc880_capture_source,
-       },
-       [ALC880_ASUS_DIG] = {
-               .mixers = { alc880_asus_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_pin_asus_init_verbs,
-                               alc880_gpio1_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
-               .dac_nids = alc880_asus_dac_nids,
-               .dig_out_nid = ALC880_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
-               .channel_mode = alc880_asus_modes,
-               .need_dac_fix = 1,
-               .input_mux = &alc880_capture_source,
-       },
-       [ALC880_ASUS_DIG2] = {
-               .mixers = { alc880_asus_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_pin_asus_init_verbs,
-                               alc880_gpio2_init_verbs }, /* use GPIO2 */
-               .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
-               .dac_nids = alc880_asus_dac_nids,
-               .dig_out_nid = ALC880_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
-               .channel_mode = alc880_asus_modes,
-               .need_dac_fix = 1,
-               .input_mux = &alc880_capture_source,
-       },
-       [ALC880_ASUS_W1V] = {
-               .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_pin_asus_init_verbs,
-                               alc880_gpio1_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
-               .dac_nids = alc880_asus_dac_nids,
-               .dig_out_nid = ALC880_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
-               .channel_mode = alc880_asus_modes,
-               .need_dac_fix = 1,
-               .input_mux = &alc880_capture_source,
-       },
-       [ALC880_UNIWILL_DIG] = {
-               .mixers = { alc880_asus_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_pin_asus_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
-               .dac_nids = alc880_asus_dac_nids,
-               .dig_out_nid = ALC880_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
-               .channel_mode = alc880_asus_modes,
-               .need_dac_fix = 1,
-               .input_mux = &alc880_capture_source,
-       },
-       [ALC880_UNIWILL] = {
-               .mixers = { alc880_uniwill_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_uniwill_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
-               .dac_nids = alc880_asus_dac_nids,
-               .dig_out_nid = ALC880_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
-               .channel_mode = alc880_threestack_modes,
-               .need_dac_fix = 1,
-               .input_mux = &alc880_capture_source,
-               .unsol_event = alc880_uniwill_unsol_event,
-               .setup = alc880_uniwill_setup,
-               .init_hook = alc880_uniwill_init_hook,
-       },
-       [ALC880_UNIWILL_P53] = {
-               .mixers = { alc880_uniwill_p53_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_uniwill_p53_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
-               .dac_nids = alc880_asus_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
-               .channel_mode = alc880_threestack_modes,
-               .input_mux = &alc880_capture_source,
-               .unsol_event = alc880_uniwill_p53_unsol_event,
-               .setup = alc880_uniwill_p53_setup,
-               .init_hook = alc_hp_automute,
-       },
-       [ALC880_FUJITSU] = {
-               .mixers = { alc880_fujitsu_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_uniwill_p53_init_verbs,
-                               alc880_beep_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_dac_nids),
-               .dac_nids = alc880_dac_nids,
-               .dig_out_nid = ALC880_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
-               .channel_mode = alc880_2_jack_modes,
-               .input_mux = &alc880_capture_source,
-               .unsol_event = alc880_uniwill_p53_unsol_event,
-               .setup = alc880_uniwill_p53_setup,
-               .init_hook = alc_hp_automute,
-       },
-       [ALC880_CLEVO] = {
-               .mixers = { alc880_three_stack_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_pin_clevo_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_dac_nids),
-               .dac_nids = alc880_dac_nids,
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
-               .channel_mode = alc880_threestack_modes,
-               .need_dac_fix = 1,
-               .input_mux = &alc880_capture_source,
-       },
-       [ALC880_LG] = {
-               .mixers = { alc880_lg_mixer },
-               .init_verbs = { alc880_volume_init_verbs,
-                               alc880_lg_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
-               .dac_nids = alc880_lg_dac_nids,
-               .dig_out_nid = ALC880_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
-               .channel_mode = alc880_lg_ch_modes,
-               .need_dac_fix = 1,
-               .input_mux = &alc880_lg_capture_source,
-               .unsol_event = alc880_unsol_event,
-               .setup = alc880_lg_setup,
-               .init_hook = alc_hp_automute,
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-               .loopbacks = alc880_lg_loopbacks,
-#endif
-       },
-#ifdef CONFIG_SND_DEBUG
-       [ALC880_TEST] = {
-               .mixers = { alc880_test_mixer },
-               .init_verbs = { alc880_test_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
-               .dac_nids = alc880_test_dac_nids,
-               .dig_out_nid = ALC880_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
-               .channel_mode = alc880_test_modes,
-               .input_mux = &alc880_test_capture_source,
-       },
-#endif
-};
-
diff --git a/sound/pci/hda/alc882_quirks.c b/sound/pci/hda/alc882_quirks.c
deleted file mode 100644 (file)
index bb364a5..0000000
+++ /dev/null
@@ -1,866 +0,0 @@
-/*
- * ALC882/ALC883/ALC888/ALC889 quirk models
- * included by patch_realtek.c
- */
-
-/* ALC882 models */
-enum {
-       ALC882_AUTO,
-       ALC885_MBA21,
-       ALC885_MBP3,
-       ALC885_MB5,
-       ALC885_MACMINI3,
-       ALC885_IMAC91,
-       ALC889A_MB31,
-       ALC882_MODEL_LAST,
-};
-
-#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 const struct hda_channel_mode alc882_ch_modes[1] = {
-       { 8, NULL }
-};
-
-/* DACs */
-static const hda_nid_t alc882_dac_nids[4] = {
-       /* front, rear, clfe, rear_surr */
-       0x02, 0x03, 0x04, 0x05
-};
-#define alc883_dac_nids                alc882_dac_nids
-
-/* 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 const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
-#define alc883_capsrc_nids     alc882_capsrc_nids_alt
-
-/* input MUX */
-/* FIXME: should be a matrix-type input source selection */
-
-static const struct hda_input_mux alc882_capture_source = {
-       .num_items = 4,
-       .items = {
-               { "Mic", 0x0 },
-               { "Front Mic", 0x1 },
-               { "Line", 0x2 },
-               { "CD", 0x4 },
-       },
-};
-
-#define alc883_capture_source  alc882_capture_source
-
-static const struct hda_input_mux mb5_capture_source = {
-       .num_items = 3,
-       .items = {
-               { "Mic", 0x1 },
-               { "Line", 0x7 },
-               { "CD", 0x4 },
-       },
-};
-
-static const struct hda_input_mux macmini3_capture_source = {
-       .num_items = 2,
-       .items = {
-               { "Line", 0x2 },
-               { "CD", 0x4 },
-       },
-};
-
-static const struct hda_input_mux alc883_3stack_6ch_intel = {
-       .num_items = 4,
-       .items = {
-               { "Mic", 0x1 },
-               { "Front Mic", 0x0 },
-               { "Line", 0x2 },
-               { "CD", 0x4 },
-       },
-};
-
-static const 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) unused? */
-       },
-};
-
-static const struct hda_input_mux alc889A_imac91_capture_source = {
-       .num_items = 2,
-       .items = {
-               { "Mic", 0x01 },
-               { "Line", 0x2 }, /* Not sure! */
-       },
-};
-
-/* Macbook Air 2,1 */
-
-static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
-      { 2, NULL },
-};
-
-/*
- * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
- */
-
-/*
- * 2ch mode
- */
-static const struct hda_verb alc885_mbp_ch2_init[] = {
-       { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
-       { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       { } /* end */
-};
-
-/*
- * 4ch mode
- */
-static const struct hda_verb alc885_mbp_ch4_init[] = {
-       { 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 },
-       { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       { } /* end */
-};
-
-static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
-       { 2, alc885_mbp_ch2_init },
-       { 4, alc885_mbp_ch4_init },
-};
-
-/*
- * 2ch
- * Speakers/Woofer/HP = Front
- * LineIn = Input
- */
-static const struct hda_verb alc885_mb5_ch2_init[] = {
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       { } /* end */
-};
-
-/*
- * 6ch mode
- * Speakers/HP = Front
- * Woofer = LFE
- * LineIn = Surround
- */
-static const struct hda_verb alc885_mb5_ch6_init[] = {
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
-       { } /* end */
-};
-
-static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
-       { 2, alc885_mb5_ch2_init },
-       { 6, alc885_mb5_ch6_init },
-};
-
-#define alc885_macmini3_6ch_modes      alc885_mb5_6ch_modes
-
-/* Macbook Air 2,1 same control for HP and internal Speaker */
-
-static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
-      HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
-      HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
-     { }
-};
-
-
-static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
-       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE   ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
-       HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE   ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE   ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
-       HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE   ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE   ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
-       HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
-       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
-       { } /* end */
-};
-
-
-static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Channel Mode",
-               .info = alc_ch_mode_info,
-               .get = alc_ch_mode_get,
-               .put = alc_ch_mode_put,
-       },
-       { } /* end */
-};
-
-static const 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_IN_MUTE(0)},
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       /* Rear mixer */
-       {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_IN_MUTE(0)},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       /* Side mixer */
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-
-       /* 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)},
-       /* Input mixer3 */
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       /* ADC2: mute amp left and right */
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
-       /* ADC3: mute amp left and right */
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       { }
-};
-
-#define alc883_init_verbs      alc882_base_init_verbs
-
-/* Macbook 5,1 */
-static const struct hda_verb alc885_mb5_init_verbs[] = {
-       /* DACs */
-       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Front mixer */
-       {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)},
-       /* Surround mixer */
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       /* LFE mixer */
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       /* HP mixer */
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       /* Front Pin (0x0c) */
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
-       /* LFE Pin (0x0e) */
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
-       /* HP Pin (0x0f) */
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
-       {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-       /* 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 */
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
-       { }
-};
-
-/* Macmini 3,1 */
-static const struct hda_verb alc885_macmini3_init_verbs[] = {
-       /* DACs */
-       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Front mixer */
-       {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)},
-       /* Surround mixer */
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       /* LFE mixer */
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       /* HP mixer */
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       /* Front Pin (0x0c) */
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
-       /* LFE Pin (0x0e) */
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
-       /* HP Pin (0x0f) */
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
-       {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-       /* Line In pin */
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {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)},
-       { }
-};
-
-
-static const struct hda_verb alc885_mba21_init_verbs[] = {
-       /*Internal and HP Speaker Mixer*/
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       /*Internal Speaker Pin (0x0c)*/
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
-       /* HP Pin: output 0 (0x0e) */
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)},
-       /* Line in (is hp when jack connected)*/
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-
-       { }
- };
-
-
-/* Macbook Pro rev3 */
-static const struct hda_verb alc885_mbp3_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)},
-       {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)},
-       /* HP 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)},
-       /* 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},
-       /* HP Pin: output 0 (0x0e) */
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-       /* 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: use output 1 when in LineOut mode */
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
-
-       /* 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)},
-       {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(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},
-       /* ADC3: mute amp left and right */
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       { }
-};
-
-/* iMac 9,1 */
-static const struct hda_verb alc885_imac91_init_verbs[] = {
-       /* Internal Speaker Pin (0x0c) */
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
-       /* HP Pin: Rear */
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)},
-       /* Line in Rear */
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
-       {0x15, 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},
-       /* 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)},
-       /* Line-Out 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)},
-       /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
-       {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)},
-       /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-       /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-       /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
-       /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
-       /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
-       { }
-};
-
-/* Toggle speaker-output according to the hp-jack state */
-static void alc885_imac24_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-
-       spec->autocfg.hp_pins[0] = 0x14;
-       spec->autocfg.speaker_pins[0] = 0x18;
-       spec->autocfg.speaker_pins[1] = 0x1a;
-       alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-#define alc885_mb5_setup       alc885_imac24_setup
-#define alc885_macmini3_setup  alc885_imac24_setup
-
-/* Macbook Air 2,1 */
-static void alc885_mba21_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-
-       spec->autocfg.hp_pins[0] = 0x14;
-       spec->autocfg.speaker_pins[0] = 0x18;
-       alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-
-
-static void alc885_mbp3_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-
-       spec->autocfg.hp_pins[0] = 0x15;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static void alc885_imac91_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-
-       spec->autocfg.hp_pins[0] = 0x14;
-       spec->autocfg.speaker_pins[0] = 0x18;
-       spec->autocfg.speaker_pins[1] = 0x1a;
-       alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
-static const 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 const 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 const 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 const 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 const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
-       { 2, alc889A_mb31_ch2_init },
-       { 4, alc889A_mb31_ch4_init },
-       { 5, alc889A_mb31_ch5_init },
-       { 6, alc889A_mb31_ch6_init },
-};
-
-static const struct snd_kcontrol_new alc883_3ST_6ch_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_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 Volume", 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 Volume", 0x19, 0, HDA_INPUT),
-       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
-       /* Output mixers */
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
-               HDA_OUTPUT),
-       HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
-       /* Output switches */
-       HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
-       /* Boost mixers */
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
-       /* Input mixers */
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Channel Mode",
-               .info = alc_ch_mode_info,
-               .get = alc_ch_mode_get,
-               .put = alc_ch_mode_put,
-       },
-       { } /* end */
-};
-
-static const struct hda_verb alc889A_mb31_verbs[] = {
-       /* Init rear pin (used as headphone output) */
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},    /* Apple Headphones */
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},           /* Connect to front */
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-       /* Init line pin (used as output in 4ch and 6ch mode) */
-       {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},           /* Connect to CLFE */
-       /* Init line 2 pin (used as headphone out by default) */
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  /* Use as input */
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
-       { } /* end */
-};
-
-/* Mute speakers according to the headphone jack state */
-static void alc889A_mb31_automute(struct hda_codec *codec)
-{
-       unsigned int present;
-
-       /* Mute only in 2ch or 4ch mode */
-       if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
-           == 0x00) {
-               present = snd_hda_jack_detect(codec, 0x15);
-               snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
-                       HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
-               snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
-                       HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
-       }
-}
-
-static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
-{
-       if ((res >> 26) == ALC_HP_EVENT)
-               alc889A_mb31_automute(codec);
-}
-
-static void alc882_unsol_event(struct hda_codec *codec, unsigned int res)
-{
-       alc_exec_unsol_event(codec, res >> 26);
-}
-
-/*
- * configuration and preset
- */
-static const char * const alc882_models[ALC882_MODEL_LAST] = {
-       [ALC885_MB5]            = "mb5",
-       [ALC885_MACMINI3]       = "macmini3",
-       [ALC885_MBA21]          = "mba21",
-       [ALC885_MBP3]           = "mbp3",
-       [ALC885_IMAC91]         = "imac91",
-       [ALC889A_MB31]          = "mb31",
-       [ALC882_AUTO]           = "auto",
-};
-
-/* codec SSID table for Intel Mac */
-static const 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, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
-       SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
-       SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
-       SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
-       SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
-       SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
-       SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
-       SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
-       SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
-       /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
-        * so apparently no perfect solution yet
-        */
-       SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
-       SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
-       SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
-       {} /* terminator */
-};
-
-static const struct alc_config_preset alc882_presets[] = {
-          [ALC885_MBA21] = {
-                       .mixers = { alc885_mba21_mixer },
-                       .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
-                       .num_dacs = 2,
-                       .dac_nids = alc882_dac_nids,
-                       .channel_mode = alc885_mba21_ch_modes,
-                       .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
-                       .input_mux = &alc882_capture_source,
-                       .unsol_event = alc882_unsol_event,
-                       .setup = alc885_mba21_setup,
-                       .init_hook = alc_hp_automute,
-       },
-       [ALC885_MBP3] = {
-               .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
-               .init_verbs = { alc885_mbp3_init_verbs,
-                               alc880_gpio1_init_verbs },
-               .num_dacs = 2,
-               .dac_nids = alc882_dac_nids,
-               .hp_nid = 0x04,
-               .channel_mode = alc885_mbp_4ch_modes,
-               .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
-               .input_mux = &alc882_capture_source,
-               .dig_out_nid = ALC882_DIGOUT_NID,
-               .dig_in_nid = ALC882_DIGIN_NID,
-               .unsol_event = alc882_unsol_event,
-               .setup = alc885_mbp3_setup,
-               .init_hook = alc_hp_automute,
-       },
-       [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,
-               .unsol_event = alc882_unsol_event,
-               .setup = alc885_mb5_setup,
-               .init_hook = alc_hp_automute,
-       },
-       [ALC885_MACMINI3] = {
-               .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
-               .init_verbs = { alc885_macmini3_init_verbs,
-                               alc880_gpio1_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc882_dac_nids),
-               .dac_nids = alc882_dac_nids,
-               .channel_mode = alc885_macmini3_6ch_modes,
-               .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
-               .input_mux = &macmini3_capture_source,
-               .dig_out_nid = ALC882_DIGOUT_NID,
-               .dig_in_nid = ALC882_DIGIN_NID,
-               .unsol_event = alc882_unsol_event,
-               .setup = alc885_macmini3_setup,
-               .init_hook = alc_hp_automute,
-       },
-       [ALC885_IMAC91] = {
-               .mixers = {alc885_imac91_mixer},
-               .init_verbs = { alc885_imac91_init_verbs,
-                               alc880_gpio1_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc882_dac_nids),
-               .dac_nids = alc882_dac_nids,
-               .channel_mode = alc885_mba21_ch_modes,
-               .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
-               .input_mux = &alc889A_imac91_capture_source,
-               .dig_out_nid = ALC882_DIGOUT_NID,
-               .dig_in_nid = ALC882_DIGIN_NID,
-               .unsol_event = alc882_unsol_event,
-               .setup = alc885_imac91_setup,
-               .init_hook = alc_hp_automute,
-       },
-       [ALC889A_MB31] = {
-               .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
-               .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
-                       alc880_gpio1_init_verbs },
-               .adc_nids = alc883_adc_nids,
-               .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
-               .capsrc_nids = alc883_capsrc_nids,
-               .dac_nids = alc883_dac_nids,
-               .num_dacs = ARRAY_SIZE(alc883_dac_nids),
-               .channel_mode = alc889A_mb31_6ch_modes,
-               .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
-               .input_mux = &alc889A_mb31_capture_source,
-               .dig_out_nid = ALC883_DIGOUT_NID,
-               .unsol_event = alc889A_mb31_unsol_event,
-               .init_hook = alc889A_mb31_automute,
-       },
-};
-
-
diff --git a/sound/pci/hda/alc_quirks.c b/sound/pci/hda/alc_quirks.c
deleted file mode 100644 (file)
index a18952e..0000000
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- * Common codes for Realtek codec quirks
- * included by patch_realtek.c
- */
-
-/*
- * configuration template - to be copied to the spec instance
- */
-struct alc_config_preset {
-       const struct snd_kcontrol_new *mixers[5]; /* should be identical size
-                                            * with spec
-                                            */
-       const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
-       const struct hda_verb *init_verbs[5];
-       unsigned int num_dacs;
-       const hda_nid_t *dac_nids;
-       hda_nid_t dig_out_nid;          /* optional */
-       hda_nid_t hp_nid;               /* optional */
-       const hda_nid_t *slave_dig_outs;
-       unsigned int num_adc_nids;
-       const hda_nid_t *adc_nids;
-       const hda_nid_t *capsrc_nids;
-       hda_nid_t dig_in_nid;
-       unsigned int num_channel_mode;
-       const struct hda_channel_mode *channel_mode;
-       int need_dac_fix;
-       int const_channel_count;
-       unsigned int num_mux_defs;
-       const struct hda_input_mux *input_mux;
-       void (*unsol_event)(struct hda_codec *, unsigned int);
-       void (*setup)(struct hda_codec *);
-       void (*init_hook)(struct hda_codec *);
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-       const struct hda_amp_list *loopbacks;
-       void (*power_hook)(struct hda_codec *codec);
-#endif
-};
-
-/*
- * channel mode setting
- */
-static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
-                           struct snd_ctl_elem_info *uinfo)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       struct alc_spec *spec = codec->spec;
-       return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
-                                   spec->num_channel_mode);
-}
-
-static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
-                          struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       struct alc_spec *spec = codec->spec;
-       return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
-                                  spec->num_channel_mode,
-                                  spec->ext_channel_count);
-}
-
-static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
-                          struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       struct alc_spec *spec = codec->spec;
-       int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
-                                     spec->num_channel_mode,
-                                     &spec->ext_channel_count);
-       if (err >= 0 && !spec->const_channel_count) {
-               spec->multiout.max_channels = spec->ext_channel_count;
-               if (spec->need_dac_fix)
-                       spec->multiout.num_dacs = spec->multiout.max_channels / 2;
-       }
-       return err;
-}
-
-/*
- * Control the mode of pin widget settings via the mixer.  "pc" is used
- * instead of "%" to avoid consequences of accidentally treating the % as
- * being part of a format specifier.  Maximum allowed length of a value is
- * 63 characters plus NULL terminator.
- *
- * Note: some retasking pin complexes seem to ignore requests for input
- * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
- * are requested.  Therefore order this list so that this behaviour will not
- * cause problems when mixer clients move through the enum sequentially.
- * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
- * March 2006.
- */
-static const char * const alc_pin_mode_names[] = {
-       "Mic 50pc bias", "Mic 80pc bias",
-       "Line in", "Line out", "Headphone out",
-};
-static const unsigned char alc_pin_mode_values[] = {
-       PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
-};
-/* The control can present all 5 options, or it can limit the options based
- * in the pin being assumed to be exclusively an input or an output pin.  In
- * addition, "input" pins may or may not process the mic bias option
- * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
- * accept requests for bias as of chip versions up to March 2006) and/or
- * wiring in the computer.
- */
-#define ALC_PIN_DIR_IN              0x00
-#define ALC_PIN_DIR_OUT             0x01
-#define ALC_PIN_DIR_INOUT           0x02
-#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
-#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
-
-/* Info about the pin modes supported by the different pin direction modes.
- * For each direction the minimum and maximum values are given.
- */
-static const signed char alc_pin_mode_dir_info[5][2] = {
-       { 0, 2 },    /* ALC_PIN_DIR_IN */
-       { 3, 4 },    /* ALC_PIN_DIR_OUT */
-       { 0, 4 },    /* ALC_PIN_DIR_INOUT */
-       { 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
-       { 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
-};
-#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
-#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
-#define alc_pin_mode_n_items(_dir) \
-       (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
-
-static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
-                            struct snd_ctl_elem_info *uinfo)
-{
-       unsigned int item_num = uinfo->value.enumerated.item;
-       unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
-
-       uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-       uinfo->count = 1;
-       uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
-
-       if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
-               item_num = alc_pin_mode_min(dir);
-       strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
-       return 0;
-}
-
-static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
-                           struct snd_ctl_elem_value *ucontrol)
-{
-       unsigned int i;
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       hda_nid_t nid = kcontrol->private_value & 0xffff;
-       unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
-       long *valp = ucontrol->value.integer.value;
-       unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
-                                                AC_VERB_GET_PIN_WIDGET_CONTROL,
-                                                0x00);
-
-       /* Find enumerated value for current pinctl setting */
-       i = alc_pin_mode_min(dir);
-       while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
-               i++;
-       *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
-       return 0;
-}
-
-static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
-                           struct snd_ctl_elem_value *ucontrol)
-{
-       signed int change;
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       hda_nid_t nid = kcontrol->private_value & 0xffff;
-       unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
-       long val = *ucontrol->value.integer.value;
-       unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
-                                                AC_VERB_GET_PIN_WIDGET_CONTROL,
-                                                0x00);
-
-       if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
-               val = alc_pin_mode_min(dir);
-
-       change = pinctl != alc_pin_mode_values[val];
-       if (change) {
-               /* Set pin mode to that requested */
-               snd_hda_codec_write_cache(codec, nid, 0,
-                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
-                                         alc_pin_mode_values[val]);
-
-               /* Also enable the retasking pin's input/output as required
-                * for the requested pin mode.  Enum values of 2 or less are
-                * input modes.
-                *
-                * Dynamically switching the input/output buffers probably
-                * reduces noise slightly (particularly on input) so we'll
-                * do it.  However, having both input and output buffers
-                * enabled simultaneously doesn't seem to be problematic if
-                * this turns out to be necessary in the future.
-                */
-               if (val <= 2) {
-                       snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
-                                                HDA_AMP_MUTE, HDA_AMP_MUTE);
-                       snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
-                                                HDA_AMP_MUTE, 0);
-               } else {
-                       snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
-                                                HDA_AMP_MUTE, HDA_AMP_MUTE);
-                       snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
-                                                HDA_AMP_MUTE, 0);
-               }
-       }
-       return change;
-}
-
-#define ALC_PIN_MODE(xname, nid, dir) \
-       { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
-         .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
-         .info = alc_pin_mode_info, \
-         .get = alc_pin_mode_get, \
-         .put = alc_pin_mode_put, \
-         .private_value = nid | (dir<<16) }
-
-/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
- * together using a mask with more than one bit set.  This control is
- * currently used only by the ALC260 test model.  At this stage they are not
- * needed for any "production" models.
- */
-#ifdef CONFIG_SND_DEBUG
-#define alc_gpio_data_info     snd_ctl_boolean_mono_info
-
-static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
-                            struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       hda_nid_t nid = kcontrol->private_value & 0xffff;
-       unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-       long *valp = ucontrol->value.integer.value;
-       unsigned int val = snd_hda_codec_read(codec, nid, 0,
-                                             AC_VERB_GET_GPIO_DATA, 0x00);
-
-       *valp = (val & mask) != 0;
-       return 0;
-}
-static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
-                            struct snd_ctl_elem_value *ucontrol)
-{
-       signed int change;
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       hda_nid_t nid = kcontrol->private_value & 0xffff;
-       unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-       long val = *ucontrol->value.integer.value;
-       unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
-                                                   AC_VERB_GET_GPIO_DATA,
-                                                   0x00);
-
-       /* Set/unset the masked GPIO bit(s) as needed */
-       change = (val == 0 ? 0 : mask) != (gpio_data & mask);
-       if (val == 0)
-               gpio_data &= ~mask;
-       else
-               gpio_data |= mask;
-       snd_hda_codec_write_cache(codec, nid, 0,
-                                 AC_VERB_SET_GPIO_DATA, gpio_data);
-
-       return change;
-}
-#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
-       { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
-         .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
-         .info = alc_gpio_data_info, \
-         .get = alc_gpio_data_get, \
-         .put = alc_gpio_data_put, \
-         .private_value = nid | (mask<<16) }
-#endif   /* CONFIG_SND_DEBUG */
-
-/* A switch control to allow the enabling of the digital IO pins on the
- * ALC260.  This is incredibly simplistic; the intention of this control is
- * to provide something in the test model allowing digital outputs to be
- * identified if present.  If models are found which can utilise these
- * outputs a more complete mixer control can be devised for those models if
- * necessary.
- */
-#ifdef CONFIG_SND_DEBUG
-#define alc_spdif_ctrl_info    snd_ctl_boolean_mono_info
-
-static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
-                             struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       hda_nid_t nid = kcontrol->private_value & 0xffff;
-       unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-       long *valp = ucontrol->value.integer.value;
-       unsigned int val = snd_hda_codec_read(codec, nid, 0,
-                                             AC_VERB_GET_DIGI_CONVERT_1, 0x00);
-
-       *valp = (val & mask) != 0;
-       return 0;
-}
-static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
-                             struct snd_ctl_elem_value *ucontrol)
-{
-       signed int change;
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       hda_nid_t nid = kcontrol->private_value & 0xffff;
-       unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-       long val = *ucontrol->value.integer.value;
-       unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
-                                                   AC_VERB_GET_DIGI_CONVERT_1,
-                                                   0x00);
-
-       /* Set/unset the masked control bit(s) as needed */
-       change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
-       if (val==0)
-               ctrl_data &= ~mask;
-       else
-               ctrl_data |= mask;
-       snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
-                                 ctrl_data);
-
-       return change;
-}
-#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
-       { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
-         .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
-         .info = alc_spdif_ctrl_info, \
-         .get = alc_spdif_ctrl_get, \
-         .put = alc_spdif_ctrl_put, \
-         .private_value = nid | (mask<<16) }
-#endif   /* CONFIG_SND_DEBUG */
-
-/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
- * Again, this is only used in the ALC26x test models to help identify when
- * the EAPD line must be asserted for features to work.
- */
-#ifdef CONFIG_SND_DEBUG
-#define alc_eapd_ctrl_info     snd_ctl_boolean_mono_info
-
-static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
-                             struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       hda_nid_t nid = kcontrol->private_value & 0xffff;
-       unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-       long *valp = ucontrol->value.integer.value;
-       unsigned int val = snd_hda_codec_read(codec, nid, 0,
-                                             AC_VERB_GET_EAPD_BTLENABLE, 0x00);
-
-       *valp = (val & mask) != 0;
-       return 0;
-}
-
-static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
-                             struct snd_ctl_elem_value *ucontrol)
-{
-       int change;
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       hda_nid_t nid = kcontrol->private_value & 0xffff;
-       unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-       long val = *ucontrol->value.integer.value;
-       unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
-                                                   AC_VERB_GET_EAPD_BTLENABLE,
-                                                   0x00);
-
-       /* Set/unset the masked control bit(s) as needed */
-       change = (!val ? 0 : mask) != (ctrl_data & mask);
-       if (!val)
-               ctrl_data &= ~mask;
-       else
-               ctrl_data |= mask;
-       snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
-                                 ctrl_data);
-
-       return change;
-}
-
-#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
-       { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
-         .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
-         .info = alc_eapd_ctrl_info, \
-         .get = alc_eapd_ctrl_get, \
-         .put = alc_eapd_ctrl_put, \
-         .private_value = nid | (mask<<16) }
-#endif   /* CONFIG_SND_DEBUG */
-
-static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       struct auto_pin_cfg *cfg = &spec->autocfg;
-
-       if (!cfg->line_outs) {
-               while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
-                      cfg->line_out_pins[cfg->line_outs])
-                       cfg->line_outs++;
-       }
-       if (!cfg->speaker_outs) {
-               while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
-                      cfg->speaker_pins[cfg->speaker_outs])
-                       cfg->speaker_outs++;
-       }
-       if (!cfg->hp_outs) {
-               while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
-                      cfg->hp_pins[cfg->hp_outs])
-                       cfg->hp_outs++;
-       }
-}
-
-/*
- * set up from the preset table
- */
-static void setup_preset(struct hda_codec *codec,
-                        const struct alc_config_preset *preset)
-{
-       struct alc_spec *spec = codec->spec;
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
-               add_mixer(spec, preset->mixers[i]);
-       spec->cap_mixer = preset->cap_mixer;
-       for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
-            i++)
-               add_verb(spec, preset->init_verbs[i]);
-
-       spec->channel_mode = preset->channel_mode;
-       spec->num_channel_mode = preset->num_channel_mode;
-       spec->need_dac_fix = preset->need_dac_fix;
-       spec->const_channel_count = preset->const_channel_count;
-
-       if (preset->const_channel_count)
-               spec->multiout.max_channels = preset->const_channel_count;
-       else
-               spec->multiout.max_channels = spec->channel_mode[0].channels;
-       spec->ext_channel_count = spec->channel_mode[0].channels;
-
-       spec->multiout.num_dacs = preset->num_dacs;
-       spec->multiout.dac_nids = preset->dac_nids;
-       spec->multiout.dig_out_nid = preset->dig_out_nid;
-       spec->multiout.slave_dig_outs = preset->slave_dig_outs;
-       spec->multiout.hp_nid = preset->hp_nid;
-
-       spec->num_mux_defs = preset->num_mux_defs;
-       if (!spec->num_mux_defs)
-               spec->num_mux_defs = 1;
-       spec->input_mux = preset->input_mux;
-
-       spec->num_adc_nids = preset->num_adc_nids;
-       spec->adc_nids = preset->adc_nids;
-       spec->capsrc_nids = preset->capsrc_nids;
-       spec->dig_in_nid = preset->dig_in_nid;
-
-       spec->unsol_event = preset->unsol_event;
-       spec->init_hook = preset->init_hook;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-       spec->power_hook = preset->power_hook;
-       spec->loopback.amplist = preset->loopbacks;
-#endif
-
-       if (preset->setup)
-               preset->setup(codec);
-
-       alc_fixup_autocfg_pin_nums(codec);
-}
-
-static void alc_simple_setup_automute(struct alc_spec *spec, int mode)
-{
-       int lo_pin = spec->autocfg.line_out_pins[0];
-
-       if (lo_pin == spec->autocfg.speaker_pins[0] ||
-               lo_pin == spec->autocfg.hp_pins[0])
-               lo_pin = 0;
-       spec->automute_mode = mode;
-       spec->detect_hp = !!spec->autocfg.hp_pins[0];
-       spec->detect_lo = !!lo_pin;
-       spec->automute_lo = spec->automute_lo_possible = !!lo_pin;
-       spec->automute_speaker = spec->automute_speaker_possible = !!spec->autocfg.speaker_pins[0];
-}
-
-/* auto-toggle front mic */
-static void alc88x_simple_mic_automute(struct hda_codec *codec)
-{
-       unsigned int present;
-       unsigned char bits;
-
-       present = snd_hda_jack_detect(codec, 0x18);
-       bits = present ? HDA_AMP_MUTE : 0;
-       snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
-}
-
index 684307372d73e87535323ecc2e250a2ffab21f8e..7a8fcc4c15f84acf5baab4ec9301f35f84a75049 100644 (file)
@@ -19,6 +19,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
+#include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
@@ -2304,7 +2305,7 @@ typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *);
 
 /* apply the function to all matching slave ctls in the mixer list */
 static int map_slaves(struct hda_codec *codec, const char * const *slaves,
-                     map_slave_func_t func, void *data) 
+                     const char *suffix, map_slave_func_t func, void *data) 
 {
        struct hda_nid_item *items;
        const char * const *s;
@@ -2317,7 +2318,14 @@ static int map_slaves(struct hda_codec *codec, const char * const *slaves,
                    sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER)
                        continue;
                for (s = slaves; *s; s++) {
-                       if (!strcmp(sctl->id.name, *s)) {
+                       char tmpname[sizeof(sctl->id.name)];
+                       const char *name = *s;
+                       if (suffix) {
+                               snprintf(tmpname, sizeof(tmpname), "%s %s",
+                                        name, suffix);
+                               name = tmpname;
+                       }
+                       if (!strcmp(sctl->id.name, name)) {
                                err = func(data, sctl);
                                if (err)
                                        return err;
@@ -2333,12 +2341,65 @@ static int check_slave_present(void *data, struct snd_kcontrol *sctl)
        return 1;
 }
 
+/* guess the value corresponding to 0dB */
+static int get_kctl_0dB_offset(struct snd_kcontrol *kctl)
+{
+       int _tlv[4];
+       const int *tlv = NULL;
+       int val = -1;
+
+       if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
+               /* FIXME: set_fs() hack for obtaining user-space TLV data */
+               mm_segment_t fs = get_fs();
+               set_fs(get_ds());
+               if (!kctl->tlv.c(kctl, 0, sizeof(_tlv), _tlv))
+                       tlv = _tlv;
+               set_fs(fs);
+       } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ)
+               tlv = kctl->tlv.p;
+       if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE)
+               val = -tlv[2] / tlv[3];
+       return val;
+}
+
+/* call kctl->put with the given value(s) */
+static int put_kctl_with_value(struct snd_kcontrol *kctl, int val)
+{
+       struct snd_ctl_elem_value *ucontrol;
+       ucontrol = kzalloc(sizeof(*ucontrol), GFP_KERNEL);
+       if (!ucontrol)
+               return -ENOMEM;
+       ucontrol->value.integer.value[0] = val;
+       ucontrol->value.integer.value[1] = val;
+       kctl->put(kctl, ucontrol);
+       kfree(ucontrol);
+       return 0;
+}
+
+/* initialize the slave volume with 0dB */
+static int init_slave_0dB(void *data, struct snd_kcontrol *slave)
+{
+       int offset = get_kctl_0dB_offset(slave);
+       if (offset > 0)
+               put_kctl_with_value(slave, offset);
+       return 0;
+}
+
+/* unmute the slave */
+static int init_slave_unmute(void *data, struct snd_kcontrol *slave)
+{
+       return put_kctl_with_value(slave, 1);
+}
+
 /**
  * snd_hda_add_vmaster - create a virtual master control and add slaves
  * @codec: HD-audio codec
  * @name: vmaster control name
  * @tlv: TLV data (optional)
  * @slaves: slave control names (optional)
+ * @suffix: suffix string to each slave name (optional)
+ * @init_slave_vol: initialize slaves to unmute/0dB
+ * @ctl_ret: store the vmaster kcontrol in return
  *
  * Create a virtual master control with the given name.  The TLV data
  * must be either NULL or a valid data.
@@ -2349,13 +2410,18 @@ static int check_slave_present(void *data, struct snd_kcontrol *sctl)
  *
  * This function returns zero if successful or a negative error code.
  */
-int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
-                       unsigned int *tlv, const char * const *slaves)
+int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
+                       unsigned int *tlv, const char * const *slaves,
+                         const char *suffix, bool init_slave_vol,
+                         struct snd_kcontrol **ctl_ret)
 {
        struct snd_kcontrol *kctl;
        int err;
 
-       err = map_slaves(codec, slaves, check_slave_present, NULL);
+       if (ctl_ret)
+               *ctl_ret = NULL;
+
+       err = map_slaves(codec, slaves, suffix, check_slave_present, NULL);
        if (err != 1) {
                snd_printdd("No slave found for %s\n", name);
                return 0;
@@ -2367,13 +2433,119 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
        if (err < 0)
                return err;
 
-       err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave,
-                        kctl);
+       err = map_slaves(codec, slaves, suffix,
+                        (map_slave_func_t)snd_ctl_add_slave, kctl);
        if (err < 0)
                return err;
+
+       /* init with master mute & zero volume */
+       put_kctl_with_value(kctl, 0);
+       if (init_slave_vol)
+               map_slaves(codec, slaves, suffix,
+                          tlv ? init_slave_0dB : init_slave_unmute, kctl);
+
+       if (ctl_ret)
+               *ctl_ret = kctl;
        return 0;
 }
-EXPORT_SYMBOL_HDA(snd_hda_add_vmaster);
+EXPORT_SYMBOL_HDA(__snd_hda_add_vmaster);
+
+/*
+ * mute-LED control using vmaster
+ */
+static int vmaster_mute_mode_info(struct snd_kcontrol *kcontrol,
+                                 struct snd_ctl_elem_info *uinfo)
+{
+       static const char * const texts[] = {
+               "Off", "On", "Follow Master"
+       };
+       unsigned int index;
+
+       uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+       uinfo->count = 1;
+       uinfo->value.enumerated.items = 3;
+       index = uinfo->value.enumerated.item;
+       if (index >= 3)
+               index = 2;
+       strcpy(uinfo->value.enumerated.name, texts[index]);
+       return 0;
+}
+
+static int vmaster_mute_mode_get(struct snd_kcontrol *kcontrol,
+                                struct snd_ctl_elem_value *ucontrol)
+{
+       struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
+       ucontrol->value.enumerated.item[0] = hook->mute_mode;
+       return 0;
+}
+
+static int vmaster_mute_mode_put(struct snd_kcontrol *kcontrol,
+                                struct snd_ctl_elem_value *ucontrol)
+{
+       struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
+       unsigned int old_mode = hook->mute_mode;
+
+       hook->mute_mode = ucontrol->value.enumerated.item[0];
+       if (hook->mute_mode > HDA_VMUTE_FOLLOW_MASTER)
+               hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
+       if (old_mode == hook->mute_mode)
+               return 0;
+       snd_hda_sync_vmaster_hook(hook);
+       return 1;
+}
+
+static struct snd_kcontrol_new vmaster_mute_mode = {
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+       .name = "Mute-LED Mode",
+       .info = vmaster_mute_mode_info,
+       .get = vmaster_mute_mode_get,
+       .put = vmaster_mute_mode_put,
+};
+
+/*
+ * Add a mute-LED hook with the given vmaster switch kctl
+ * "Mute-LED Mode" control is automatically created and associated with
+ * the given hook.
+ */
+int snd_hda_add_vmaster_hook(struct hda_codec *codec,
+                            struct hda_vmaster_mute_hook *hook,
+                            bool expose_enum_ctl)
+{
+       struct snd_kcontrol *kctl;
+
+       if (!hook->hook || !hook->sw_kctl)
+               return 0;
+       snd_ctl_add_vmaster_hook(hook->sw_kctl, hook->hook, codec);
+       hook->codec = codec;
+       hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
+       if (!expose_enum_ctl)
+               return 0;
+       kctl = snd_ctl_new1(&vmaster_mute_mode, hook);
+       if (!kctl)
+               return -ENOMEM;
+       return snd_hda_ctl_add(codec, 0, kctl);
+}
+EXPORT_SYMBOL_HDA(snd_hda_add_vmaster_hook);
+
+/*
+ * Call the hook with the current value for synchronization
+ * Should be called in init callback
+ */
+void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook)
+{
+       if (!hook->hook || !hook->codec)
+               return;
+       switch (hook->mute_mode) {
+       case HDA_VMUTE_FOLLOW_MASTER:
+               snd_ctl_sync_vmaster_hook(hook->sw_kctl);
+               break;
+       default:
+               hook->hook(hook->codec, hook->mute_mode);
+               break;
+       }
+}
+EXPORT_SYMBOL_HDA(snd_hda_sync_vmaster_hook);
+
 
 /**
  * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch
@@ -5272,6 +5444,10 @@ int snd_hda_suspend(struct hda_bus *bus)
        list_for_each_entry(codec, &bus->codec_list, list) {
                if (hda_codec_is_power_on(codec))
                        hda_call_codec_suspend(codec);
+               else /* forcibly change the power to D3 even if not used */
+                       hda_set_power_state(codec,
+                                           codec->afg ? codec->afg : codec->mfg,
+                                           AC_PWRST_D3);
                if (codec->patch_ops.post_suspend)
                        codec->patch_ops.post_suspend(codec);
        }
index f0f1943a4b2c890ce4affe17425de6210e53ea89..9a9f372e1be4f50070e818116dd7786156fb089c 100644 (file)
@@ -855,6 +855,7 @@ struct hda_codec {
        unsigned int pins_shutup:1;     /* pins are shut up */
        unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
        unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */
+       unsigned int no_jack_detect:1;  /* Machine has no jack-detection */
 #ifdef CONFIG_SND_HDA_POWER_SAVE
        unsigned int power_on :1;       /* current (global) power-state */
        unsigned int power_transition :1; /* power-state in transition */
index 95dfb687494144e54b191e3f7f4dbe7179bcf37d..c19e71a94e1bd5a792ff100cba817134bae04b12 100644 (file)
@@ -84,7 +84,7 @@ module_param_array(model, charp, NULL, 0444);
 MODULE_PARM_DESC(model, "Use the given board model.");
 module_param_array(position_fix, int, NULL, 0444);
 MODULE_PARM_DESC(position_fix, "DMA pointer read method."
-                "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO).");
+                "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO).");
 module_param_array(bdl_pos_adj, int, NULL, 0644);
 MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
 module_param_array(probe_mask, int, NULL, 0444);
@@ -94,7 +94,7 @@ MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
 module_param(single_cmd, bool, 0444);
 MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
                 "(for debugging only).");
-module_param(enable_msi, int, 0444);
+module_param(enable_msi, bint, 0444);
 MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
 #ifdef CONFIG_SND_HDA_PATCH_LOADER
 module_param_array(patch, charp, NULL, 0444);
@@ -121,8 +121,8 @@ module_param(power_save_controller, bool, 0644);
 MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
 #endif
 
-static bool align_buffer_size = 1;
-module_param(align_buffer_size, bool, 0644);
+static int align_buffer_size = -1;
+module_param(align_buffer_size, bint, 0644);
 MODULE_PARM_DESC(align_buffer_size,
                "Force buffer and period sizes to be multiple of 128 bytes.");
 
@@ -148,6 +148,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
                         "{Intel, PCH},"
                         "{Intel, CPT},"
                         "{Intel, PPT},"
+                        "{Intel, LPT},"
                         "{Intel, PBG},"
                         "{Intel, SCH},"
                         "{ATI, SB450},"
@@ -329,6 +330,7 @@ enum {
        POS_FIX_LPIB,
        POS_FIX_POSBUF,
        POS_FIX_VIACOMBO,
+       POS_FIX_COMBO,
 };
 
 /* Defines for ATI HD Audio support in SB450 south bridge */
@@ -515,6 +517,7 @@ enum {
 #define AZX_DCAPS_SYNC_WRITE   (1 << 19)       /* sync each cmd write */
 #define AZX_DCAPS_OLD_SSYNC    (1 << 20)       /* Old SSYNC reg for ICH */
 #define AZX_DCAPS_BUFSIZE      (1 << 21)       /* no buffer size alignment */
+#define AZX_DCAPS_ALIGN_BUFSIZE        (1 << 22)       /* buffer size alignment */
 
 /* quirks for ATI SB / AMD Hudson */
 #define AZX_DCAPS_PRESET_ATI_SB \
@@ -527,7 +530,8 @@ enum {
 
 /* quirks for Nvidia */
 #define AZX_DCAPS_PRESET_NVIDIA \
-       (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI)
+       (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\
+        AZX_DCAPS_ALIGN_BUFSIZE)
 
 static char *driver_short_names[] __devinitdata = {
        [AZX_DRIVER_ICH] = "HDA Intel",
@@ -2347,17 +2351,6 @@ static void azx_power_notify(struct hda_bus *bus)
  * power management
  */
 
-static int snd_hda_codecs_inuse(struct hda_bus *bus)
-{
-       struct hda_codec *codec;
-
-       list_for_each_entry(codec, &bus->codec_list, list) {
-               if (snd_hda_codec_needs_resume(codec))
-                       return 1;
-       }
-       return 0;
-}
-
 static int azx_suspend(struct pci_dev *pci, pm_message_t state)
 {
        struct snd_card *card = pci_get_drvdata(pci);
@@ -2404,8 +2397,7 @@ static int azx_resume(struct pci_dev *pci)
                return -EIO;
        azx_init_pci(chip);
 
-       if (snd_hda_codecs_inuse(chip->bus))
-               azx_init_chip(chip, 1);
+       azx_init_chip(chip, 1);
 
        snd_hda_resume(chip->bus);
        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
@@ -2517,6 +2509,7 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
        case POS_FIX_LPIB:
        case POS_FIX_POSBUF:
        case POS_FIX_VIACOMBO:
+       case POS_FIX_COMBO:
                return fix;
        }
 
@@ -2696,6 +2689,12 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
 
        chip->position_fix[0] = chip->position_fix[1] =
                check_position_fix(chip, position_fix[dev]);
+       /* combo mode uses LPIB for playback */
+       if (chip->position_fix[0] == POS_FIX_COMBO) {
+               chip->position_fix[0] = POS_FIX_LPIB;
+               chip->position_fix[1] = POS_FIX_AUTO;
+       }
+
        check_probe_mask(chip, dev);
 
        chip->single_cmd = single_cmd;
@@ -2774,9 +2773,16 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
        }
 
        /* disable buffer size rounding to 128-byte multiples if supported */
-       chip->align_buffer_size = align_buffer_size;
-       if (chip->driver_caps & AZX_DCAPS_BUFSIZE)
-               chip->align_buffer_size = 0;
+       if (align_buffer_size >= 0)
+               chip->align_buffer_size = !!align_buffer_size;
+       else {
+               if (chip->driver_caps & AZX_DCAPS_BUFSIZE)
+                       chip->align_buffer_size = 0;
+               else if (chip->driver_caps & AZX_DCAPS_ALIGN_BUFSIZE)
+                       chip->align_buffer_size = 1;
+               else
+                       chip->align_buffer_size = 1;
+       }
 
        /* allow 64bit DMA address if supported by H/W */
        if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
@@ -2992,6 +2998,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
        { PCI_DEVICE(0x8086, 0x1e20),
          .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
          AZX_DCAPS_BUFSIZE},
+       /* Lynx Point */
+       { PCI_DEVICE(0x8086, 0x8c20),
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
+         AZX_DCAPS_BUFSIZE},
        /* SCH */
        { PCI_DEVICE(0x8086, 0x811b),
          .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
index 9d819c4b4923d18c67447953b02395408e923afc..d68948499fbc15d7342ba0c9a63675d769b95a92 100644 (file)
 #include "hda_local.h"
 #include "hda_jack.h"
 
+bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
+{
+       if (codec->no_jack_detect)
+               return false;
+       if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
+               return false;
+       if (!codec->ignore_misc_bit &&
+           (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
+            AC_DEFCFG_MISC_NO_PRESENCE))
+               return false;
+       if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
+               return false;
+       return true;
+}
+EXPORT_SYMBOL_HDA(is_jack_detectable);
+
 /* execute pin sense measurement */
 static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid)
 {
index f8f97c71c9c1a05fc8016187228f77aca71256d7..c66655cf413a1bc074f62ac91e0ed6e3907e342d 100644 (file)
@@ -62,18 +62,7 @@ int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
 u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
 int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
 
-static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
-{
-       if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
-               return false;
-       if (!codec->ignore_misc_bit &&
-           (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
-            AC_DEFCFG_MISC_NO_PRESENCE))
-               return false;
-       if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
-               return false;
-       return true;
-}
+bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid);
 
 int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
                          const char *name, int idx);
index aca8d3193b9507f55080b13811936fca3a301a28..0ec9248165bca9c7f7f7d47aaffe4abc863b600c 100644 (file)
@@ -139,10 +139,36 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
                             unsigned int *tlv);
 struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
                                            const char *name);
-int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
-                       unsigned int *tlv, const char * const *slaves);
+int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
+                         unsigned int *tlv, const char * const *slaves,
+                         const char *suffix, bool init_slave_vol,
+                         struct snd_kcontrol **ctl_ret);
+#define snd_hda_add_vmaster(codec, name, tlv, slaves, suffix) \
+       __snd_hda_add_vmaster(codec, name, tlv, slaves, suffix, true, NULL)
 int snd_hda_codec_reset(struct hda_codec *codec);
 
+enum {
+       HDA_VMUTE_OFF,
+       HDA_VMUTE_ON,
+       HDA_VMUTE_FOLLOW_MASTER,
+};
+
+struct hda_vmaster_mute_hook {
+       /* below two fields must be filled by the caller of
+        * snd_hda_add_vmaster_hook() beforehand
+        */
+       struct snd_kcontrol *sw_kctl;
+       void (*hook)(void *, int);
+       /* below are initialized automatically */
+       unsigned int mute_mode; /* HDA_VMUTE_XXX */
+       struct hda_codec *codec;
+};
+
+int snd_hda_add_vmaster_hook(struct hda_codec *codec,
+                            struct hda_vmaster_mute_hook *hook,
+                            bool expose_enum_ctl);
+void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook);
+
 /* amp value bits */
 #define HDA_AMP_MUTE   0x80
 #define HDA_AMP_UNMUTE 0x00
index 9cb14b42dfff48f890ee10871dea7fffb14b7054..7143393927da34ddeac2c86ce6538c669e85d16a 100644 (file)
@@ -82,6 +82,7 @@ struct ad198x_spec {
        unsigned int inv_jack_detect: 1;/* inverted jack-detection */
        unsigned int inv_eapd: 1;       /* inverted EAPD implementation */
        unsigned int analog_beep: 1;    /* analog beep input present */
+       unsigned int avoid_init_slave_vol:1;
 
 #ifdef CONFIG_SND_HDA_POWER_SAVE
        struct hda_loopback_check loopback;
@@ -137,51 +138,17 @@ static int ad198x_init(struct hda_codec *codec)
        return 0;
 }
 
-static const char * const ad_slave_vols[] = {
-       "Front Playback Volume",
-       "Surround Playback Volume",
-       "Center Playback Volume",
-       "LFE Playback Volume",
-       "Side Playback Volume",
-       "Headphone Playback Volume",
-       "Mono Playback Volume",
-       "Speaker Playback Volume",
-       "IEC958 Playback Volume",
+static const char * const ad_slave_pfxs[] = {
+       "Front", "Surround", "Center", "LFE", "Side",
+       "Headphone", "Mono", "Speaker", "IEC958",
        NULL
 };
 
-static const char * const ad_slave_sws[] = {
-       "Front Playback Switch",
-       "Surround Playback Switch",
-       "Center Playback Switch",
-       "LFE Playback Switch",
-       "Side Playback Switch",
-       "Headphone Playback Switch",
-       "Mono Playback Switch",
-       "Speaker Playback Switch",
-       "IEC958 Playback Switch",
+static const char * const ad1988_6stack_fp_slave_pfxs[] = {
+       "Front", "Surround", "Center", "LFE", "Side", "IEC958",
        NULL
 };
 
-static const char * const ad1988_6stack_fp_slave_vols[] = {
-       "Front Playback Volume",
-       "Surround Playback Volume",
-       "Center Playback Volume",
-       "LFE Playback Volume",
-       "Side Playback Volume",
-       "IEC958 Playback Volume",
-       NULL
-};
-
-static const char * const ad1988_6stack_fp_slave_sws[] = {
-       "Front Playback Switch",
-       "Surround Playback Switch",
-       "Center Playback Switch",
-       "LFE Playback Switch",
-       "Side Playback Switch",
-       "IEC958 Playback Switch",
-       NULL
-};
 static void ad198x_free_kctls(struct hda_codec *codec);
 
 #ifdef CONFIG_SND_HDA_INPUT_BEEP
@@ -257,10 +224,12 @@ static int ad198x_build_controls(struct hda_codec *codec)
                unsigned int vmaster_tlv[4];
                snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
                                        HDA_OUTPUT, vmaster_tlv);
-               err = snd_hda_add_vmaster(codec, "Master Playback Volume",
+               err = __snd_hda_add_vmaster(codec, "Master Playback Volume",
                                          vmaster_tlv,
                                          (spec->slave_vols ?
-                                          spec->slave_vols : ad_slave_vols));
+                                          spec->slave_vols : ad_slave_pfxs),
+                                         "Playback Volume",
+                                         !spec->avoid_init_slave_vol, NULL);
                if (err < 0)
                        return err;
        }
@@ -268,7 +237,8 @@ static int ad198x_build_controls(struct hda_codec *codec)
                err = snd_hda_add_vmaster(codec, "Master Playback Switch",
                                          NULL,
                                          (spec->slave_sws ?
-                                          spec->slave_sws : ad_slave_sws));
+                                          spec->slave_sws : ad_slave_pfxs),
+                                         "Playback Switch");
                if (err < 0)
                        return err;
        }
@@ -3385,8 +3355,8 @@ static int patch_ad1988(struct hda_codec *codec)
 
        if (spec->autocfg.hp_pins[0]) {
                spec->mixers[spec->num_mixers++] = ad1988_hp_mixers;
-               spec->slave_vols = ad1988_6stack_fp_slave_vols;
-               spec->slave_sws = ad1988_6stack_fp_slave_sws;
+               spec->slave_vols = ad1988_6stack_fp_slave_pfxs;
+               spec->slave_sws = ad1988_6stack_fp_slave_pfxs;
                spec->alt_dac_nid = ad1988_alt_dac_nid;
                spec->stream_analog_alt_playback =
                        &ad198x_pcm_analog_alt_playback;
@@ -3594,16 +3564,8 @@ static const struct hda_amp_list ad1884_loopbacks[] = {
 #endif
 
 static const char * const ad1884_slave_vols[] = {
-       "PCM Playback Volume",
-       "Mic Playback Volume",
-       "Mono Playback Volume",
-       "Front Mic Playback Volume",
-       "Mic Playback Volume",
-       "CD Playback Volume",
-       "Internal Mic Playback Volume",
-       "Docking Mic Playback Volume",
-       /* "Beep Playback Volume", */
-       "IEC958 Playback Volume",
+       "PCM", "Mic", "Mono", "Front Mic", "Mic", "CD",
+       "Internal Mic", "Docking Mic", /* "Beep", */ "IEC958",
        NULL
 };
 
@@ -3644,6 +3606,8 @@ static int patch_ad1884(struct hda_codec *codec)
        spec->vmaster_nid = 0x04;
        /* we need to cover all playback volumes */
        spec->slave_vols = ad1884_slave_vols;
+       /* slaves may contain input volumes, so we can't raise to 0dB blindly */
+       spec->avoid_init_slave_vol = 1;
 
        codec->patch_ops = ad198x_patch_ops;
 
index d29d6d37790425924ce818acff4f6402f0fa8e82..e6eafb18c8f54871265c142c61e14ea939cacc64 100644 (file)
@@ -70,6 +70,8 @@ struct conexant_spec {
        const struct snd_kcontrol_new *mixers[5];
        int num_mixers;
        hda_nid_t vmaster_nid;
+       struct hda_vmaster_mute_hook vmaster_mute;
+       bool vmaster_mute_led;
 
        const struct hda_verb *init_verbs[5];   /* initialization verbs
                                                 * don't forget NULL
@@ -465,21 +467,8 @@ static const struct snd_kcontrol_new cxt_beep_mixer[] = {
 };
 #endif
 
-static const char * const slave_vols[] = {
-       "Headphone Playback Volume",
-       "Speaker Playback Volume",
-       "Front Playback Volume",
-       "Surround Playback Volume",
-       "CLFE Playback Volume",
-       NULL
-};
-
-static const char * const slave_sws[] = {
-       "Headphone Playback Switch",
-       "Speaker Playback Switch",
-       "Front Playback Switch",
-       "Surround Playback Switch",
-       "CLFE Playback Switch",
+static const char * const slave_pfxs[] = {
+       "Headphone", "Speaker", "Front", "Surround", "CLFE",
        NULL
 };
 
@@ -519,14 +508,17 @@ static int conexant_build_controls(struct hda_codec *codec)
                snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
                                        HDA_OUTPUT, vmaster_tlv);
                err = snd_hda_add_vmaster(codec, "Master Playback Volume",
-                                         vmaster_tlv, slave_vols);
+                                         vmaster_tlv, slave_pfxs,
+                                         "Playback Volume");
                if (err < 0)
                        return err;
        }
        if (spec->vmaster_nid &&
            !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
-               err = snd_hda_add_vmaster(codec, "Master Playback Switch",
-                                         NULL, slave_sws);
+               err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
+                                           NULL, slave_pfxs,
+                                           "Playback Switch", true,
+                                           &spec->vmaster_mute.sw_kctl);
                if (err < 0)
                        return err;
        }
@@ -3034,7 +3026,6 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),
        SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
        SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO),
-       SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */
        SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO),
        {}
 };
@@ -3943,6 +3934,63 @@ static void enable_unsol_pins(struct hda_codec *codec, int num_pins,
                snd_hda_jack_detect_enable(codec, pins[i], action);
 }
 
+static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
+{
+       int i;
+       for (i = 0; i < nums; i++)
+               if (list[i] == nid)
+                       return true;
+       return false;
+}
+
+/* is the given NID found in any of autocfg items? */
+static bool found_in_autocfg(struct auto_pin_cfg *cfg, hda_nid_t nid)
+{
+       int i;
+
+       if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
+           found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
+           found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs) ||
+           found_in_nid_list(nid, cfg->dig_out_pins, cfg->dig_outs))
+               return true;
+       for (i = 0; i < cfg->num_inputs; i++)
+               if (cfg->inputs[i].pin == nid)
+                       return true;
+       if (cfg->dig_in_pin == nid)
+               return true;
+       return false;
+}
+
+/* clear unsol-event tags on unused pins; Conexant codecs seem to leave
+ * invalid unsol tags by some reason
+ */
+static void clear_unsol_on_unused_pins(struct hda_codec *codec)
+{
+       struct conexant_spec *spec = codec->spec;
+       struct auto_pin_cfg *cfg = &spec->autocfg;
+       int i;
+
+       for (i = 0; i < codec->init_pins.used; i++) {
+               struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
+               if (!found_in_autocfg(cfg, pin->nid))
+                       snd_hda_codec_write(codec, pin->nid, 0,
+                                           AC_VERB_SET_UNSOLICITED_ENABLE, 0);
+       }
+}
+
+/* turn on/off EAPD according to Master switch */
+static void cx_auto_vmaster_hook(void *private_data, int enabled)
+{
+       struct hda_codec *codec = private_data;
+       struct conexant_spec *spec = codec->spec;
+
+       if (enabled && spec->pin_eapd_ctrls) {
+               cx_auto_update_speakers(codec);
+               return;
+       }
+       cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled);
+}
+
 static void cx_auto_init_output(struct hda_codec *codec)
 {
        struct conexant_spec *spec = codec->spec;
@@ -3983,6 +4031,7 @@ static void cx_auto_init_output(struct hda_codec *codec)
        /* turn on all EAPDs if no individual EAPD control is available */
        if (!spec->pin_eapd_ctrls)
                cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
+       clear_unsol_on_unused_pins(codec);
 }
 
 static void cx_auto_init_input(struct hda_codec *codec)
@@ -4046,11 +4095,13 @@ static void cx_auto_init_digital(struct hda_codec *codec)
 
 static int cx_auto_init(struct hda_codec *codec)
 {
+       struct conexant_spec *spec = codec->spec;
        /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/
        cx_auto_init_output(codec);
        cx_auto_init_input(codec);
        cx_auto_init_digital(codec);
        snd_hda_jack_report_sync(codec);
+       snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
        return 0;
 }
 
@@ -4296,6 +4347,13 @@ static int cx_auto_build_controls(struct hda_codec *codec)
        err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
        if (err < 0)
                return err;
+       if (spec->vmaster_mute.sw_kctl) {
+               spec->vmaster_mute.hook = cx_auto_vmaster_hook;
+               err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute,
+                                              spec->vmaster_mute_led);
+               if (err < 0)
+                       return err;
+       }
        return 0;
 }
 
@@ -4320,7 +4378,6 @@ static int cx_auto_search_adcs(struct hda_codec *codec)
        return 0;
 }
 
-
 static const struct hda_codec_ops cx_auto_patch_ops = {
        .build_controls = cx_auto_build_controls,
        .build_pcms = conexant_build_pcms,
@@ -4368,6 +4425,7 @@ static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {
        { 0x16, 0x042140ff }, /* HP (seq# overridden) */
        { 0x17, 0x21a11000 }, /* dock-mic */
        { 0x19, 0x2121103f }, /* dock-HP */
+       { 0x1c, 0x21440100 }, /* dock SPDIF out */
        {}
 };
 
@@ -4421,6 +4479,18 @@ static int patch_conexant_auto(struct hda_codec *codec)
 
        apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
 
+       /* Show mute-led control only on HP laptops
+        * This is a sort of white-list: on HP laptops, EAPD corresponds
+        * only to the mute-LED without actualy amp function.  Meanwhile,
+        * others may use EAPD really as an amp switch, so it might be
+        * not good to expose it blindly.
+        */
+       switch (codec->subsystem_id >> 16) {
+       case 0x103c:
+               spec->vmaster_mute_led = 1;
+               break;
+       }
+
        err = cx_auto_search_adcs(codec);
        if (err < 0)
                return err;
@@ -4434,6 +4504,18 @@ static int patch_conexant_auto(struct hda_codec *codec)
        codec->patch_ops = cx_auto_patch_ops;
        if (spec->beep_amp)
                snd_hda_attach_beep_device(codec, spec->beep_amp);
+
+       /* Some laptops with Conexant chips show stalls in S3 resume,
+        * which falls into the single-cmd mode.
+        * Better to make reset, then.
+        */
+       if (!codec->bus->sync_write) {
+               snd_printd("hda_codec: "
+                          "Enable sync_write for stable communication\n");
+               codec->bus->sync_write = 1;
+               codec->bus->allow_bus_reset = 1;
+       }
+
        return 0;
 }
 
index 1168ebd3fb5c9cfe3bc964b9e223f45f3513c471..540cd13f7f15e4fd4ecd3a0ae3a114a16683b76d 100644 (file)
@@ -1912,6 +1912,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
 { .id = 0x80862804, .name = "IbexPeak HDMI",   .patch = patch_generic_hdmi },
 { .id = 0x80862805, .name = "CougarPoint HDMI",        .patch = patch_generic_hdmi },
 { .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi },
+{ .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi },
 { .id = 0x808629fb, .name = "Crestline HDMI",  .patch = patch_generic_hdmi },
 {} /* terminator */
 };
@@ -1958,6 +1959,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862803");
 MODULE_ALIAS("snd-hda-codec-id:80862804");
 MODULE_ALIAS("snd-hda-codec-id:80862805");
 MODULE_ALIAS("snd-hda-codec-id:80862806");
+MODULE_ALIAS("snd-hda-codec-id:80862880");
 MODULE_ALIAS("snd-hda-codec-id:808629fb");
 
 MODULE_LICENSE("GPL");
index 22c73b78ac6f193b635ef362c026bf51b8fe1da8..8ea2fd65432718411776151a9b034a1251c46a49 100644 (file)
@@ -198,8 +198,11 @@ struct alc_spec {
 
        /* for virtual master */
        hda_nid_t vmaster_nid;
+       struct hda_vmaster_mute_hook vmaster_mute;
 #ifdef CONFIG_SND_HDA_POWER_SAVE
        struct hda_loopback_check loopback;
+       int num_loopbacks;
+       struct hda_amp_list loopback_list[8];
 #endif
 
        /* for PLL fix */
@@ -220,8 +223,6 @@ struct alc_spec {
        struct snd_array bind_ctls;
 };
 
-#define ALC_MODEL_AUTO         0       /* common for all chips */
-
 static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid,
                           int dir, unsigned int bits)
 {
@@ -300,6 +301,9 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
        int i, type, num_conns;
        hda_nid_t nid;
 
+       if (!spec->input_mux)
+               return 0;
+
        mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
        imux = &spec->input_mux[mux_idx];
        if (!imux->num_items && mux_idx > 0)
@@ -651,15 +655,51 @@ static void alc_exec_unsol_event(struct hda_codec *codec, int action)
        snd_hda_jack_report_sync(codec);
 }
 
+/* update the master volume per volume-knob's unsol event */
+static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
+{
+       unsigned int val;
+       struct snd_kcontrol *kctl;
+       struct snd_ctl_elem_value *uctl;
+
+       kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
+       if (!kctl)
+               return;
+       uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
+       if (!uctl)
+               return;
+       val = snd_hda_codec_read(codec, nid, 0,
+                                AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
+       val &= HDA_AMP_VOLMASK;
+       uctl->value.integer.value[0] = val;
+       uctl->value.integer.value[1] = val;
+       kctl->put(kctl, uctl);
+       kfree(uctl);
+}
+
 /* unsolicited event for HP jack sensing */
 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
 {
+       int action;
+
        if (codec->vendor_id == 0x10ec0880)
                res >>= 28;
        else
                res >>= 26;
-       res = snd_hda_jack_get_action(codec, res);
-       alc_exec_unsol_event(codec, res);
+       action = snd_hda_jack_get_action(codec, res);
+       if (action == ALC_DCVOL_EVENT) {
+               /* Execute the dc-vol event here as it requires the NID
+                * but we don't pass NID to alc_exec_unsol_event().
+                * Once when we convert all static quirks to the auto-parser,
+                * this can be integerated into there.
+                */
+               struct hda_jack_tbl *jack;
+               jack = snd_hda_jack_tbl_get_from_tag(codec, res);
+               if (jack)
+                       alc_update_knob_master(codec, jack->nid);
+               return;
+       }
+       alc_exec_unsol_event(codec, action);
 }
 
 /* call init functions of standard auto-mute helpers */
@@ -1033,45 +1073,6 @@ static bool alc_check_dyn_adc_switch(struct hda_codec *codec)
        return true;
 }
 
-/* rebuild imux for matching with the given auto-mic pins (if not yet) */
-static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       struct hda_input_mux *imux;
-       static char * const texts[3] = {
-               "Mic", "Internal Mic", "Dock Mic"
-       };
-       int i;
-
-       if (!spec->auto_mic)
-               return false;
-       imux = &spec->private_imux[0];
-       if (spec->input_mux == imux)
-               return true;
-       spec->imux_pins[0] = spec->ext_mic_pin;
-       spec->imux_pins[1] = spec->int_mic_pin;
-       spec->imux_pins[2] = spec->dock_mic_pin;
-       for (i = 0; i < 3; i++) {
-               strcpy(imux->items[i].label, texts[i]);
-               if (spec->imux_pins[i]) {
-                       hda_nid_t pin = spec->imux_pins[i];
-                       int c;
-                       for (c = 0; c < spec->num_adc_nids; c++) {
-                               hda_nid_t cap = get_capsrc(spec, c);
-                               int idx = get_connection_index(codec, cap, pin);
-                               if (idx >= 0) {
-                                       imux->items[i].index = idx;
-                                       break;
-                               }
-                       }
-                       imux->num_items = i + 1;
-               }
-       }
-       spec->num_mux_defs = 1;
-       spec->input_mux = imux;
-       return true;
-}
-
 /* check whether all auto-mic pins are valid; setup indices if OK */
 static bool alc_auto_mic_check_imux(struct hda_codec *codec)
 {
@@ -1441,6 +1442,7 @@ enum {
        ALC_FIXUP_ACT_PRE_PROBE,
        ALC_FIXUP_ACT_PROBE,
        ALC_FIXUP_ACT_INIT,
+       ALC_FIXUP_ACT_BUILD,
 };
 
 static void alc_apply_fixup(struct hda_codec *codec, int action)
@@ -1520,6 +1522,13 @@ static void alc_pick_fixup(struct hda_codec *codec,
        int id = -1;
        const char *name = NULL;
 
+       /* when model=nofixup is given, don't pick up any fixups */
+       if (codec->modelname && !strcmp(codec->modelname, "nofixup")) {
+               spec->fixup_list = NULL;
+               spec->fixup_id = -1;
+               return;
+       }
+
        if (codec->modelname && models) {
                while (models->name) {
                        if (!strcmp(codec->modelname, models->name)) {
@@ -1847,36 +1856,10 @@ DEFINE_CAPMIX_NOSRC(3);
 /*
  * slave controls for virtual master
  */
-static const char * const alc_slave_vols[] = {
-       "Front Playback Volume",
-       "Surround Playback Volume",
-       "Center Playback Volume",
-       "LFE Playback Volume",
-       "Side Playback Volume",
-       "Headphone Playback Volume",
-       "Speaker Playback Volume",
-       "Mono Playback Volume",
-       "Line Out Playback Volume",
-       "CLFE Playback Volume",
-       "Bass Speaker Playback Volume",
-       "PCM Playback Volume",
-       NULL,
-};
-
-static const char * const alc_slave_sws[] = {
-       "Front Playback Switch",
-       "Surround Playback Switch",
-       "Center Playback Switch",
-       "LFE Playback Switch",
-       "Side Playback Switch",
-       "Headphone Playback Switch",
-       "Speaker Playback Switch",
-       "Mono Playback Switch",
-       "IEC958 Playback Switch",
-       "Line Out Playback Switch",
-       "CLFE Playback Switch",
-       "Bass Speaker Playback Switch",
-       "PCM Playback Switch",
+static const char * const alc_slave_pfxs[] = {
+       "Front", "Surround", "Center", "LFE", "Side",
+       "Headphone", "Speaker", "Mono", "Line Out",
+       "CLFE", "Bass Speaker", "PCM",
        NULL,
 };
 
@@ -1967,14 +1950,17 @@ static int __alc_build_controls(struct hda_codec *codec)
                snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
                                        HDA_OUTPUT, vmaster_tlv);
                err = snd_hda_add_vmaster(codec, "Master Playback Volume",
-                                         vmaster_tlv, alc_slave_vols);
+                                         vmaster_tlv, alc_slave_pfxs,
+                                         "Playback Volume");
                if (err < 0)
                        return err;
        }
        if (!spec->no_analog &&
            !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
-               err = snd_hda_add_vmaster(codec, "Master Playback Switch",
-                                         NULL, alc_slave_sws);
+               err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
+                                           NULL, alc_slave_pfxs,
+                                           "Playback Switch",
+                                           true, &spec->vmaster_mute.sw_kctl);
                if (err < 0)
                        return err;
        }
@@ -2059,7 +2045,11 @@ static int alc_build_controls(struct hda_codec *codec)
        int err = __alc_build_controls(codec);
        if (err < 0)
                return err;
-       return snd_hda_jack_add_kctls(codec, &spec->autocfg);
+       err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
+       if (err < 0)
+               return err;
+       alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD);
+       return 0;
 }
 
 
@@ -2068,15 +2058,15 @@ static int alc_build_controls(struct hda_codec *codec)
  */
 
 static void alc_init_special_input_src(struct hda_codec *codec);
-static int alc269_fill_coef(struct hda_codec *codec);
+static void alc_auto_init_std(struct hda_codec *codec);
 
 static int alc_init(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
        unsigned int i;
 
-       if (codec->vendor_id == 0x10ec0269)
-               alc269_fill_coef(codec);
+       if (spec->init_hook)
+               spec->init_hook(codec);
 
        alc_fix_pll(codec);
        alc_auto_init_amp(codec, spec->init_amp);
@@ -2084,9 +2074,7 @@ static int alc_init(struct hda_codec *codec)
        for (i = 0; i < spec->num_init_verbs; i++)
                snd_hda_sequence_write(codec, spec->init_verbs[i]);
        alc_init_special_input_src(codec);
-
-       if (spec->init_hook)
-               spec->init_hook(codec);
+       alc_auto_init_std(codec);
 
        alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
 
@@ -2675,6 +2663,25 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
        return channel_name[ch];
 }
 
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+/* add the powersave loopback-list entry */
+static void add_loopback_list(struct alc_spec *spec, hda_nid_t mix, int idx)
+{
+       struct hda_amp_list *list;
+
+       if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1)
+               return;
+       list = spec->loopback_list + spec->num_loopbacks;
+       list->nid = mix;
+       list->dir = HDA_INPUT;
+       list->idx = idx;
+       spec->num_loopbacks++;
+       spec->loopback.amplist = spec->loopback_list;
+}
+#else
+#define add_loopback_list(spec, mix, idx) /* NOP */
+#endif
+
 /* create input playback/capture controls for the given pin */
 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
                            const char *ctlname, int ctlidx,
@@ -2690,6 +2697,7 @@ static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
                          HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
        if (err < 0)
                return err;
+       add_loopback_list(spec, mix_nid, idx);
        return 0;
 }
 
@@ -2954,10 +2962,27 @@ static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
        return 0;
 }
 
+static bool alc_is_dac_already_used(struct hda_codec *codec, hda_nid_t nid)
+{
+       struct alc_spec *spec = codec->spec;
+       int i;
+       if (found_in_nid_list(nid, spec->multiout.dac_nids,
+                             ARRAY_SIZE(spec->private_dac_nids)) ||
+           found_in_nid_list(nid, spec->multiout.hp_out_nid,
+                             ARRAY_SIZE(spec->multiout.hp_out_nid)) ||
+           found_in_nid_list(nid, spec->multiout.extra_out_nid,
+                             ARRAY_SIZE(spec->multiout.extra_out_nid)))
+               return true;
+       for (i = 0; i < spec->multi_ios; i++) {
+               if (spec->multi_io[i].dac == nid)
+                       return true;
+       }
+       return false;
+}
+
 /* look for an empty DAC slot */
 static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
 {
-       struct alc_spec *spec = codec->spec;
        hda_nid_t srcs[5];
        int i, num;
 
@@ -2967,16 +2992,8 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
                hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
                if (!nid)
                        continue;
-               if (found_in_nid_list(nid, spec->multiout.dac_nids,
-                                     ARRAY_SIZE(spec->private_dac_nids)))
-                       continue;
-               if (found_in_nid_list(nid, spec->multiout.hp_out_nid,
-                                     ARRAY_SIZE(spec->multiout.hp_out_nid)))
-                   continue;
-               if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
-                                     ARRAY_SIZE(spec->multiout.extra_out_nid)))
-                   continue;
-               return nid;
+               if (!alc_is_dac_already_used(codec, nid))
+                       return nid;
        }
        return 0;
 }
@@ -2988,6 +3005,8 @@ static bool alc_auto_is_dac_reachable(struct hda_codec *codec,
        hda_nid_t srcs[5];
        int i, num;
 
+       if (!pin || !dac)
+               return false;
        pin = alc_go_down_to_selector(codec, pin);
        num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
        for (i = 0; i < num; i++) {
@@ -3000,83 +3019,260 @@ static bool alc_auto_is_dac_reachable(struct hda_codec *codec,
 
 static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
 {
+       struct alc_spec *spec = codec->spec;
        hda_nid_t sel = alc_go_down_to_selector(codec, pin);
-       if (snd_hda_get_conn_list(codec, sel, NULL) == 1)
+       hda_nid_t nid, nid_found, srcs[5];
+       int i, num = snd_hda_get_connections(codec, sel, srcs,
+                                         ARRAY_SIZE(srcs));
+       if (num == 1)
                return alc_auto_look_for_dac(codec, pin);
-       return 0;
+       nid_found = 0;
+       for (i = 0; i < num; i++) {
+               if (srcs[i] == spec->mixer_nid)
+                       continue;
+               nid = alc_auto_mix_to_dac(codec, srcs[i]);
+               if (nid && !alc_is_dac_already_used(codec, nid)) {
+                       if (nid_found)
+                               return 0;
+                       nid_found = nid;
+               }
+       }
+       return nid_found;
 }
 
-/* return 0 if no possible DAC is found, 1 if one or more found */
-static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs,
-                                   const hda_nid_t *pins, hda_nid_t *dacs)
+/* mark up volume and mute control NIDs: used during badness parsing and
+ * at creating actual controls
+ */
+static inline unsigned int get_ctl_pos(unsigned int data)
 {
-       int i;
+       hda_nid_t nid = get_amp_nid_(data);
+       unsigned int dir;
+       if (snd_BUG_ON(nid >= MAX_VOL_NIDS))
+               return 0;
+       dir = get_amp_direction_(data);
+       return (nid << 1) | dir;
+}
 
-       if (num_outs && !dacs[0]) {
-               dacs[0] = alc_auto_look_for_dac(codec, pins[0]);
-               if (!dacs[0])
-                       return 0;
-       }
+#define is_ctl_used(bits, data) \
+       test_bit(get_ctl_pos(data), bits)
+#define mark_ctl_usage(bits, data) \
+       set_bit(get_ctl_pos(data), bits)
 
-       for (i = 1; i < num_outs; i++)
-               dacs[i] = get_dac_if_single(codec, pins[i]);
-       for (i = 1; i < num_outs; i++) {
+static void clear_vol_marks(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       memset(spec->vol_ctls, 0, sizeof(spec->vol_ctls));
+       memset(spec->sw_ctls, 0, sizeof(spec->sw_ctls));
+}
+
+/* badness definition */
+enum {
+       /* No primary DAC is found for the main output */
+       BAD_NO_PRIMARY_DAC = 0x10000,
+       /* No DAC is found for the extra output */
+       BAD_NO_DAC = 0x4000,
+       /* No possible multi-ios */
+       BAD_MULTI_IO = 0x103,
+       /* No individual DAC for extra output */
+       BAD_NO_EXTRA_DAC = 0x102,
+       /* No individual DAC for extra surrounds */
+       BAD_NO_EXTRA_SURR_DAC = 0x101,
+       /* Primary DAC shared with main surrounds */
+       BAD_SHARED_SURROUND = 0x100,
+       /* Primary DAC shared with main CLFE */
+       BAD_SHARED_CLFE = 0x10,
+       /* Primary DAC shared with extra surrounds */
+       BAD_SHARED_EXTRA_SURROUND = 0x10,
+       /* Volume widget is shared */
+       BAD_SHARED_VOL = 0x10,
+};
+
+static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec,
+                                          hda_nid_t pin, hda_nid_t dac);
+static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
+                                         hda_nid_t pin, hda_nid_t dac);
+
+static int eval_shared_vol_badness(struct hda_codec *codec, hda_nid_t pin,
+                                  hda_nid_t dac)
+{
+       struct alc_spec *spec = codec->spec;
+       hda_nid_t nid;
+       unsigned int val;
+       int badness = 0;
+
+       nid = alc_look_for_out_vol_nid(codec, pin, dac);
+       if (nid) {
+               val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
+               if (is_ctl_used(spec->vol_ctls, nid))
+                       badness += BAD_SHARED_VOL;
+               else
+                       mark_ctl_usage(spec->vol_ctls, val);
+       } else
+               badness += BAD_SHARED_VOL;
+       nid = alc_look_for_out_mute_nid(codec, pin, dac);
+       if (nid) {
+               unsigned int wid_type = get_wcaps_type(get_wcaps(codec, nid));
+               if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT)
+                       val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
+               else
+                       val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT);
+               if (is_ctl_used(spec->sw_ctls, val))
+                       badness += BAD_SHARED_VOL;
+               else
+                       mark_ctl_usage(spec->sw_ctls, val);
+       } else
+               badness += BAD_SHARED_VOL;
+       return badness;
+}
+
+struct badness_table {
+       int no_primary_dac;     /* no primary DAC */
+       int no_dac;             /* no secondary DACs */
+       int shared_primary;     /* primary DAC is shared with main output */
+       int shared_surr;        /* secondary DAC shared with main or primary */
+       int shared_clfe;        /* third DAC shared with main or primary */
+       int shared_surr_main;   /* secondary DAC sahred with main/DAC0 */
+};
+
+static struct badness_table main_out_badness = {
+       .no_primary_dac = BAD_NO_PRIMARY_DAC,
+       .no_dac = BAD_NO_DAC,
+       .shared_primary = BAD_NO_PRIMARY_DAC,
+       .shared_surr = BAD_SHARED_SURROUND,
+       .shared_clfe = BAD_SHARED_CLFE,
+       .shared_surr_main = BAD_SHARED_SURROUND,
+};
+
+static struct badness_table extra_out_badness = {
+       .no_primary_dac = BAD_NO_DAC,
+       .no_dac = BAD_NO_DAC,
+       .shared_primary = BAD_NO_EXTRA_DAC,
+       .shared_surr = BAD_SHARED_EXTRA_SURROUND,
+       .shared_clfe = BAD_SHARED_EXTRA_SURROUND,
+       .shared_surr_main = BAD_NO_EXTRA_SURR_DAC,
+};
+
+/* try to assign DACs to pins and return the resultant badness */
+static int alc_auto_fill_dacs(struct hda_codec *codec, int num_outs,
+                             const hda_nid_t *pins, hda_nid_t *dacs,
+                             const struct badness_table *bad)
+{
+       struct alc_spec *spec = codec->spec;
+       struct auto_pin_cfg *cfg = &spec->autocfg;
+       int i, j;
+       int badness = 0;
+       hda_nid_t dac;
+
+       if (!num_outs)
+               return 0;
+
+       for (i = 0; i < num_outs; i++) {
+               hda_nid_t pin = pins[i];
                if (!dacs[i])
-                       dacs[i] = alc_auto_look_for_dac(codec, pins[i]);
+                       dacs[i] = alc_auto_look_for_dac(codec, pin);
+               if (!dacs[i] && !i) {
+                       for (j = 1; j < num_outs; j++) {
+                               if (alc_auto_is_dac_reachable(codec, pin, dacs[j])) {
+                                       dacs[0] = dacs[j];
+                                       dacs[j] = 0;
+                                       break;
+                               }
+                       }
+               }
+               dac = dacs[i];
+               if (!dac) {
+                       if (alc_auto_is_dac_reachable(codec, pin, dacs[0]))
+                               dac = dacs[0];
+                       else if (cfg->line_outs > i &&
+                                alc_auto_is_dac_reachable(codec, pin,
+                                       spec->private_dac_nids[i]))
+                               dac = spec->private_dac_nids[i];
+                       if (dac) {
+                               if (!i)
+                                       badness += bad->shared_primary;
+                               else if (i == 1)
+                                       badness += bad->shared_surr;
+                               else
+                                       badness += bad->shared_clfe;
+                       } else if (alc_auto_is_dac_reachable(codec, pin,
+                                       spec->private_dac_nids[0])) {
+                               dac = spec->private_dac_nids[0];
+                               badness += bad->shared_surr_main;
+                       } else if (!i)
+                               badness += bad->no_primary_dac;
+                       else
+                               badness += bad->no_dac;
+               }
+               if (dac)
+                       badness += eval_shared_vol_badness(codec, pin, dac);
        }
-       return 1;
+
+       return badness;
 }
 
 static int alc_auto_fill_multi_ios(struct hda_codec *codec,
-                                  unsigned int location, int offset);
-static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
-                                         hda_nid_t pin, hda_nid_t dac);
+                                  hda_nid_t reference_pin,
+                                  bool hardwired, int offset);
+
+static bool alc_map_singles(struct hda_codec *codec, int outs,
+                           const hda_nid_t *pins, hda_nid_t *dacs)
+{
+       int i;
+       bool found = false;
+       for (i = 0; i < outs; i++) {
+               if (dacs[i])
+                       continue;
+               dacs[i] = get_dac_if_single(codec, pins[i]);
+               if (dacs[i])
+                       found = true;
+       }
+       return found;
+}
 
 /* fill in the dac_nids table from the parsed pin configuration */
-static int alc_auto_fill_dac_nids(struct hda_codec *codec)
+static int fill_and_eval_dacs(struct hda_codec *codec,
+                             bool fill_hardwired,
+                             bool fill_mio_first)
 {
        struct alc_spec *spec = codec->spec;
        struct auto_pin_cfg *cfg = &spec->autocfg;
-       unsigned int location, defcfg;
-       int num_pins;
-       bool redone = false;
-       int i;
+       int i, err, badness;
 
- again:
        /* set num_dacs once to full for alc_auto_look_for_dac() */
        spec->multiout.num_dacs = cfg->line_outs;
-       spec->multiout.hp_out_nid[0] = 0;
-       spec->multiout.extra_out_nid[0] = 0;
-       memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
        spec->multiout.dac_nids = spec->private_dac_nids;
+       memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
+       memset(spec->multiout.hp_out_nid, 0, sizeof(spec->multiout.hp_out_nid));
+       memset(spec->multiout.extra_out_nid, 0, sizeof(spec->multiout.extra_out_nid));
        spec->multi_ios = 0;
+       clear_vol_marks(codec);
+       badness = 0;
 
        /* fill hard-wired DACs first */
-       if (!redone) {
-               for (i = 0; i < cfg->line_outs; i++)
-                       spec->private_dac_nids[i] =
-                               get_dac_if_single(codec, cfg->line_out_pins[i]);
-               if (cfg->hp_outs)
-                       spec->multiout.hp_out_nid[0] =
-                               get_dac_if_single(codec, cfg->hp_pins[0]);
-               if (cfg->speaker_outs)
-                       spec->multiout.extra_out_nid[0] =
-                               get_dac_if_single(codec, cfg->speaker_pins[0]);
+       if (fill_hardwired) {
+               bool mapped;
+               do {
+                       mapped = alc_map_singles(codec, cfg->line_outs,
+                                                cfg->line_out_pins,
+                                                spec->private_dac_nids);
+                       mapped |= alc_map_singles(codec, cfg->hp_outs,
+                                                 cfg->hp_pins,
+                                                 spec->multiout.hp_out_nid);
+                       mapped |= alc_map_singles(codec, cfg->speaker_outs,
+                                                 cfg->speaker_pins,
+                                                 spec->multiout.extra_out_nid);
+                       if (fill_mio_first && cfg->line_outs == 1 &&
+                           cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
+                               err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], true, 0);
+                               if (!err)
+                                       mapped = true;
+                       }
+               } while (mapped);
        }
 
-       for (i = 0; i < cfg->line_outs; i++) {
-               hda_nid_t pin = cfg->line_out_pins[i];
-               if (spec->private_dac_nids[i])
-                       continue;
-               spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
-               if (!spec->private_dac_nids[i] && !redone) {
-                       /* if we can't find primary DACs, re-probe without
-                        * checking the hard-wired DACs
-                        */
-                       redone = true;
-                       goto again;
-               }
-       }
+       badness += alc_auto_fill_dacs(codec, cfg->line_outs, cfg->line_out_pins,
+                                     spec->private_dac_nids,
+                                     &main_out_badness);
 
        /* re-count num_dacs and squash invalid entries */
        spec->multiout.num_dacs = 0;
@@ -3091,30 +3287,144 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
                }
        }
 
-       if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
+       if (fill_mio_first &&
+           cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
                /* try to fill multi-io first */
-               defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
-               location = get_defcfg_location(defcfg);
-
-               num_pins = alc_auto_fill_multi_ios(codec, location, 0);
-               if (num_pins > 0) {
-                       spec->multi_ios = num_pins;
-                       spec->ext_channel_count = 2;
-                       spec->multiout.num_dacs = num_pins + 1;
-               }
+               err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0);
+               if (err < 0)
+                       return err;
+               /* we don't count badness at this stage yet */
        }
 
-       if (cfg->line_out_type != AUTO_PIN_HP_OUT)
-               alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins,
-                                spec->multiout.hp_out_nid);
+       if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
+               err = alc_auto_fill_dacs(codec, cfg->hp_outs, cfg->hp_pins,
+                                        spec->multiout.hp_out_nid,
+                                        &extra_out_badness);
+               if (err < 0)
+                       return err;
+               badness += err;
+       }
        if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
-               int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs,
-                                       cfg->speaker_pins,
-                                       spec->multiout.extra_out_nid);
-               /* if no speaker volume is assigned, try again as the primary
-                * output
-                */
-               if (!err && cfg->speaker_outs > 0 &&
+               err = alc_auto_fill_dacs(codec, cfg->speaker_outs,
+                                        cfg->speaker_pins,
+                                        spec->multiout.extra_out_nid,
+                                        &extra_out_badness);
+               if (err < 0)
+                       return err;
+               badness += err;
+       }
+       if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
+               err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0);
+               if (err < 0)
+                       return err;
+               badness += err;
+       }
+       if (cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
+               /* try multi-ios with HP + inputs */
+               int offset = 0;
+               if (cfg->line_outs >= 3)
+                       offset = 1;
+               err = alc_auto_fill_multi_ios(codec, cfg->hp_pins[0], false,
+                                             offset);
+               if (err < 0)
+                       return err;
+               badness += err;
+       }
+
+       if (spec->multi_ios == 2) {
+               for (i = 0; i < 2; i++)
+                       spec->private_dac_nids[spec->multiout.num_dacs++] =
+                               spec->multi_io[i].dac;
+               spec->ext_channel_count = 2;
+       } else if (spec->multi_ios) {
+               spec->multi_ios = 0;
+               badness += BAD_MULTI_IO;
+       }
+
+       return badness;
+}
+
+#define DEBUG_BADNESS
+
+#ifdef DEBUG_BADNESS
+#define debug_badness  snd_printdd
+#else
+#define debug_badness(...)
+#endif
+
+static void debug_show_configs(struct alc_spec *spec, struct auto_pin_cfg *cfg)
+{
+       debug_badness("multi_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
+                     cfg->line_out_pins[0], cfg->line_out_pins[1],
+                     cfg->line_out_pins[2], cfg->line_out_pins[2],
+                     spec->multiout.dac_nids[0],
+                     spec->multiout.dac_nids[1],
+                     spec->multiout.dac_nids[2],
+                     spec->multiout.dac_nids[3]);
+       if (spec->multi_ios > 0)
+               debug_badness("multi_ios(%d) = %x/%x : %x/%x\n",
+                             spec->multi_ios,
+                             spec->multi_io[0].pin, spec->multi_io[1].pin,
+                             spec->multi_io[0].dac, spec->multi_io[1].dac);
+       debug_badness("hp_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
+                     cfg->hp_pins[0], cfg->hp_pins[1],
+                     cfg->hp_pins[2], cfg->hp_pins[2],
+                     spec->multiout.hp_out_nid[0],
+                     spec->multiout.hp_out_nid[1],
+                     spec->multiout.hp_out_nid[2],
+                     spec->multiout.hp_out_nid[3]);
+       debug_badness("spk_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
+                     cfg->speaker_pins[0], cfg->speaker_pins[1],
+                     cfg->speaker_pins[2], cfg->speaker_pins[3],
+                     spec->multiout.extra_out_nid[0],
+                     spec->multiout.extra_out_nid[1],
+                     spec->multiout.extra_out_nid[2],
+                     spec->multiout.extra_out_nid[3]);
+}
+
+static int alc_auto_fill_dac_nids(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       struct auto_pin_cfg *cfg = &spec->autocfg;
+       struct auto_pin_cfg *best_cfg;
+       int best_badness = INT_MAX;
+       int badness;
+       bool fill_hardwired = true, fill_mio_first = true;
+       bool best_wired = true, best_mio = true;
+       bool hp_spk_swapped = false;
+
+       best_cfg = kmalloc(sizeof(*best_cfg), GFP_KERNEL);
+       if (!best_cfg)
+               return -ENOMEM;
+       *best_cfg = *cfg;
+
+       for (;;) {
+               badness = fill_and_eval_dacs(codec, fill_hardwired,
+                                            fill_mio_first);
+               if (badness < 0)
+                       return badness;
+               debug_badness("==> lo_type=%d, wired=%d, mio=%d, badness=0x%x\n",
+                             cfg->line_out_type, fill_hardwired, fill_mio_first,
+                             badness);
+               debug_show_configs(spec, cfg);
+               if (badness < best_badness) {
+                       best_badness = badness;
+                       *best_cfg = *cfg;
+                       best_wired = fill_hardwired;
+                       best_mio = fill_mio_first;
+               }
+               if (!badness)
+                       break;
+               fill_mio_first = !fill_mio_first;
+               if (!fill_mio_first)
+                       continue;
+               fill_hardwired = !fill_hardwired;
+               if (!fill_hardwired)
+                       continue;
+               if (hp_spk_swapped)
+                       break;
+               hp_spk_swapped = true;
+               if (cfg->speaker_outs > 0 &&
                    cfg->line_out_type == AUTO_PIN_HP_OUT) {
                        cfg->hp_outs = cfg->line_outs;
                        memcpy(cfg->hp_pins, cfg->line_out_pins,
@@ -3125,48 +3435,45 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
                        cfg->speaker_outs = 0;
                        memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
                        cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
-                       redone = false;
-                       goto again;
-               }
+                       fill_hardwired = true;
+                       continue;
+               } 
+               if (cfg->hp_outs > 0 &&
+                   cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
+                       cfg->speaker_outs = cfg->line_outs;
+                       memcpy(cfg->speaker_pins, cfg->line_out_pins,
+                              sizeof(cfg->speaker_pins));
+                       cfg->line_outs = cfg->hp_outs;
+                       memcpy(cfg->line_out_pins, cfg->hp_pins,
+                              sizeof(cfg->hp_pins));
+                       cfg->hp_outs = 0;
+                       memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
+                       cfg->line_out_type = AUTO_PIN_HP_OUT;
+                       fill_hardwired = true;
+                       continue;
+               } 
+               break;
        }
 
-       if (!spec->multi_ios &&
-           cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
-           cfg->hp_outs) {
-               /* try multi-ios with HP + inputs */
-               defcfg = snd_hda_codec_get_pincfg(codec, cfg->hp_pins[0]);
-               location = get_defcfg_location(defcfg);
-
-               num_pins = alc_auto_fill_multi_ios(codec, location, 1);
-               if (num_pins > 0) {
-                       spec->multi_ios = num_pins;
-                       spec->ext_channel_count = 2;
-                       spec->multiout.num_dacs = num_pins + 1;
-               }
+       if (badness) {
+               *cfg = *best_cfg;
+               fill_and_eval_dacs(codec, best_wired, best_mio);
        }
+       debug_badness("==> Best config: lo_type=%d, wired=%d, mio=%d\n",
+                     cfg->line_out_type, best_wired, best_mio);
+       debug_show_configs(spec, cfg);
 
        if (cfg->line_out_pins[0])
                spec->vmaster_nid =
                        alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0],
                                                 spec->multiout.dac_nids[0]);
-       return 0;
-}
 
-static inline unsigned int get_ctl_pos(unsigned int data)
-{
-       hda_nid_t nid = get_amp_nid_(data);
-       unsigned int dir;
-       if (snd_BUG_ON(nid >= MAX_VOL_NIDS))
-               return 0;
-       dir = get_amp_direction_(data);
-       return (nid << 1) | dir;
+       /* clear the bitmap flags for creating controls */
+       clear_vol_marks(codec);
+       kfree(best_cfg);
+       return 0;
 }
 
-#define is_ctl_used(bits, data) \
-       test_bit(get_ctl_pos(data), bits)
-#define mark_ctl_usage(bits, data) \
-       set_bit(get_ctl_pos(data), bits)
-
 static int alc_auto_add_vol_ctl(struct hda_codec *codec,
                              const char *pfx, int cidx,
                              hda_nid_t nid, unsigned int chs)
@@ -3278,14 +3585,17 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
                dac = spec->multiout.dac_nids[i];
                if (!dac)
                        continue;
-               if (i >= cfg->line_outs)
+               if (i >= cfg->line_outs) {
                        pin = spec->multi_io[i - 1].pin;
-               else
+                       index = 0;
+                       name = channel_name[i];
+               } else {
                        pin = cfg->line_out_pins[i];
+                       name = alc_get_line_out_pfx(spec, i, true, &index);
+               }
 
                sw = alc_look_for_out_mute_nid(codec, pin, dac);
                vol = alc_look_for_out_vol_nid(codec, pin, dac);
-               name = alc_get_line_out_pfx(spec, i, true, &index);
                if (!name || !strcmp(name, "CLFE")) {
                        /* Center/LFE */
                        err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1);
@@ -3382,41 +3692,31 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
                return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0);
        }
 
-       if (dacs[num_pins - 1]) {
-               /* OK, we have a multi-output system with individual volumes */
-               for (i = 0; i < num_pins; i++) {
-                       if (num_pins >= 3) {
-                               snprintf(name, sizeof(name), "%s %s",
-                                        pfx, channel_name[i]);
-                               err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
-                                                               name, 0);
-                       } else {
-                               err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
-                                                               pfx, i);
-                       }
-                       if (err < 0)
-                               return err;
-               }
-               return 0;
-       }
-
-       /* Let's create a bind-controls */
-       ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_sw);
-       if (!ctl)
-               return -ENOMEM;
-       n = 0;
        for (i = 0; i < num_pins; i++) {
-               if (get_wcaps(codec, pins[i]) & AC_WCAP_OUT_AMP)
-                       ctl->values[n++] =
-                               HDA_COMPOSE_AMP_VAL(pins[i], 3, 0, HDA_OUTPUT);
-       }
-       if (n) {
-               snprintf(name, sizeof(name), "%s Playback Switch", pfx);
-               err = add_control(spec, ALC_CTL_BIND_SW, name, 0, (long)ctl);
+               hda_nid_t dac;
+               if (dacs[num_pins - 1])
+                       dac = dacs[i]; /* with individual volumes */
+               else
+                       dac = 0;
+               if (num_pins == 2 && i == 1 && !strcmp(pfx, "Speaker")) {
+                       err = alc_auto_create_extra_out(codec, pins[i], dac,
+                                                       "Bass Speaker", 0);
+               } else if (num_pins >= 3) {
+                       snprintf(name, sizeof(name), "%s %s",
+                                pfx, channel_name[i]);
+                       err = alc_auto_create_extra_out(codec, pins[i], dac,
+                                                       name, 0);
+               } else {
+                       err = alc_auto_create_extra_out(codec, pins[i], dac,
+                                                       pfx, i);
+               }
                if (err < 0)
                        return err;
        }
+       if (dacs[num_pins - 1])
+               return 0;
 
+       /* Let's create a bind-controls for volumes */
        ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol);
        if (!ctl)
                return -ENOMEM;
@@ -3552,58 +3852,111 @@ static void alc_auto_init_extra_out(struct hda_codec *codec)
        }
 }
 
+/* check whether the given pin can be a multi-io pin */
+static bool can_be_multiio_pin(struct hda_codec *codec,
+                              unsigned int location, hda_nid_t nid)
+{
+       unsigned int defcfg, caps;
+
+       defcfg = snd_hda_codec_get_pincfg(codec, nid);
+       if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
+               return false;
+       if (location && get_defcfg_location(defcfg) != location)
+               return false;
+       caps = snd_hda_query_pin_caps(codec, nid);
+       if (!(caps & AC_PINCAP_OUT))
+               return false;
+       return true;
+}
+
 /*
  * multi-io helper
+ *
+ * When hardwired is set, try to fill ony hardwired pins, and returns
+ * zero if any pins are filled, non-zero if nothing found.
+ * When hardwired is off, try to fill possible input pins, and returns
+ * the badness value.
  */
 static int alc_auto_fill_multi_ios(struct hda_codec *codec,
-                                  unsigned int location,
-                                  int offset)
+                                  hda_nid_t reference_pin,
+                                  bool hardwired, int offset)
 {
        struct alc_spec *spec = codec->spec;
        struct auto_pin_cfg *cfg = &spec->autocfg;
-       hda_nid_t prime_dac = spec->private_dac_nids[0];
-       int type, i, dacs, num_pins = 0;
+       int type, i, j, dacs, num_pins, old_pins;
+       unsigned int defcfg = snd_hda_codec_get_pincfg(codec, reference_pin);
+       unsigned int location = get_defcfg_location(defcfg);
+       int badness = 0;
 
-       dacs = spec->multiout.num_dacs;
+       old_pins = spec->multi_ios;
+       if (old_pins >= 2)
+               goto end_fill;
+
+       num_pins = 0;
        for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
                for (i = 0; i < cfg->num_inputs; i++) {
-                       hda_nid_t nid = cfg->inputs[i].pin;
-                       hda_nid_t dac = 0;
-                       unsigned int defcfg, caps;
                        if (cfg->inputs[i].type != type)
                                continue;
-                       defcfg = snd_hda_codec_get_pincfg(codec, nid);
-                       if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
+                       if (can_be_multiio_pin(codec, location,
+                                              cfg->inputs[i].pin))
+                               num_pins++;
+               }
+       }
+       if (num_pins < 2)
+               goto end_fill;
+
+       dacs = spec->multiout.num_dacs;
+       for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
+               for (i = 0; i < cfg->num_inputs; i++) {
+                       hda_nid_t nid = cfg->inputs[i].pin;
+                       hda_nid_t dac = 0;
+
+                       if (cfg->inputs[i].type != type)
                                continue;
-                       if (location && get_defcfg_location(defcfg) != location)
+                       if (!can_be_multiio_pin(codec, location, nid))
                                continue;
-                       caps = snd_hda_query_pin_caps(codec, nid);
-                       if (!(caps & AC_PINCAP_OUT))
+                       for (j = 0; j < spec->multi_ios; j++) {
+                               if (nid == spec->multi_io[j].pin)
+                                       break;
+                       }
+                       if (j < spec->multi_ios)
                                continue;
-                       if (offset && offset + num_pins < dacs) {
-                               dac = spec->private_dac_nids[offset + num_pins];
+
+                       if (offset && offset + spec->multi_ios < dacs) {
+                               dac = spec->private_dac_nids[offset + spec->multi_ios];
                                if (!alc_auto_is_dac_reachable(codec, nid, dac))
                                        dac = 0;
                        }
-                       if (!dac)
+                       if (hardwired)
+                               dac = get_dac_if_single(codec, nid);
+                       else if (!dac)
                                dac = alc_auto_look_for_dac(codec, nid);
-                       if (!dac)
+                       if (!dac) {
+                               badness++;
                                continue;
-                       spec->multi_io[num_pins].pin = nid;
-                       spec->multi_io[num_pins].dac = dac;
-                       num_pins++;
-                       spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
+                       }
+                       spec->multi_io[spec->multi_ios].pin = nid;
+                       spec->multi_io[spec->multi_ios].dac = dac;
+                       spec->multi_ios++;
+                       if (spec->multi_ios >= 2)
+                               break;
                }
        }
-       spec->multiout.num_dacs = dacs;
-       if (num_pins < 2) {
-               /* clear up again */
-               memset(spec->private_dac_nids + dacs, 0,
-                      sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - dacs));
-               spec->private_dac_nids[0] = prime_dac;
-               return 0;
+ end_fill:
+       if (badness)
+               badness = BAD_MULTI_IO;
+       if (old_pins == spec->multi_ios) {
+               if (hardwired)
+                       return 1; /* nothing found */
+               else
+                       return badness; /* no badness if nothing found */
+       }
+       if (!hardwired && spec->multi_ios < 2) {
+               spec->multi_ios = old_pins;
+               return badness;
        }
-       return num_pins;
+
+       return 0;
 }
 
 static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
@@ -3958,6 +4311,7 @@ static const struct snd_pci_quirk beep_white_list[] = {
        SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
        SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
        SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
+       SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
        SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
        {}
 };
@@ -4057,6 +4411,9 @@ static int alc_parse_auto_config(struct hda_codec *codec,
        if (spec->kctls.list)
                add_mixer(spec, spec->kctls.list);
 
+       if (!spec->no_analog && !spec->cap_mixer)
+               set_capture_mixer(codec);
+
        return 1;
 }
 
@@ -4067,26 +4424,47 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
        return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static const struct hda_amp_list alc880_loopbacks[] = {
-       { 0x0b, HDA_INPUT, 0 },
-       { 0x0b, HDA_INPUT, 1 },
-       { 0x0b, HDA_INPUT, 2 },
-       { 0x0b, HDA_INPUT, 3 },
-       { 0x0b, HDA_INPUT, 4 },
-       { } /* end */
-};
-#endif
-
 /*
  * ALC880 fix-ups
  */
 enum {
+       ALC880_FIXUP_GPIO1,
        ALC880_FIXUP_GPIO2,
        ALC880_FIXUP_MEDION_RIM,
+       ALC880_FIXUP_LG,
+       ALC880_FIXUP_W810,
+       ALC880_FIXUP_EAPD_COEF,
+       ALC880_FIXUP_TCL_S700,
+       ALC880_FIXUP_VOL_KNOB,
+       ALC880_FIXUP_FUJITSU,
+       ALC880_FIXUP_F1734,
+       ALC880_FIXUP_UNIWILL,
+       ALC880_FIXUP_UNIWILL_DIG,
+       ALC880_FIXUP_Z71V,
+       ALC880_FIXUP_3ST_BASE,
+       ALC880_FIXUP_3ST,
+       ALC880_FIXUP_3ST_DIG,
+       ALC880_FIXUP_5ST_BASE,
+       ALC880_FIXUP_5ST,
+       ALC880_FIXUP_5ST_DIG,
+       ALC880_FIXUP_6ST_BASE,
+       ALC880_FIXUP_6ST,
+       ALC880_FIXUP_6ST_DIG,
 };
 
+/* enable the volume-knob widget support on NID 0x21 */
+static void alc880_fixup_vol_knob(struct hda_codec *codec,
+                                 const struct alc_fixup *fix, int action)
+{
+       if (action == ALC_FIXUP_ACT_PROBE)
+               snd_hda_jack_detect_enable(codec, 0x21, ALC_DCVOL_EVENT);
+}
+
 static const struct alc_fixup alc880_fixups[] = {
+       [ALC880_FIXUP_GPIO1] = {
+               .type = ALC_FIXUP_VERBS,
+               .v.verbs = alc_gpio1_init_verbs,
+       },
        [ALC880_FIXUP_GPIO2] = {
                .type = ALC_FIXUP_VERBS,
                .v.verbs = alc_gpio2_init_verbs,
@@ -4101,40 +4479,323 @@ static const struct alc_fixup alc880_fixups[] = {
                .chained = true,
                .chain_id = ALC880_FIXUP_GPIO2,
        },
+       [ALC880_FIXUP_LG] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       /* disable bogus unused pins */
+                       { 0x16, 0x411111f0 },
+                       { 0x18, 0x411111f0 },
+                       { 0x1a, 0x411111f0 },
+                       { }
+               }
+       },
+       [ALC880_FIXUP_W810] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       /* disable bogus unused pins */
+                       { 0x17, 0x411111f0 },
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC880_FIXUP_GPIO2,
+       },
+       [ALC880_FIXUP_EAPD_COEF] = {
+               .type = ALC_FIXUP_VERBS,
+               .v.verbs = (const struct hda_verb[]) {
+                       /* change to EAPD mode */
+                       { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
+                       { 0x20, AC_VERB_SET_PROC_COEF,  0x3060 },
+                       {}
+               },
+       },
+       [ALC880_FIXUP_TCL_S700] = {
+               .type = ALC_FIXUP_VERBS,
+               .v.verbs = (const struct hda_verb[]) {
+                       /* change to EAPD mode */
+                       { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
+                       { 0x20, AC_VERB_SET_PROC_COEF,  0x3070 },
+                       {}
+               },
+               .chained = true,
+               .chain_id = ALC880_FIXUP_GPIO2,
+       },
+       [ALC880_FIXUP_VOL_KNOB] = {
+               .type = ALC_FIXUP_FUNC,
+               .v.func = alc880_fixup_vol_knob,
+       },
+       [ALC880_FIXUP_FUJITSU] = {
+               /* override all pins as BIOS on old Amilo is broken */
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x14, 0x0121411f }, /* HP */
+                       { 0x15, 0x99030120 }, /* speaker */
+                       { 0x16, 0x99030130 }, /* bass speaker */
+                       { 0x17, 0x411111f0 }, /* N/A */
+                       { 0x18, 0x411111f0 }, /* N/A */
+                       { 0x19, 0x01a19950 }, /* mic-in */
+                       { 0x1a, 0x411111f0 }, /* N/A */
+                       { 0x1b, 0x411111f0 }, /* N/A */
+                       { 0x1c, 0x411111f0 }, /* N/A */
+                       { 0x1d, 0x411111f0 }, /* N/A */
+                       { 0x1e, 0x01454140 }, /* SPDIF out */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC880_FIXUP_VOL_KNOB,
+       },
+       [ALC880_FIXUP_F1734] = {
+               /* almost compatible with FUJITSU, but no bass and SPDIF */
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x14, 0x0121411f }, /* HP */
+                       { 0x15, 0x99030120 }, /* speaker */
+                       { 0x16, 0x411111f0 }, /* N/A */
+                       { 0x17, 0x411111f0 }, /* N/A */
+                       { 0x18, 0x411111f0 }, /* N/A */
+                       { 0x19, 0x01a19950 }, /* mic-in */
+                       { 0x1a, 0x411111f0 }, /* N/A */
+                       { 0x1b, 0x411111f0 }, /* N/A */
+                       { 0x1c, 0x411111f0 }, /* N/A */
+                       { 0x1d, 0x411111f0 }, /* N/A */
+                       { 0x1e, 0x411111f0 }, /* N/A */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC880_FIXUP_VOL_KNOB,
+       },
+       [ALC880_FIXUP_UNIWILL] = {
+               /* need to fix HP and speaker pins to be parsed correctly */
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x14, 0x0121411f }, /* HP */
+                       { 0x15, 0x99030120 }, /* speaker */
+                       { 0x16, 0x99030130 }, /* bass speaker */
+                       { }
+               },
+       },
+       [ALC880_FIXUP_UNIWILL_DIG] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       /* disable bogus unused pins */
+                       { 0x17, 0x411111f0 },
+                       { 0x19, 0x411111f0 },
+                       { 0x1b, 0x411111f0 },
+                       { 0x1f, 0x411111f0 },
+                       { }
+               }
+       },
+       [ALC880_FIXUP_Z71V] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       /* set up the whole pins as BIOS is utterly broken */
+                       { 0x14, 0x99030120 }, /* speaker */
+                       { 0x15, 0x0121411f }, /* HP */
+                       { 0x16, 0x411111f0 }, /* N/A */
+                       { 0x17, 0x411111f0 }, /* N/A */
+                       { 0x18, 0x01a19950 }, /* mic-in */
+                       { 0x19, 0x411111f0 }, /* N/A */
+                       { 0x1a, 0x01813031 }, /* line-in */
+                       { 0x1b, 0x411111f0 }, /* N/A */
+                       { 0x1c, 0x411111f0 }, /* N/A */
+                       { 0x1d, 0x411111f0 }, /* N/A */
+                       { 0x1e, 0x0144111e }, /* SPDIF */
+                       { }
+               }
+       },
+       [ALC880_FIXUP_3ST_BASE] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x14, 0x01014010 }, /* line-out */
+                       { 0x15, 0x411111f0 }, /* N/A */
+                       { 0x16, 0x411111f0 }, /* N/A */
+                       { 0x17, 0x411111f0 }, /* N/A */
+                       { 0x18, 0x01a19c30 }, /* mic-in */
+                       { 0x19, 0x0121411f }, /* HP */
+                       { 0x1a, 0x01813031 }, /* line-in */
+                       { 0x1b, 0x02a19c40 }, /* front-mic */
+                       { 0x1c, 0x411111f0 }, /* N/A */
+                       { 0x1d, 0x411111f0 }, /* N/A */
+                       /* 0x1e is filled in below */
+                       { 0x1f, 0x411111f0 }, /* N/A */
+                       { }
+               }
+       },
+       [ALC880_FIXUP_3ST] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x1e, 0x411111f0 }, /* N/A */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC880_FIXUP_3ST_BASE,
+       },
+       [ALC880_FIXUP_3ST_DIG] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x1e, 0x0144111e }, /* SPDIF */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC880_FIXUP_3ST_BASE,
+       },
+       [ALC880_FIXUP_5ST_BASE] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x14, 0x01014010 }, /* front */
+                       { 0x15, 0x411111f0 }, /* N/A */
+                       { 0x16, 0x01011411 }, /* CLFE */
+                       { 0x17, 0x01016412 }, /* surr */
+                       { 0x18, 0x01a19c30 }, /* mic-in */
+                       { 0x19, 0x0121411f }, /* HP */
+                       { 0x1a, 0x01813031 }, /* line-in */
+                       { 0x1b, 0x02a19c40 }, /* front-mic */
+                       { 0x1c, 0x411111f0 }, /* N/A */
+                       { 0x1d, 0x411111f0 }, /* N/A */
+                       /* 0x1e is filled in below */
+                       { 0x1f, 0x411111f0 }, /* N/A */
+                       { }
+               }
+       },
+       [ALC880_FIXUP_5ST] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x1e, 0x411111f0 }, /* N/A */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC880_FIXUP_5ST_BASE,
+       },
+       [ALC880_FIXUP_5ST_DIG] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x1e, 0x0144111e }, /* SPDIF */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC880_FIXUP_5ST_BASE,
+       },
+       [ALC880_FIXUP_6ST_BASE] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x14, 0x01014010 }, /* front */
+                       { 0x15, 0x01016412 }, /* surr */
+                       { 0x16, 0x01011411 }, /* CLFE */
+                       { 0x17, 0x01012414 }, /* side */
+                       { 0x18, 0x01a19c30 }, /* mic-in */
+                       { 0x19, 0x02a19c40 }, /* front-mic */
+                       { 0x1a, 0x01813031 }, /* line-in */
+                       { 0x1b, 0x0121411f }, /* HP */
+                       { 0x1c, 0x411111f0 }, /* N/A */
+                       { 0x1d, 0x411111f0 }, /* N/A */
+                       /* 0x1e is filled in below */
+                       { 0x1f, 0x411111f0 }, /* N/A */
+                       { }
+               }
+       },
+       [ALC880_FIXUP_6ST] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x1e, 0x411111f0 }, /* N/A */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC880_FIXUP_6ST_BASE,
+       },
+       [ALC880_FIXUP_6ST_DIG] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x1e, 0x0144111e }, /* SPDIF */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC880_FIXUP_6ST_BASE,
+       },
 };
 
 static const struct snd_pci_quirk alc880_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
+       SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
+       SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
+       SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
+       SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
+       SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
+       SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
+       SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
+       SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
+       SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
        SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
+       SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734),
+       SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
+       SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
+       SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
+       SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
+       SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
+       SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
+       SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
+
+       /* Below is the copied entries from alc880_quirks.c.
+        * It's not quite sure whether BIOS sets the correct pin-config table
+        * on these machines, thus they are kept to be compatible with
+        * the old static quirks.  Once when it's confirmed to work without
+        * these overrides, it'd be better to remove.
+        */
+       SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
+       SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
+       SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
+       SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
+       SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
+       SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
+       SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
+       SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
+       SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
+       SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
+       SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
+       SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
+       SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
+       SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
+       SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
+       SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
+       SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
+       SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
+       SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
+       SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
+       SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
+       SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
+       SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
+       SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
+       SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
+       SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
+       SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
+       SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
+       SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
+       SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
+       SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
+       SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
+       SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
+       /* default Intel */
+       SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
+       SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
+       SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
        {}
 };
 
+static const struct alc_model_fixup alc880_fixup_models[] = {
+       {.id = ALC880_FIXUP_3ST, .name = "3stack"},
+       {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
+       {.id = ALC880_FIXUP_5ST, .name = "5stack"},
+       {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
+       {.id = ALC880_FIXUP_6ST, .name = "6stack"},
+       {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
+       {}
+};
 
-/*
- * board setups
- */
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-#define alc_board_config \
-       snd_hda_check_board_config
-#define alc_board_codec_sid_config \
-       snd_hda_check_board_codec_sid_config
-#include "alc_quirks.c"
-#else
-#define alc_board_config(codec, nums, models, tbl)     -1
-#define alc_board_codec_sid_config(codec, nums, models, tbl)   -1
-#define setup_preset(codec, x) /* NOP */
-#endif
 
 /*
  * OK, here we have finally the patch for ALC880
  */
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-#include "alc880_quirks.c"
-#endif
-
 static int patch_alc880(struct hda_codec *codec)
 {
        struct alc_spec *spec;
-       int board_config;
        int err;
 
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -4146,47 +4807,14 @@ static int patch_alc880(struct hda_codec *codec)
        spec->mixer_nid = 0x0b;
        spec->need_dac_fix = 1;
 
-       board_config = alc_board_config(codec, ALC880_MODEL_LAST,
-                                       alc880_models, alc880_cfg_tbl);
-       if (board_config < 0) {
-               printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
-                      codec->chip_name);
-               board_config = ALC_MODEL_AUTO;
-       }
-
-       if (board_config == ALC_MODEL_AUTO) {
-               alc_pick_fixup(codec, NULL, alc880_fixup_tbl, alc880_fixups);
-               alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-       }
-
-       if (board_config == ALC_MODEL_AUTO) {
-               /* automatic parse from the BIOS config */
-               err = alc880_parse_auto_config(codec);
-               if (err < 0)
-                       goto error;
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-               else if (!err) {
-                       printk(KERN_INFO
-                              "hda_codec: Cannot set up configuration "
-                              "from BIOS.  Using 3-stack mode...\n");
-                       board_config = ALC880_3ST;
-               }
-#endif
-       }
-
-       if (board_config != ALC_MODEL_AUTO) {
-               spec->vmaster_nid = 0x0c;
-               setup_preset(codec, &alc880_presets[board_config]);
-       }
-
-       if (!spec->no_analog && !spec->adc_nids) {
-               alc_auto_fill_adc_caps(codec);
-               alc_rebuild_imux_for_auto_mic(codec);
-               alc_remove_invalid_adc_nids(codec);
-       }
+       alc_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
+                      alc880_fixups);
+       alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
 
-       if (!spec->no_analog && !spec->cap_mixer)
-               set_capture_mixer(codec);
+       /* automatic parse from the BIOS config */
+       err = alc880_parse_auto_config(codec);
+       if (err < 0)
+               goto error;
 
        if (!spec->no_analog) {
                err = snd_hda_attach_beep_device(codec, 0x1);
@@ -4195,17 +4823,9 @@ static int patch_alc880(struct hda_codec *codec)
                set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
        }
 
-       alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
        codec->patch_ops = alc_patch_ops;
-       if (board_config == ALC_MODEL_AUTO)
-               spec->init_hook = alc_auto_init_std;
-       else
-               codec->patch_ops.build_controls = __alc_build_controls;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-       if (!spec->loopback.amplist)
-               spec->loopback.amplist = alc880_loopbacks;
-#endif
+
+       alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
        return 0;
 
@@ -4225,49 +4845,115 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
        return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static const struct hda_amp_list alc260_loopbacks[] = {
-       { 0x07, HDA_INPUT, 0 },
-       { 0x07, HDA_INPUT, 1 },
-       { 0x07, HDA_INPUT, 2 },
-       { 0x07, HDA_INPUT, 3 },
-       { 0x07, HDA_INPUT, 4 },
-       { } /* end */
-};
-#endif
-
 /*
  * Pin config fixes
  */
 enum {
-       PINFIX_HP_DC5750,
+       ALC260_FIXUP_HP_DC5750,
+       ALC260_FIXUP_HP_PIN_0F,
+       ALC260_FIXUP_COEF,
+       ALC260_FIXUP_GPIO1,
+       ALC260_FIXUP_GPIO1_TOGGLE,
+       ALC260_FIXUP_REPLACER,
+       ALC260_FIXUP_HP_B1900,
 };
 
+static void alc260_gpio1_automute(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
+                           spec->hp_jack_present);
+}
+
+static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
+                                     const struct alc_fixup *fix, int action)
+{
+       struct alc_spec *spec = codec->spec;
+       if (action == ALC_FIXUP_ACT_PROBE) {
+               /* although the machine has only one output pin, we need to
+                * toggle GPIO1 according to the jack state
+                */
+               spec->automute_hook = alc260_gpio1_automute;
+               spec->detect_hp = 1;
+               spec->automute_speaker = 1;
+               spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
+               snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT);
+               spec->unsol_event = alc_sku_unsol_event;
+               add_verb(codec->spec, alc_gpio1_init_verbs);
+       }
+}
+
 static const struct alc_fixup alc260_fixups[] = {
-       [PINFIX_HP_DC5750] = {
+       [ALC260_FIXUP_HP_DC5750] = {
                .type = ALC_FIXUP_PINS,
                .v.pins = (const struct alc_pincfg[]) {
                        { 0x11, 0x90130110 }, /* speaker */
                        { }
                }
        },
+       [ALC260_FIXUP_HP_PIN_0F] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x0f, 0x01214000 }, /* HP */
+                       { }
+               }
+       },
+       [ALC260_FIXUP_COEF] = {
+               .type = ALC_FIXUP_VERBS,
+               .v.verbs = (const struct hda_verb[]) {
+                       { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
+                       { 0x20, AC_VERB_SET_PROC_COEF,  0x3040 },
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC260_FIXUP_HP_PIN_0F,
+       },
+       [ALC260_FIXUP_GPIO1] = {
+               .type = ALC_FIXUP_VERBS,
+               .v.verbs = alc_gpio1_init_verbs,
+       },
+       [ALC260_FIXUP_GPIO1_TOGGLE] = {
+               .type = ALC_FIXUP_FUNC,
+               .v.func = alc260_fixup_gpio1_toggle,
+               .chained = true,
+               .chain_id = ALC260_FIXUP_HP_PIN_0F,
+       },
+       [ALC260_FIXUP_REPLACER] = {
+               .type = ALC_FIXUP_VERBS,
+               .v.verbs = (const struct hda_verb[]) {
+                       { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
+                       { 0x20, AC_VERB_SET_PROC_COEF,  0x3050 },
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
+       },
+       [ALC260_FIXUP_HP_B1900] = {
+               .type = ALC_FIXUP_FUNC,
+               .v.func = alc260_fixup_gpio1_toggle,
+               .chained = true,
+               .chain_id = ALC260_FIXUP_COEF,
+       }
 };
 
 static const struct snd_pci_quirk alc260_fixup_tbl[] = {
-       SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
+       SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
+       SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
+       SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
+       SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
+       SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
+       SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
+       SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
+       SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
        {}
 };
 
 /*
  */
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-#include "alc260_quirks.c"
-#endif
-
 static int patch_alc260(struct hda_codec *codec)
 {
        struct alc_spec *spec;
-       int err, board_config;
+       int err;
 
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
@@ -4277,47 +4963,13 @@ static int patch_alc260(struct hda_codec *codec)
 
        spec->mixer_nid = 0x07;
 
-       board_config = alc_board_config(codec, ALC260_MODEL_LAST,
-                                       alc260_models, alc260_cfg_tbl);
-       if (board_config < 0) {
-               snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
-                          codec->chip_name);
-               board_config = ALC_MODEL_AUTO;
-       }
-
-       if (board_config == ALC_MODEL_AUTO) {
-               alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
-               alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-       }
-
-       if (board_config == ALC_MODEL_AUTO) {
-               /* automatic parse from the BIOS config */
-               err = alc260_parse_auto_config(codec);
-               if (err < 0)
-                       goto error;
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-               else if (!err) {
-                       printk(KERN_INFO
-                              "hda_codec: Cannot set up configuration "
-                              "from BIOS.  Using base mode...\n");
-                       board_config = ALC260_BASIC;
-               }
-#endif
-       }
-
-       if (board_config != ALC_MODEL_AUTO) {
-               setup_preset(codec, &alc260_presets[board_config]);
-               spec->vmaster_nid = 0x08;
-       }
-
-       if (!spec->no_analog && !spec->adc_nids) {
-               alc_auto_fill_adc_caps(codec);
-               alc_rebuild_imux_for_auto_mic(codec);
-               alc_remove_invalid_adc_nids(codec);
-       }
+       alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
+       alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
 
-       if (!spec->no_analog && !spec->cap_mixer)
-               set_capture_mixer(codec);
+       /* automatic parse from the BIOS config */
+       err = alc260_parse_auto_config(codec);
+       if (err < 0)
+               goto error;
 
        if (!spec->no_analog) {
                err = snd_hda_attach_beep_device(codec, 0x1);
@@ -4326,18 +4978,10 @@ static int patch_alc260(struct hda_codec *codec)
                set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
        }
 
-       alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
        codec->patch_ops = alc_patch_ops;
-       if (board_config == ALC_MODEL_AUTO)
-               spec->init_hook = alc_auto_init_std;
-       else
-               codec->patch_ops.build_controls = __alc_build_controls;
        spec->shutup = alc_eapd_shutup;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-       if (!spec->loopback.amplist)
-               spec->loopback.amplist = alc260_loopbacks;
-#endif
+
+       alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
        return 0;
 
@@ -4358,9 +5002,6 @@ static int patch_alc260(struct hda_codec *codec)
  * In addition, an independent DAC for the multi-playback (not used in this
  * driver yet).
  */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-#define alc882_loopbacks       alc880_loopbacks
-#endif
 
 /*
  * Pin config fixes
@@ -4377,6 +5018,8 @@ enum {
        ALC882_FIXUP_EAPD,
        ALC883_FIXUP_EAPD,
        ALC883_FIXUP_ACER_EAPD,
+       ALC882_FIXUP_GPIO1,
+       ALC882_FIXUP_GPIO2,
        ALC882_FIXUP_GPIO3,
        ALC889_FIXUP_COEF,
        ALC882_FIXUP_ASUS_W2JC,
@@ -4385,6 +5028,8 @@ enum {
        ALC882_FIXUP_ASPIRE_8930G_VERBS,
        ALC885_FIXUP_MACPRO_GPIO,
        ALC889_FIXUP_DAC_ROUTE,
+       ALC889_FIXUP_MBP_VREF,
+       ALC889_FIXUP_IMAC91_VREF,
 };
 
 static void alc889_fixup_coef(struct hda_codec *codec,
@@ -4463,6 +5108,51 @@ static void alc889_fixup_dac_route(struct hda_codec *codec,
        }
 }
 
+/* Set VREF on HP pin */
+static void alc889_fixup_mbp_vref(struct hda_codec *codec,
+                                 const struct alc_fixup *fix, int action)
+{
+       struct alc_spec *spec = codec->spec;
+       static hda_nid_t nids[2] = { 0x14, 0x15 };
+       int i;
+
+       if (action != ALC_FIXUP_ACT_INIT)
+               return;
+       for (i = 0; i < ARRAY_SIZE(nids); i++) {
+               unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
+               if (get_defcfg_device(val) != AC_JACK_HP_OUT)
+                       continue;
+               val = snd_hda_codec_read(codec, nids[i], 0,
+                                        AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+               val |= AC_PINCTL_VREF_80;
+               snd_hda_codec_write(codec, nids[i], 0,
+                                   AC_VERB_SET_PIN_WIDGET_CONTROL, val);
+               spec->keep_vref_in_automute = 1;
+               break;
+       }
+}
+
+/* Set VREF on speaker pins on imac91 */
+static void alc889_fixup_imac91_vref(struct hda_codec *codec,
+                                    const struct alc_fixup *fix, int action)
+{
+       struct alc_spec *spec = codec->spec;
+       static hda_nid_t nids[2] = { 0x18, 0x1a };
+       int i;
+
+       if (action != ALC_FIXUP_ACT_INIT)
+               return;
+       for (i = 0; i < ARRAY_SIZE(nids); i++) {
+               unsigned int val;
+               val = snd_hda_codec_read(codec, nids[i], 0,
+                                        AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+               val |= AC_PINCTL_VREF_50;
+               snd_hda_codec_write(codec, nids[i], 0,
+                                   AC_VERB_SET_PIN_WIDGET_CONTROL, val);
+       }
+       spec->keep_vref_in_automute = 1;
+}
+
 static const struct alc_fixup alc882_fixups[] = {
        [ALC882_FIXUP_ABIT_AW9D_MAX] = {
                .type = ALC_FIXUP_PINS,
@@ -4548,6 +5238,14 @@ static const struct alc_fixup alc882_fixups[] = {
                        { }
                }
        },
+       [ALC882_FIXUP_GPIO1] = {
+               .type = ALC_FIXUP_VERBS,
+               .v.verbs = alc_gpio1_init_verbs,
+       },
+       [ALC882_FIXUP_GPIO2] = {
+               .type = ALC_FIXUP_VERBS,
+               .v.verbs = alc_gpio2_init_verbs,
+       },
        [ALC882_FIXUP_GPIO3] = {
                .type = ALC_FIXUP_VERBS,
                .v.verbs = alc_gpio3_init_verbs,
@@ -4621,6 +5319,18 @@ static const struct alc_fixup alc882_fixups[] = {
                .type = ALC_FIXUP_FUNC,
                .v.func = alc889_fixup_dac_route,
        },
+       [ALC889_FIXUP_MBP_VREF] = {
+               .type = ALC_FIXUP_FUNC,
+               .v.func = alc889_fixup_mbp_vref,
+               .chained = true,
+               .chain_id = ALC882_FIXUP_GPIO1,
+       },
+       [ALC889_FIXUP_IMAC91_VREF] = {
+               .type = ALC_FIXUP_FUNC,
+               .v.func = alc889_fixup_imac91_vref,
+               .chained = true,
+               .chain_id = ALC882_FIXUP_GPIO1,
+       },
 };
 
 static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -4654,11 +5364,26 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
        SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
 
        /* All Apple entries are in codec SSIDs */
+       SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
+       SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
+       SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
        SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO),
        SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
        SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
+       SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
+       SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
        SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
+       SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBP_VREF),
+       SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBP_VREF),
+       SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
+       SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
        SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
+       SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
+       SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
+       SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
+       SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
+       SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
+       SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF),
 
        SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
        SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
@@ -4684,14 +5409,10 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
 
 /*
  */
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-#include "alc882_quirks.c"
-#endif
-
 static int patch_alc882(struct hda_codec *codec)
 {
        struct alc_spec *spec;
-       int err, board_config;
+       int err;
 
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
@@ -4715,45 +5436,15 @@ static int patch_alc882(struct hda_codec *codec)
        if (err < 0)
                goto error;
 
-       board_config = alc_board_config(codec, ALC882_MODEL_LAST,
-                                       alc882_models, NULL);
-       if (board_config < 0)
-               board_config = alc_board_codec_sid_config(codec,
-                       ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
-
-       if (board_config < 0) {
-               printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
-                      codec->chip_name);
-               board_config = ALC_MODEL_AUTO;
-       }
-
-       if (board_config == ALC_MODEL_AUTO) {
-               alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
-               alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-       }
+       alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
+       alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
 
        alc_auto_parse_customize_define(codec);
 
-       if (board_config == ALC_MODEL_AUTO) {
-               /* automatic parse from the BIOS config */
-               err = alc882_parse_auto_config(codec);
-               if (err < 0)
-                       goto error;
-       }
-
-       if (board_config != ALC_MODEL_AUTO) {
-               setup_preset(codec, &alc882_presets[board_config]);
-               spec->vmaster_nid = 0x0c;
-       }
-
-       if (!spec->no_analog && !spec->adc_nids) {
-               alc_auto_fill_adc_caps(codec);
-               alc_rebuild_imux_for_auto_mic(codec);
-               alc_remove_invalid_adc_nids(codec);
-       }
-
-       if (!spec->no_analog && !spec->cap_mixer)
-               set_capture_mixer(codec);
+       /* automatic parse from the BIOS config */
+       err = alc882_parse_auto_config(codec);
+       if (err < 0)
+               goto error;
 
        if (!spec->no_analog && has_cdefine_beep(codec)) {
                err = snd_hda_attach_beep_device(codec, 0x1);
@@ -4762,18 +5453,9 @@ static int patch_alc882(struct hda_codec *codec)
                set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
        }
 
-       alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
        codec->patch_ops = alc_patch_ops;
-       if (board_config == ALC_MODEL_AUTO)
-               spec->init_hook = alc_auto_init_std;
-       else
-               codec->patch_ops.build_controls = __alc_build_controls;
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-       if (!spec->loopback.amplist)
-               spec->loopback.amplist = alc882_loopbacks;
-#endif
+       alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
        return 0;
 
@@ -4869,10 +5551,6 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
 };
 
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-#define alc262_loopbacks       alc880_loopbacks
-#endif
-
 /*
  */
 static int patch_alc262(struct hda_codec *codec)
@@ -4912,15 +5590,6 @@ static int patch_alc262(struct hda_codec *codec)
        if (err < 0)
                goto error;
 
-       if (!spec->no_analog && !spec->adc_nids) {
-               alc_auto_fill_adc_caps(codec);
-               alc_rebuild_imux_for_auto_mic(codec);
-               alc_remove_invalid_adc_nids(codec);
-       }
-
-       if (!spec->no_analog && !spec->cap_mixer)
-               set_capture_mixer(codec);
-
        if (!spec->no_analog && has_cdefine_beep(codec)) {
                err = snd_hda_attach_beep_device(codec, 0x1);
                if (err < 0)
@@ -4928,16 +5597,10 @@ static int patch_alc262(struct hda_codec *codec)
                set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
        }
 
-       alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
        codec->patch_ops = alc_patch_ops;
-       spec->init_hook = alc_auto_init_std;
        spec->shutup = alc_eapd_shutup;
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-       if (!spec->loopback.amplist)
-               spec->loopback.amplist = alc262_loopbacks;
-#endif
+       alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
        return 0;
 
@@ -5031,17 +5694,7 @@ static int patch_alc268(struct hda_codec *codec)
                                          (0 << AC_AMPCAP_MUTE_SHIFT));
        }
 
-       if (!spec->no_analog && !spec->adc_nids) {
-               alc_auto_fill_adc_caps(codec);
-               alc_rebuild_imux_for_auto_mic(codec);
-               alc_remove_invalid_adc_nids(codec);
-       }
-
-       if (!spec->no_analog && !spec->cap_mixer)
-               set_capture_mixer(codec);
-
        codec->patch_ops = alc_patch_ops;
-       spec->init_hook = alc_auto_init_std;
        spec->shutup = alc_eapd_shutup;
 
        return 0;
@@ -5054,10 +5707,6 @@ static int patch_alc268(struct hda_codec *codec)
 /*
  * ALC269
  */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-#define alc269_loopbacks       alc880_loopbacks
-#endif
-
 static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
        .substreams = 1,
        .channels_min = 2,
@@ -5079,35 +5728,6 @@ static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
        /* NID is set in alc_build_pcms */
 };
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static int alc269_mic2_for_mute_led(struct hda_codec *codec)
-{
-       switch (codec->subsystem_id) {
-       case 0x103c1586:
-               return 1;
-       }
-       return 0;
-}
-
-static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
-{
-       /* update mute-LED according to the speaker mute state */
-       if (nid == 0x01 || nid == 0x14) {
-               int pinval;
-               if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
-                   HDA_AMP_MUTE)
-                       pinval = 0x24;
-               else
-                       pinval = 0x20;
-               /* mic2 vref pin is used for mute LED control */
-               snd_hda_codec_update_cache(codec, 0x19, 0,
-                                          AC_VERB_SET_PIN_WIDGET_CONTROL,
-                                          pinval);
-       }
-       return alc_check_power_status(codec, nid);
-}
-#endif /* CONFIG_SND_HDA_POWER_SAVE */
-
 /* different alc269-variants */
 enum {
        ALC269_TYPE_ALC269VA,
@@ -5258,6 +5878,31 @@ static void alc269_fixup_quanta_mute(struct hda_codec *codec,
        spec->automute_hook = alc269_quanta_automute;
 }
 
+/* update mute-LED according to the speaker mute state via mic2 VREF pin */
+static void alc269_fixup_mic2_mute_hook(void *private_data, int enabled)
+{
+       struct hda_codec *codec = private_data;
+       unsigned int pinval = enabled ? 0x20 : 0x24;
+       snd_hda_codec_update_cache(codec, 0x19, 0,
+                                  AC_VERB_SET_PIN_WIDGET_CONTROL,
+                                  pinval);
+}
+
+static void alc269_fixup_mic2_mute(struct hda_codec *codec,
+                                  const struct alc_fixup *fix, int action)
+{
+       struct alc_spec *spec = codec->spec;
+       switch (action) {
+       case ALC_FIXUP_ACT_BUILD:
+               spec->vmaster_mute.hook = alc269_fixup_mic2_mute_hook;
+               snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true);
+               /* fallthru */
+       case ALC_FIXUP_ACT_INIT:
+               snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
+               break;
+       }
+}
+
 enum {
        ALC269_FIXUP_SONY_VAIO,
        ALC275_FIXUP_SONY_VAIO_GPIO2,
@@ -5275,6 +5920,7 @@ enum {
        ALC269_FIXUP_DMIC,
        ALC269VB_FIXUP_AMIC,
        ALC269VB_FIXUP_DMIC,
+       ALC269_FIXUP_MIC2_MUTE_LED,
 };
 
 static const struct alc_fixup alc269_fixups[] = {
@@ -5395,9 +6041,14 @@ static const struct alc_fixup alc269_fixups[] = {
                        { }
                },
        },
+       [ALC269_FIXUP_MIC2_MUTE_LED] = {
+               .type = ALC_FIXUP_FUNC,
+               .v.func = alc269_fixup_mic2_mute,
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED),
        SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
        SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
@@ -5420,7 +6071,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K),
        SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
 
-#if 1
+#if 0
        /* Below is a quirk table taken from the old code.
         * Basically the device should work as is without the fixup table.
         * If BIOS doesn't give a proper info, enable the corresponding
@@ -5478,13 +6129,13 @@ static const struct alc_model_fixup alc269_fixup_models[] = {
 };
 
 
-static int alc269_fill_coef(struct hda_codec *codec)
+static void alc269_fill_coef(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
        int val;
 
        if (spec->codec_variant != ALC269_TYPE_ALC269VB)
-               return 0;
+               return;
 
        if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
                alc_write_coef_idx(codec, 0xf, 0x960b);
@@ -5520,8 +6171,6 @@ static int alc269_fill_coef(struct hda_codec *codec)
 
        val = alc_read_coef_idx(codec, 0x4); /* HP */
        alc_write_coef_idx(codec, 0x4, val | (1<<11));
-
-       return 0;
 }
 
 /*
@@ -5565,6 +6214,7 @@ static int patch_alc269(struct hda_codec *codec)
                }
                if (err < 0)
                        goto error;
+               spec->init_hook = alc269_fill_coef;
                alc269_fill_coef(codec);
        }
 
@@ -5577,15 +6227,6 @@ static int patch_alc269(struct hda_codec *codec)
        if (err < 0)
                goto error;
 
-       if (!spec->no_analog && !spec->adc_nids) {
-               alc_auto_fill_adc_caps(codec);
-               alc_rebuild_imux_for_auto_mic(codec);
-               alc_remove_invalid_adc_nids(codec);
-       }
-
-       if (!spec->no_analog && !spec->cap_mixer)
-               set_capture_mixer(codec);
-
        if (!spec->no_analog && has_cdefine_beep(codec)) {
                err = snd_hda_attach_beep_device(codec, 0x1);
                if (err < 0)
@@ -5593,21 +6234,13 @@ static int patch_alc269(struct hda_codec *codec)
                set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
        }
 
-       alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
        codec->patch_ops = alc_patch_ops;
 #ifdef CONFIG_PM
        codec->patch_ops.resume = alc269_resume;
 #endif
-       spec->init_hook = alc_auto_init_std;
        spec->shutup = alc269_shutup;
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-       if (!spec->loopback.amplist)
-               spec->loopback.amplist = alc269_loopbacks;
-       if (alc269_mic2_for_mute_led(codec))
-               codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
-#endif
+       alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
        return 0;
 
@@ -5627,21 +6260,12 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
        return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static const struct hda_amp_list alc861_loopbacks[] = {
-       { 0x15, HDA_INPUT, 0 },
-       { 0x15, HDA_INPUT, 1 },
-       { 0x15, HDA_INPUT, 2 },
-       { 0x15, HDA_INPUT, 3 },
-       { } /* end */
-};
-#endif
-
-
 /* Pin config fixes */
 enum {
-       PINFIX_FSC_AMILO_PI1505,
-       PINFIX_ASUS_A6RP,
+       ALC861_FIXUP_FSC_AMILO_PI1505,
+       ALC861_FIXUP_AMP_VREF_0F,
+       ALC861_FIXUP_NO_JACK_DETECT,
+       ALC861_FIXUP_ASUS_A6RP,
 };
 
 /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
@@ -5663,8 +6287,16 @@ static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
        spec->keep_vref_in_automute = 1;
 }
 
+/* suppress the jack-detection */
+static void alc_fixup_no_jack_detect(struct hda_codec *codec,
+                                    const struct alc_fixup *fix, int action)
+{
+       if (action == ALC_FIXUP_ACT_PRE_PROBE)
+               codec->no_jack_detect = 1;
+}      
+
 static const struct alc_fixup alc861_fixups[] = {
-       [PINFIX_FSC_AMILO_PI1505] = {
+       [ALC861_FIXUP_FSC_AMILO_PI1505] = {
                .type = ALC_FIXUP_PINS,
                .v.pins = (const struct alc_pincfg[]) {
                        { 0x0b, 0x0221101f }, /* HP */
@@ -5672,17 +6304,29 @@ static const struct alc_fixup alc861_fixups[] = {
                        { }
                }
        },
-       [PINFIX_ASUS_A6RP] = {
+       [ALC861_FIXUP_AMP_VREF_0F] = {
                .type = ALC_FIXUP_FUNC,
                .v.func = alc861_fixup_asus_amp_vref_0f,
        },
+       [ALC861_FIXUP_NO_JACK_DETECT] = {
+               .type = ALC_FIXUP_FUNC,
+               .v.func = alc_fixup_no_jack_detect,
+       },
+       [ALC861_FIXUP_ASUS_A6RP] = {
+               .type = ALC_FIXUP_FUNC,
+               .v.func = alc861_fixup_asus_amp_vref_0f,
+               .chained = true,
+               .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
+       }
 };
 
 static const struct snd_pci_quirk alc861_fixup_tbl[] = {
-       SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", PINFIX_ASUS_A6RP),
-       SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", PINFIX_ASUS_A6RP),   
-       SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP),
-       SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
+       SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
+       SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
+       SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
+       SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
+       SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
+       SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
        {}
 };
 
@@ -5709,15 +6353,6 @@ static int patch_alc861(struct hda_codec *codec)
        if (err < 0)
                goto error;
 
-       if (!spec->no_analog && !spec->adc_nids) {
-               alc_auto_fill_adc_caps(codec);
-               alc_rebuild_imux_for_auto_mic(codec);
-               alc_remove_invalid_adc_nids(codec);
-       }
-
-       if (!spec->no_analog && !spec->cap_mixer)
-               set_capture_mixer(codec);
-
        if (!spec->no_analog) {
                err = snd_hda_attach_beep_device(codec, 0x23);
                if (err < 0)
@@ -5725,16 +6360,13 @@ static int patch_alc861(struct hda_codec *codec)
                set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
        }
 
-       alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
        codec->patch_ops = alc_patch_ops;
-       spec->init_hook = alc_auto_init_std;
 #ifdef CONFIG_SND_HDA_POWER_SAVE
        spec->power_hook = alc_power_eapd;
-       if (!spec->loopback.amplist)
-               spec->loopback.amplist = alc861_loopbacks;
 #endif
 
+       alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
+
        return 0;
 
  error:
@@ -5749,10 +6381,6 @@ static int patch_alc861(struct hda_codec *codec)
  *
  * In addition, an independent DAC
  */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-#define alc861vd_loopbacks     alc880_loopbacks
-#endif
-
 static int alc861vd_parse_auto_config(struct hda_codec *codec)
 {
        static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
@@ -5833,15 +6461,6 @@ static int patch_alc861vd(struct hda_codec *codec)
                add_verb(spec, alc660vd_eapd_verbs);
        }
 
-       if (!spec->no_analog && !spec->adc_nids) {
-               alc_auto_fill_adc_caps(codec);
-               alc_rebuild_imux_for_auto_mic(codec);
-               alc_remove_invalid_adc_nids(codec);
-       }
-
-       if (!spec->no_analog && !spec->cap_mixer)
-               set_capture_mixer(codec);
-
        if (!spec->no_analog) {
                err = snd_hda_attach_beep_device(codec, 0x23);
                if (err < 0)
@@ -5849,16 +6468,11 @@ static int patch_alc861vd(struct hda_codec *codec)
                set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
        }
 
-       alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
        codec->patch_ops = alc_patch_ops;
 
-       spec->init_hook = alc_auto_init_std;
        spec->shutup = alc_eapd_shutup;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-       if (!spec->loopback.amplist)
-               spec->loopback.amplist = alc861vd_loopbacks;
-#endif
+
+       alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
        return 0;
 
@@ -5878,9 +6492,6 @@ static int patch_alc861vd(struct hda_codec *codec)
  * In addition, an independent DAC for the multi-playback (not used in this
  * driver yet).
  */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-#define alc662_loopbacks       alc880_loopbacks
-#endif
 
 /*
  * BIOS auto configuration
@@ -5930,6 +6541,7 @@ enum {
        ALC662_FIXUP_ASUS_MODE6,
        ALC662_FIXUP_ASUS_MODE7,
        ALC662_FIXUP_ASUS_MODE8,
+       ALC662_FIXUP_NO_JACK_DETECT,
 };
 
 static const struct alc_fixup alc662_fixups[] = {
@@ -6075,6 +6687,10 @@ static const struct alc_fixup alc662_fixups[] = {
                .chained = true,
                .chain_id = ALC662_FIXUP_SKU_IGNORE
        },
+       [ALC662_FIXUP_NO_JACK_DETECT] = {
+               .type = ALC_FIXUP_FUNC,
+               .v.func = alc_fixup_no_jack_detect,
+       },
 };
 
 static const struct snd_pci_quirk alc662_fixup_tbl[] = {
@@ -6083,6 +6699,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
        SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
+       SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
        SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
        SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
@@ -6204,15 +6821,6 @@ static int patch_alc662(struct hda_codec *codec)
        if (err < 0)
                goto error;
 
-       if (!spec->no_analog && !spec->adc_nids) {
-               alc_auto_fill_adc_caps(codec);
-               alc_rebuild_imux_for_auto_mic(codec);
-               alc_remove_invalid_adc_nids(codec);
-       }
-
-       if (!spec->no_analog && !spec->cap_mixer)
-               set_capture_mixer(codec);
-
        if (!spec->no_analog && has_cdefine_beep(codec)) {
                err = snd_hda_attach_beep_device(codec, 0x1);
                if (err < 0)
@@ -6232,16 +6840,10 @@ static int patch_alc662(struct hda_codec *codec)
                }
        }
 
-       alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
        codec->patch_ops = alc_patch_ops;
-       spec->init_hook = alc_auto_init_std;
        spec->shutup = alc_eapd_shutup;
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-       if (!spec->loopback.amplist)
-               spec->loopback.amplist = alc662_loopbacks;
-#endif
+       alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
        return 0;
 
@@ -6281,11 +6883,7 @@ static int patch_alc680(struct hda_codec *codec)
                return err;
        }
 
-       if (!spec->no_analog && !spec->cap_mixer)
-               set_capture_mixer(codec);
-
        codec->patch_ops = alc_patch_ops;
-       spec->init_hook = alc_auto_init_std;
 
        return 0;
 }
index 9dbb5735d778692c81f0010311b2958309a9fa43..33a9946b492cb333184b1a9405c11f553fc55566 100644 (file)
@@ -99,6 +99,7 @@ enum {
        STAC_DELL_VOSTRO_3500,
        STAC_92HD83XXX_HP_cNB11_INTQUAD,
        STAC_HP_DV7_4000,
+       STAC_HP_ZEPHYR,
        STAC_92HD83XXX_MODELS
 };
 
@@ -309,6 +310,8 @@ struct sigmatel_spec {
        unsigned long auto_capvols[MAX_ADCS_NUM];
        unsigned auto_dmic_cnt;
        hda_nid_t auto_dmic_nids[MAX_DMICS_NUM];
+
+       struct hda_vmaster_mute_hook vmaster_mute;
 };
 
 static const hda_nid_t stac9200_adc_nids[1] = {
@@ -662,7 +665,6 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
 static int stac_vrefout_set(struct hda_codec *codec,
                                        hda_nid_t nid, unsigned int new_vref)
 {
@@ -686,7 +688,6 @@ static int stac_vrefout_set(struct hda_codec *codec,
 
        return 1;
 }
-#endif
 
 static unsigned int stac92xx_vref_set(struct hda_codec *codec,
                                        hda_nid_t nid, unsigned int new_vref)
@@ -894,6 +895,13 @@ static const struct hda_verb stac92hd83xxx_core_init[] = {
        {}
 };
 
+static const struct hda_verb stac92hd83xxx_hp_zephyr_init[] = {
+       { 0x22, 0x785, 0x43 },
+       { 0x22, 0x782, 0xe0 },
+       { 0x22, 0x795, 0x00 },
+       {}
+};
+
 static const struct hda_verb stac92hd71bxx_core_init[] = {
        /* set master volume and direct control */
        { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
@@ -999,8 +1007,8 @@ static const struct hda_verb stac9205_core_init[] = {
        }
 
 static const struct snd_kcontrol_new stac9200_mixer[] = {
-       HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xb, 0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("PCM Playback Switch", 0xb, 0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
        { } /* end */
@@ -1027,8 +1035,8 @@ static const struct snd_kcontrol_new stac92hd71bxx_loopback[] = {
 };
 
 static const struct snd_kcontrol_new stac925x_mixer[] = {
-       HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xe, 0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xe, 0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("PCM Playback Switch", 0x0e, 0, HDA_OUTPUT),
        { } /* end */
 };
 
@@ -1060,34 +1068,25 @@ static struct snd_kcontrol_new stac_smux_mixer = {
        .put = stac92xx_smux_enum_put,
 };
 
-static const char * const slave_vols[] = {
-       "Front Playback Volume",
-       "Surround Playback Volume",
-       "Center Playback Volume",
-       "LFE Playback Volume",
-       "Side Playback Volume",
-       "Headphone Playback Volume",
-       "Speaker Playback Volume",
+static const char * const slave_pfxs[] = {
+       "Front", "Surround", "Center", "LFE", "Side",
+       "Headphone", "Speaker", "IEC958",
        NULL
 };
 
-static const char * const slave_sws[] = {
-       "Front Playback Switch",
-       "Surround Playback Switch",
-       "Center Playback Switch",
-       "LFE Playback Switch",
-       "Side Playback Switch",
-       "Headphone Playback Switch",
-       "Speaker Playback Switch",
-       "IEC958 Playback Switch",
-       NULL
-};
+static void stac92xx_update_led_status(struct hda_codec *codec, int enabled);
+
+static void stac92xx_vmaster_hook(void *private_data, int val)
+{
+       stac92xx_update_led_status(private_data, val);
+}
 
 static void stac92xx_free_kctls(struct hda_codec *codec);
 
 static int stac92xx_build_controls(struct hda_codec *codec)
 {
        struct sigmatel_spec *spec = codec->spec;
+       unsigned int vmaster_tlv[4];
        int err;
        int i;
 
@@ -1144,22 +1143,28 @@ static int stac92xx_build_controls(struct hda_codec *codec)
        }
 
        /* if we have no master control, let's create it */
-       if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
-               unsigned int vmaster_tlv[4];
-               snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
-                                       HDA_OUTPUT, vmaster_tlv);
-               /* correct volume offset */
-               vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset;
-               /* minimum value is actually mute */
-               vmaster_tlv[3] |= TLV_DB_SCALE_MUTE;
-               err = snd_hda_add_vmaster(codec, "Master Playback Volume",
-                                         vmaster_tlv, slave_vols);
-               if (err < 0)
-                       return err;
-       }
-       if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
-               err = snd_hda_add_vmaster(codec, "Master Playback Switch",
-                                         NULL, slave_sws);
+       snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
+                               HDA_OUTPUT, vmaster_tlv);
+       /* correct volume offset */
+       vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset;
+       /* minimum value is actually mute */
+       vmaster_tlv[3] |= TLV_DB_SCALE_MUTE;
+       err = snd_hda_add_vmaster(codec, "Master Playback Volume",
+                                 vmaster_tlv, slave_pfxs,
+                                 "Playback Volume");
+       if (err < 0)
+               return err;
+
+       err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
+                                   NULL, slave_pfxs,
+                                   "Playback Switch", true,
+                                   &spec->vmaster_mute.sw_kctl);
+       if (err < 0)
+               return err;
+
+       if (spec->gpio_led) {
+               spec->vmaster_mute.hook = stac92xx_vmaster_hook;
+               err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true);
                if (err < 0)
                        return err;
        }
@@ -1636,6 +1641,12 @@ static const unsigned int hp_dv7_4000_pin_configs[10] = {
        0x40f000f0, 0x40f000f0,
 };
 
+static const unsigned int hp_zephyr_pin_configs[10] = {
+       0x01813050, 0x0421201f, 0x04a1205e, 0x96130310,
+       0x96130310, 0x0101401f, 0x1111611f, 0xd5a30130,
+       0, 0,
+};
+
 static const unsigned int hp_cNB11_intquad_pin_configs[10] = {
        0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110,
        0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130,
@@ -1649,6 +1660,7 @@ static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
        [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs,
        [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs,
        [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
+       [STAC_HP_ZEPHYR] = hp_zephyr_pin_configs,
 };
 
 static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
@@ -1659,6 +1671,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
        [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500",
        [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
        [STAC_HP_DV7_4000] = "hp-dv7-4000",
+       [STAC_HP_ZEPHYR] = "hp-zephyr",
 };
 
 static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
@@ -1711,6 +1724,14 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
                          "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
        SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
                          "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
+                         "HP", STAC_HP_ZEPHYR),
+       {} /* terminator */
+};
+
+static const struct snd_pci_quirk stac92hd83xxx_codec_id_cfg_tbl[] = {
+       SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
+                         "HP", STAC_HP_ZEPHYR),
        {} /* terminator */
 };
 
@@ -4410,8 +4431,7 @@ static int stac92xx_init(struct hda_codec *codec)
        snd_hda_jack_report_sync(codec);
 
        /* sync mute LED */
-       if (spec->gpio_led)
-               hda_call_check_power_status(codec, 0x01);
+       snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
        if (spec->dac_list)
                stac92xx_power_down(codec);
        return 0;
@@ -4989,7 +5009,6 @@ static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
        return 0;
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
 static int stac92xx_pre_resume(struct hda_codec *codec)
 {
        struct sigmatel_spec *spec = codec->spec;
@@ -5024,82 +5043,40 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
                        afg_power_state);
        snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
 }
+#else
+#define stac92xx_suspend       NULL
+#define stac92xx_resume                NULL
+#define stac92xx_pre_resume    NULL
+#define stac92xx_set_power_state NULL
+#endif /* CONFIG_PM */
 
-/*
- * For this feature CONFIG_SND_HDA_POWER_SAVE is needed
- * as mute LED state is updated in check_power_status hook
- */
-static int stac92xx_update_led_status(struct hda_codec *codec)
+/* update mute-LED accoring to the master switch */
+static void stac92xx_update_led_status(struct hda_codec *codec, int enabled)
 {
        struct sigmatel_spec *spec = codec->spec;
-       int i, num_ext_dacs, muted = 1;
-       unsigned int muted_lvl, notmtd_lvl;
-       hda_nid_t nid;
+       int muted = !enabled;
 
        if (!spec->gpio_led)
-               return 0;
+               return;
+
+       /* LED state is inverted on these systems */
+       if (spec->gpio_led_polarity)
+               muted = !muted;
 
-       for (i = 0; i < spec->multiout.num_dacs; i++) {
-               nid = spec->multiout.dac_nids[i];
-               if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
-                     HDA_AMP_MUTE)) {
-                       muted = 0; /* something heard */
-                       break;
-               }
-       }
-       if (muted && spec->multiout.hp_nid)
-               if (!(snd_hda_codec_amp_read(codec,
-                               spec->multiout.hp_nid, 0, HDA_OUTPUT, 0) &
-                                       HDA_AMP_MUTE)) {
-                       muted = 0; /* HP is not muted */
-               }
-       num_ext_dacs = ARRAY_SIZE(spec->multiout.extra_out_nid);
-       for (i = 0; muted && i < num_ext_dacs; i++) {
-               nid = spec->multiout.extra_out_nid[i];
-               if (nid == 0)
-                       break;
-               if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
-                     HDA_AMP_MUTE)) {
-                       muted = 0; /* extra output is not muted */
-               }
-       }
        /*polarity defines *not* muted state level*/
        if (!spec->vref_mute_led_nid) {
                if (muted)
                        spec->gpio_data &= ~spec->gpio_led; /* orange */
                else
                        spec->gpio_data |= spec->gpio_led; /* white */
-
-               if (!spec->gpio_led_polarity) {
-                       /* LED state is inverted on these systems */
-                       spec->gpio_data ^= spec->gpio_led;
-               }
                stac_gpio_set(codec, spec->gpio_mask,
                                spec->gpio_dir, spec->gpio_data);
        } else {
-               notmtd_lvl = spec->gpio_led_polarity ?
-                               AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
-               muted_lvl = spec->gpio_led_polarity ?
-                               AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_50;
-               spec->vref_led = muted ? muted_lvl : notmtd_lvl;
+               spec->vref_led = muted ? AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
                stac_vrefout_set(codec, spec->vref_mute_led_nid,
                                 spec->vref_led);
        }
-       return 0;
-}
-
-/*
- * use power check for controlling mute led of HP notebooks
- */
-static int stac92xx_check_power_status(struct hda_codec *codec,
-                                             hda_nid_t nid)
-{
-       stac92xx_update_led_status(codec);
-
-       return 0;
 }
-#endif /* CONFIG_SND_HDA_POWER_SAVE */
-#endif /* CONFIG_PM */
 
 static const struct hda_codec_ops stac92xx_patch_ops = {
        .build_controls = stac92xx_build_controls,
@@ -5580,6 +5557,12 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
                                                        STAC_92HD83XXX_MODELS,
                                                        stac92hd83xxx_models,
                                                        stac92hd83xxx_cfg_tbl);
+       /* check codec subsystem id if not found */
+       if (spec->board_config < 0)
+               spec->board_config =
+                       snd_hda_check_board_codec_sid_config(codec,
+                               STAC_92HD83XXX_MODELS, stac92hd83xxx_models,
+                               stac92hd83xxx_codec_id_cfg_tbl);
 again:
        if (spec->board_config < 0)
                snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
@@ -5590,12 +5573,17 @@ again:
 
        codec->patch_ops = stac92xx_patch_ops;
 
+       switch (spec->board_config) {
+       case STAC_HP_ZEPHYR:
+               spec->init = stac92hd83xxx_hp_zephyr_init;
+               break;
+       }
+
        if (find_mute_led_cfg(codec, -1/*no default cfg*/))
                snd_printd("mute LED gpio %d polarity %d\n",
                                spec->gpio_led,
                                spec->gpio_led_polarity);
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
        if (spec->gpio_led) {
                if (!spec->vref_mute_led_nid) {
                        spec->gpio_mask |= spec->gpio_led;
@@ -5605,11 +5593,10 @@ again:
                        codec->patch_ops.set_power_state =
                                        stac92xx_set_power_state;
                }
+#ifdef CONFIG_PM
                codec->patch_ops.pre_resume = stac92xx_pre_resume;
-               codec->patch_ops.check_power_status =
-                       stac92xx_check_power_status;
+#endif
        }
-#endif 
 
        err = stac92xx_parse_auto_config(codec);
        if (!err) {
@@ -5906,7 +5893,6 @@ again:
                                spec->gpio_led,
                                spec->gpio_led_polarity);
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
        if (spec->gpio_led) {
                if (!spec->vref_mute_led_nid) {
                        spec->gpio_mask |= spec->gpio_led;
@@ -5916,11 +5902,10 @@ again:
                        codec->patch_ops.set_power_state =
                                        stac92xx_set_power_state;
                }
+#ifdef CONFIG_PM
                codec->patch_ops.pre_resume = stac92xx_pre_resume;
-               codec->patch_ops.check_power_status =
-                       stac92xx_check_power_status;
+#endif
        }
-#endif 
 
        spec->multiout.dac_nids = spec->dac_nids;
 
index dff9a00ee8fbf136101243c031d3cd3222cff291..06214fdc9486d2c5d1d6c59eca22325330c5c3f3 100644 (file)
@@ -550,7 +550,10 @@ static void via_auto_init_output(struct hda_codec *codec,
        pin = path->path[path->depth - 1];
 
        init_output_pin(codec, pin, pin_type);
-       caps = query_amp_caps(codec, pin, HDA_OUTPUT);
+       if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
+               caps = query_amp_caps(codec, pin, HDA_OUTPUT);
+       else
+               caps = 0;
        if (caps & AC_AMPCAP_MUTE) {
                unsigned int val;
                val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
@@ -645,6 +648,10 @@ static void via_auto_init_analog_input(struct hda_codec *codec)
 
        /* init ADCs */
        for (i = 0; i < spec->num_adc_nids; i++) {
+               hda_nid_t nid = spec->adc_nids[i];
+               if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP) ||
+                   !(query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE))
+                       continue;
                snd_hda_codec_write(codec, spec->adc_nids[i], 0,
                                    AC_VERB_SET_AMP_GAIN_MUTE,
                                    AMP_IN_UNMUTE(0));
@@ -1445,25 +1452,9 @@ static const struct hda_pcm_stream via_pcm_digital_capture = {
 /*
  * slave controls for virtual master
  */
-static const char * const via_slave_vols[] = {
-       "Front Playback Volume",
-       "Surround Playback Volume",
-       "Center Playback Volume",
-       "LFE Playback Volume",
-       "Side Playback Volume",
-       "Headphone Playback Volume",
-       "Speaker Playback Volume",
-       NULL,
-};
-
-static const char * const via_slave_sws[] = {
-       "Front Playback Switch",
-       "Surround Playback Switch",
-       "Center Playback Switch",
-       "LFE Playback Switch",
-       "Side Playback Switch",
-       "Headphone Playback Switch",
-       "Speaker Playback Switch",
+static const char * const via_slave_pfxs[] = {
+       "Front", "Surround", "Center", "LFE", "Side",
+       "Headphone", "Speaker",
        NULL,
 };
 
@@ -1508,13 +1499,15 @@ static int via_build_controls(struct hda_codec *codec)
                snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
                                        HDA_OUTPUT, vmaster_tlv);
                err = snd_hda_add_vmaster(codec, "Master Playback Volume",
-                                         vmaster_tlv, via_slave_vols);
+                                         vmaster_tlv, via_slave_pfxs,
+                                         "Playback Volume");
                if (err < 0)
                        return err;
        }
        if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
                err = snd_hda_add_vmaster(codec, "Master Playback Switch",
-                                         NULL, via_slave_sws);
+                                         NULL, via_slave_pfxs,
+                                         "Playback Switch");
                if (err < 0)
                        return err;
        }
@@ -1522,6 +1515,8 @@ static int via_build_controls(struct hda_codec *codec)
        /* assign Capture Source enums to NID */
        kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
        for (i = 0; kctl && i < kctl->count; i++) {
+               if (!spec->mux_nids[i])
+                       continue;
                err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
                if (err < 0)
                        return err;
@@ -2488,6 +2483,8 @@ static int create_mic_boost_ctls(struct hda_codec *codec)
 {
        struct via_spec *spec = codec->spec;
        const struct auto_pin_cfg *cfg = &spec->autocfg;
+       const char *prev_label = NULL;
+       int type_idx = 0;
        int i, err;
 
        for (i = 0; i < cfg->num_inputs; i++) {
@@ -2502,8 +2499,13 @@ static int create_mic_boost_ctls(struct hda_codec *codec)
                if (caps == -1 || !(caps & AC_AMPCAP_NUM_STEPS))
                        continue;
                label = hda_get_autocfg_input_label(codec, cfg, i);
+               if (prev_label && !strcmp(label, prev_label))
+                       type_idx++;
+               else
+                       type_idx = 0;
+               prev_label = label;
                snprintf(name, sizeof(name), "%s Boost Volume", label);
-               err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
+               err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx,
                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT));
                if (err < 0)
                        return err;