]> xenbits.xen.org Git - xenclient/linux-2.6.27-pq.git/commitdiff
Fix intel-hda-2.6.30 patch and re-enable.
authorroot <root@debian.hsd1.wa.comcast.net>
Thu, 16 Jul 2009 10:41:22 +0000 (03:41 -0700)
committerroot <root@debian.hsd1.wa.comcast.net>
Thu, 16 Jul 2009 10:41:22 +0000 (03:41 -0700)
master/intel-hda-2.6.30
master/series

index a7e075f4f195ca4173a4e527a994bdb48cedae9e..06f187ed97ba86bc48eb20732c564a66769f7057 100644 (file)
@@ -1,8 +1,8 @@
 diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
-index 4a6eba5..094bf89 100644
+index 2300030..3181bcf 100644
 --- a/include/linux/pci_ids.h
 +++ b/include/linux/pci_ids.h
-@@ -2087,6 +2087,8 @@
+@@ -2090,6 +2090,8 @@
  #define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c
  #define PCI_DEVICE_ID_MELLANOX_SINAI  0x6274
  
@@ -190,200 +190,6 @@ index 0000000..f236e42
 +#endif
 +
 +#endif
-diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
-new file mode 100644
-index 0000000..eb2a19b
---- /dev/null
-+++ b/sound/pci/hda/Kconfig
-@@ -0,0 +1,188 @@
-+menuconfig SND_HDA_INTEL
-+      tristate "Intel HD Audio"
-+      select SND_PCM
-+      select SND_VMASTER
-+      select SND_JACK if INPUT=y || INPUT=SND
-+      help
-+        Say Y here to include support for Intel "High Definition
-+        Audio" (Azalia) and its compatible devices.
-+
-+        This option enables the HD-audio controller.  Don't forget
-+        to choose the appropriate codec options below.
-+
-+        To compile this driver as a module, choose M here: the module
-+        will be called snd-hda-intel.
-+
-+if SND_HDA_INTEL
-+
-+config SND_HDA_HWDEP
-+      bool "Build hwdep interface for HD-audio driver"
-+      select SND_HWDEP
-+      help
-+        Say Y here to build a hwdep interface for HD-audio driver.
-+        This interface can be used for out-of-band communication
-+        with codecs for debugging purposes.
-+
-+config SND_HDA_RECONFIG
-+      bool "Allow dynamic codec reconfiguration (EXPERIMENTAL)"
-+      depends on SND_HDA_HWDEP && EXPERIMENTAL
-+      help
-+        Say Y here to enable the HD-audio codec re-configuration feature.
-+        This adds the sysfs interfaces to allow user to clear the whole
-+        codec configuration, change the codec setup, add extra verbs,
-+        and re-configure the codec dynamically.
-+
-+config SND_HDA_INPUT_BEEP
-+      bool "Support digital beep via input layer"
-+      depends on INPUT=y || INPUT=SND_HDA_INTEL
-+      help
-+        Say Y here to build a digital beep interface for HD-audio
-+        driver. This interface is used to generate digital beeps.
-+
-+config SND_HDA_CODEC_REALTEK
-+      bool "Build Realtek HD-audio codec support"
-+      default y
-+      help
-+        Say Y here to include Realtek HD-audio codec support in
-+        snd-hda-intel driver, such as ALC880.
-+
-+        When the HD-audio driver is built as a module, the codec
-+        support code is also built as another module,
-+        snd-hda-codec-realtek.
-+        This module is automatically loaded at probing.
-+
-+config SND_HDA_CODEC_ANALOG
-+      bool "Build Analog Device HD-audio codec support"
-+      default y
-+      help
-+        Say Y here to include Analog Device HD-audio codec support in
-+        snd-hda-intel driver, such as AD1986A.
-+
-+        When the HD-audio driver is built as a module, the codec
-+        support code is also built as another module,
-+        snd-hda-codec-analog.
-+        This module is automatically loaded at probing.
-+
-+config SND_HDA_CODEC_SIGMATEL
-+      bool "Build IDT/Sigmatel HD-audio codec support"
-+      default y
-+      help
-+        Say Y here to include IDT (Sigmatel) HD-audio codec support in
-+        snd-hda-intel driver, such as STAC9200.
-+
-+        When the HD-audio driver is built as a module, the codec
-+        support code is also built as another module,
-+        snd-hda-codec-idt.
-+        This module is automatically loaded at probing.
-+
-+config SND_HDA_CODEC_VIA
-+      bool "Build VIA HD-audio codec support"
-+      default y
-+      help
-+        Say Y here to include VIA HD-audio codec support in
-+        snd-hda-intel driver, such as VT1708.
-+
-+        When the HD-audio driver is built as a module, the codec
-+        support code is also built as another module,
-+        snd-hda-codec-via.
-+        This module is automatically loaded at probing.
-+
-+config SND_HDA_CODEC_ATIHDMI
-+      bool "Build ATI HDMI HD-audio codec support"
-+      default y
-+      help
-+        Say Y here to include ATI HDMI HD-audio codec support in
-+        snd-hda-intel driver, such as ATI RS600 HDMI.
-+
-+        When the HD-audio driver is built as a module, the codec
-+        support code is also built as another module,
-+        snd-hda-codec-atihdmi.
-+        This module is automatically loaded at probing.
-+
-+config SND_HDA_CODEC_NVHDMI
-+      bool "Build NVIDIA HDMI HD-audio codec support"
-+      default y
-+      help
-+        Say Y here to include NVIDIA HDMI HD-audio codec support in
-+        snd-hda-intel driver, such as NVIDIA MCP78 HDMI.
-+
-+        When the HD-audio driver is built as a module, the codec
-+        support code is also built as another module,
-+        snd-hda-codec-nvhdmi.
-+        This module is automatically loaded at probing.
-+
-+config SND_HDA_CODEC_INTELHDMI
-+      bool "Build INTEL HDMI HD-audio codec support"
-+      default y
-+      help
-+        Say Y here to include INTEL HDMI HD-audio codec support in
-+        snd-hda-intel driver, such as Eaglelake integrated HDMI.
-+
-+        When the HD-audio driver is built as a module, the codec
-+        support code is also built as another module,
-+        snd-hda-codec-intelhdmi.
-+        This module is automatically loaded at probing.
-+
-+config SND_HDA_ELD
-+      def_bool y
-+      depends on SND_HDA_CODEC_INTELHDMI
-+
-+config SND_HDA_CODEC_CONEXANT
-+      bool "Build Conexant HD-audio codec support"
-+      default y
-+      help
-+        Say Y here to include Conexant HD-audio codec support in
-+        snd-hda-intel driver, such as CX20549.
-+
-+        When the HD-audio driver is built as a module, the codec
-+        support code is also built as another module,
-+        snd-hda-codec-conexant.
-+        This module is automatically loaded at probing.
-+
-+config SND_HDA_CODEC_CMEDIA
-+      bool "Build C-Media HD-audio codec support"
-+      default y
-+      help
-+        Say Y here to include C-Media HD-audio codec support in
-+        snd-hda-intel driver, such as CMI9880.
-+
-+        When the HD-audio driver is built as a module, the codec
-+        support code is also built as another module,
-+        snd-hda-codec-cmedia.
-+        This module is automatically loaded at probing.
-+
-+config SND_HDA_CODEC_SI3054
-+      bool "Build Silicon Labs 3054 HD-modem codec support"
-+      default y
-+      help
-+        Say Y here to include Silicon Labs 3054 HD-modem codec
-+        (and compatibles) support in snd-hda-intel driver.
-+
-+        When the HD-audio driver is built as a module, the codec
-+        support code is also built as another module,
-+        snd-hda-codec-si3054.
-+        This module is automatically loaded at probing.
-+
-+config SND_HDA_GENERIC
-+      bool "Enable generic HD-audio codec parser"
-+      default y
-+      help
-+        Say Y here to enable the generic HD-audio codec parser
-+        in snd-hda-intel driver.
-+
-+config SND_HDA_POWER_SAVE
-+      bool "Aggressive power-saving on HD-audio"
-+      help
-+        Say Y here to enable more aggressive power-saving mode on
-+        HD-audio driver.  The power-saving timeout can be configured
-+        via power_save option or over sysfs on-the-fly.
-+
-+config SND_HDA_POWER_SAVE_DEFAULT
-+      int "Default time-out for HD-audio power-save mode"
-+      depends on SND_HDA_POWER_SAVE
-+      default 0
-+      help
-+        The default time-out value in seconds for HD-audio automatic
-+        power-save mode.  0 means to disable the power-save mode.
-+
-+endif
 diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
 index 1980c6d..50f9d09 100644
 --- a/sound/pci/hda/Makefile
@@ -467,10 +273,10 @@ index 1980c6d..50f9d09 100644
 +# when built in kernel
  obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
 diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
-index 3ecd7e7..4de5bac 100644
+index b4d0d35..4de5bac 100644
 --- a/sound/pci/hda/hda_beep.c
 +++ b/sound/pci/hda/hda_beep.c
-@@ -128,15 +128,17 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
+@@ -128,6 +128,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
        INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
        return 0;
  }
@@ -478,10 +284,7 @@ index 3ecd7e7..4de5bac 100644
  
  void snd_hda_detach_beep_device(struct hda_codec *codec)
  {
-       struct hda_beep *beep = codec->beep;
-       if (beep) {
-               cancel_work_sync(&beep->beep_work);
--              flush_scheduled_work();
+@@ -137,5 +138,7 @@ void snd_hda_detach_beep_device(struct hda_codec *codec)
  
                input_unregister_device(beep->dev);
                kfree(beep);
@@ -503,7 +306,7 @@ index b9679f0..51bf6a5 100644
  #endif
  #endif
 diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
-index b5b1ba5..8820faf 100644
+index 21f609b..8820faf 100644
 --- a/sound/pci/hda/hda_codec.c
 +++ b/sound/pci/hda/hda_codec.c
 @@ -31,15 +31,6 @@
@@ -594,7 +397,7 @@ index b5b1ba5..8820faf 100644
  
  #ifdef CONFIG_SND_HDA_POWER_SAVE
  static void hda_power_work(struct work_struct *work);
-@@ -107,6 +91,72 @@ static void hda_keep_power_on(struct hda_codec *codec);
+@@ -107,6 +91,55 @@ static void hda_keep_power_on(struct hda_codec *codec);
  static inline void hda_keep_power_on(struct hda_codec *codec) {}
  #endif
  
@@ -647,45 +450,36 @@ index b5b1ba5..8820faf 100644
 +}
 +EXPORT_SYMBOL_HDA(snd_hda_get_jack_type);
 +
-+/*
-+ * Compose a 32bit command word to be sent to the HD-audio controller
-+ */
-+static inline unsigned int
-+make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
-+             unsigned int verb, unsigned int parm)
-+{
-+      u32 val;
-+
-+      val = (u32)(codec->addr & 0x0f) << 28;
-+      val |= (u32)direct << 27;
-+      val |= (u32)nid << 20;
-+      val |= verb << 8;
-+      val |= parm;
-+      return val;
-+}
-+
- /**
-  * snd_hda_codec_read - send a command and get the response
-  * @codec: the HDA codec
-@@ -123,17 +173,21 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
-                               int direct,
+ /*
+  * Compose a 32bit command word to be sent to the HD-audio controller
+  */
+@@ -141,28 +174,20 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
                                unsigned int verb, unsigned int parm)
  {
-+      struct hda_bus *bus = codec->bus;
-       unsigned int res;
-+
+       struct hda_bus *bus = codec->bus;
+-      unsigned int cmd, res;
+-      int repeated = 0;
++      unsigned int res;
+-      cmd = make_codec_cmd(codec, nid, direct, verb, parm);
 +      res = make_codec_cmd(codec, nid, direct, verb, parm);
        snd_hda_power_up(codec);
--      mutex_lock(&codec->bus->cmd_mutex);
--      if (!codec->bus->ops.command(codec, nid, direct, verb, parm))
--              res = codec->bus->ops.get_response(codec);
-+      mutex_lock(&bus->cmd_mutex);
+       mutex_lock(&bus->cmd_mutex);
+- again:
+-      if (!bus->ops.command(bus, cmd)) {
 +      if (!bus->ops.command(bus, res))
-+              res = bus->ops.get_response(bus);
-       else
+               res = bus->ops.get_response(bus);
+-              if (res == -1 && bus->rirb_error) {
+-                      if (repeated++ < 1) {
+-                              snd_printd(KERN_WARNING "hda_codec: "
+-                                         "Trying verb 0x%08x again\n", cmd);
+-                              goto again;
+-                      }
+-              }
+-      } else
++      else
                res = (unsigned int)-1;
--      mutex_unlock(&codec->bus->cmd_mutex);
-+      mutex_unlock(&bus->cmd_mutex);
+       mutex_unlock(&bus->cmd_mutex);
        snd_hda_power_down(codec);
        return res;
  }
@@ -693,22 +487,7 @@ index b5b1ba5..8820faf 100644
  
  /**
   * snd_hda_codec_write - send a single command without waiting for response
-@@ -150,14 +204,19 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
- int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
-                        unsigned int verb, unsigned int parm)
- {
-+      struct hda_bus *bus = codec->bus;
-+      unsigned int res;
-       int err;
-+
-+      res = make_codec_cmd(codec, nid, direct, verb, parm);
-       snd_hda_power_up(codec);
--      mutex_lock(&codec->bus->cmd_mutex);
--      err = codec->bus->ops.command(codec, nid, direct, verb, parm);
--      mutex_unlock(&codec->bus->cmd_mutex);
-+      mutex_lock(&bus->cmd_mutex);
-+      err = bus->ops.command(bus, res);
-+      mutex_unlock(&bus->cmd_mutex);
+@@ -191,6 +216,7 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
        snd_hda_power_down(codec);
        return err;
  }
@@ -716,7 +495,7 @@ index b5b1ba5..8820faf 100644
  
  /**
   * snd_hda_sequence_write - sequence writes
-@@ -172,6 +231,7 @@ void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq)
+@@ -205,6 +231,7 @@ void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq)
        for (; seq->nid; seq++)
                snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param);
  }
@@ -724,7 +503,7 @@ index b5b1ba5..8820faf 100644
  
  /**
   * snd_hda_get_sub_nodes - get the range of sub nodes
-@@ -193,6 +253,7 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
+@@ -226,6 +253,7 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
        *start_id = (parm >> 16) & 0x7fff;
        return (int)(parm & 0x7fff);
  }
@@ -732,7 +511,7 @@ index b5b1ba5..8820faf 100644
  
  /**
   * snd_hda_get_connections - get connection list
-@@ -214,7 +275,8 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
+@@ -247,7 +275,8 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
        unsigned int shift, num_elems, mask;
        hda_nid_t prev_nid;
  
@@ -742,7 +521,7 @@ index b5b1ba5..8820faf 100644
  
        parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN);
        if (parm & AC_CLIST_LONG) {
-@@ -280,6 +342,7 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
+@@ -313,6 +342,7 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
        }
        return conns;
  }
@@ -750,12 +529,7 @@ index b5b1ba5..8820faf 100644
  
  
  /**
-@@ -310,13 +373,14 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
-       unsol->queue[wp] = res;
-       unsol->queue[wp + 1] = res_ex;
--      schedule_work(&unsol->work);
-+      queue_work(bus->workq, &unsol->work);
+@@ -347,9 +377,10 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
  
        return 0;
  }
@@ -767,7 +541,7 @@ index b5b1ba5..8820faf 100644
   */
  static void process_unsol_events(struct work_struct *work)
  {
-@@ -343,7 +407,7 @@ static void process_unsol_events(struct work_struct *work)
+@@ -376,7 +407,7 @@ static void process_unsol_events(struct work_struct *work)
  /*
   * initialize unsolicited queue
   */
@@ -776,28 +550,7 @@ index b5b1ba5..8820faf 100644
  {
        struct hda_bus_unsolicited *unsol;
  
-@@ -373,15 +437,17 @@ static int snd_hda_bus_free(struct hda_bus *bus)
-       if (!bus)
-               return 0;
--      if (bus->unsol) {
--              flush_scheduled_work();
-+      if (bus->workq)
-+              flush_workqueue(bus->workq);
-+      if (bus->unsol)
-               kfree(bus->unsol);
--      }
-       list_for_each_entry_safe(codec, n, &bus->codec_list, list) {
-               snd_hda_codec_free(codec);
-       }
-       if (bus->ops.private_free)
-               bus->ops.private_free(bus);
-+      if (bus->workq)
-+              destroy_workqueue(bus->workq);
-       kfree(bus);
-       return 0;
- }
-@@ -389,9 +455,24 @@ static int snd_hda_bus_free(struct hda_bus *bus)
+@@ -424,9 +455,24 @@ static int snd_hda_bus_free(struct hda_bus *bus)
  static int snd_hda_bus_dev_free(struct snd_device *device)
  {
        struct hda_bus *bus = device->device_data;
@@ -822,7 +575,7 @@ index b5b1ba5..8820faf 100644
  /**
   * snd_hda_bus_new - create a HDA bus
   * @card: the card entry
-@@ -400,18 +481,21 @@ static int snd_hda_bus_dev_free(struct snd_device *device)
+@@ -435,18 +481,21 @@ static int snd_hda_bus_dev_free(struct snd_device *device)
   *
   * Returns 0 if successful, or a negative error code.
   */
@@ -847,7 +600,7 @@ index b5b1ba5..8820faf 100644
  
        if (busp)
                *busp = NULL;
-@@ -426,11 +510,22 @@ int __devinit snd_hda_bus_new(struct snd_card *card,
+@@ -461,6 +510,7 @@ int __devinit snd_hda_bus_new(struct snd_card *card,
        bus->private_data = temp->private_data;
        bus->pci = temp->pci;
        bus->modelname = temp->modelname;
@@ -855,22 +608,7 @@ index b5b1ba5..8820faf 100644
        bus->ops = temp->ops;
  
        mutex_init(&bus->cmd_mutex);
-       INIT_LIST_HEAD(&bus->codec_list);
-+      snprintf(bus->workq_name, sizeof(bus->workq_name),
-+               "hd-audio%d", card->number);
-+      bus->workq = create_singlethread_workqueue(bus->workq_name);
-+      if (!bus->workq) {
-+              snd_printk(KERN_ERR "cannot create workqueue %s\n",
-+                         bus->workq_name);
-+              kfree(bus);
-+              return -ENOMEM;
-+      }
-+
-       err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops);
-       if (err < 0) {
-               snd_hda_bus_free(bus);
-@@ -440,27 +535,42 @@ int __devinit snd_hda_bus_new(struct snd_card *card,
+@@ -485,27 +535,42 @@ int __devinit snd_hda_bus_new(struct snd_card *card,
                *busp = bus;
        return 0;
  }
@@ -918,7 +656,7 @@ index b5b1ba5..8820faf 100644
                        u32 mask = preset->mask;
                        if (preset->afg && preset->afg != codec->afg)
                                continue;
-@@ -470,23 +580,40 @@ find_codec_preset(struct hda_codec *codec)
+@@ -515,23 +580,40 @@ find_codec_preset(struct hda_codec *codec)
                                mask = ~0;
                        if (preset->id == (codec->vendor_id & mask) &&
                            (!preset->rev ||
@@ -964,7 +702,7 @@ index b5b1ba5..8820faf 100644
  
        for (c = hda_vendor_ids; c->id; c++) {
                if (c->id == vendor_id) {
-@@ -499,30 +626,37 @@ void snd_hda_get_codec_name(struct hda_codec *codec,
+@@ -544,30 +626,37 @@ void snd_hda_get_codec_name(struct hda_codec *codec,
                vendor = tmp;
        }
        if (codec->preset && codec->preset->name)
@@ -1009,7 +747,7 @@ index b5b1ba5..8820faf 100644
                        break;
                default:
                        break;
-@@ -550,11 +684,140 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node)
+@@ -595,11 +684,140 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node)
        return 0;
  }
  
@@ -1150,15 +888,14 @@ index b5b1ba5..8820faf 100644
  /*
   * codec destructor
   */
-@@ -562,20 +825,28 @@ static void snd_hda_codec_free(struct hda_codec *codec)
+@@ -607,20 +825,28 @@ static void snd_hda_codec_free(struct hda_codec *codec)
  {
        if (!codec)
                return;
 +      restore_init_pincfgs(codec);
  #ifdef CONFIG_SND_HDA_POWER_SAVE
        cancel_delayed_work(&codec->power_work);
--      flush_scheduled_work();
-+      flush_workqueue(codec->bus->workq);
+       flush_workqueue(codec->bus->workq);
  #endif
        list_del(&codec->list);
 +      snd_array_free(&codec->mixers);
@@ -1180,7 +917,7 @@ index b5b1ba5..8820faf 100644
  /**
   * snd_hda_codec_new - create a HDA codec
   * @bus: the bus to assign
-@@ -584,15 +855,17 @@ static void snd_hda_codec_free(struct hda_codec *codec)
+@@ -629,15 +855,17 @@ static void snd_hda_codec_free(struct hda_codec *codec)
   *
   * Returns 0 if successful, or a negative error code.
   */
@@ -1203,7 +940,7 @@ index b5b1ba5..8820faf 100644
  
        if (bus->caddr_tbl[codec_addr]) {
                snd_printk(KERN_ERR "hda_codec: "
-@@ -609,8 +882,19 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
+@@ -654,8 +882,19 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
        codec->bus = bus;
        codec->addr = codec_addr;
        mutex_init(&codec->spdif_mutex);
@@ -1223,7 +960,7 @@ index b5b1ba5..8820faf 100644
  
  #ifdef CONFIG_SND_HDA_POWER_SAVE
        INIT_DELAYED_WORK(&codec->power_work, hda_power_work);
-@@ -640,15 +924,18 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
+@@ -685,15 +924,18 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
        setup_fg_nodes(codec);
        if (!codec->afg && !codec->mfg) {
                snd_printdd("hda_codec: no AFG or MFG node found\n");
@@ -1247,7 +984,7 @@ index b5b1ba5..8820faf 100644
  
        if (!codec->subsystem_id) {
                hda_nid_t nid = codec->afg ? codec->afg : codec->mfg;
-@@ -656,12 +943,51 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
+@@ -701,12 +943,51 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
                        snd_hda_codec_read(codec, nid, 0,
                                           AC_VERB_GET_SUBSYSTEM_ID, 0);
        }
@@ -1302,7 +1039,7 @@ index b5b1ba5..8820faf 100644
  
        if (is_generic_config(codec)) {
                err = snd_hda_parse_generic_codec(codec);
-@@ -678,25 +1004,9 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
+@@ -723,25 +1004,9 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
                printk(KERN_ERR "hda-codec: No codec parser is available\n");
  
   patched:
@@ -1331,7 +1068,7 @@ index b5b1ba5..8820faf 100644
  }
  
  /**
-@@ -722,6 +1032,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
+@@ -767,6 +1032,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
        msleep(1);
        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format);
  }
@@ -1339,7 +1076,7 @@ index b5b1ba5..8820faf 100644
  
  void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
  {
-@@ -735,6 +1046,7 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
+@@ -780,6 +1046,7 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0);
  #endif
  }
@@ -1347,7 +1084,7 @@ index b5b1ba5..8820faf 100644
  
  /*
   * amp access functions
-@@ -742,21 +1054,22 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
+@@ -787,21 +1054,22 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
  
  /* FIXME: more better hash key? */
  #define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24))
@@ -1373,7 +1110,7 @@ index b5b1ba5..8820faf 100644
  }
  
  /* query the hash.  allocate an entry if not found. */
-@@ -768,35 +1081,17 @@ static struct hda_cache_head  *get_alloc_hash(struct hda_cache_rec *cache,
+@@ -813,35 +1081,17 @@ static struct hda_cache_head  *get_alloc_hash(struct hda_cache_rec *cache,
        struct hda_cache_head *info;
  
        while (cur != 0xffff) {
@@ -1414,7 +1151,7 @@ index b5b1ba5..8820faf 100644
        info->key = key;
        info->val = 0;
        info->next = cache->hash[idx];
-@@ -834,6 +1129,7 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
+@@ -879,6 +1129,7 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
        }
        return info->amp_caps;
  }
@@ -1422,7 +1159,7 @@ index b5b1ba5..8820faf 100644
  
  int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
                              unsigned int caps)
-@@ -847,6 +1143,22 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
+@@ -892,6 +1143,22 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
        info->head.val |= INFO_AMP_CAPS;
        return 0;
  }
@@ -1445,7 +1182,7 @@ index b5b1ba5..8820faf 100644
  
  /*
   * read the current volume to info
-@@ -900,6 +1212,7 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
+@@ -945,6 +1212,7 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
                return 0;
        return get_vol_mute(codec, info, nid, ch, direction, index);
  }
@@ -1453,7 +1190,7 @@ index b5b1ba5..8820faf 100644
  
  /*
   * update the AMP value, mask = bit mask to set, val = the value
-@@ -919,6 +1232,7 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
+@@ -964,6 +1232,7 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
        put_vol_mute(codec, info, nid, ch, direction, idx, val);
        return 1;
  }
@@ -1461,7 +1198,7 @@ index b5b1ba5..8820faf 100644
  
  /*
   * update the AMP stereo with the same mask and value
-@@ -932,15 +1246,16 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
+@@ -977,15 +1246,16 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
                                                idx, mask, val);
        return ret;
  }
@@ -1480,7 +1217,7 @@ index b5b1ba5..8820faf 100644
                u32 key = buffer->head.key;
                hda_nid_t nid;
                unsigned int idx, dir, ch;
-@@ -957,6 +1272,7 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec)
+@@ -1002,6 +1272,7 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec)
                }
        }
  }
@@ -1488,7 +1225,7 @@ index b5b1ba5..8820faf 100644
  #endif /* SND_HDA_NEEDS_RESUME */
  
  /* volume */
-@@ -987,6 +1303,7 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
+@@ -1032,6 +1303,7 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
        uinfo->value.integer.max = caps;
        return 0;
  }
@@ -1496,7 +1233,7 @@ index b5b1ba5..8820faf 100644
  
  
  static inline unsigned int
-@@ -1031,6 +1348,7 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
+@@ -1076,6 +1348,7 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
                *valp = read_amp_value(codec, nid, 1, dir, idx, ofs);
        return 0;
  }
@@ -1504,7 +1241,7 @@ index b5b1ba5..8820faf 100644
  
  int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
-@@ -1054,6 +1372,7 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
+@@ -1099,6 +1372,7 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
        snd_hda_power_down(codec);
        return change;
  }
@@ -1512,7 +1249,7 @@ index b5b1ba5..8820faf 100644
  
  int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
                          unsigned int size, unsigned int __user *_tlv)
-@@ -1082,6 +1401,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
+@@ -1127,6 +1401,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
                return -EFAULT;
        return 0;
  }
@@ -1520,7 +1257,7 @@ index b5b1ba5..8820faf 100644
  
  /*
   * set (static) TLV for virtual master volume; recalculated as max 0dB
-@@ -1101,6 +1421,7 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
+@@ -1146,6 +1421,7 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
        tlv[2] = -nums * step;
        tlv[3] = step;
  }
@@ -1528,7 +1265,7 @@ index b5b1ba5..8820faf 100644
  
  /* find a mixer control element with the given name */
  static struct snd_kcontrol *
-@@ -1120,6 +1441,119 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
+@@ -1165,6 +1441,119 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
  {
        return _snd_hda_find_mixer_ctl(codec, name, 0);
  }
@@ -1648,7 +1385,7 @@ index b5b1ba5..8820faf 100644
  
  /* create a virtual master control and add slaves */
  int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
-@@ -1138,24 +1572,30 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
+@@ -1183,24 +1572,30 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
        kctl = snd_ctl_make_virtual_master(name, tlv);
        if (!kctl)
                return -ENOMEM;
@@ -1688,7 +1425,7 @@ index b5b1ba5..8820faf 100644
  
  /* switch */
  int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
-@@ -1169,6 +1609,7 @@ int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
+@@ -1214,6 +1609,7 @@ int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
        uinfo->value.integer.max = 1;
        return 0;
  }
@@ -1696,7 +1433,7 @@ index b5b1ba5..8820faf 100644
  
  int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
-@@ -1188,6 +1629,7 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
+@@ -1233,6 +1629,7 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
                         HDA_AMP_MUTE) ? 0 : 1;
        return 0;
  }
@@ -1704,7 +1441,7 @@ index b5b1ba5..8820faf 100644
  
  int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
-@@ -1218,6 +1660,7 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
+@@ -1263,6 +1660,7 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
        snd_hda_power_down(codec);
        return change;
  }
@@ -1712,7 +1449,7 @@ index b5b1ba5..8820faf 100644
  
  /*
   * bound volume controls
-@@ -1235,14 +1678,15 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
+@@ -1280,14 +1678,15 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
        unsigned long pval;
        int err;
  
@@ -1730,7 +1467,7 @@ index b5b1ba5..8820faf 100644
  
  int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
                                  struct snd_ctl_elem_value *ucontrol)
-@@ -1251,7 +1695,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
+@@ -1296,7 +1695,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
        unsigned long pval;
        int i, indices, err = 0, change = 0;
  
@@ -1739,7 +1476,7 @@ index b5b1ba5..8820faf 100644
        pval = kcontrol->private_value;
        indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
        for (i = 0; i < indices; i++) {
-@@ -1263,9 +1707,10 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
+@@ -1308,9 +1707,10 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
                change |= err;
        }
        kcontrol->private_value = pval;
@@ -1751,7 +1488,7 @@ index b5b1ba5..8820faf 100644
  
  /*
   * generic bound volume/swtich controls
-@@ -1277,14 +1722,15 @@ int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
+@@ -1322,14 +1722,15 @@ int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
        struct hda_bind_ctls *c;
        int err;
  
@@ -1769,7 +1506,7 @@ index b5b1ba5..8820faf 100644
  
  int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
-@@ -1293,14 +1739,15 @@ int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
+@@ -1338,14 +1739,15 @@ int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
        struct hda_bind_ctls *c;
        int err;
  
@@ -1787,7 +1524,7 @@ index b5b1ba5..8820faf 100644
  
  int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
-@@ -1310,7 +1757,7 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
+@@ -1355,7 +1757,7 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
        unsigned long *vals;
        int err = 0, change = 0;
  
@@ -1796,7 +1533,7 @@ index b5b1ba5..8820faf 100644
        c = (struct hda_bind_ctls *)kcontrol->private_value;
        for (vals = c->values; *vals; vals++) {
                kcontrol->private_value = *vals;
-@@ -1320,9 +1767,10 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
+@@ -1365,9 +1767,10 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
                change |= err;
        }
        kcontrol->private_value = (long)c;
@@ -1808,7 +1545,7 @@ index b5b1ba5..8820faf 100644
  
  int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
                           unsigned int size, unsigned int __user *tlv)
-@@ -1331,14 +1779,15 @@ int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
+@@ -1376,14 +1779,15 @@ int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
        struct hda_bind_ctls *c;
        int err;
  
@@ -1826,7 +1563,7 @@ index b5b1ba5..8820faf 100644
  
  struct hda_ctl_ops snd_hda_bind_vol = {
        .info = snd_hda_mixer_amp_volume_info,
-@@ -1346,6 +1795,7 @@ struct hda_ctl_ops snd_hda_bind_vol = {
+@@ -1391,6 +1795,7 @@ struct hda_ctl_ops snd_hda_bind_vol = {
        .put = snd_hda_mixer_amp_volume_put,
        .tlv = snd_hda_mixer_amp_tlv
  };
@@ -1834,7 +1571,7 @@ index b5b1ba5..8820faf 100644
  
  struct hda_ctl_ops snd_hda_bind_sw = {
        .info = snd_hda_mixer_amp_switch_info,
-@@ -1353,6 +1803,7 @@ struct hda_ctl_ops snd_hda_bind_sw = {
+@@ -1398,6 +1803,7 @@ struct hda_ctl_ops snd_hda_bind_sw = {
        .put = snd_hda_mixer_amp_switch_put,
        .tlv = snd_hda_mixer_amp_tlv
  };
@@ -1842,7 +1579,7 @@ index b5b1ba5..8820faf 100644
  
  /*
   * SPDIF out controls
-@@ -1600,9 +2051,11 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
+@@ -1645,9 +2051,11 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
        }
        for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
                kctl = snd_ctl_new1(dig_mix, codec);
@@ -1855,7 +1592,7 @@ index b5b1ba5..8820faf 100644
                if (err < 0)
                        return err;
        }
-@@ -1612,6 +2065,7 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
+@@ -1657,6 +2065,7 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
        codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls);
        return 0;
  }
@@ -1863,7 +1600,7 @@ index b5b1ba5..8820faf 100644
  
  /*
   * SPDIF sharing with analog output
-@@ -1646,9 +2100,10 @@ int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
+@@ -1691,9 +2100,10 @@ int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
        if (!mout->dig_out_nid)
                return 0;
        /* ATTENTION: here mout is passed as private_data, instead of codec */
@@ -1875,7 +1612,7 @@ index b5b1ba5..8820faf 100644
  
  /*
   * SPDIF input
-@@ -1747,8 +2202,10 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
+@@ -1792,8 +2202,10 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
        }
        for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {
                kctl = snd_ctl_new1(dig_mix, codec);
@@ -1887,7 +1624,7 @@ index b5b1ba5..8820faf 100644
                if (err < 0)
                        return err;
        }
-@@ -1758,6 +2215,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
+@@ -1803,6 +2215,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
                AC_DIG1_ENABLE;
        return 0;
  }
@@ -1895,20 +1632,8 @@ index b5b1ba5..8820faf 100644
  
  #ifdef SND_HDA_NEEDS_RESUME
  /*
-@@ -1784,29 +2242,38 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
- int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
-                             int direct, unsigned int verb, unsigned int parm)
- {
-+      struct hda_bus *bus = codec->bus;
-+      unsigned int res;
-       int err;
-+
-+      res = make_codec_cmd(codec, nid, direct, verb, parm);
-       snd_hda_power_up(codec);
--      mutex_lock(&codec->bus->cmd_mutex);
--      err = codec->bus->ops.command(codec, nid, direct, verb, parm);
-+      mutex_lock(&bus->cmd_mutex);
-+      err = bus->ops.command(bus, res);
+@@ -1839,7 +2252,11 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
+       err = bus->ops.command(bus, res);
        if (!err) {
                struct hda_cache_head *c;
 -              u32 key = build_cmd_cache_key(nid, verb);
@@ -1920,9 +1645,7 @@ index b5b1ba5..8820faf 100644
                c = get_alloc_hash(&codec->cmd_cache, key);
                if (c)
                        c->val = parm;
-       }
--      mutex_unlock(&codec->bus->cmd_mutex);
-+      mutex_unlock(&bus->cmd_mutex);
+@@ -1848,14 +2265,15 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
        snd_hda_power_down(codec);
        return err;
  }
@@ -1940,7 +1663,7 @@ index b5b1ba5..8820faf 100644
                u32 key = buffer->key;
                if (!key)
                        continue;
-@@ -1814,6 +2281,7 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec)
+@@ -1863,6 +2281,7 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec)
                                    get_cmd_cache_cmd(key), buffer->val);
        }
  }
@@ -1948,7 +1671,7 @@ index b5b1ba5..8820faf 100644
  
  /**
   * snd_hda_sequence_write_cache - sequence writes with caching
-@@ -1831,6 +2299,7 @@ void snd_hda_sequence_write_cache(struct hda_codec *codec,
+@@ -1880,6 +2299,7 @@ void snd_hda_sequence_write_cache(struct hda_codec *codec,
                snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb,
                                          seq->param);
  }
@@ -1956,7 +1679,7 @@ index b5b1ba5..8820faf 100644
  #endif /* SND_HDA_NEEDS_RESUME */
  
  /*
-@@ -1858,8 +2327,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
+@@ -1907,8 +2327,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
                                 * don't power down the widget if it controls
                                 * eapd and EAPD_BTLENABLE is set.
                                 */
@@ -1966,7 +1689,7 @@ index b5b1ba5..8820faf 100644
                                if (pincap & AC_PINCAP_EAPD) {
                                        int eapd = snd_hda_codec_read(codec,
                                                nid, 0,
-@@ -1891,6 +2359,17 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
+@@ -1940,6 +2359,17 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
        }
  }
  
@@ -1984,7 +1707,7 @@ index b5b1ba5..8820faf 100644
  #ifdef SND_HDA_NEEDS_RESUME
  /*
   * call suspend and power-down; used both from PM and power-save
-@@ -1917,6 +2396,8 @@ static void hda_call_codec_resume(struct hda_codec *codec)
+@@ -1966,6 +2396,8 @@ static void hda_call_codec_resume(struct hda_codec *codec)
        hda_set_power_state(codec,
                            codec->afg ? codec->afg : codec->mfg,
                            AC_PWRST_D0);
@@ -1993,7 +1716,7 @@ index b5b1ba5..8820faf 100644
        if (codec->patch_ops.resume)
                codec->patch_ops.resume(codec);
        else {
-@@ -1937,28 +2418,38 @@ static void hda_call_codec_resume(struct hda_codec *codec)
+@@ -1986,28 +2418,38 @@ static void hda_call_codec_resume(struct hda_codec *codec)
   *
   * Returns 0 if successful, otherwise a negative error code.
   */
@@ -2048,7 +1771,7 @@ index b5b1ba5..8820faf 100644
        return 0;
  }
  
-@@ -2051,6 +2542,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
+@@ -2100,6 +2542,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
  
        return val;
  }
@@ -2056,7 +1779,7 @@ index b5b1ba5..8820faf 100644
  
  /**
   * snd_hda_query_supported_pcm - query the supported PCM rates and formats
-@@ -2065,15 +2557,14 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
+@@ -2114,15 +2557,14 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
   *
   * Returns 0 if successful, otherwise a negative error code.
   */
@@ -2076,7 +1799,7 @@ index b5b1ba5..8820faf 100644
                val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
                if (val == -1)
                        return -EIO;
-@@ -2087,15 +2578,20 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
+@@ -2136,15 +2578,20 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
                        if (val & (1 << i))
                                rates |= rate_bits[i].alsa_bits;
                }
@@ -2100,7 +1823,7 @@ index b5b1ba5..8820faf 100644
                streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
                if (streams == -1)
                        return -EIO;
-@@ -2148,6 +2644,15 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
+@@ -2197,6 +2644,15 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
                        formats |= SNDRV_PCM_FMTBIT_U8;
                        bps = 8;
                }
@@ -2116,7 +1839,7 @@ index b5b1ba5..8820faf 100644
                if (formatsp)
                        *formatsp = formats;
                if (bpsp)
-@@ -2230,6 +2735,7 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
+@@ -2279,6 +2735,7 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
  
        return 1;
  }
@@ -2124,7 +1847,7 @@ index b5b1ba5..8820faf 100644
  
  /*
   * PCM stuff
-@@ -2259,31 +2765,151 @@ static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo,
+@@ -2308,31 +2765,151 @@ static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo,
        return 0;
  }
  
@@ -2281,7 +2004,7 @@ index b5b1ba5..8820faf 100644
  /**
   * snd_hda_build_pcms - build PCM information
   * @bus: the BUS
-@@ -2315,27 +2941,13 @@ int __devinit snd_hda_build_pcms(struct hda_bus *bus)
+@@ -2364,27 +2941,13 @@ int __devinit snd_hda_build_pcms(struct hda_bus *bus)
        struct hda_codec *codec;
  
        list_for_each_entry(codec, &bus->codec_list, list) {
@@ -2311,7 +2034,7 @@ index b5b1ba5..8820faf 100644
  
  /**
   * snd_hda_check_board_config - compare the current codec with the config table
-@@ -2354,11 +2966,11 @@ int snd_hda_check_board_config(struct hda_codec *codec,
+@@ -2403,11 +2966,11 @@ int snd_hda_check_board_config(struct hda_codec *codec,
                               int num_configs, const char **models,
                               const struct snd_pci_quirk *tbl)
  {
@@ -2325,7 +2048,7 @@ index b5b1ba5..8820faf 100644
                                snd_printd(KERN_INFO "hda_codec: model '%s' is "
                                           "selected\n", models[i]);
                                return i;
-@@ -2391,6 +3003,7 @@ int snd_hda_check_board_config(struct hda_codec *codec,
+@@ -2440,6 +3003,7 @@ int snd_hda_check_board_config(struct hda_codec *codec,
        }
        return -1;
  }
@@ -2333,7 +2056,7 @@ index b5b1ba5..8820faf 100644
  
  /**
   * snd_hda_check_board_codec_sid_config - compare the current codec
-@@ -2451,6 +3064,7 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
+@@ -2500,6 +3064,7 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
        }
        return -1;
  }
@@ -2341,7 +2064,7 @@ index b5b1ba5..8820faf 100644
  
  /**
   * snd_hda_add_new_ctls - create controls from the array
-@@ -2471,7 +3085,7 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
+@@ -2520,7 +3085,7 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
                kctl = snd_ctl_new1(knew, codec);
                if (!kctl)
                        return -ENOMEM;
@@ -2350,7 +2073,7 @@ index b5b1ba5..8820faf 100644
                if (err < 0) {
                        if (!codec->addr)
                                return err;
-@@ -2479,13 +3093,14 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
+@@ -2528,13 +3093,14 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
                        if (!kctl)
                                return -ENOMEM;
                        kctl->id.device = codec->addr;
@@ -2366,41 +2089,7 @@ index b5b1ba5..8820faf 100644
  
  #ifdef CONFIG_SND_HDA_POWER_SAVE
  static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
-@@ -2495,6 +3110,7 @@ static void hda_power_work(struct work_struct *work)
- {
-       struct hda_codec *codec =
-               container_of(work, struct hda_codec, power_work.work);
-+      struct hda_bus *bus = codec->bus;
-       if (!codec->power_on || codec->power_count) {
-               codec->power_transition = 0;
-@@ -2502,8 +3118,8 @@ static void hda_power_work(struct work_struct *work)
-       }
-       hda_call_codec_suspend(codec);
--      if (codec->bus->ops.pm_notify)
--              codec->bus->ops.pm_notify(codec);
-+      if (bus->ops.pm_notify)
-+              bus->ops.pm_notify(bus);
- }
- static void hda_keep_power_on(struct hda_codec *codec)
-@@ -2514,29 +3130,39 @@ static void hda_keep_power_on(struct hda_codec *codec)
- void snd_hda_power_up(struct hda_codec *codec)
- {
-+      struct hda_bus *bus = codec->bus;
-+
-       codec->power_count++;
-       if (codec->power_on || codec->power_transition)
-               return;
-       codec->power_on = 1;
--      if (codec->bus->ops.pm_notify)
--              codec->bus->ops.pm_notify(codec);
-+      if (bus->ops.pm_notify)
-+              bus->ops.pm_notify(bus);
-       hda_call_codec_resume(codec);
+@@ -2577,18 +3143,26 @@ void snd_hda_power_up(struct hda_codec *codec)
        cancel_delayed_work(&codec->power_work);
        codec->power_transition = 0;
  }
@@ -2420,9 +2109,8 @@ index b5b1ba5..8820faf 100644
 -      if (power_save) {
 +      if (power_save(codec)) {
                codec->power_transition = 1; /* avoid reentrance */
--              schedule_delayed_work(&codec->power_work,
+               queue_delayed_work(codec->bus->workq, &codec->power_work,
 -                                    msecs_to_jiffies(power_save * 1000));
-+              queue_delayed_work(codec->bus->workq, &codec->power_work,
 +                              msecs_to_jiffies(power_save(codec) * 1000));
        }
  }
@@ -2430,7 +2118,7 @@ index b5b1ba5..8820faf 100644
  
  int snd_hda_check_amp_list_power(struct hda_codec *codec,
                                 struct hda_loopback_check *check,
-@@ -2573,6 +3199,7 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
+@@ -2625,6 +3199,7 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
        }
        return 0;
  }
@@ -2438,7 +2126,7 @@ index b5b1ba5..8820faf 100644
  #endif
  
  /*
-@@ -2592,6 +3219,7 @@ int snd_hda_ch_mode_info(struct hda_codec *codec,
+@@ -2644,6 +3219,7 @@ int snd_hda_ch_mode_info(struct hda_codec *codec,
                chmode[uinfo->value.enumerated.item].channels);
        return 0;
  }
@@ -2446,7 +2134,7 @@ index b5b1ba5..8820faf 100644
  
  int snd_hda_ch_mode_get(struct hda_codec *codec,
                        struct snd_ctl_elem_value *ucontrol,
-@@ -2609,6 +3237,7 @@ int snd_hda_ch_mode_get(struct hda_codec *codec,
+@@ -2661,6 +3237,7 @@ int snd_hda_ch_mode_get(struct hda_codec *codec,
        }
        return 0;
  }
@@ -2454,7 +2142,7 @@ index b5b1ba5..8820faf 100644
  
  int snd_hda_ch_mode_put(struct hda_codec *codec,
                        struct snd_ctl_elem_value *ucontrol,
-@@ -2629,6 +3258,7 @@ int snd_hda_ch_mode_put(struct hda_codec *codec,
+@@ -2681,6 +3258,7 @@ int snd_hda_ch_mode_put(struct hda_codec *codec,
                snd_hda_sequence_write_cache(codec, chmode[mode].sequence);
        return 1;
  }
@@ -2462,7 +2150,7 @@ index b5b1ba5..8820faf 100644
  
  /*
   * input MUX helper
-@@ -2649,6 +3279,7 @@ int snd_hda_input_mux_info(const struct hda_input_mux *imux,
+@@ -2701,6 +3279,7 @@ int snd_hda_input_mux_info(const struct hda_input_mux *imux,
        strcpy(uinfo->value.enumerated.name, imux->items[index].label);
        return 0;
  }
@@ -2470,7 +2158,7 @@ index b5b1ba5..8820faf 100644
  
  int snd_hda_input_mux_put(struct hda_codec *codec,
                          const struct hda_input_mux *imux,
-@@ -2670,6 +3301,7 @@ int snd_hda_input_mux_put(struct hda_codec *codec,
+@@ -2722,6 +3301,7 @@ int snd_hda_input_mux_put(struct hda_codec *codec,
        *cur_val = idx;
        return 1;
  }
@@ -2478,7 +2166,7 @@ index b5b1ba5..8820faf 100644
  
  
  /*
-@@ -2682,7 +3314,7 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
+@@ -2734,7 +3314,7 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
  {
        /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
        if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
@@ -2487,7 +2175,7 @@ index b5b1ba5..8820faf 100644
                                    codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff,
                                    -1);
        snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
-@@ -2722,6 +3354,7 @@ int snd_hda_multi_out_dig_open(struct hda_codec *codec,
+@@ -2774,6 +3354,7 @@ int snd_hda_multi_out_dig_open(struct hda_codec *codec,
        mutex_unlock(&codec->spdif_mutex);
        return 0;
  }
@@ -2495,7 +2183,7 @@ index b5b1ba5..8820faf 100644
  
  int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
                                  struct hda_multi_out *mout,
-@@ -2734,6 +3367,17 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
+@@ -2786,6 +3367,17 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
        mutex_unlock(&codec->spdif_mutex);
        return 0;
  }
@@ -2513,7 +2201,7 @@ index b5b1ba5..8820faf 100644
  
  /*
   * release the digital out
-@@ -2746,6 +3390,7 @@ int snd_hda_multi_out_dig_close(struct hda_codec *codec,
+@@ -2798,6 +3390,7 @@ int snd_hda_multi_out_dig_close(struct hda_codec *codec,
        mutex_unlock(&codec->spdif_mutex);
        return 0;
  }
@@ -2521,7 +2209,7 @@ index b5b1ba5..8820faf 100644
  
  /*
   * set up more restrictions for analog out
-@@ -2785,6 +3430,7 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec,
+@@ -2837,6 +3430,7 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec,
        return snd_pcm_hw_constraint_step(substream->runtime, 0,
                                          SNDRV_PCM_HW_PARAM_CHANNELS, 2);
  }
@@ -2529,7 +2217,7 @@ index b5b1ba5..8820faf 100644
  
  /*
   * set up the i/o for analog out
-@@ -2843,6 +3489,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
+@@ -2895,6 +3489,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
        }
        return 0;
  }
@@ -2537,7 +2225,7 @@ index b5b1ba5..8820faf 100644
  
  /*
   * clean up the setting for analog out
-@@ -2869,9 +3516,10 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
+@@ -2921,9 +3516,10 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
        mutex_unlock(&codec->spdif_mutex);
        return 0;
  }
@@ -2549,7 +2237,7 @@ index b5b1ba5..8820faf 100644
   */
  
  static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
-@@ -2957,8 +3605,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
+@@ -3009,8 +3605,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
                if (ignore_nids && is_in_nid_list(nid, ignore_nids))
                        continue;
  
@@ -2559,7 +2247,7 @@ index b5b1ba5..8820faf 100644
                if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
                        continue;
                loc = get_defcfg_location(def_conf);
-@@ -3034,10 +3681,22 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
+@@ -3086,10 +3681,22 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
                        cfg->input_pins[AUTO_PIN_AUX] = nid;
                        break;
                case AC_JACK_SPDIF_OUT:
@@ -2583,7 +2271,7 @@ index b5b1ba5..8820faf 100644
                        break;
                }
        }
-@@ -3143,6 +3802,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
+@@ -3195,6 +3802,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
                   cfg->hp_pins[1], cfg->hp_pins[2],
                   cfg->hp_pins[3], cfg->hp_pins[4]);
        snd_printd("   mono: mono_out=0x%x\n", cfg->mono_out_pin);
@@ -2593,7 +2281,7 @@ index b5b1ba5..8820faf 100644
        snd_printd("   inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x,"
                   " cd=0x%x, aux=0x%x\n",
                   cfg->input_pins[AUTO_PIN_MIC],
-@@ -3151,14 +3813,18 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
+@@ -3203,14 +3813,18 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
                   cfg->input_pins[AUTO_PIN_FRONT_LINE],
                   cfg->input_pins[AUTO_PIN_CD],
                   cfg->input_pins[AUTO_PIN_AUX]);
@@ -2612,7 +2300,7 @@ index b5b1ba5..8820faf 100644
  
  
  #ifdef CONFIG_PM
-@@ -3186,11 +3852,11 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
+@@ -3238,11 +3852,11 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
        }
        return 0;
  }
@@ -2625,7 +2313,7 @@ index b5b1ba5..8820faf 100644
   *
   * Returns 0 if successful.
   *
-@@ -3207,16 +3873,79 @@ int snd_hda_resume(struct hda_bus *bus)
+@@ -3259,16 +3873,79 @@ int snd_hda_resume(struct hda_bus *bus)
        }
        return 0;
  }
@@ -2716,7 +2404,7 @@ index b5b1ba5..8820faf 100644
 +MODULE_DESCRIPTION("HDA codec core");
 +MODULE_LICENSE("GPL");
 diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
-index 26f6f9e..2fdecf4 100644
+index 84e28db..2fdecf4 100644
 --- a/sound/pci/hda/hda_codec.h
 +++ b/sound/pci/hda/hda_codec.h
 @@ -306,15 +306,15 @@ enum {
@@ -2775,16 +2463,8 @@ index 26f6f9e..2fdecf4 100644
   * Structures
   */
  
-@@ -536,15 +566,17 @@ typedef u16 hda_nid_t;
- /* bus operators */
- struct hda_bus_ops {
-       /* send a single command */
--      int (*command)(struct hda_codec *codec, hda_nid_t nid, int direct,
--                     unsigned int verb, unsigned int parm);
-+      int (*command)(struct hda_bus *bus, unsigned int cmd);
-       /* get a response from the last command */
--      unsigned int (*get_response)(struct hda_codec *codec);
-+      unsigned int (*get_response)(struct hda_bus *bus);
+@@ -541,6 +571,9 @@ struct hda_bus_ops {
+       unsigned int (*get_response)(struct hda_bus *bus);
        /* free the private data */
        void (*private_free)(struct hda_bus *);
 +      /* attach a PCM stream */
@@ -2792,12 +2472,8 @@ index 26f6f9e..2fdecf4 100644
 +                        struct hda_pcm *pcm);
  #ifdef CONFIG_SND_HDA_POWER_SAVE
        /* notify power-up/down from codec to controller */
--      void (*pm_notify)(struct hda_codec *codec);
-+      void (*pm_notify)(struct hda_bus *bus);
- #endif
- };
-@@ -553,6 +585,7 @@ struct hda_bus_template {
+       void (*pm_notify)(struct hda_bus *bus);
+@@ -552,6 +585,7 @@ struct hda_bus_template {
        void *private_data;
        struct pci_dev *pci;
        const char *modelname;
@@ -2805,7 +2481,7 @@ index 26f6f9e..2fdecf4 100644
        struct hda_bus_ops ops;
  };
  
-@@ -569,6 +602,7 @@ struct hda_bus {
+@@ -568,6 +602,7 @@ struct hda_bus {
        void *private_data;
        struct pci_dev *pci;
        const char *modelname;
@@ -2813,12 +2489,9 @@ index 26f6f9e..2fdecf4 100644
        struct hda_bus_ops ops;
  
        /* codec linked list */
-@@ -580,11 +614,15 @@ struct hda_bus {
-       /* unsolicited event queue */
-       struct hda_bus_unsolicited *unsol;
-+      char workq_name[16];
-+      struct workqueue_struct *workq; /* common workqueue for codecs */
+@@ -582,11 +617,12 @@ struct hda_bus {
+       char workq_name[16];
+       struct workqueue_struct *workq; /* common workqueue for codecs */
  
 -      struct snd_info_entry *proc;
 +      /* assigned PCMs */
@@ -2826,11 +2499,12 @@ index 26f6f9e..2fdecf4 100644
  
        /* misc op flags */
        unsigned int needs_damn_long_delay :1;
+-      unsigned int rirb_error:1;      /* error in codec communication */
 +      unsigned int shutdown :1;       /* being unloaded */
  };
  
  /*
-@@ -604,6 +642,16 @@ struct hda_codec_preset {
+@@ -606,6 +642,16 @@ struct hda_codec_preset {
        int (*patch)(struct hda_codec *codec);
  };
        
@@ -2847,7 +2521,7 @@ index 26f6f9e..2fdecf4 100644
  /* ops set by the preset patch */
  struct hda_codec_ops {
        int (*build_controls)(struct hda_codec *codec);
-@@ -635,10 +683,7 @@ struct hda_amp_info {
+@@ -637,10 +683,7 @@ struct hda_amp_info {
  
  struct hda_cache_rec {
        u16 hash[64];                   /* hash table for index */
@@ -2859,7 +2533,7 @@ index 26f6f9e..2fdecf4 100644
  };
  
  /* PCM callbacks */
-@@ -680,7 +725,8 @@ struct hda_pcm {
+@@ -682,7 +725,8 @@ struct hda_pcm {
        char *name;
        struct hda_pcm_stream stream[2];
        unsigned int pcm_type;  /* HDA_PCM_TYPE_XXX */
@@ -2869,7 +2543,7 @@ index 26f6f9e..2fdecf4 100644
  };
  
  /* codec information */
-@@ -693,12 +739,16 @@ struct hda_codec {
+@@ -695,12 +739,16 @@ struct hda_codec {
        hda_nid_t mfg;  /* MFG node id */
  
        /* ids */
@@ -2886,7 +2560,7 @@ index 26f6f9e..2fdecf4 100644
  
        /* set by patch */
        struct hda_codec_ops patch_ops;
-@@ -718,28 +768,45 @@ struct hda_codec {
+@@ -720,28 +768,45 @@ struct hda_codec {
        hda_nid_t start_nid;
        u32 *wcaps;
  
@@ -2932,7 +2606,7 @@ index 26f6f9e..2fdecf4 100644
  };
  
  /* direction */
-@@ -754,7 +821,7 @@ enum {
+@@ -756,7 +821,7 @@ enum {
  int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
                    struct hda_bus **busp);
  int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
@@ -2941,7 +2615,7 @@ index 26f6f9e..2fdecf4 100644
  
  /*
   * low level functions
-@@ -795,15 +862,29 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec);
+@@ -797,15 +862,29 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec);
  #define snd_hda_sequence_write_cache  snd_hda_sequence_write
  #endif
  
@@ -2971,7 +2645,7 @@ index 26f6f9e..2fdecf4 100644
  void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
                                u32 stream_tag,
                                int channel_id, int format);
-@@ -812,8 +893,6 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
+@@ -814,8 +893,6 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
                                        unsigned int channels,
                                        unsigned int format,
                                        unsigned int maxbps);
@@ -2980,7 +2654,7 @@ index 26f6f9e..2fdecf4 100644
  int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
                                unsigned int format);
  
-@@ -831,18 +910,38 @@ int snd_hda_resume(struct hda_bus *bus);
+@@ -833,18 +910,38 @@ int snd_hda_resume(struct hda_bus *bus);
  #endif
  
  /*
@@ -3021,602 +2695,6 @@ index 26f6f9e..2fdecf4 100644
  #endif
  
  #endif /* __SOUND_HDA_CODEC_H */
-diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
-new file mode 100644
-index 0000000..fcad5ec
---- /dev/null
-+++ b/sound/pci/hda/hda_eld.c
-@@ -0,0 +1,590 @@
-+/*
-+ * Generic routines and proc interface for ELD(EDID Like Data) information
-+ *
-+ * Copyright(c) 2008 Intel Corporation.
-+ *
-+ * Authors:
-+ *            Wu Fengguang <wfg@linux.intel.com>
-+ *
-+ *  This driver is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation; either version 2 of the License, or
-+ *  (at your option) any later version.
-+ *
-+ *  This driver is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-+ */
-+
-+#include <linux/init.h>
-+#include <sound/core.h>
-+#include <asm/unaligned.h>
-+#include "hda_codec.h"
-+#include "hda_local.h"
-+
-+enum eld_versions {
-+      ELD_VER_CEA_861D        = 2,
-+      ELD_VER_PARTIAL         = 31,
-+};
-+
-+enum cea_edid_versions {
-+      CEA_EDID_VER_NONE       = 0,
-+      CEA_EDID_VER_CEA861     = 1,
-+      CEA_EDID_VER_CEA861A    = 2,
-+      CEA_EDID_VER_CEA861BCD  = 3,
-+      CEA_EDID_VER_RESERVED   = 4,
-+};
-+
-+static char *cea_speaker_allocation_names[] = {
-+      /*  0 */ "FL/FR",
-+      /*  1 */ "LFE",
-+      /*  2 */ "FC",
-+      /*  3 */ "RL/RR",
-+      /*  4 */ "RC",
-+      /*  5 */ "FLC/FRC",
-+      /*  6 */ "RLC/RRC",
-+      /*  7 */ "FLW/FRW",
-+      /*  8 */ "FLH/FRH",
-+      /*  9 */ "TC",
-+      /* 10 */ "FCH",
-+};
-+
-+static char *eld_connection_type_names[4] = {
-+      "HDMI",
-+      "DisplayPort",
-+      "2-reserved",
-+      "3-reserved"
-+};
-+
-+enum cea_audio_coding_types {
-+      AUDIO_CODING_TYPE_REF_STREAM_HEADER     =  0,
-+      AUDIO_CODING_TYPE_LPCM                  =  1,
-+      AUDIO_CODING_TYPE_AC3                   =  2,
-+      AUDIO_CODING_TYPE_MPEG1                 =  3,
-+      AUDIO_CODING_TYPE_MP3                   =  4,
-+      AUDIO_CODING_TYPE_MPEG2                 =  5,
-+      AUDIO_CODING_TYPE_AACLC                 =  6,
-+      AUDIO_CODING_TYPE_DTS                   =  7,
-+      AUDIO_CODING_TYPE_ATRAC                 =  8,
-+      AUDIO_CODING_TYPE_SACD                  =  9,
-+      AUDIO_CODING_TYPE_EAC3                  = 10,
-+      AUDIO_CODING_TYPE_DTS_HD                = 11,
-+      AUDIO_CODING_TYPE_MLP                   = 12,
-+      AUDIO_CODING_TYPE_DST                   = 13,
-+      AUDIO_CODING_TYPE_WMAPRO                = 14,
-+      AUDIO_CODING_TYPE_REF_CXT               = 15,
-+      /* also include valid xtypes below */
-+      AUDIO_CODING_TYPE_HE_AAC                = 15,
-+      AUDIO_CODING_TYPE_HE_AAC2               = 16,
-+      AUDIO_CODING_TYPE_MPEG_SURROUND         = 17,
-+};
-+
-+enum cea_audio_coding_xtypes {
-+      AUDIO_CODING_XTYPE_HE_REF_CT            = 0,
-+      AUDIO_CODING_XTYPE_HE_AAC               = 1,
-+      AUDIO_CODING_XTYPE_HE_AAC2              = 2,
-+      AUDIO_CODING_XTYPE_MPEG_SURROUND        = 3,
-+      AUDIO_CODING_XTYPE_FIRST_RESERVED       = 4,
-+};
-+
-+static char *cea_audio_coding_type_names[] = {
-+      /*  0 */ "undefined",
-+      /*  1 */ "LPCM",
-+      /*  2 */ "AC-3",
-+      /*  3 */ "MPEG1",
-+      /*  4 */ "MP3",
-+      /*  5 */ "MPEG2",
-+      /*  6 */ "AAC-LC",
-+      /*  7 */ "DTS",
-+      /*  8 */ "ATRAC",
-+      /*  9 */ "DSD (One Bit Audio)",
-+      /* 10 */ "E-AC-3/DD+ (Dolby Digital Plus)",
-+      /* 11 */ "DTS-HD",
-+      /* 12 */ "MLP (Dolby TrueHD)",
-+      /* 13 */ "DST",
-+      /* 14 */ "WMAPro",
-+      /* 15 */ "HE-AAC",
-+      /* 16 */ "HE-AACv2",
-+      /* 17 */ "MPEG Surround",
-+};
-+
-+/*
-+ * The following two lists are shared between
-+ *    - HDMI audio InfoFrame (source to sink)
-+ *    - CEA E-EDID Extension (sink to source)
-+ */
-+
-+/*
-+ * SS1:SS0 index => sample size
-+ */
-+static int cea_sample_sizes[4] = {
-+      0,                      /* 0: Refer to Stream Header */
-+      AC_SUPPCM_BITS_16,      /* 1: 16 bits */
-+      AC_SUPPCM_BITS_20,      /* 2: 20 bits */
-+      AC_SUPPCM_BITS_24,      /* 3: 24 bits */
-+};
-+
-+/*
-+ * SF2:SF1:SF0 index => sampling frequency
-+ */
-+static int cea_sampling_frequencies[8] = {
-+      0,                      /* 0: Refer to Stream Header */
-+      SNDRV_PCM_RATE_32000,   /* 1:  32000Hz */
-+      SNDRV_PCM_RATE_44100,   /* 2:  44100Hz */
-+      SNDRV_PCM_RATE_48000,   /* 3:  48000Hz */
-+      SNDRV_PCM_RATE_88200,   /* 4:  88200Hz */
-+      SNDRV_PCM_RATE_96000,   /* 5:  96000Hz */
-+      SNDRV_PCM_RATE_176400,  /* 6: 176400Hz */
-+      SNDRV_PCM_RATE_192000,  /* 7: 192000Hz */
-+};
-+
-+static unsigned char hdmi_get_eld_byte(struct hda_codec *codec, hda_nid_t nid,
-+                                      int byte_index)
-+{
-+      unsigned int val;
-+
-+      val = snd_hda_codec_read(codec, nid, 0,
-+                                      AC_VERB_GET_HDMI_ELDD, byte_index);
-+
-+#ifdef BE_PARANOID
-+      printk(KERN_INFO "HDMI: ELD data byte %d: 0x%x\n", byte_index, val);
-+#endif
-+
-+      if ((val & AC_ELDD_ELD_VALID) == 0) {
-+              snd_printd(KERN_INFO "HDMI: invalid ELD data byte %d\n",
-+                                                              byte_index);
-+              val = 0;
-+      }
-+
-+      return val & AC_ELDD_ELD_DATA;
-+}
-+
-+#define GRAB_BITS(buf, byte, lowbit, bits)            \
-+({                                                    \
-+      BUILD_BUG_ON(lowbit > 7);                       \
-+      BUILD_BUG_ON(bits > 8);                         \
-+      BUILD_BUG_ON(bits <= 0);                        \
-+                                                      \
-+      (buf[byte] >> (lowbit)) & ((1 << (bits)) - 1);  \
-+})
-+
-+static void hdmi_update_short_audio_desc(struct cea_sad *a,
-+                                       const unsigned char *buf)
-+{
-+      int i;
-+      int val;
-+
-+      val = GRAB_BITS(buf, 1, 0, 7);
-+      a->rates = 0;
-+      for (i = 0; i < 7; i++)
-+              if (val & (1 << i))
-+                      a->rates |= cea_sampling_frequencies[i + 1];
-+
-+      a->channels = GRAB_BITS(buf, 0, 0, 3);
-+      a->channels++;
-+
-+      a->format = GRAB_BITS(buf, 0, 3, 4);
-+      switch (a->format) {
-+      case AUDIO_CODING_TYPE_REF_STREAM_HEADER:
-+              snd_printd(KERN_INFO
-+                              "HDMI: audio coding type 0 not expected\n");
-+              break;
-+
-+      case AUDIO_CODING_TYPE_LPCM:
-+              val = GRAB_BITS(buf, 2, 0, 3);
-+              a->sample_bits = 0;
-+              for (i = 0; i < 3; i++)
-+                      if (val & (1 << i))
-+                              a->sample_bits |= cea_sample_sizes[i + 1];
-+              break;
-+
-+      case AUDIO_CODING_TYPE_AC3:
-+      case AUDIO_CODING_TYPE_MPEG1:
-+      case AUDIO_CODING_TYPE_MP3:
-+      case AUDIO_CODING_TYPE_MPEG2:
-+      case AUDIO_CODING_TYPE_AACLC:
-+      case AUDIO_CODING_TYPE_DTS:
-+      case AUDIO_CODING_TYPE_ATRAC:
-+              a->max_bitrate = GRAB_BITS(buf, 2, 0, 8);
-+              a->max_bitrate *= 8000;
-+              break;
-+
-+      case AUDIO_CODING_TYPE_SACD:
-+              break;
-+
-+      case AUDIO_CODING_TYPE_EAC3:
-+              break;
-+
-+      case AUDIO_CODING_TYPE_DTS_HD:
-+              break;
-+
-+      case AUDIO_CODING_TYPE_MLP:
-+              break;
-+
-+      case AUDIO_CODING_TYPE_DST:
-+              break;
-+
-+      case AUDIO_CODING_TYPE_WMAPRO:
-+              a->profile = GRAB_BITS(buf, 2, 0, 3);
-+              break;
-+
-+      case AUDIO_CODING_TYPE_REF_CXT:
-+              a->format = GRAB_BITS(buf, 2, 3, 5);
-+              if (a->format == AUDIO_CODING_XTYPE_HE_REF_CT ||
-+                  a->format >= AUDIO_CODING_XTYPE_FIRST_RESERVED) {
-+                      snd_printd(KERN_INFO
-+                              "HDMI: audio coding xtype %d not expected\n",
-+                              a->format);
-+                      a->format = 0;
-+              } else
-+                      a->format += AUDIO_CODING_TYPE_HE_AAC -
-+                                   AUDIO_CODING_XTYPE_HE_AAC;
-+              break;
-+      }
-+}
-+
-+/*
-+ * Be careful, ELD buf could be totally rubbish!
-+ */
-+static int hdmi_update_eld(struct hdmi_eld *e,
-+                         const unsigned char *buf, int size)
-+{
-+      int mnl;
-+      int i;
-+
-+      e->eld_ver = GRAB_BITS(buf, 0, 3, 5);
-+      if (e->eld_ver != ELD_VER_CEA_861D &&
-+          e->eld_ver != ELD_VER_PARTIAL) {
-+              snd_printd(KERN_INFO "HDMI: Unknown ELD version %d\n",
-+                                                              e->eld_ver);
-+              goto out_fail;
-+      }
-+
-+      e->eld_size = size;
-+      e->baseline_len = GRAB_BITS(buf, 2, 0, 8);
-+      mnl             = GRAB_BITS(buf, 4, 0, 5);
-+      e->cea_edid_ver = GRAB_BITS(buf, 4, 5, 3);
-+
-+      e->support_hdcp = GRAB_BITS(buf, 5, 0, 1);
-+      e->support_ai   = GRAB_BITS(buf, 5, 1, 1);
-+      e->conn_type    = GRAB_BITS(buf, 5, 2, 2);
-+      e->sad_count    = GRAB_BITS(buf, 5, 4, 4);
-+
-+      e->aud_synch_delay = GRAB_BITS(buf, 6, 0, 8) * 2;
-+      e->spk_alloc    = GRAB_BITS(buf, 7, 0, 7);
-+
-+      e->port_id        = get_unaligned_le64(buf + 8);
-+
-+      /* not specified, but the spec's tendency is little endian */
-+      e->manufacture_id = get_unaligned_le16(buf + 16);
-+      e->product_id     = get_unaligned_le16(buf + 18);
-+
-+      if (mnl > ELD_MAX_MNL) {
-+              snd_printd(KERN_INFO "HDMI: MNL is reserved value %d\n", mnl);
-+              goto out_fail;
-+      } else if (ELD_FIXED_BYTES + mnl > size) {
-+              snd_printd(KERN_INFO "HDMI: out of range MNL %d\n", mnl);
-+              goto out_fail;
-+      } else
-+              strlcpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl);
-+
-+      for (i = 0; i < e->sad_count; i++) {
-+              if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) {
-+                      snd_printd(KERN_INFO "HDMI: out of range SAD %d\n", i);
-+                      goto out_fail;
-+              }
-+              hdmi_update_short_audio_desc(e->sad + i,
-+                                      buf + ELD_FIXED_BYTES + mnl + 3 * i);
-+      }
-+
-+      return 0;
-+
-+out_fail:
-+      e->eld_ver = 0;
-+      return -EINVAL;
-+}
-+
-+static int hdmi_present_sense(struct hda_codec *codec, hda_nid_t nid)
-+{
-+      return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0);
-+}
-+
-+static int hdmi_eld_valid(struct hda_codec *codec, hda_nid_t nid)
-+{
-+      int eldv;
-+      int present;
-+
-+      present = hdmi_present_sense(codec, nid);
-+      eldv    = (present & AC_PINSENSE_ELDV);
-+      present = (present & AC_PINSENSE_PRESENCE);
-+
-+#ifdef CONFIG_SND_DEBUG_VERBOSE
-+      printk(KERN_INFO "HDMI: sink_present = %d, eld_valid = %d\n",
-+                      !!present, !!eldv);
-+#endif
-+
-+      return eldv && present;
-+}
-+
-+int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
-+{
-+      return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
-+                                               AC_DIPSIZE_ELD_BUF);
-+}
-+
-+int snd_hdmi_get_eld(struct hdmi_eld *eld,
-+                   struct hda_codec *codec, hda_nid_t nid)
-+{
-+      int i;
-+      int ret;
-+      int size;
-+      unsigned char *buf;
-+
-+      if (!hdmi_eld_valid(codec, nid))
-+              return -ENOENT;
-+
-+      size = snd_hdmi_get_eld_size(codec, nid);
-+      if (size == 0) {
-+              /* wfg: workaround for ASUS P5E-VM HDMI board */
-+              snd_printd(KERN_INFO "HDMI: ELD buf size is 0, force 128\n");
-+              size = 128;
-+      }
-+      if (size < ELD_FIXED_BYTES || size > PAGE_SIZE) {
-+              snd_printd(KERN_INFO "HDMI: invalid ELD buf size %d\n", size);
-+              return -ERANGE;
-+      }
-+
-+      buf = kmalloc(size, GFP_KERNEL);
-+      if (!buf)
-+              return -ENOMEM;
-+
-+      for (i = 0; i < size; i++)
-+              buf[i] = hdmi_get_eld_byte(codec, nid, i);
-+
-+      ret = hdmi_update_eld(eld, buf, size);
-+
-+      kfree(buf);
-+      return ret;
-+}
-+
-+static void hdmi_show_short_audio_desc(struct cea_sad *a)
-+{
-+      char buf[SND_PRINT_RATES_ADVISED_BUFSIZE];
-+      char buf2[8 + SND_PRINT_BITS_ADVISED_BUFSIZE] = ", bits =";
-+
-+      if (!a->format)
-+              return;
-+
-+      snd_print_pcm_rates(a->rates, buf, sizeof(buf));
-+
-+      if (a->format == AUDIO_CODING_TYPE_LPCM)
-+              snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2 - 8));
-+      else if (a->max_bitrate)
-+              snprintf(buf2, sizeof(buf2),
-+                              ", max bitrate = %d", a->max_bitrate);
-+      else
-+              buf2[0] = '\0';
-+
-+      printk(KERN_INFO "HDMI: supports coding type %s:"
-+                      " channels = %d, rates =%s%s\n",
-+                      cea_audio_coding_type_names[a->format],
-+                      a->channels,
-+                      buf,
-+                      buf2);
-+}
-+
-+void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
-+{
-+      int i, j;
-+
-+      for (i = 0, j = 0; i < ARRAY_SIZE(cea_speaker_allocation_names); i++) {
-+              if (spk_alloc & (1 << i))
-+                      j += snprintf(buf + j, buflen - j,  " %s",
-+                                      cea_speaker_allocation_names[i]);
-+      }
-+      buf[j] = '\0';  /* necessary when j == 0 */
-+}
-+
-+void snd_hdmi_show_eld(struct hdmi_eld *e)
-+{
-+      int i;
-+
-+      printk(KERN_INFO "HDMI: detected monitor %s at connection type %s\n",
-+                      e->monitor_name,
-+                      eld_connection_type_names[e->conn_type]);
-+
-+      if (e->spk_alloc) {
-+              char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
-+              snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf));
-+              printk(KERN_INFO "HDMI: available speakers:%s\n", buf);
-+      }
-+
-+      for (i = 0; i < e->sad_count; i++)
-+              hdmi_show_short_audio_desc(e->sad + i);
-+}
-+
-+#ifdef CONFIG_PROC_FS
-+
-+static void hdmi_print_sad_info(int i, struct cea_sad *a,
-+                              struct snd_info_buffer *buffer)
-+{
-+      char buf[SND_PRINT_RATES_ADVISED_BUFSIZE];
-+
-+      snd_iprintf(buffer, "sad%d_coding_type\t[0x%x] %s\n",
-+                      i, a->format, cea_audio_coding_type_names[a->format]);
-+      snd_iprintf(buffer, "sad%d_channels\t\t%d\n", i, a->channels);
-+
-+      snd_print_pcm_rates(a->rates, buf, sizeof(buf));
-+      snd_iprintf(buffer, "sad%d_rates\t\t[0x%x]%s\n", i, a->rates, buf);
-+
-+      if (a->format == AUDIO_CODING_TYPE_LPCM) {
-+              snd_print_pcm_bits(a->sample_bits, buf, sizeof(buf));
-+              snd_iprintf(buffer, "sad%d_bits\t\t[0x%x]%s\n",
-+                                                      i, a->sample_bits, buf);
-+      }
-+
-+      if (a->max_bitrate)
-+              snd_iprintf(buffer, "sad%d_max_bitrate\t%d\n",
-+                                                      i, a->max_bitrate);
-+
-+      if (a->profile)
-+              snd_iprintf(buffer, "sad%d_profile\t\t%d\n", i, a->profile);
-+}
-+
-+static void hdmi_print_eld_info(struct snd_info_entry *entry,
-+                              struct snd_info_buffer *buffer)
-+{
-+      struct hdmi_eld *e = entry->private_data;
-+      char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
-+      int i;
-+      static char *eld_versoin_names[32] = {
-+              "reserved",
-+              "reserved",
-+              "CEA-861D or below",
-+              [3 ... 30] = "reserved",
-+              [31] = "partial"
-+      };
-+      static char *cea_edid_version_names[8] = {
-+              "no CEA EDID Timing Extension block present",
-+              "CEA-861",
-+              "CEA-861-A",
-+              "CEA-861-B, C or D",
-+              [4 ... 7] = "reserved"
-+      };
-+
-+      snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name);
-+      snd_iprintf(buffer, "connection_type\t\t%s\n",
-+                              eld_connection_type_names[e->conn_type]);
-+      snd_iprintf(buffer, "eld_version\t\t[0x%x] %s\n", e->eld_ver,
-+                                      eld_versoin_names[e->eld_ver]);
-+      snd_iprintf(buffer, "edid_version\t\t[0x%x] %s\n", e->cea_edid_ver,
-+                              cea_edid_version_names[e->cea_edid_ver]);
-+      snd_iprintf(buffer, "manufacture_id\t\t0x%x\n", e->manufacture_id);
-+      snd_iprintf(buffer, "product_id\t\t0x%x\n", e->product_id);
-+      snd_iprintf(buffer, "port_id\t\t\t0x%llx\n", (long long)e->port_id);
-+      snd_iprintf(buffer, "support_hdcp\t\t%d\n", e->support_hdcp);
-+      snd_iprintf(buffer, "support_ai\t\t%d\n", e->support_ai);
-+      snd_iprintf(buffer, "audio_sync_delay\t%d\n", e->aud_synch_delay);
-+
-+      snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf));
-+      snd_iprintf(buffer, "speakers\t\t[0x%x]%s\n", e->spk_alloc, buf);
-+
-+      snd_iprintf(buffer, "sad_count\t\t%d\n", e->sad_count);
-+
-+      for (i = 0; i < e->sad_count; i++)
-+              hdmi_print_sad_info(i, e->sad + i, buffer);
-+}
-+
-+static void hdmi_write_eld_info(struct snd_info_entry *entry,
-+                              struct snd_info_buffer *buffer)
-+{
-+      struct hdmi_eld *e = entry->private_data;
-+      char line[64];
-+      char name[64];
-+      char *sname;
-+      long long val;
-+      int n;
-+
-+      while (!snd_info_get_line(buffer, line, sizeof(line))) {
-+              if (sscanf(line, "%s %llx", name, &val) != 2)
-+                      continue;
-+              /*
-+               * We don't allow modification to these fields:
-+               *      monitor_name manufacture_id product_id
-+               *      eld_version edid_version
-+               */
-+              if (!strcmp(name, "connection_type"))
-+                      e->conn_type = val;
-+              else if (!strcmp(name, "port_id"))
-+                      e->port_id = val;
-+              else if (!strcmp(name, "support_hdcp"))
-+                      e->support_hdcp = val;
-+              else if (!strcmp(name, "support_ai"))
-+                      e->support_ai = val;
-+              else if (!strcmp(name, "audio_sync_delay"))
-+                      e->aud_synch_delay = val;
-+              else if (!strcmp(name, "speakers"))
-+                      e->spk_alloc = val;
-+              else if (!strcmp(name, "sad_count"))
-+                      e->sad_count = val;
-+              else if (!strncmp(name, "sad", 3)) {
-+                      sname = name + 4;
-+                      n = name[3] - '0';
-+                      if (name[4] >= '0' && name[4] <= '9') {
-+                              sname++;
-+                              n = 10 * n + name[4] - '0';
-+                      }
-+                      if (n < 0 || n > 31) /* double the CEA limit */
-+                              continue;
-+                      if (!strcmp(sname, "_coding_type"))
-+                              e->sad[n].format = val;
-+                      else if (!strcmp(sname, "_channels"))
-+                              e->sad[n].channels = val;
-+                      else if (!strcmp(sname, "_rates"))
-+                              e->sad[n].rates = val;
-+                      else if (!strcmp(sname, "_bits"))
-+                              e->sad[n].sample_bits = val;
-+                      else if (!strcmp(sname, "_max_bitrate"))
-+                              e->sad[n].max_bitrate = val;
-+                      else if (!strcmp(sname, "_profile"))
-+                              e->sad[n].profile = val;
-+                      if (n >= e->sad_count)
-+                              e->sad_count = n + 1;
-+              }
-+      }
-+}
-+
-+
-+int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld)
-+{
-+      char name[32];
-+      struct snd_info_entry *entry;
-+      int err;
-+
-+      snprintf(name, sizeof(name), "eld#%d", codec->addr);
-+      err = snd_card_proc_new(codec->bus->card, name, &entry);
-+      if (err < 0)
-+              return err;
-+
-+      snd_info_set_text_ops(entry, eld, hdmi_print_eld_info);
-+      entry->c.text.write = hdmi_write_eld_info;
-+      entry->mode |= S_IWUSR;
-+      eld->proc_entry = entry;
-+
-+      return 0;
-+}
-+
-+void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
-+{
-+      if (!codec->bus->shutdown && eld->proc_entry) {
-+              snd_device_free(codec->bus->card, eld->proc_entry);
-+              eld->proc_entry = NULL;
-+      }
-+}
-+
-+#endif /* CONFIG_PROC_FS */
 diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
 index 59e4389..1d5797a 100644
 --- a/sound/pci/hda/hda_generic.c
@@ -4178,7 +3256,7 @@ index 6e18a42..1c57505 100644
 +
 +#endif /* CONFIG_SND_HDA_RECONFIG */
 diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
-index d9d2943..d1c03f9 100644
+index 0d1a74b..d1c03f9 100644
 --- a/sound/pci/hda/hda_intel.c
 +++ b/sound/pci/hda/hda_intel.c
 @@ -58,6 +58,7 @@ static char *model[SNDRV_CARDS];
@@ -4219,41 +3297,23 @@ index d9d2943..d1c03f9 100644
  
  /*
   */
-@@ -304,6 +312,8 @@ struct azx_dev {
+@@ -304,7 +312,6 @@ struct azx_dev {
        unsigned int period_bytes; /* size of the period in bytes */
        unsigned int frags;     /* number for period in the play buffer */
        unsigned int fifo_size; /* FIFO size */
-+      unsigned long start_jiffies;    /* start + minimum jiffies */
-+      unsigned long min_jiffies;      /* minimum jiffies before position is valid */
-       void __iomem *sd_addr;  /* stream descriptor pointer */
+-      unsigned int start_flag: 1;     /* stream full start flag */
+       unsigned long start_jiffies;    /* start + minimum jiffies */
+       unsigned long min_jiffies;      /* minimum jiffies before position is valid */
  
-@@ -322,7 +332,7 @@ struct azx_dev {
+@@ -325,6 +332,7 @@ struct azx_dev {
        unsigned int opened :1;
        unsigned int running :1;
        unsigned int irq_pending :1;
--      unsigned int irq_ignore :1;
 +      unsigned int start_flag: 1;     /* stream full start flag */
        /*
         * For VIA:
         *  A flag to ensure DMA position is 0
-@@ -373,6 +383,7 @@ struct azx {
-       /* HD codec */
-       unsigned short codec_mask;
-+      int  codec_probe_mask; /* copied from probe_mask option */
-       struct hda_bus *bus;
-       /* CORB/RIRB */
-@@ -392,6 +403,7 @@ struct azx {
-       unsigned int msi :1;
-       unsigned int irq_pending_warned :1;
-       unsigned int via_dmapos_patch :1; /* enable DMA-position fix for VIA */
-+      unsigned int probing :1; /* codec probing phase */
-       /* for debugging */
-       unsigned int last_cmd;  /* last issued command (to sync) */
-@@ -414,6 +426,7 @@ enum {
+@@ -418,6 +426,7 @@ enum {
        AZX_DRIVER_ULI,
        AZX_DRIVER_NVIDIA,
        AZX_DRIVER_TERA,
@@ -4261,7 +3321,7 @@ index d9d2943..d1c03f9 100644
        AZX_NUM_DRIVERS, /* keep this as last entry */
  };
  
-@@ -427,6 +440,7 @@ static char *driver_short_names[] __devinitdata = {
+@@ -431,6 +440,7 @@ static char *driver_short_names[] __devinitdata = {
        [AZX_DRIVER_ULI] = "HDA ULI M5461",
        [AZX_DRIVER_NVIDIA] = "HDA NVidia",
        [AZX_DRIVER_TERA] = "HDA Teradici", 
@@ -4269,313 +3329,67 @@ index d9d2943..d1c03f9 100644
  };
  
  /*
-@@ -527,9 +541,9 @@ static void azx_free_cmd_io(struct azx *chip)
- }
- /* send a command */
--static int azx_corb_send_cmd(struct hda_codec *codec, u32 val)
-+static int azx_corb_send_cmd(struct hda_bus *bus, u32 val)
- {
--      struct azx *chip = codec->bus->private_data;
-+      struct azx *chip = bus->private_data;
-       unsigned int wp;
-       /* add command to corb */
-@@ -577,9 +591,9 @@ static void azx_update_rirb(struct azx *chip)
- }
- /* receive a response */
--static unsigned int azx_rirb_get_response(struct hda_codec *codec)
-+static unsigned int azx_rirb_get_response(struct hda_bus *bus)
- {
--      struct azx *chip = codec->bus->private_data;
-+      struct azx *chip = bus->private_data;
-       unsigned long timeout;
-  again:
-@@ -596,7 +610,7 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
+@@ -596,7 +606,6 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
+               }
+               if (!chip->rirb.cmds) {
+                       smp_rmb();
+-                      bus->rirb_error = 0;
+                       return chip->rirb.res; /* the last value */
                }
                if (time_after(jiffies, timeout))
-                       break;
--              if (codec->bus->needs_damn_long_delay)
-+              if (bus->needs_damn_long_delay)
-                       msleep(2); /* temporary workaround */
-               else {
-                       udelay(10);
-@@ -624,6 +638,14 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
+@@ -616,10 +625,8 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
+               chip->irq = -1;
+               pci_disable_msi(chip->pci);
+               chip->msi = 0;
+-              if (azx_acquire_irq(chip, 1) < 0) {
+-                      bus->rirb_error = 1;
++              if (azx_acquire_irq(chip, 1) < 0)
+                       return -1;
+-              }
                goto again;
        }
  
-+      if (chip->probing) {
-+              /* If this critical timeout happens during the codec probing
-+               * phase, this is likely an access to a non-existing codec
-+               * slot.  Better to return an error and reset the system.
-+               */
-+              return -1;
-+      }
-+
-       snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, "
-                  "switching to single_cmd mode: last cmd=0x%08x\n",
-                  chip->last_cmd);
-@@ -646,9 +668,9 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
-  */
- /* send a command */
--static int azx_single_send_cmd(struct hda_codec *codec, u32 val)
-+static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
- {
--      struct azx *chip = codec->bus->private_data;
-+      struct azx *chip = bus->private_data;
-       int timeout = 50;
-       while (timeout--) {
-@@ -671,9 +693,9 @@ static int azx_single_send_cmd(struct hda_codec *codec, u32 val)
- }
- /* receive a response */
--static unsigned int azx_single_get_response(struct hda_codec *codec)
-+static unsigned int azx_single_get_response(struct hda_bus *bus)
- {
--      struct azx *chip = codec->bus->private_data;
-+      struct azx *chip = bus->private_data;
-       int timeout = 50;
-       while (timeout--) {
-@@ -696,38 +718,29 @@ static unsigned int azx_single_get_response(struct hda_codec *codec)
-  */
- /* send a command */
--static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid,
--                      int direct, unsigned int verb,
--                      unsigned int para)
--{
--      struct azx *chip = codec->bus->private_data;
--      u32 val;
--
--      val = (u32)(codec->addr & 0x0f) << 28;
--      val |= (u32)direct << 27;
--      val |= (u32)nid << 20;
--      val |= verb << 8;
--      val |= para;
--      chip->last_cmd = val;
-+static int azx_send_cmd(struct hda_bus *bus, unsigned int val)
-+{
-+      struct azx *chip = bus->private_data;
-+      chip->last_cmd = val;
-       if (chip->single_cmd)
--              return azx_single_send_cmd(codec, val);
-+              return azx_single_send_cmd(bus, val);
-       else
--              return azx_corb_send_cmd(codec, val);
-+              return azx_corb_send_cmd(bus, val);
- }
- /* get a response */
--static unsigned int azx_get_response(struct hda_codec *codec)
-+static unsigned int azx_get_response(struct hda_bus *bus)
- {
--      struct azx *chip = codec->bus->private_data;
-+      struct azx *chip = bus->private_data;
-       if (chip->single_cmd)
--              return azx_single_get_response(codec);
-+              return azx_single_get_response(bus);
-       else
--              return azx_rirb_get_response(codec);
-+              return azx_rirb_get_response(bus);
- }
- #ifdef CONFIG_SND_HDA_POWER_SAVE
--static void azx_power_notify(struct hda_codec *codec);
-+static void azx_power_notify(struct hda_bus *bus);
- #endif
- /* reset codec link */
-@@ -848,13 +861,18 @@ static void azx_stream_start(struct azx *chip, struct azx_dev *azx_dev)
-                     SD_CTL_DMA_START | SD_INT_MASK);
- }
--/* stop a stream */
--static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
-+/* stop DMA */
-+static void azx_stream_clear(struct azx *chip, struct azx_dev *azx_dev)
- {
--      /* stop DMA */
-       azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) &
-                     ~(SD_CTL_DMA_START | SD_INT_MASK));
-       azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */
-+}
-+
-+/* stop a stream */
-+static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
-+{
-+      azx_stream_clear(chip, azx_dev);
-       /* disable SIE */
-       azx_writeb(chip, INTCTL,
-                  azx_readb(chip, INTCTL) & ~(1 << azx_dev->index));
-@@ -959,7 +977,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
-       struct azx *chip = dev_id;
-       struct azx_dev *azx_dev;
-       u32 status;
--      int i;
-+      int i, ok;
-       spin_lock(&chip->reg_lock);
-@@ -975,21 +993,18 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
-                       azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK);
-                       if (!azx_dev->substream || !azx_dev->running)
-                               continue;
--                      /* ignore the first dummy IRQ (due to pos_adj) */
--                      if (azx_dev->irq_ignore) {
--                              azx_dev->irq_ignore = 0;
--                              continue;
--                      }
-                       /* check whether this IRQ is really acceptable */
--                      if (azx_position_ok(chip, azx_dev)) {
-+                      ok = azx_position_ok(chip, azx_dev);
-+                      if (ok == 1) {
-                               azx_dev->irq_pending = 0;
-                               spin_unlock(&chip->reg_lock);
-                               snd_pcm_period_elapsed(azx_dev->substream);
-                               spin_lock(&chip->reg_lock);
--                      } else {
-+                      } else if (ok == 0 && chip->bus && chip->bus->workq) {
-                               /* bogus IRQ, process it later */
-                               azx_dev->irq_pending = 1;
--                              schedule_work(&chip->irq_pending_work);
-+                              queue_work(chip->bus->workq,
-+                                         &chip->irq_pending_work);
-                       }
-               }
-       }
-@@ -1067,15 +1082,13 @@ static int azx_setup_periods(struct azx *chip,
-       azx_sd_writel(azx_dev, SD_BDLPL, 0);
-       azx_sd_writel(azx_dev, SD_BDLPU, 0);
--      period_bytes = snd_pcm_lib_period_bytes(substream);
--      azx_dev->period_bytes = period_bytes;
-+      period_bytes = azx_dev->period_bytes;
-       periods = azx_dev->bufsize / period_bytes;
-       /* program the initial BDL entries */
-       bdl = (u32 *)azx_dev->bdl.area;
-       ofs = 0;
-       azx_dev->frags = 0;
--      azx_dev->irq_ignore = 0;
-       pos_adj = bdl_pos_adj[chip->dev_index];
-       if (pos_adj > 0) {
-               struct snd_pcm_runtime *runtime = substream->runtime;
-@@ -1096,7 +1109,6 @@ static int azx_setup_periods(struct azx *chip,
-                                        &bdl, ofs, pos_adj, 1);
-                       if (ofs < 0)
-                               goto error;
--                      azx_dev->irq_ignore = 1;
-               }
-       } else
-               pos_adj = 0;
-@@ -1115,24 +1127,17 @@ static int azx_setup_periods(struct azx *chip,
-  error:
-       snd_printk(KERN_ERR "Too many BDL entries: buffer=%d, period=%d\n",
-                  azx_dev->bufsize, period_bytes);
--      /* reset */
--      azx_sd_writel(azx_dev, SD_BDLPL, 0);
--      azx_sd_writel(azx_dev, SD_BDLPU, 0);
-       return -EINVAL;
+@@ -639,12 +646,14 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
+               return -1;
+       }
+-      snd_printk(KERN_ERR "hda_intel: azx_get_response timeout (ERROR): "
+-                 "last cmd=0x%08x\n", chip->last_cmd);
+-      spin_lock_irq(&chip->reg_lock);
+-      chip->rirb.cmds = 0; /* reset the index */
+-      bus->rirb_error = 1;
+-      spin_unlock_irq(&chip->reg_lock);
++      snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, "
++                 "switching to single_cmd mode: last cmd=0x%08x\n",
++                 chip->last_cmd);
++      chip->rirb.rp = azx_readb(chip, RIRBWP);
++      chip->rirb.cmds = 0;
++      /* switch to single_cmd mode */
++      chip->single_cmd = 1;
++      azx_free_cmd_io(chip);
+       return -1;
  }
  
--/*
-- * set up the SD for streaming
-- */
--static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
-+/* reset stream */
-+static void azx_stream_reset(struct azx *chip, struct azx_dev *azx_dev)
- {
-       unsigned char val;
-       int timeout;
--      /* make sure the run bit is zero for SD */
--      azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) &
--                    ~SD_CTL_DMA_START);
--      /* reset stream */
-+      azx_stream_clear(chip, azx_dev);
-+
-       azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) |
-                     SD_CTL_STREAM_RESET);
-       udelay(3);
-@@ -1150,6 +1155,17 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
-              --timeout)
-               ;
-+      /* reset first position - may not be synced with hw at this time */
-+      *azx_dev->posbuf = 0;
-+}
-+
-+/*
-+ * set up the SD for streaming
-+ */
-+static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
-+{
-+      /* make sure the run bit is zero for SD */
-+      azx_stream_clear(chip, azx_dev);
-       /* program the stream_tag */
-       azx_sd_writel(azx_dev, SD_CTL,
-                     (azx_sd_readl(azx_dev, SD_CTL) & ~SD_CTL_STREAM_TAG_MASK)|
-@@ -1187,6 +1203,28 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
+@@ -1213,6 +1222,8 @@ static int probe_codec(struct azx *chip, int addr)
        return 0;
  }
  
-+/*
-+ * Probe the given codec address
-+ */
-+static int probe_codec(struct azx *chip, int addr)
-+{
-+      unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) |
-+              (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
-+      unsigned int res;
-+
-+      chip->probing = 1;
-+      azx_send_cmd(chip->bus, cmd);
-+      res = azx_get_response(chip->bus);
-+      chip->probing = 0;
-+      if (res == -1)
-+              return -EIO;
-+      snd_printdd("hda_intel: codec #%d probed OK\n", addr);
-+      return 0;
-+}
-+
 +static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
 +                               struct hda_pcm *cpcm);
-+static void azx_stop_chip(struct azx *chip);
+ static void azx_stop_chip(struct azx *chip);
  
  /*
-  * Codec initialization
-@@ -1197,21 +1235,12 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
+@@ -1224,7 +1235,8 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
        [AZX_DRIVER_TERA] = 1,
  };
  
--/* number of slots to probe as default
-- * this can be different from azx_max_codecs[] -- e.g. some boards
-- * report wrongly the non-existing 4th slot availability
-- */
--static unsigned int azx_default_codecs[AZX_NUM_DRIVERS] __devinitdata = {
--      [AZX_DRIVER_ICH] = 3,
--      [AZX_DRIVER_ATI] = 3,
--};
--
- static int __devinit azx_codec_create(struct azx *chip, const char *model,
--                                    unsigned int codec_probe_mask)
+-static int __devinit azx_codec_create(struct azx *chip, const char *model)
++static int __devinit azx_codec_create(struct azx *chip, const char *model,
 +                                    int no_init)
  {
        struct hda_bus_template bus_temp;
--      int c, codecs, audio_codecs, err;
--      int def_slots, max_slots;
-+      int c, codecs, err;
-+      int max_slots;
-       memset(&bus_temp, 0, sizeof(bus_temp));
-       bus_temp.private_data = chip;
-@@ -1219,7 +1248,9 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
+       int c, codecs, err;
+@@ -1236,7 +1248,9 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
        bus_temp.pci = chip->pci;
        bus_temp.ops.command = azx_send_cmd;
        bus_temp.ops.get_response = azx_get_response;
@@ -4585,199 +3399,16 @@ index d9d2943..d1c03f9 100644
        bus_temp.ops.pm_notify = azx_power_notify;
  #endif
  
-@@ -1230,33 +1261,43 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
-       if (chip->driver_type == AZX_DRIVER_NVIDIA)
-               chip->bus->needs_damn_long_delay = 1;
--      codecs = audio_codecs = 0;
-+      codecs = 0;
-       max_slots = azx_max_codecs[chip->driver_type];
-       if (!max_slots)
-               max_slots = AZX_MAX_CODECS;
--      def_slots = azx_default_codecs[chip->driver_type];
--      if (!def_slots)
--              def_slots = max_slots;
--      for (c = 0; c < def_slots; c++) {
--              if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
-+
-+      /* First try to probe all given codec slots */
-+      for (c = 0; c < max_slots; c++) {
-+              if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
-+                      if (probe_codec(chip, c) < 0) {
-+                              /* Some BIOSen give you wrong codec addresses
-+                               * that don't exist
-+                               */
-+                              snd_printk(KERN_WARNING
-+                                         "hda_intel: Codec #%d probe error; "
-+                                         "disabling it...\n", c);
-+                              chip->codec_mask &= ~(1 << c);
-+                              /* More badly, accessing to a non-existing
-+                               * codec often screws up the controller chip,
-+                               * and distrubs the further communications.
-+                               * Thus if an error occurs during probing,
-+                               * better to reset the controller chip to
-+                               * get back to the sanity state.
-+                               */
-+                              azx_stop_chip(chip);
-+                              azx_init_chip(chip);
-+                      }
-+              }
-+      }
-+
-+      /* Then create codec instances */
-+      for (c = 0; c < max_slots; c++) {
-+              if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
+@@ -1280,7 +1294,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
+       for (c = 0; c < max_slots; c++) {
+               if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
                        struct hda_codec *codec;
 -                      err = snd_hda_codec_new(chip->bus, c, &codec);
 +                      err = snd_hda_codec_new(chip->bus, c, !no_init, &codec);
                        if (err < 0)
                                continue;
                        codecs++;
--                      if (codec->afg)
--                              audio_codecs++;
--              }
--      }
--      if (!audio_codecs) {
--              /* probe additional slots if no codec is found */
--              for (; c < max_slots; c++) {
--                      if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
--                              err = snd_hda_codec_new(chip->bus, c, NULL);
--                              if (err < 0)
--                                      continue;
--                              codecs++;
--                      }
-               }
-       }
-       if (!codecs) {
-@@ -1369,6 +1410,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
-       runtime->private_data = azx_dev;
-       snd_pcm_set_sync(substream);
-       mutex_unlock(&chip->open_mutex);
-+
-       return 0;
- }
-@@ -1395,6 +1437,11 @@ static int azx_pcm_close(struct snd_pcm_substream *substream)
- static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
-                            struct snd_pcm_hw_params *hw_params)
- {
-+      struct azx_dev *azx_dev = get_azx_dev(substream);
-+
-+      azx_dev->bufsize = 0;
-+      azx_dev->period_bytes = 0;
-+      azx_dev->format_val = 0;
-       return snd_pcm_lib_malloc_pages(substream,
-                                       params_buffer_bytes(hw_params));
- }
-@@ -1409,6 +1456,9 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
-       azx_sd_writel(azx_dev, SD_BDLPL, 0);
-       azx_sd_writel(azx_dev, SD_BDLPU, 0);
-       azx_sd_writel(azx_dev, SD_CTL, 0);
-+      azx_dev->bufsize = 0;
-+      azx_dev->period_bytes = 0;
-+      azx_dev->format_val = 0;
-       hinfo->ops.cleanup(hinfo, apcm->codec, substream);
-@@ -1422,23 +1472,40 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
-       struct azx_dev *azx_dev = get_azx_dev(substream);
-       struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
-       struct snd_pcm_runtime *runtime = substream->runtime;
-+      unsigned int bufsize, period_bytes, format_val;
-+      int err;
--      azx_dev->bufsize = snd_pcm_lib_buffer_bytes(substream);
--      azx_dev->format_val = snd_hda_calc_stream_format(runtime->rate,
--                                                       runtime->channels,
--                                                       runtime->format,
--                                                       hinfo->maxbps);
--      if (!azx_dev->format_val) {
-+      azx_stream_reset(chip, azx_dev);
-+      format_val = snd_hda_calc_stream_format(runtime->rate,
-+                                              runtime->channels,
-+                                              runtime->format,
-+                                              hinfo->maxbps);
-+      if (!format_val) {
-               snd_printk(KERN_ERR SFX
-                          "invalid format_val, rate=%d, ch=%d, format=%d\n",
-                          runtime->rate, runtime->channels, runtime->format);
-               return -EINVAL;
-       }
-+      bufsize = snd_pcm_lib_buffer_bytes(substream);
-+      period_bytes = snd_pcm_lib_period_bytes(substream);
-+
-       snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n",
--                  azx_dev->bufsize, azx_dev->format_val);
--      if (azx_setup_periods(chip, substream, azx_dev) < 0)
--              return -EINVAL;
-+                  bufsize, format_val);
-+
-+      if (bufsize != azx_dev->bufsize ||
-+          period_bytes != azx_dev->period_bytes ||
-+          format_val != azx_dev->format_val) {
-+              azx_dev->bufsize = bufsize;
-+              azx_dev->period_bytes = period_bytes;
-+              azx_dev->format_val = format_val;
-+              err = azx_setup_periods(chip, substream, azx_dev);
-+              if (err < 0)
-+                      return err;
-+      }
-+
-+      azx_dev->min_jiffies = (runtime->period_size * HZ) /
-+                                              (runtime->rate * 2);
-       azx_setup_controller(chip, azx_dev);
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1;
-@@ -1455,13 +1522,14 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-       struct azx *chip = apcm->chip;
-       struct azx_dev *azx_dev;
-       struct snd_pcm_substream *s;
--      int start, nsync = 0, sbits = 0;
-+      int rstart = 0, start, nsync = 0, sbits = 0;
-       int nwait, timeout;
-       switch (cmd) {
-+      case SNDRV_PCM_TRIGGER_START:
-+              rstart = 1;
-       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-       case SNDRV_PCM_TRIGGER_RESUME:
--      case SNDRV_PCM_TRIGGER_START:
-               start = 1;
-               break;
-       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-@@ -1491,6 +1559,10 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-               if (s->pcm->card != substream->pcm->card)
-                       continue;
-               azx_dev = get_azx_dev(s);
-+              if (rstart) {
-+                      azx_dev->start_flag = 1;
-+                      azx_dev->start_jiffies = jiffies + azx_dev->min_jiffies;
-+              }
-               if (start)
-                       azx_stream_start(chip, azx_dev);
-               else
-@@ -1640,6 +1712,11 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
- {
-       unsigned int pos;
-+      if (azx_dev->start_flag &&
-+          time_before_eq(jiffies, azx_dev->start_jiffies))
-+              return -1;      /* bogus (too early) interrupt */
-+      azx_dev->start_flag = 0;
-+
-       pos = azx_get_position(chip, azx_dev);
-       if (chip->position_fix == POS_FIX_AUTO) {
-               if (!pos) {
-@@ -1708,7 +1785,6 @@ static void azx_clear_irq_pending(struct azx *chip)
-       for (i = 0; i < chip->num_streams; i++)
-               chip->azx_dev[i].irq_pending = 0;
-       spin_unlock_irq(&chip->reg_lock);
--      flush_scheduled_work();
- }
- static struct snd_pcm_ops azx_pcm_ops = {
-@@ -1725,110 +1801,59 @@ static struct snd_pcm_ops azx_pcm_ops = {
+@@ -1787,110 +1801,59 @@ static struct snd_pcm_ops azx_pcm_ops = {
  
  static void azx_pcm_free(struct snd_pcm *pcm)
  {
@@ -4922,24 +3553,7 @@ index d9d2943..d1c03f9 100644
        return 0;
  }
  
-@@ -1905,13 +1930,13 @@ static void azx_stop_chip(struct azx *chip)
- #ifdef CONFIG_SND_HDA_POWER_SAVE
- /* power-up/down the controller */
--static void azx_power_notify(struct hda_codec *codec)
-+static void azx_power_notify(struct hda_bus *bus)
- {
--      struct azx *chip = codec->bus->private_data;
-+      struct azx *chip = bus->private_data;
-       struct hda_codec *c;
-       int power_on = 0;
--      list_for_each_entry(c, &codec->bus->codec_list, list) {
-+      list_for_each_entry(c, &bus->codec_list, list) {
-               if (c->power_on) {
-                       power_on = 1;
-                       break;
-@@ -1928,6 +1953,18 @@ static void azx_power_notify(struct hda_codec *codec)
+@@ -1990,6 +1953,18 @@ static void azx_power_notify(struct hda_bus *bus)
  /*
   * power management
   */
@@ -4958,114 +3572,31 @@ index d9d2943..d1c03f9 100644
  static int azx_suspend(struct pci_dev *pci, pm_message_t state)
  {
        struct snd_card *card = pci_get_drvdata(pci);
-@@ -2065,26 +2102,31 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
- {
-       const struct snd_pci_quirk *q;
--      /* Check VIA HD Audio Controller exist */
--      if (chip->pci->vendor == PCI_VENDOR_ID_VIA &&
--          chip->pci->device == VIA_HDAC_DEVICE_ID) {
-+      switch (fix) {
-+      case POS_FIX_LPIB:
-+      case POS_FIX_POSBUF:
-+              return fix;
-+      }
-+
-+      /* Check VIA/ATI HD Audio Controller exist */
-+      switch (chip->driver_type) {
-+      case AZX_DRIVER_VIA:
-+      case AZX_DRIVER_ATI:
-               chip->via_dmapos_patch = 1;
-               /* Use link position directly, avoid any transfer problem. */
-               return POS_FIX_LPIB;
-       }
-       chip->via_dmapos_patch = 0;
--      if (fix == POS_FIX_AUTO) {
--              q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
--              if (q) {
--                      printk(KERN_INFO
--                                  "hda_intel: position_fix set to %d "
--                                  "for device %04x:%04x\n",
--                                  q->value, q->subvendor, q->subdevice);
--                      return q->value;
--              }
-+      q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
-+      if (q) {
-+              printk(KERN_INFO
-+                     "hda_intel: position_fix set to %d "
-+                     "for device %04x:%04x\n",
-+                     q->value, q->subvendor, q->subdevice);
-+              return q->value;
-       }
--      return fix;
-+      return POS_FIX_AUTO;
- }
- /*
-@@ -2099,23 +2141,39 @@ static struct snd_pci_quirk probe_mask_list[] __devinitdata = {
-       SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X/T/R61", 0x01),
-       /* broken BIOS */
-       SND_PCI_QUIRK(0x1028, 0x20ac, "Dell Studio Desktop", 0x01),
-+      /* including bogus ALC268 in slot#2 that conflicts with ALC888 */
-+      SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01),
-+      /* forced codec slots */
+@@ -2169,6 +2144,7 @@ static struct snd_pci_quirk probe_mask_list[] __devinitdata = {
+       /* including bogus ALC268 in slot#2 that conflicts with ALC888 */
+       SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01),
+       /* forced codec slots */
 +      SND_PCI_QUIRK(0x1043, 0x1262, "ASUS W5Fm", 0x103),
-+      SND_PCI_QUIRK(0x1046, 0x1262, "ASUS W5F", 0x103),
+       SND_PCI_QUIRK(0x1046, 0x1262, "ASUS W5F", 0x103),
        {}
  };
+@@ -2299,11 +2275,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
+               gcap &= ~0x01;
  
-+#define AZX_FORCE_CODEC_MASK  0x100
-+
- static void __devinit check_probe_mask(struct azx *chip, int dev)
- {
-       const struct snd_pci_quirk *q;
--      if (probe_mask[dev] == -1) {
-+      chip->codec_probe_mask = probe_mask[dev];
-+      if (chip->codec_probe_mask == -1) {
-               q = snd_pci_quirk_lookup(chip->pci, probe_mask_list);
-               if (q) {
-                       printk(KERN_INFO
-                              "hda_intel: probe_mask set to 0x%x "
-                              "for device %04x:%04x\n",
-                              q->value, q->subvendor, q->subdevice);
--                      probe_mask[dev] = q->value;
-+                      chip->codec_probe_mask = q->value;
-               }
-       }
-+
-+      /* check forced option */
-+      if (chip->codec_probe_mask != -1 &&
-+          (chip->codec_probe_mask & AZX_FORCE_CODEC_MASK)) {
-+              chip->codec_mask = chip->codec_probe_mask & 0xff;
-+              printk(KERN_INFO "hda_intel: codec_mask forced to 0x%x\n",
-+                     chip->codec_mask);
-+      }
- }
-@@ -2212,9 +2270,17 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
-       gcap = azx_readw(chip, GCAP);
-       snd_printdd("chipset global capabilities = 0x%x\n", gcap);
-+      /* ATI chips seems buggy about 64bit DMA addresses */
-+      if (chip->driver_type == AZX_DRIVER_ATI)
-+              gcap &= ~0x01;
-+
        /* allow 64bit DMA address if supported by H/W */
 -      if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_64BIT_MASK))
 -              pci_set_consistent_dma_mask(pci, DMA_64BIT_MASK);
 +      if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
 +              pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
-+      else {
+       else {
+-              pci_set_dma_mask(pci, DMA_32BIT_MASK);
+-              pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK);
 +              pci_set_dma_mask(pci, DMA_BIT_MASK(32));
 +              pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32));
-+      }
+       }
  
        /* read number of streams from GCAP register instead of using
-        * hardcoded value
-@@ -2233,6 +2299,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
+@@ -2323,6 +2299,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
                        chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
                        chip->capture_streams = ATIHDMI_NUM_CAPTURE;
                        break;
@@ -5073,70 +3604,22 @@ index d9d2943..d1c03f9 100644
                default:
                        chip->playback_streams = ICH6_NUM_PLAYBACK;
                        chip->capture_streams = ICH6_NUM_CAPTURE;
-@@ -2342,40 +2409,30 @@ static int __devinit azx_probe(struct pci_dev *pci,
-       }
-       err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
--      if (err < 0) {
--              snd_card_free(card);
--              return err;
--      }
-+      if (err < 0)
-+              goto out_free;
+@@ -2437,12 +2414,12 @@ static int __devinit azx_probe(struct pci_dev *pci,
        card->private_data = chip;
  
        /* create codec instances */
--      err = azx_codec_create(chip, model[dev], probe_mask[dev]);
--      if (err < 0) {
--              snd_card_free(card);
--              return err;
--      }
+-      err = azx_codec_create(chip, model[dev]);
 +      err = azx_codec_create(chip, model[dev], probe_only[dev]);
-+      if (err < 0)
-+              goto out_free;
+       if (err < 0)
+               goto out_free;
  
        /* create PCM streams */
 -      err = azx_pcm_create(chip);
--      if (err < 0) {
--              snd_card_free(card);
--              return err;
--      }
 +      err = snd_hda_build_pcms(chip->bus);
-+      if (err < 0)
-+              goto out_free;
-       /* create mixer controls */
-       err = azx_mixer_create(chip);
--      if (err < 0) {
--              snd_card_free(card);
--              return err;
--      }
-+      if (err < 0)
-+              goto out_free;
-       snd_card_set_dev(card, &pci->dev);
-       err = snd_card_register(card);
--      if (err < 0) {
--              snd_card_free(card);
--              return err;
--      }
-+      if (err < 0)
-+              goto out_free;
-       pci_set_drvdata(pci, card);
-       chip->running = 1;
-@@ -2384,6 +2441,9 @@ static int __devinit azx_probe(struct pci_dev *pci,
-       dev++;
-       return err;
-+out_free:
-+      snd_card_free(card);
-+      return err;
- }
+       if (err < 0)
+               goto out_free;
  
- static void __devexit azx_remove(struct pci_dev *pci)
-@@ -2451,12 +2511,17 @@ static struct pci_device_id azx_ids[] = {
+@@ -2534,12 +2511,17 @@ static struct pci_device_id azx_ids[] = {
        { PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA },
        { PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA },
        { PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA },
@@ -5362,34 +3845,6 @@ index 3018b76..8334901 100644
 +void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen);
 +
  #endif /* __SOUND_HDA_LOCAL_H */
-diff --git a/sound/pci/hda/hda_patch.h b/sound/pci/hda/hda_patch.h
-deleted file mode 100644
-index dfbcfa8..0000000
---- a/sound/pci/hda/hda_patch.h
-+++ /dev/null
-@@ -1,22 +0,0 @@
--/*
-- * HDA Patches - included by hda_codec.c
-- */
--
--/* Realtek codecs */
--extern struct hda_codec_preset snd_hda_preset_realtek[];
--/* C-Media codecs */
--extern struct hda_codec_preset snd_hda_preset_cmedia[];
--/* Analog Devices codecs */
--extern struct hda_codec_preset snd_hda_preset_analog[];
--/* SigmaTel codecs */
--extern struct hda_codec_preset snd_hda_preset_sigmatel[];
--/* SiLabs 3054/3055 modem codecs */
--extern struct hda_codec_preset snd_hda_preset_si3054[];
--/* ATI HDMI codecs */
--extern struct hda_codec_preset snd_hda_preset_atihdmi[];
--/* Conexant audio codec */
--extern struct hda_codec_preset snd_hda_preset_conexant[];
--/* VIA codecs */
--extern struct hda_codec_preset snd_hda_preset_via[];
--/* NVIDIA HDMI codecs */
--extern struct hda_codec_preset snd_hda_preset_nvhdmi[];
 diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
 index 0890528..93d7499 100644
 --- a/sound/pci/hda/hda_proc.c
@@ -5608,7 +4063,7 @@ index 0890528..93d7499 100644
        snd_hda_power_down(codec);
  }
 diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
-index 10fe100..84cc49c 100644
+index d26f31c..84cc49c 100644
 --- a/sound/pci/hda/patch_analog.c
 +++ b/sound/pci/hda/patch_analog.c
 @@ -27,12 +27,12 @@
@@ -6097,13 +4552,11 @@ index 10fe100..84cc49c 100644
        /* Analog mixer; mute as default */
        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-@@ -3233,8 +3256,8 @@ static const char *ad1884_slave_vols[] = {
-       "Mic Playback Volume",
+@@ -3234,7 +3257,7 @@ static const char *ad1884_slave_vols[] = {
        "CD Playback Volume",
        "Internal Mic Playback Volume",
--      "Docking Mic Playback Volume"
+       "Docking Mic Playback Volume",
 -      "Beep Playback Volume",
-+      "Docking Mic Playback Volume",
 +      /* "Beep Playback Volume", */
        "IEC958 Playback Volume",
        NULL
@@ -6208,57 +4661,7 @@ index 10fe100..84cc49c 100644
        HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
-@@ -3798,6 +3817,49 @@ static struct hda_verb ad1884a_laptop_verbs[] = {
-       { } /* end */
- };
-+static struct hda_verb ad1884a_mobile_verbs[] = {
-+      /* DACs; unmute as default */
-+      {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
-+      {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
-+      /* Port-A (HP) mixer - route only from analog mixer */
-+      {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-+      {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-+      /* Port-A pin */
-+      {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-+      /* Port-A (HP) pin - always unmuted */
-+      {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-+      /* Port-B (mic jack) pin */
-+      {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-+      {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
-+      /* Port-C (int mic) pin */
-+      {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-+      {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
-+      /* Port-F (int speaker) mixer - route only from analog mixer */
-+      {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-+      {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-+      /* Port-F pin */
-+      {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-+      {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-+      /* Analog mixer; mute as default */
-+      {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-+      {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-+      {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-+      {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-+      {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-+      {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
-+      /* Analog Mix output amp */
-+      {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-+      /* capture sources */
-+      /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
-+      {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-+      {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
-+      {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-+      /* unsolicited event for pin-sense */
-+      {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
-+      {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
-+      { } /* end */
-+};
-+
- /*
-  * Thinkpad X300
-  * 0x11 - HP
-@@ -3830,8 +3892,6 @@ static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
+@@ -3873,8 +3892,6 @@ static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
        HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
@@ -6267,27 +4670,32 @@ index 10fe100..84cc49c 100644
        HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
-@@ -3905,16 +3965,9 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
+@@ -3948,21 +3965,9 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
        SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP),
        SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
 -      SND_PCI_QUIRK(0x103c, 0x3072, "HP", AD1884A_MOBILE),
 -      SND_PCI_QUIRK(0x103c, 0x3073, "HP", AD1884A_MOBILE),
+-      SND_PCI_QUIRK(0x103c, 0x3074, "HP", AD1884A_MOBILE),
+-      SND_PCI_QUIRK(0x103c, 0x3075, "HP", AD1884A_MOBILE),
 -      SND_PCI_QUIRK(0x103c, 0x3076, "HP", AD1884A_MOBILE),
 -      SND_PCI_QUIRK(0x103c, 0x3077, "HP", AD1884A_MOBILE),
+-      SND_PCI_QUIRK(0x103c, 0x3078, "HP", AD1884A_MOBILE),
 -      SND_PCI_QUIRK(0x103c, 0x3079, "HP", AD1884A_MOBILE),
 -      SND_PCI_QUIRK(0x103c, 0x307a, "HP", AD1884A_MOBILE),
+-      SND_PCI_QUIRK(0x103c, 0x30e1, "HP 2530p", AD1884A_LAPTOP),
 -      SND_PCI_QUIRK(0x103c, 0x30e6, "HP 6730b", AD1884A_LAPTOP),
 -      SND_PCI_QUIRK(0x103c, 0x30e7, "HP EliteBook 8530p", AD1884A_LAPTOP),
--      SND_PCI_QUIRK(0x103c, 0x30db, "HP EliteBook 6930p", AD1884A_LAPTOP),
+-      SND_PCI_QUIRK(0x103c, 0x360d, "HP 6530b", AD1884A_LAPTOP),
 -      SND_PCI_QUIRK(0x103c, 0x3614, "HP 6730s", AD1884A_LAPTOP),
+-      SND_PCI_QUIRK(0x103c, 0x3632, "HP", AD1884A_MOBILE),
 +      SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x3070, "HP", AD1884A_MOBILE),
 +      SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30e0, "HP laptop", AD1884A_LAPTOP),
 +      SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP),
        SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
        {}
  };
-@@ -3922,7 +3975,7 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
+@@ -3970,7 +3975,7 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
  static int patch_ad1884a(struct hda_codec *codec)
  {
        struct ad198x_spec *spec;
@@ -6296,7 +4704,7 @@ index 10fe100..84cc49c 100644
  
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
-@@ -3930,6 +3983,13 @@ static int patch_ad1884a(struct hda_codec *codec)
+@@ -3978,6 +3983,13 @@ static int patch_ad1884a(struct hda_codec *codec)
  
        codec->spec = spec;
  
@@ -6310,27 +4718,7 @@ index 10fe100..84cc49c 100644
        spec->multiout.max_channels = 2;
        spec->multiout.num_dacs = ARRAY_SIZE(ad1884a_dac_nids);
        spec->multiout.dac_nids = ad1884a_dac_nids;
-@@ -3971,10 +4031,18 @@ static int patch_ad1884a(struct hda_codec *codec)
-               break;
-       case AD1884A_MOBILE:
-               spec->mixers[0] = ad1884a_mobile_mixers;
--              spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs;
-+              spec->init_verbs[0] = ad1884a_mobile_verbs;
-               spec->multiout.dig_out_nid = 0;
-               codec->patch_ops.unsol_event = ad1884a_hp_unsol_event;
-               codec->patch_ops.init = ad1884a_hp_init;
-+              /* set the upper-limit for mixer amp to 0dB for avoiding the
-+               * possible damage by overloading
-+               */
-+              snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
-+                                        (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
-+                                        (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
-+                                        (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
-+                                        (1 << AC_AMPCAP_MUTE_SHIFT));
-               break;
-       case AD1884A_THINKPAD:
-               spec->mixers[0] = ad1984a_thinkpad_mixers;
-@@ -4092,8 +4160,6 @@ static struct snd_kcontrol_new ad1882_loopback_mixers[] = {
+@@ -4148,8 +4160,6 @@ static struct snd_kcontrol_new ad1882_loopback_mixers[] = {
        HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
        HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
        HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
@@ -6339,7 +4727,7 @@ index 10fe100..84cc49c 100644
        { } /* end */
  };
  
-@@ -4106,8 +4172,6 @@ static struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
+@@ -4162,8 +4172,6 @@ static struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
        HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
        HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
        HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
@@ -6348,7 +4736,7 @@ index 10fe100..84cc49c 100644
        HDA_CODEC_VOLUME("Digital Mic Boost", 0x1f, 0x0, HDA_INPUT),
        { } /* end */
  };
-@@ -4266,7 +4330,7 @@ static const char *ad1882_models[AD1986A_MODELS] = {
+@@ -4322,7 +4330,7 @@ static const char *ad1882_models[AD1986A_MODELS] = {
  static int patch_ad1882(struct hda_codec *codec)
  {
        struct ad198x_spec *spec;
@@ -6357,7 +4745,7 @@ index 10fe100..84cc49c 100644
  
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
-@@ -4274,6 +4338,13 @@ static int patch_ad1882(struct hda_codec *codec)
+@@ -4330,6 +4338,13 @@ static int patch_ad1882(struct hda_codec *codec)
  
        codec->spec = spec;
  
@@ -6371,7 +4759,7 @@ index 10fe100..84cc49c 100644
        spec->multiout.max_channels = 6;
        spec->multiout.num_dacs = 3;
        spec->multiout.dac_nids = ad1882_dac_nids;
-@@ -4327,7 +4398,7 @@ static int patch_ad1882(struct hda_codec *codec)
+@@ -4383,7 +4398,7 @@ static int patch_ad1882(struct hda_codec *codec)
  /*
   * patch entries
   */
@@ -6380,7 +4768,7 @@ index 10fe100..84cc49c 100644
        { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a },
        { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
        { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a },
-@@ -4345,3 +4416,26 @@ struct hda_codec_preset snd_hda_preset_analog[] = {
+@@ -4401,3 +4416,26 @@ struct hda_codec_preset snd_hda_preset_analog[] = {
        { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 },
        {} /* terminator */
  };
@@ -6542,7 +4930,7 @@ index 6ef57fb..c921264 100644
 +module_init(patch_cmedia_init)
 +module_exit(patch_cmedia_exit)
 diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
-index a50089f..4fcbe21 100644
+index 5139c8c..4fcbe21 100644
 --- a/sound/pci/hda/patch_conexant.c
 +++ b/sound/pci/hda/patch_conexant.c
 @@ -25,9 +25,10 @@
@@ -6562,12 +4950,12 @@ index a50089f..4fcbe21 100644
  #define CONEXANT_MIC_EVENT    0x38
  
 +/* Conexant 5051 specific */
++
 +#define CXT5051_SPDIF_OUT     0x1C
 +#define CXT5051_PORTB_EVENT   0x38
 +#define CXT5051_PORTC_EVENT   0x39
 +
-+
 +struct conexant_jack {
 +
 +      hda_nid_t nid;
@@ -6584,15 +4972,7 @@ index a50089f..4fcbe21 100644
  
        const struct hda_verb *init_verbs[5];   /* initialization verbs
                                                 * don't forget NULL
-@@ -58,6 +73,7 @@ struct conexant_spec {
-                                        */
-       unsigned int cur_eapd;
-       unsigned int hp_present;
-+      unsigned int no_auto_mic;
-       unsigned int need_dac_fix;
-       /* capture */
-@@ -84,10 +100,11 @@ struct conexant_spec {
+@@ -85,10 +100,11 @@ struct conexant_spec {
  
        unsigned int spdif_route;
  
@@ -6606,7 +4986,7 @@ index a50089f..4fcbe21 100644
        struct hda_input_mux private_imux;
        hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
  
-@@ -332,6 +349,108 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
+@@ -333,6 +349,108 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
                                     &spec->cur_mux[adc_idx]);
  }
  
@@ -6715,7 +5095,7 @@ index a50089f..4fcbe21 100644
  static int conexant_init(struct hda_codec *codec)
  {
        struct conexant_spec *spec = codec->spec;
-@@ -344,18 +463,44 @@ static int conexant_init(struct hda_codec *codec)
+@@ -345,18 +463,44 @@ static int conexant_init(struct hda_codec *codec)
  
  static void conexant_free(struct hda_codec *codec)
  {
@@ -6769,7 +5149,7 @@ index a50089f..4fcbe21 100644
  static int conexant_build_controls(struct hda_codec *codec)
  {
        struct conexant_spec *spec = codec->spec;
-@@ -383,6 +528,32 @@ static int conexant_build_controls(struct hda_codec *codec)
+@@ -384,6 +528,32 @@ static int conexant_build_controls(struct hda_codec *codec)
                if (err < 0)
                        return err;
        }
@@ -6802,7 +5182,7 @@ index a50089f..4fcbe21 100644
        return 0;
  }
  
-@@ -614,13 +785,6 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec,
+@@ -615,13 +785,6 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec,
  }
  
  static struct snd_kcontrol_new cxt5045_mixers[] = {
@@ -6816,7 +5196,7 @@ index a50089f..4fcbe21 100644
        HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
        HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
        HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
-@@ -654,13 +818,6 @@ static struct snd_kcontrol_new cxt5045_benq_mixers[] = {
+@@ -655,13 +818,6 @@ static struct snd_kcontrol_new cxt5045_benq_mixers[] = {
  };
  
  static struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
@@ -6830,7 +5210,7 @@ index a50089f..4fcbe21 100644
        HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
        HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
        HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
-@@ -897,15 +1054,9 @@ static const char *cxt5045_models[CXT5045_MODELS] = {
+@@ -898,15 +1054,9 @@ static const char *cxt5045_models[CXT5045_MODELS] = {
  };
  
  static struct snd_pci_quirk cxt5045_cfg_tbl[] = {
@@ -6848,7 +5228,7 @@ index a50089f..4fcbe21 100644
        SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
        SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
        SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
-@@ -915,8 +1066,8 @@ static struct snd_pci_quirk cxt5045_cfg_tbl[] = {
+@@ -916,8 +1066,8 @@ static struct snd_pci_quirk cxt5045_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE),
        SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE),
        SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE),
@@ -6859,7 +5239,7 @@ index a50089f..4fcbe21 100644
        SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP_HPSENSE),
        {}
  };
-@@ -930,6 +1081,7 @@ static int patch_cxt5045(struct hda_codec *codec)
+@@ -931,6 +1081,7 @@ static int patch_cxt5045(struct hda_codec *codec)
        if (!spec)
                return -ENOMEM;
        codec->spec = spec;
@@ -6867,7 +5247,7 @@ index a50089f..4fcbe21 100644
  
        spec->multiout.max_channels = 2;
        spec->multiout.num_dacs = ARRAY_SIZE(cxt5045_dac_nids);
-@@ -1029,7 +1181,7 @@ static int patch_cxt5045(struct hda_codec *codec)
+@@ -1030,7 +1181,7 @@ static int patch_cxt5045(struct hda_codec *codec)
  /* Conexant 5047 specific */
  #define CXT5047_SPDIF_OUT     0x11
  
@@ -6876,7 +5256,7 @@ index a50089f..4fcbe21 100644
  static hda_nid_t cxt5047_adc_nids[1] = { 0x12 };
  static hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a };
  
-@@ -1037,20 +1189,6 @@ static struct hda_channel_mode cxt5047_modes[1] = {
+@@ -1038,20 +1189,6 @@ static struct hda_channel_mode cxt5047_modes[1] = {
        { 2, NULL },
  };
  
@@ -6897,7 +5277,7 @@ index a50089f..4fcbe21 100644
  static struct hda_input_mux cxt5047_toshiba_capture_source = {
        .num_items = 2,
        .items = {
-@@ -1074,7 +1212,11 @@ static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
+@@ -1075,7 +1212,11 @@ static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
         * the headphone jack
         */
        bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
@@ -6910,7 +5290,7 @@ index a50089f..4fcbe21 100644
                                 HDA_AMP_MUTE, bits);
        bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
        snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
-@@ -1082,16 +1224,6 @@ static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
+@@ -1083,16 +1224,6 @@ static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
        return 1;
  }
  
@@ -6927,7 +5307,7 @@ index a50089f..4fcbe21 100644
  /* mute internal speaker if HP is plugged */
  static void cxt5047_hp_automute(struct hda_codec *codec)
  {
-@@ -1102,27 +1234,8 @@ static void cxt5047_hp_automute(struct hda_codec *codec)
+@@ -1103,27 +1234,8 @@ static void cxt5047_hp_automute(struct hda_codec *codec)
                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  
        bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
@@ -6957,7 +5337,7 @@ index a50089f..4fcbe21 100644
                                 HDA_AMP_MUTE, bits);
  }
  
-@@ -1163,55 +1276,14 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec,
+@@ -1164,55 +1276,14 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec,
        }
  }
  
@@ -7017,7 +5397,7 @@ index a50089f..4fcbe21 100644
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Master Playback Switch",
-@@ -1224,29 +1296,15 @@ static struct snd_kcontrol_new cxt5047_toshiba_mixers[] = {
+@@ -1225,29 +1296,15 @@ static struct snd_kcontrol_new cxt5047_toshiba_mixers[] = {
        {}
  };
  
@@ -7055,7 +5435,7 @@ index a50089f..4fcbe21 100644
        { } /* end */
  };
  
-@@ -1257,8 +1315,8 @@ static struct hda_verb cxt5047_init_verbs[] = {
+@@ -1258,8 +1315,8 @@ static struct hda_verb cxt5047_init_verbs[] = {
        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
        /* HP, Speaker  */
        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
@@ -7066,7 +5446,7 @@ index a50089f..4fcbe21 100644
        /* Record selector: Mic */
        {0x12, AC_VERB_SET_CONNECT_SEL,0x03},
        {0x19, AC_VERB_SET_AMP_GAIN_MUTE,
-@@ -1278,30 +1336,7 @@ static struct hda_verb cxt5047_init_verbs[] = {
+@@ -1279,30 +1336,7 @@ static struct hda_verb cxt5047_init_verbs[] = {
  
  /* configuration for Toshiba Laptops */
  static struct hda_verb cxt5047_toshiba_init_verbs[] = {
@@ -7098,7 +5478,7 @@ index a50089f..4fcbe21 100644
        {}
  };
  
-@@ -1466,11 +1501,9 @@ static const char *cxt5047_models[CXT5047_MODELS] = {
+@@ -1467,11 +1501,9 @@ static const char *cxt5047_models[CXT5047_MODELS] = {
  };
  
  static struct snd_pci_quirk cxt5047_cfg_tbl[] = {
@@ -7112,7 +5492,7 @@ index a50089f..4fcbe21 100644
        SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD),
        {}
  };
-@@ -1484,6 +1517,7 @@ static int patch_cxt5047(struct hda_codec *codec)
+@@ -1485,6 +1517,7 @@ static int patch_cxt5047(struct hda_codec *codec)
        if (!spec)
                return -ENOMEM;
        codec->spec = spec;
@@ -7120,7 +5500,7 @@ index a50089f..4fcbe21 100644
  
        spec->multiout.max_channels = 2;
        spec->multiout.num_dacs = ARRAY_SIZE(cxt5047_dac_nids);
-@@ -1492,9 +1526,8 @@ static int patch_cxt5047(struct hda_codec *codec)
+@@ -1493,9 +1526,8 @@ static int patch_cxt5047(struct hda_codec *codec)
        spec->num_adc_nids = 1;
        spec->adc_nids = cxt5047_adc_nids;
        spec->capsrc_nids = cxt5047_capsrc_nids;
@@ -7131,7 +5511,7 @@ index a50089f..4fcbe21 100644
        spec->num_init_verbs = 1;
        spec->init_verbs[0] = cxt5047_init_verbs;
        spec->spdif_route = 0;
-@@ -1508,21 +1541,22 @@ static int patch_cxt5047(struct hda_codec *codec)
+@@ -1509,21 +1541,22 @@ static int patch_cxt5047(struct hda_codec *codec)
                                                  cxt5047_cfg_tbl);
        switch (board_config) {
        case CXT5047_LAPTOP:
@@ -7160,7 +5540,7 @@ index a50089f..4fcbe21 100644
                codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
                break;
  #ifdef CONFIG_SND_DEBUG
-@@ -1533,15 +1567,13 @@ static int patch_cxt5047(struct hda_codec *codec)
+@@ -1534,15 +1567,13 @@ static int patch_cxt5047(struct hda_codec *codec)
                codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
  #endif        
        }
@@ -7177,28 +5557,7 @@ index a50089f..4fcbe21 100644
  
  static struct hda_channel_mode cxt5051_modes[1] = {
        { 2, NULL },
-@@ -1571,8 +1603,11 @@ static int cxt5051_hp_master_sw_put(struct snd_kcontrol *kcontrol,
- /* toggle input of built-in and mic jack appropriately */
- static void cxt5051_portb_automic(struct hda_codec *codec)
- {
-+      struct conexant_spec *spec = codec->spec;
-       unsigned int present;
-+      if (spec->no_auto_mic)
-+              return;
-       present = snd_hda_codec_read(codec, 0x17, 0,
-                                    AC_VERB_GET_PIN_SENSE, 0) &
-               AC_PINSENSE_PRESENCE;
-@@ -1588,6 +1623,8 @@ static void cxt5051_portc_automic(struct hda_codec *codec)
-       unsigned int present;
-       hda_nid_t new_adc;
-+      if (spec->no_auto_mic)
-+              return;
-       present = snd_hda_codec_read(codec, 0x18, 0,
-                                    AC_VERB_GET_PIN_SENSE, 0) &
-               AC_PINSENSE_PRESENCE;
-@@ -1621,6 +1658,7 @@ static void cxt5051_hp_automute(struct hda_codec *codec)
+@@ -1627,6 +1658,7 @@ static void cxt5051_hp_automute(struct hda_codec *codec)
  static void cxt5051_hp_unsol_event(struct hda_codec *codec,
                                   unsigned int res)
  {
@@ -7206,7 +5565,7 @@ index a50089f..4fcbe21 100644
        switch (res >> 26) {
        case CONEXANT_HP_EVENT:
                cxt5051_hp_automute(codec);
-@@ -1632,6 +1670,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec,
+@@ -1638,6 +1670,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec,
                cxt5051_portc_automic(codec);
                break;
        }
@@ -7214,94 +5573,7 @@ index a50089f..4fcbe21 100644
  }
  
  static struct snd_kcontrol_new cxt5051_mixers[] = {
-@@ -1672,6 +1711,22 @@ static struct snd_kcontrol_new cxt5051_hp_mixers[] = {
-       {}
- };
-+static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
-+      HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x00, HDA_INPUT),
-+      HDA_CODEC_MUTE("Mic Switch", 0x14, 0x00, HDA_INPUT),
-+      HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
-+      {
-+              .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-+              .name = "Master Playback Switch",
-+              .info = cxt_eapd_info,
-+              .get = cxt_eapd_get,
-+              .put = cxt5051_hp_master_sw_put,
-+              .private_value = 0x1a,
-+      },
-+
-+      {}
-+};
-+
- static struct hda_verb cxt5051_init_verbs[] = {
-       /* Line in, Mic */
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
-@@ -1702,10 +1757,71 @@ static struct hda_verb cxt5051_init_verbs[] = {
-       { } /* end */
- };
-+static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
-+      /* Line in, Mic */
-+      {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
-+      {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-+      {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
-+      {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
-+      /* SPK  */
-+      {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-+      {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
-+      /* HP, Amp  */
-+      {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-+      {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
-+      /* DAC1 */
-+      {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-+      /* Record selector: Int mic */
-+      {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
-+      {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
-+      /* SPDIF route: PCM */
-+      {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
-+      /* EAPD */
-+      {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
-+      {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
-+      {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
-+      { } /* end */
-+};
-+
-+static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
-+      /* Line in, Mic */
-+      {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
-+      {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-+      {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
-+      {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-+      {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-+      {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
-+      /* SPK  */
-+      {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-+      {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
-+      /* HP, Amp  */
-+      {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-+      {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
-+      /* Docking HP */
-+      {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-+      {0x19, AC_VERB_SET_CONNECT_SEL, 0x00},
-+      /* DAC1 */
-+      {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-+      /* Record selector: Int mic */
-+      {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
-+      {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
-+      {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
-+      /* SPDIF route: PCM */
-+      {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
-+      /* EAPD */
-+      {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
-+      {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
-+      {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
-+      {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT},
-+      {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
-+      { } /* end */
-+};
-+
- /* initialize jack-sensing, too */
+@@ -1788,6 +1821,7 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
  static int cxt5051_init(struct hda_codec *codec)
  {
        conexant_init(codec);
@@ -7309,33 +5581,15 @@ index a50089f..4fcbe21 100644
        if (codec->patch_ops.unsol_event) {
                cxt5051_hp_automute(codec);
                cxt5051_portb_automic(codec);
-@@ -1718,18 +1834,25 @@ static int cxt5051_init(struct hda_codec *codec)
- enum {
-       CXT5051_LAPTOP,  /* Laptops w/ EAPD support */
-       CXT5051_HP,     /* no docking */
-+      CXT5051_HP_DV6736,      /* HP without mic switch */
-+      CXT5051_LENOVO_X200,    /* Lenovo X200 laptop */
-       CXT5051_MODELS
- };
- static const char *cxt5051_models[CXT5051_MODELS] = {
-       [CXT5051_LAPTOP]        = "laptop",
-       [CXT5051_HP]            = "hp",
-+      [CXT5051_HP_DV6736]     = "hp-dv6736",
-+      [CXT5051_LENOVO_X200]   = "lenovo-x200",
- };
+@@ -1814,6 +1848,7 @@ static const char *cxt5051_models[CXT5051_MODELS] = {
  
  static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
-+      SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
+       SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
 +      SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
        SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
                      CXT5051_LAPTOP),
        SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
-+      SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200),
-       {}
- };
-@@ -1742,6 +1865,7 @@ static int patch_cxt5051(struct hda_codec *codec)
+@@ -1830,6 +1865,7 @@ static int patch_cxt5051(struct hda_codec *codec)
        if (!spec)
                return -ENOMEM;
        codec->spec = spec;
@@ -7343,34 +5597,7 @@ index a50089f..4fcbe21 100644
  
        codec->patch_ops = conexant_patch_ops;
        codec->patch_ops.init = cxt5051_init;
-@@ -1762,17 +1886,22 @@ static int patch_cxt5051(struct hda_codec *codec)
-       spec->cur_adc = 0;
-       spec->cur_adc_idx = 0;
-+      codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
-+
-       board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
-                                                 cxt5051_models,
-                                                 cxt5051_cfg_tbl);
-       switch (board_config) {
-       case CXT5051_HP:
--              codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
-               spec->mixers[0] = cxt5051_hp_mixers;
-               break;
--      default:
--      case CXT5051_LAPTOP:
--              codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
-+      case CXT5051_HP_DV6736:
-+              spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs;
-+              spec->mixers[0] = cxt5051_hp_dv6736_mixers;
-+              spec->no_auto_mic = 1;
-+              break;
-+      case CXT5051_LENOVO_X200:
-+              spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs;
-               break;
-       }
-@@ -1783,7 +1912,7 @@ static int patch_cxt5051(struct hda_codec *codec)
+@@ -1876,7 +1912,7 @@ static int patch_cxt5051(struct hda_codec *codec)
  /*
   */
  
@@ -7379,7 +5606,7 @@ index a50089f..4fcbe21 100644
        { .id = 0x14f15045, .name = "CX20549 (Venice)",
          .patch = patch_cxt5045 },
        { .id = 0x14f15047, .name = "CX20551 (Waikiki)",
-@@ -1792,3 +1921,28 @@ struct hda_codec_preset snd_hda_preset_conexant[] = {
+@@ -1885,3 +1921,28 @@ struct hda_codec_preset snd_hda_preset_conexant[] = {
          .patch = patch_cxt5051 },
        {} /* terminator */
  };
@@ -7408,730 +5635,6 @@ index a50089f..4fcbe21 100644
 +
 +module_init(patch_conexant_init)
 +module_exit(patch_conexant_exit)
-diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
-new file mode 100644
-index 0000000..fcc77fe
---- /dev/null
-+++ b/sound/pci/hda/patch_intelhdmi.c
-@@ -0,0 +1,718 @@
-+/*
-+ *
-+ *  patch_intelhdmi.c - Patch for Intel HDMI codecs
-+ *
-+ *  Copyright(c) 2008 Intel Corporation. All rights reserved.
-+ *
-+ *  Authors:
-+ *                    Jiang Zhe <zhe.jiang@intel.com>
-+ *                    Wu Fengguang <wfg@linux.intel.com>
-+ *
-+ *  Maintained by:
-+ *                    Wu Fengguang <wfg@linux.intel.com>
-+ *
-+ *  This program is free software; you can redistribute it and/or modify it
-+ *  under the terms of the GNU General Public License as published by the Free
-+ *  Software Foundation; either version 2 of the License, or (at your option)
-+ *  any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful, but
-+ *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ *  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+ *  for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software Foundation,
-+ *  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <sound/core.h>
-+#include "hda_codec.h"
-+#include "hda_local.h"
-+
-+#define CVT_NID               0x02    /* audio converter */
-+#define PIN_NID               0x03    /* HDMI output pin */
-+
-+#define INTEL_HDMI_EVENT_TAG          0x08
-+
-+struct intel_hdmi_spec {
-+      struct hda_multi_out multiout;
-+      struct hda_pcm pcm_rec;
-+      struct hdmi_eld sink_eld;
-+};
-+
-+static struct hda_verb pinout_enable_verb[] = {
-+      {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-+      {} /* terminator */
-+};
-+
-+static struct hda_verb unsolicited_response_verb[] = {
-+      {PIN_NID, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN |
-+                                                INTEL_HDMI_EVENT_TAG},
-+      {}
-+};
-+
-+static struct hda_verb def_chan_map[] = {
-+      {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x00},
-+      {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x11},
-+      {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x22},
-+      {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x33},
-+      {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x44},
-+      {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x55},
-+      {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x66},
-+      {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x77},
-+      {}
-+};
-+
-+
-+struct hdmi_audio_infoframe {
-+      u8 type; /* 0x84 */
-+      u8 ver;  /* 0x01 */
-+      u8 len;  /* 0x0a */
-+
-+      u8 checksum;    /* PB0 */
-+      u8 CC02_CT47;   /* CC in bits 0:2, CT in 4:7 */
-+      u8 SS01_SF24;
-+      u8 CXT04;
-+      u8 CA;
-+      u8 LFEPBL01_LSV36_DM_INH7;
-+      u8 reserved[5]; /* PB6 - PB10 */
-+};
-+
-+/*
-+ * CEA speaker placement:
-+ *
-+ *        FLH       FCH        FRH
-+ *  FLW    FL  FLC   FC   FRC   FR   FRW
-+ *
-+ *                                  LFE
-+ *                     TC
-+ *
-+ *          RL  RLC   RC   RRC   RR
-+ *
-+ * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
-+ * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
-+ */
-+enum cea_speaker_placement {
-+      FL  = (1 <<  0),        /* Front Left           */
-+      FC  = (1 <<  1),        /* Front Center         */
-+      FR  = (1 <<  2),        /* Front Right          */
-+      FLC = (1 <<  3),        /* Front Left Center    */
-+      FRC = (1 <<  4),        /* Front Right Center   */
-+      RL  = (1 <<  5),        /* Rear Left            */
-+      RC  = (1 <<  6),        /* Rear Center          */
-+      RR  = (1 <<  7),        /* Rear Right           */
-+      RLC = (1 <<  8),        /* Rear Left Center     */
-+      RRC = (1 <<  9),        /* Rear Right Center    */
-+      LFE = (1 << 10),        /* Low Frequency Effect */
-+      FLW = (1 << 11),        /* Front Left Wide      */
-+      FRW = (1 << 12),        /* Front Right Wide     */
-+      FLH = (1 << 13),        /* Front Left High      */
-+      FCH = (1 << 14),        /* Front Center High    */
-+      FRH = (1 << 15),        /* Front Right High     */
-+      TC  = (1 << 16),        /* Top Center           */
-+};
-+
-+/*
-+ * ELD SA bits in the CEA Speaker Allocation data block
-+ */
-+static int eld_speaker_allocation_bits[] = {
-+      [0] = FL | FR,
-+      [1] = LFE,
-+      [2] = FC,
-+      [3] = RL | RR,
-+      [4] = RC,
-+      [5] = FLC | FRC,
-+      [6] = RLC | RRC,
-+      /* the following are not defined in ELD yet */
-+      [7] = FLW | FRW,
-+      [8] = FLH | FRH,
-+      [9] = TC,
-+      [10] = FCH,
-+};
-+
-+struct cea_channel_speaker_allocation {
-+      int ca_index;
-+      int speakers[8];
-+
-+      /* derived values, just for convenience */
-+      int channels;
-+      int spk_mask;
-+};
-+
-+/*
-+ * This is an ordered list!
-+ *
-+ * The preceding ones have better chances to be selected by
-+ * hdmi_setup_channel_allocation().
-+ */
-+static struct cea_channel_speaker_allocation channel_allocations[] = {
-+/*                      channel:   8     7    6    5    4     3    2    1  */
-+{ .ca_index = 0x00,  .speakers = {   0,    0,   0,   0,   0,    0,  FR,  FL } },
-+                               /* 2.1 */
-+{ .ca_index = 0x01,  .speakers = {   0,    0,   0,   0,   0,  LFE,  FR,  FL } },
-+                               /* Dolby Surround */
-+{ .ca_index = 0x02,  .speakers = {   0,    0,   0,   0,  FC,    0,  FR,  FL } },
-+{ .ca_index = 0x03,  .speakers = {   0,    0,   0,   0,  FC,  LFE,  FR,  FL } },
-+{ .ca_index = 0x04,  .speakers = {   0,    0,   0,  RC,   0,    0,  FR,  FL } },
-+{ .ca_index = 0x05,  .speakers = {   0,    0,   0,  RC,   0,  LFE,  FR,  FL } },
-+{ .ca_index = 0x06,  .speakers = {   0,    0,   0,  RC,  FC,    0,  FR,  FL } },
-+{ .ca_index = 0x07,  .speakers = {   0,    0,   0,  RC,  FC,  LFE,  FR,  FL } },
-+{ .ca_index = 0x08,  .speakers = {   0,    0,  RR,  RL,   0,    0,  FR,  FL } },
-+{ .ca_index = 0x09,  .speakers = {   0,    0,  RR,  RL,   0,  LFE,  FR,  FL } },
-+{ .ca_index = 0x0a,  .speakers = {   0,    0,  RR,  RL,  FC,    0,  FR,  FL } },
-+                               /* 5.1 */
-+{ .ca_index = 0x0b,  .speakers = {   0,    0,  RR,  RL,  FC,  LFE,  FR,  FL } },
-+{ .ca_index = 0x0c,  .speakers = {   0,   RC,  RR,  RL,   0,    0,  FR,  FL } },
-+{ .ca_index = 0x0d,  .speakers = {   0,   RC,  RR,  RL,   0,  LFE,  FR,  FL } },
-+{ .ca_index = 0x0e,  .speakers = {   0,   RC,  RR,  RL,  FC,    0,  FR,  FL } },
-+                               /* 6.1 */
-+{ .ca_index = 0x0f,  .speakers = {   0,   RC,  RR,  RL,  FC,  LFE,  FR,  FL } },
-+{ .ca_index = 0x10,  .speakers = { RRC,  RLC,  RR,  RL,   0,    0,  FR,  FL } },
-+{ .ca_index = 0x11,  .speakers = { RRC,  RLC,  RR,  RL,   0,  LFE,  FR,  FL } },
-+{ .ca_index = 0x12,  .speakers = { RRC,  RLC,  RR,  RL,  FC,    0,  FR,  FL } },
-+                               /* 7.1 */
-+{ .ca_index = 0x13,  .speakers = { RRC,  RLC,  RR,  RL,  FC,  LFE,  FR,  FL } },
-+{ .ca_index = 0x14,  .speakers = { FRC,  FLC,   0,   0,   0,    0,  FR,  FL } },
-+{ .ca_index = 0x15,  .speakers = { FRC,  FLC,   0,   0,   0,  LFE,  FR,  FL } },
-+{ .ca_index = 0x16,  .speakers = { FRC,  FLC,   0,   0,  FC,    0,  FR,  FL } },
-+{ .ca_index = 0x17,  .speakers = { FRC,  FLC,   0,   0,  FC,  LFE,  FR,  FL } },
-+{ .ca_index = 0x18,  .speakers = { FRC,  FLC,   0,  RC,   0,    0,  FR,  FL } },
-+{ .ca_index = 0x19,  .speakers = { FRC,  FLC,   0,  RC,   0,  LFE,  FR,  FL } },
-+{ .ca_index = 0x1a,  .speakers = { FRC,  FLC,   0,  RC,  FC,    0,  FR,  FL } },
-+{ .ca_index = 0x1b,  .speakers = { FRC,  FLC,   0,  RC,  FC,  LFE,  FR,  FL } },
-+{ .ca_index = 0x1c,  .speakers = { FRC,  FLC,  RR,  RL,   0,    0,  FR,  FL } },
-+{ .ca_index = 0x1d,  .speakers = { FRC,  FLC,  RR,  RL,   0,  LFE,  FR,  FL } },
-+{ .ca_index = 0x1e,  .speakers = { FRC,  FLC,  RR,  RL,  FC,    0,  FR,  FL } },
-+{ .ca_index = 0x1f,  .speakers = { FRC,  FLC,  RR,  RL,  FC,  LFE,  FR,  FL } },
-+{ .ca_index = 0x20,  .speakers = {   0,  FCH,  RR,  RL,  FC,    0,  FR,  FL } },
-+{ .ca_index = 0x21,  .speakers = {   0,  FCH,  RR,  RL,  FC,  LFE,  FR,  FL } },
-+{ .ca_index = 0x22,  .speakers = {  TC,    0,  RR,  RL,  FC,    0,  FR,  FL } },
-+{ .ca_index = 0x23,  .speakers = {  TC,    0,  RR,  RL,  FC,  LFE,  FR,  FL } },
-+{ .ca_index = 0x24,  .speakers = { FRH,  FLH,  RR,  RL,   0,    0,  FR,  FL } },
-+{ .ca_index = 0x25,  .speakers = { FRH,  FLH,  RR,  RL,   0,  LFE,  FR,  FL } },
-+{ .ca_index = 0x26,  .speakers = { FRW,  FLW,  RR,  RL,   0,    0,  FR,  FL } },
-+{ .ca_index = 0x27,  .speakers = { FRW,  FLW,  RR,  RL,   0,  LFE,  FR,  FL } },
-+{ .ca_index = 0x28,  .speakers = {  TC,   RC,  RR,  RL,  FC,    0,  FR,  FL } },
-+{ .ca_index = 0x29,  .speakers = {  TC,   RC,  RR,  RL,  FC,  LFE,  FR,  FL } },
-+{ .ca_index = 0x2a,  .speakers = { FCH,   RC,  RR,  RL,  FC,    0,  FR,  FL } },
-+{ .ca_index = 0x2b,  .speakers = { FCH,   RC,  RR,  RL,  FC,  LFE,  FR,  FL } },
-+{ .ca_index = 0x2c,  .speakers = {  TC,  FCH,  RR,  RL,  FC,    0,  FR,  FL } },
-+{ .ca_index = 0x2d,  .speakers = {  TC,  FCH,  RR,  RL,  FC,  LFE,  FR,  FL } },
-+{ .ca_index = 0x2e,  .speakers = { FRH,  FLH,  RR,  RL,  FC,    0,  FR,  FL } },
-+{ .ca_index = 0x2f,  .speakers = { FRH,  FLH,  RR,  RL,  FC,  LFE,  FR,  FL } },
-+{ .ca_index = 0x30,  .speakers = { FRW,  FLW,  RR,  RL,  FC,    0,  FR,  FL } },
-+{ .ca_index = 0x31,  .speakers = { FRW,  FLW,  RR,  RL,  FC,  LFE,  FR,  FL } },
-+};
-+
-+/*
-+ * HDMI routines
-+ */
-+
-+#ifdef BE_PARANOID
-+static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t nid,
-+                              int *packet_index, int *byte_index)
-+{
-+      int val;
-+
-+      val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_INDEX, 0);
-+
-+      *packet_index = val >> 5;
-+      *byte_index = val & 0x1f;
-+}
-+#endif
-+
-+static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t nid,
-+                              int packet_index, int byte_index)
-+{
-+      int val;
-+
-+      val = (packet_index << 5) | (byte_index & 0x1f);
-+
-+      snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
-+}
-+
-+static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t nid,
-+                              unsigned char val)
-+{
-+      snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
-+}
-+
-+static void hdmi_enable_output(struct hda_codec *codec)
-+{
-+      /* Unmute */
-+      if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP)
-+              snd_hda_codec_write(codec, PIN_NID, 0,
-+                              AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
-+      /* Enable pin out */
-+      snd_hda_sequence_write(codec, pinout_enable_verb);
-+}
-+
-+/*
-+ * Enable Audio InfoFrame Transmission
-+ */
-+static void hdmi_start_infoframe_trans(struct hda_codec *codec)
-+{
-+      hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0);
-+      snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT,
-+                                              AC_DIPXMIT_BEST);
-+}
-+
-+/*
-+ * Disable Audio InfoFrame Transmission
-+ */
-+static void hdmi_stop_infoframe_trans(struct hda_codec *codec)
-+{
-+      hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0);
-+      snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT,
-+                                              AC_DIPXMIT_DISABLE);
-+}
-+
-+static int hdmi_get_channel_count(struct hda_codec *codec)
-+{
-+      return 1 + snd_hda_codec_read(codec, CVT_NID, 0,
-+                                      AC_VERB_GET_CVT_CHAN_COUNT, 0);
-+}
-+
-+static void hdmi_set_channel_count(struct hda_codec *codec, int chs)
-+{
-+      snd_hda_codec_write(codec, CVT_NID, 0,
-+                                      AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
-+
-+      if (chs != hdmi_get_channel_count(codec))
-+              snd_printd(KERN_INFO "HDMI channel count: expect %d, get %d\n",
-+                                      chs, hdmi_get_channel_count(codec));
-+}
-+
-+static void hdmi_debug_channel_mapping(struct hda_codec *codec)
-+{
-+#ifdef CONFIG_SND_DEBUG_VERBOSE
-+      int i;
-+      int slot;
-+
-+      for (i = 0; i < 8; i++) {
-+              slot = snd_hda_codec_read(codec, CVT_NID, 0,
-+                                              AC_VERB_GET_HDMI_CHAN_SLOT, i);
-+              printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
-+                                              slot >> 4, slot & 0x7);
-+      }
-+#endif
-+}
-+
-+static void hdmi_parse_eld(struct hda_codec *codec)
-+{
-+      struct intel_hdmi_spec *spec = codec->spec;
-+      struct hdmi_eld *eld = &spec->sink_eld;
-+
-+      if (!snd_hdmi_get_eld(eld, codec, PIN_NID))
-+              snd_hdmi_show_eld(eld);
-+}
-+
-+
-+/*
-+ * Audio InfoFrame routines
-+ */
-+
-+static void hdmi_debug_dip_size(struct hda_codec *codec)
-+{
-+#ifdef CONFIG_SND_DEBUG_VERBOSE
-+      int i;
-+      int size;
-+
-+      size = snd_hdmi_get_eld_size(codec, PIN_NID);
-+      printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
-+
-+      for (i = 0; i < 8; i++) {
-+              size = snd_hda_codec_read(codec, PIN_NID, 0,
-+                                              AC_VERB_GET_HDMI_DIP_SIZE, i);
-+              printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
-+      }
-+#endif
-+}
-+
-+static void hdmi_clear_dip_buffers(struct hda_codec *codec)
-+{
-+#ifdef BE_PARANOID
-+      int i, j;
-+      int size;
-+      int pi, bi;
-+      for (i = 0; i < 8; i++) {
-+              size = snd_hda_codec_read(codec, PIN_NID, 0,
-+                                              AC_VERB_GET_HDMI_DIP_SIZE, i);
-+              if (size == 0)
-+                      continue;
-+
-+              hdmi_set_dip_index(codec, PIN_NID, i, 0x0);
-+              for (j = 1; j < 1000; j++) {
-+                      hdmi_write_dip_byte(codec, PIN_NID, 0x0);
-+                      hdmi_get_dip_index(codec, PIN_NID, &pi, &bi);
-+                      if (pi != i)
-+                              snd_printd(KERN_INFO "dip index %d: %d != %d\n",
-+                                              bi, pi, i);
-+                      if (bi == 0) /* byte index wrapped around */
-+                              break;
-+              }
-+              snd_printd(KERN_INFO
-+                      "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
-+                      i, size, j);
-+      }
-+#endif
-+}
-+
-+static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
-+                                      struct hdmi_audio_infoframe *ai)
-+{
-+      u8 *params = (u8 *)ai;
-+      u8 sum = 0;
-+      int i;
-+
-+      hdmi_debug_dip_size(codec);
-+      hdmi_clear_dip_buffers(codec); /* be paranoid */
-+
-+      for (i = 0; i < sizeof(ai); i++)
-+              sum += params[i];
-+      ai->checksum = - sum;
-+
-+      hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0);
-+      for (i = 0; i < sizeof(ai); i++)
-+              hdmi_write_dip_byte(codec, PIN_NID, params[i]);
-+}
-+
-+/*
-+ * Compute derived values in channel_allocations[].
-+ */
-+static void init_channel_allocations(void)
-+{
-+      int i, j;
-+      struct cea_channel_speaker_allocation *p;
-+
-+      for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
-+              p = channel_allocations + i;
-+              p->channels = 0;
-+              p->spk_mask = 0;
-+              for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
-+                      if (p->speakers[j]) {
-+                              p->channels++;
-+                              p->spk_mask |= p->speakers[j];
-+                      }
-+      }
-+}
-+
-+/*
-+ * The transformation takes two steps:
-+ *
-+ *    eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
-+ *          spk_mask => (channel_allocations[])         => ai->CA
-+ *
-+ * TODO: it could select the wrong CA from multiple candidates.
-+*/
-+static int hdmi_setup_channel_allocation(struct hda_codec *codec,
-+                                       struct hdmi_audio_infoframe *ai)
-+{
-+      struct intel_hdmi_spec *spec = codec->spec;
-+      struct hdmi_eld *eld = &spec->sink_eld;
-+      int i;
-+      int spk_mask = 0;
-+      int channels = 1 + (ai->CC02_CT47 & 0x7);
-+      char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
-+
-+      /*
-+       * CA defaults to 0 for basic stereo audio
-+       */
-+      if (channels <= 2)
-+              return 0;
-+
-+      /*
-+       * HDMI sink's ELD info cannot always be retrieved for now, e.g.
-+       * in console or for audio devices. Assume the highest speakers
-+       * configuration, to _not_ prohibit multi-channel audio playback.
-+       */
-+      if (!eld->spk_alloc)
-+              eld->spk_alloc = 0xffff;
-+
-+      /*
-+       * expand ELD's speaker allocation mask
-+       *
-+       * ELD tells the speaker mask in a compact(paired) form,
-+       * expand ELD's notions to match the ones used by Audio InfoFrame.
-+       */
-+      for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
-+              if (eld->spk_alloc & (1 << i))
-+                      spk_mask |= eld_speaker_allocation_bits[i];
-+      }
-+
-+      /* search for the first working match in the CA table */
-+      for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
-+              if (channels == channel_allocations[i].channels &&
-+                  (spk_mask & channel_allocations[i].spk_mask) ==
-+                              channel_allocations[i].spk_mask) {
-+                      ai->CA = channel_allocations[i].ca_index;
-+                      break;
-+              }
-+      }
-+
-+      snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
-+      snd_printdd(KERN_INFO
-+                      "HDMI: select CA 0x%x for %d-channel allocation: %s\n",
-+                      ai->CA, channels, buf);
-+
-+      return ai->CA;
-+}
-+
-+static void hdmi_setup_channel_mapping(struct hda_codec *codec,
-+                                      struct hdmi_audio_infoframe *ai)
-+{
-+      if (!ai->CA)
-+              return;
-+
-+      /*
-+       * TODO: adjust channel mapping if necessary
-+       * ALSA sequence is front/surr/clfe/side?
-+       */
-+
-+      snd_hda_sequence_write(codec, def_chan_map);
-+      hdmi_debug_channel_mapping(codec);
-+}
-+
-+
-+static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
-+                                      struct snd_pcm_substream *substream)
-+{
-+      struct hdmi_audio_infoframe ai = {
-+              .type           = 0x84,
-+              .ver            = 0x01,
-+              .len            = 0x0a,
-+              .CC02_CT47      = substream->runtime->channels - 1,
-+      };
-+
-+      hdmi_setup_channel_allocation(codec, &ai);
-+      hdmi_setup_channel_mapping(codec, &ai);
-+
-+      hdmi_fill_audio_infoframe(codec, &ai);
-+      hdmi_start_infoframe_trans(codec);
-+}
-+
-+
-+/*
-+ * Unsolicited events
-+ */
-+
-+static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
-+{
-+      int pind = !!(res & AC_UNSOL_RES_PD);
-+      int eldv = !!(res & AC_UNSOL_RES_ELDV);
-+
-+      printk(KERN_INFO
-+              "HDMI hot plug event: Presence_Detect=%d ELD_Valid=%d\n",
-+              pind, eldv);
-+
-+      if (pind && eldv) {
-+              hdmi_parse_eld(codec);
-+              /* TODO: do real things about ELD */
-+      }
-+}
-+
-+static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
-+{
-+      int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
-+      int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
-+      int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
-+
-+      printk(KERN_INFO
-+              "HDMI content protection event: SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
-+              subtag,
-+              cp_state,
-+              cp_ready);
-+
-+      /* TODO */
-+      if (cp_state)
-+              ;
-+      if (cp_ready)
-+              ;
-+}
-+
-+
-+static void intel_hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
-+{
-+      int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
-+      int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
-+
-+      if (tag != INTEL_HDMI_EVENT_TAG) {
-+              snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
-+              return;
-+      }
-+
-+      if (subtag == 0)
-+              hdmi_intrinsic_event(codec, res);
-+      else
-+              hdmi_non_intrinsic_event(codec, res);
-+}
-+
-+/*
-+ * Callbacks
-+ */
-+
-+static int intel_hdmi_playback_pcm_open(struct hda_pcm_stream *hinfo,
-+                                      struct hda_codec *codec,
-+                                      struct snd_pcm_substream *substream)
-+{
-+      struct intel_hdmi_spec *spec = codec->spec;
-+
-+      return snd_hda_multi_out_dig_open(codec, &spec->multiout);
-+}
-+
-+static int intel_hdmi_playback_pcm_close(struct hda_pcm_stream *hinfo,
-+                                       struct hda_codec *codec,
-+                                       struct snd_pcm_substream *substream)
-+{
-+      struct intel_hdmi_spec *spec = codec->spec;
-+
-+      hdmi_stop_infoframe_trans(codec);
-+
-+      return snd_hda_multi_out_dig_close(codec, &spec->multiout);
-+}
-+
-+static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
-+                                         struct hda_codec *codec,
-+                                         unsigned int stream_tag,
-+                                         unsigned int format,
-+                                         struct snd_pcm_substream *substream)
-+{
-+      struct intel_hdmi_spec *spec = codec->spec;
-+
-+      snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
-+                                           format, substream);
-+
-+      hdmi_set_channel_count(codec, substream->runtime->channels);
-+
-+      hdmi_setup_audio_infoframe(codec, substream);
-+
-+      return 0;
-+}
-+
-+static struct hda_pcm_stream intel_hdmi_pcm_playback = {
-+      .substreams = 1,
-+      .channels_min = 2,
-+      .channels_max = 8,
-+      .nid = CVT_NID, /* NID to query formats and rates and setup streams */
-+      .ops = {
-+              .open    = intel_hdmi_playback_pcm_open,
-+              .close   = intel_hdmi_playback_pcm_close,
-+              .prepare = intel_hdmi_playback_pcm_prepare
-+      },
-+};
-+
-+static int intel_hdmi_build_pcms(struct hda_codec *codec)
-+{
-+      struct intel_hdmi_spec *spec = codec->spec;
-+      struct hda_pcm *info = &spec->pcm_rec;
-+
-+      codec->num_pcms = 1;
-+      codec->pcm_info = info;
-+
-+      info->name = "INTEL HDMI";
-+      info->pcm_type = HDA_PCM_TYPE_HDMI;
-+      info->stream[SNDRV_PCM_STREAM_PLAYBACK] = intel_hdmi_pcm_playback;
-+
-+      return 0;
-+}
-+
-+static int intel_hdmi_build_controls(struct hda_codec *codec)
-+{
-+      struct intel_hdmi_spec *spec = codec->spec;
-+      int err;
-+
-+      err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
-+      if (err < 0)
-+              return err;
-+
-+      return 0;
-+}
-+
-+static int intel_hdmi_init(struct hda_codec *codec)
-+{
-+      hdmi_enable_output(codec);
-+
-+      snd_hda_sequence_write(codec, unsolicited_response_verb);
-+
-+      return 0;
-+}
-+
-+static void intel_hdmi_free(struct hda_codec *codec)
-+{
-+      struct intel_hdmi_spec *spec = codec->spec;
-+
-+      snd_hda_eld_proc_free(codec, &spec->sink_eld);
-+      kfree(spec);
-+}
-+
-+static struct hda_codec_ops intel_hdmi_patch_ops = {
-+      .init                   = intel_hdmi_init,
-+      .free                   = intel_hdmi_free,
-+      .build_pcms             = intel_hdmi_build_pcms,
-+      .build_controls         = intel_hdmi_build_controls,
-+      .unsol_event            = intel_hdmi_unsol_event,
-+};
-+
-+static int patch_intel_hdmi(struct hda_codec *codec)
-+{
-+      struct intel_hdmi_spec *spec;
-+
-+      spec = kzalloc(sizeof(*spec), GFP_KERNEL);
-+      if (spec == NULL)
-+              return -ENOMEM;
-+
-+      spec->multiout.num_dacs = 0;      /* no analog */
-+      spec->multiout.max_channels = 8;
-+      spec->multiout.dig_out_nid = CVT_NID;
-+
-+      codec->spec = spec;
-+      codec->patch_ops = intel_hdmi_patch_ops;
-+
-+      snd_hda_eld_proc_new(codec, &spec->sink_eld);
-+
-+      init_channel_allocations();
-+
-+      return 0;
-+}
-+
-+static struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
-+      { .id = 0x808629fb, .name = "G45 DEVCL",  .patch = patch_intel_hdmi },
-+      { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi },
-+      { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi },
-+      { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi },
-+      { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi },
-+      { .id = 0x10951392, .name = "SiI1392 HDMI",     .patch = patch_intel_hdmi },
-+      {} /* terminator */
-+};
-+
-+MODULE_ALIAS("snd-hda-codec-id:808629fb");
-+MODULE_ALIAS("snd-hda-codec-id:80862801");
-+MODULE_ALIAS("snd-hda-codec-id:80862802");
-+MODULE_ALIAS("snd-hda-codec-id:80862803");
-+MODULE_ALIAS("snd-hda-codec-id:80862804");
-+MODULE_ALIAS("snd-hda-codec-id:10951392");
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("Intel HDMI HD-audio codec");
-+
-+static struct hda_codec_preset_list intel_list = {
-+      .preset = snd_hda_preset_intelhdmi,
-+      .owner = THIS_MODULE,
-+};
-+
-+static int __init patch_intelhdmi_init(void)
-+{
-+      return snd_hda_add_codec_preset(&intel_list);
-+}
-+
-+static void __exit patch_intelhdmi_exit(void)
-+{
-+      snd_hda_delete_codec_preset(&intel_list);
-+}
-+
-+module_init(patch_intelhdmi_init)
-+module_exit(patch_intelhdmi_exit)
 diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
 index 2eed2c8..d57d813 100644
 --- a/sound/pci/hda/patch_nvhdmi.c
@@ -8179,7 +5682,7 @@ index 2eed2c8..d57d813 100644
 +module_init(patch_nvhdmi_init)
 +module_exit(patch_nvhdmi_exit)
 diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
-index 067e6ed..0fd258e 100644
+index 131bf5a..0fd258e 100644
 --- a/sound/pci/hda/patch_realtek.c
 +++ b/sound/pci/hda/patch_realtek.c
 @@ -30,7 +30,7 @@
@@ -8483,15 +5986,6 @@ index 067e6ed..0fd258e 100644
  #endif /* disabled */
  
  /* unsolicited event for HP jack sensing */
-@@ -884,7 +990,7 @@ static void alc888_coef_init(struct hda_codec *codec)
-       snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
-       tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
-       snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
--      if ((tmp & 0xf0) == 2)
-+      if ((tmp & 0xf0) == 0x20)
-               /* alc888S-VC */
-               snd_hda_codec_read(codec, 0x20, 0,
-                                  AC_VERB_SET_PROC_COEF, 0x830);
 @@ -923,8 +1029,7 @@ static void alc_subsystem_id(struct hda_codec *codec,
        nid = 0x1d;
        if (codec->vendor_id == 0x10ec0260)
@@ -8806,7 +6300,7 @@ index 067e6ed..0fd258e 100644
 +      mutex_unlock(&codec->control_mutex);
 +      return err;
 +}
-+
 +static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
 +                         unsigned int size, unsigned int __user *tlv)
 +{
@@ -8821,7 +6315,7 @@ index 067e6ed..0fd258e 100644
 +      mutex_unlock(&codec->control_mutex);
 +      return err;
 +}
-+
 +typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
 +                           struct snd_ctl_elem_value *ucontrol);
 +
@@ -8906,14 +6400,14 @@ index 067e6ed..0fd258e 100644
 +              .get = alc_mux_enum_get, \
 +              .put = alc_mux_enum_put, \
 +      }
++
 +#define DEFINE_CAPMIX(num) \
 +static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
 +      _DEFINE_CAPMIX(num),                                  \
 +      _DEFINE_CAPSRC(num),                                  \
 +      { } /* end */                                         \
 +}
++
 +#define DEFINE_CAPMIX_NOSRC(num) \
 +static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
 +      _DEFINE_CAPMIX(num),                                        \
@@ -10196,18 +7690,15 @@ index 067e6ed..0fd258e 100644
                }
        }
  }
-@@ -6777,8 +7190,10 @@ static int patch_alc882(struct hda_codec *codec)
+@@ -6777,6 +7190,7 @@ static int patch_alc882(struct hda_codec *codec)
                        break;
                case 0x106b1000: /* iMac 24 */
                case 0x106b2800: /* AppleTV */
 +              case 0x106b3e00: /* iMac 24 Aluminium */
                        board_config = ALC885_IMAC24;
                        break;
-+              case 0x106b00a0: /* MacBookPro3,1 - Another revision */
-               case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
-               case 0x106b00a4: /* MacbookPro4,1 */
-               case 0x106b2c00: /* Macbook Pro rev3 */
-@@ -6815,6 +7230,12 @@ static int patch_alc882(struct hda_codec *codec)
+               case 0x106b00a0: /* MacBookPro3,1 - Another revision */
+@@ -6816,6 +7230,12 @@ static int patch_alc882(struct hda_codec *codec)
                }
        }
  
@@ -10220,7 +7711,7 @@ index 067e6ed..0fd258e 100644
        if (board_config != ALC882_AUTO)
                setup_preset(spec, &alc882_presets[board_config]);
  
-@@ -6835,6 +7256,7 @@ static int patch_alc882(struct hda_codec *codec)
+@@ -6836,6 +7256,7 @@ static int patch_alc882(struct hda_codec *codec)
        spec->stream_digital_playback = &alc882_pcm_digital_playback;
        spec->stream_digital_capture = &alc882_pcm_digital_capture;
  
@@ -10228,7 +7719,7 @@ index 067e6ed..0fd258e 100644
        if (!spec->adc_nids && spec->input_mux) {
                /* check whether NID 0x07 is valid */
                unsigned int wcap = get_wcaps(codec, 0x07);
-@@ -6844,17 +7266,14 @@ static int patch_alc882(struct hda_codec *codec)
+@@ -6845,17 +7266,14 @@ static int patch_alc882(struct hda_codec *codec)
                        spec->adc_nids = alc882_adc_nids_alt;
                        spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
                        spec->capsrc_nids = alc882_capsrc_nids_alt;
@@ -10248,7 +7739,7 @@ index 067e6ed..0fd258e 100644
  
        spec->vmaster_nid = 0x0c;
  
-@@ -6865,6 +7284,7 @@ static int patch_alc882(struct hda_codec *codec)
+@@ -6866,6 +7284,7 @@ static int patch_alc882(struct hda_codec *codec)
        if (!spec->loopback.amplist)
                spec->loopback.amplist = alc882_loopbacks;
  #endif
@@ -10256,7 +7747,7 @@ index 067e6ed..0fd258e 100644
  
        return 0;
  }
-@@ -6883,6 +7303,8 @@ static int patch_alc882(struct hda_codec *codec)
+@@ -6884,6 +7303,8 @@ static int patch_alc882(struct hda_codec *codec)
  #define ALC883_DIGOUT_NID     0x06
  #define ALC883_DIGIN_NID      0x0a
  
@@ -10265,7 +7756,7 @@ index 067e6ed..0fd258e 100644
  static hda_nid_t alc883_dac_nids[4] = {
        /* front, rear, clfe, rear_surr */
        0x02, 0x03, 0x04, 0x05
-@@ -6893,8 +7315,24 @@ static hda_nid_t alc883_adc_nids[2] = {
+@@ -6894,8 +7315,24 @@ static hda_nid_t alc883_adc_nids[2] = {
        0x08, 0x09,
  };
  
@@ -10290,7 +7781,7 @@ index 067e6ed..0fd258e 100644
  /* input MUX */
  /* FIXME: should be a matrix-type input source selection */
  
-@@ -6961,11 +7399,6 @@ static struct hda_input_mux alc883_asus_eee1601_capture_source = {
+@@ -6962,11 +7399,6 @@ static struct hda_input_mux alc883_asus_eee1601_capture_source = {
        },
  };
  
@@ -10302,7 +7793,7 @@ index 067e6ed..0fd258e 100644
  /*
   * 2ch mode
   */
-@@ -7117,21 +7550,6 @@ static struct snd_kcontrol_new alc883_base_mixer[] = {
+@@ -7118,21 +7550,6 @@ static struct snd_kcontrol_new alc883_base_mixer[] = {
        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
@@ -10324,7 +7815,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -7149,19 +7567,6 @@ static struct snd_kcontrol_new alc883_mitac_mixer[] = {
+@@ -7150,19 +7567,6 @@ static struct snd_kcontrol_new alc883_mitac_mixer[] = {
        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
@@ -10344,7 +7835,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -7176,19 +7581,6 @@ static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
+@@ -7177,19 +7581,6 @@ static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
@@ -10364,7 +7855,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -7203,19 +7595,6 @@ static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
+@@ -7204,19 +7595,6 @@ static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
@@ -10384,7 +7875,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -7233,21 +7612,6 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
+@@ -7234,21 +7612,6 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
@@ -10406,7 +7897,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -7271,19 +7635,6 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
+@@ -7272,19 +7635,6 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
@@ -10426,7 +7917,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -7308,21 +7659,6 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
+@@ -7309,21 +7659,6 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
@@ -10448,7 +7939,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -7346,20 +7682,6 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
+@@ -7347,20 +7682,6 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
@@ -10469,7 +7960,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -7380,19 +7702,6 @@ static struct snd_kcontrol_new alc883_tagra_mixer[] = {
+@@ -7381,19 +7702,6 @@ static struct snd_kcontrol_new alc883_tagra_mixer[] = {
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
@@ -10489,7 +7980,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -7408,19 +7717,6 @@ static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
+@@ -7409,19 +7717,6 @@ static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
@@ -10509,7 +8000,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -7433,17 +7729,6 @@ static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
+@@ -7434,17 +7729,6 @@ static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
@@ -10527,7 +8018,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -7457,19 +7742,6 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
+@@ -7458,19 +7742,6 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
        HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
@@ -10547,7 +8038,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -7483,19 +7755,6 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
+@@ -7484,19 +7755,6 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
@@ -10567,7 +8058,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -7508,19 +7767,6 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
+@@ -7509,19 +7767,6 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
@@ -10587,7 +8078,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -7548,19 +7794,6 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
+@@ -7549,19 +7794,6 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
@@ -10607,7 +8098,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -7591,6 +7824,10 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
+@@ -7592,6 +7824,10 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
@@ -10618,7 +8109,7 @@ index 067e6ed..0fd258e 100644
        HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
        HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
        {
-@@ -7598,9 +7835,9 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
+@@ -7599,9 +7835,9 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
                /* .name = "Capture Source", */
                .name = "Input Source",
                .count = 1,
@@ -10631,99 +8122,7 @@ index 067e6ed..0fd258e 100644
        },
        { } /* end */
  };
-@@ -7852,36 +8089,83 @@ static struct hda_verb alc888_lenovo_sky_verbs[] = {
-       { } /* end */
- };
-+static struct hda_verb alc888_6st_dell_verbs[] = {
-+      {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
-+      { }
-+};
-+
-+static void alc888_3st_hp_front_automute(struct hda_codec *codec)
-+{
-+      unsigned int present, bits;
-+
-+      present = snd_hda_codec_read(codec, 0x1b, 0,
-+                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
-+      bits = present ? HDA_AMP_MUTE : 0;
-+      snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
-+                               HDA_AMP_MUTE, bits);
-+      snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
-+                               HDA_AMP_MUTE, bits);
-+      snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
-+                               HDA_AMP_MUTE, bits);
-+}
-+
-+static void alc888_3st_hp_unsol_event(struct hda_codec *codec,
-+                                    unsigned int res)
-+{
-+      switch (res >> 26) {
-+      case ALC880_HP_EVENT:
-+              alc888_3st_hp_front_automute(codec);
-+              break;
-+      }
-+}
-+
- static struct hda_verb alc888_3st_hp_verbs[] = {
-       {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
-       {0x16, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Rear : output 1 (0x0d) */
-       {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},  /* CLFE : output 2 (0x0e) */
--      { }
--};
--
--static struct hda_verb alc888_6st_dell_verbs[] = {
-       {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
--      { }
-+      { } /* end */
- };
-+/*
-+ * 2ch mode
-+ */
- static struct hda_verb alc888_3st_hp_2ch_init[] = {
-       { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
-       { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
-       { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
-       { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
--      { }
-+      { } /* end */
- };
-+/*
-+ * 4ch mode
-+ */
-+static struct hda_verb alc888_3st_hp_4ch_init[] = {
-+      { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
-+      { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
-+      { 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, 0x01 },
-+      { } /* end */
-+};
-+
-+/*
-+ * 6ch mode
-+ */
- static struct hda_verb alc888_3st_hp_6ch_init[] = {
-       { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-       { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
-+      { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
-       { 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, 0x01 },
-+      { } /* end */
- };
--static struct hda_channel_mode alc888_3st_hp_modes[2] = {
-+static struct hda_channel_mode alc888_3st_hp_modes[3] = {
-       { 2, alc888_3st_hp_2ch_init },
-+      { 4, alc888_3st_hp_4ch_init },
-       { 6, alc888_3st_hp_6ch_init },
- };
-@@ -8142,7 +8426,7 @@ static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
+@@ -8190,7 +8426,7 @@ static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
  {
        switch (res >> 26) {
        case ALC880_HP_EVENT:
@@ -10732,7 +8131,7 @@ index 067e6ed..0fd258e 100644
                alc888_6st_dell_front_automute(codec);
                break;
        }
-@@ -8255,27 +8539,6 @@ static struct hda_verb alc883_auto_init_verbs[] = {
+@@ -8303,27 +8539,6 @@ static struct hda_verb alc883_auto_init_verbs[] = {
        { }
  };
  
@@ -10760,7 +8159,7 @@ index 067e6ed..0fd258e 100644
  static struct hda_verb alc888_asus_m90v_verbs[] = {
        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-@@ -8398,6 +8661,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
+@@ -8446,6 +8661,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
        [ALC883_TARGA_2ch_DIG]  = "targa-2ch-dig",
        [ALC883_ACER]           = "acer",
        [ALC883_ACER_ASPIRE]    = "acer-aspire",
@@ -10768,7 +8167,7 @@ index 067e6ed..0fd258e 100644
        [ALC883_MEDION]         = "medion",
        [ALC883_MEDION_MD2]     = "medion-md2",
        [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
-@@ -8411,7 +8675,9 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
+@@ -8459,7 +8675,9 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
        [ALC883_MITAC]          = "mitac",
        [ALC883_CLEVO_M720]     = "clevo-m720",
        [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
@@ -10778,7 +8177,7 @@ index 067e6ed..0fd258e 100644
        [ALC883_AUTO]           = "auto",
  };
  
-@@ -8419,20 +8685,37 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
+@@ -8467,10 +8685,22 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
        SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
        SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
@@ -10802,12 +8201,11 @@ index 067e6ed..0fd258e 100644
        SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
        SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
-       SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
-       SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
-+      SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
-+      SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
+@@ -8480,10 +8710,12 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
+       SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
        SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
        SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
+-      SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
 +      SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
 +      SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
        SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
@@ -10817,7 +8215,7 @@ index 067e6ed..0fd258e 100644
        SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
        SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
        SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
-@@ -8456,6 +8739,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
+@@ -8507,6 +8739,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
@@ -10825,7 +8223,7 @@ index 067e6ed..0fd258e 100644
        SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
        SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
-@@ -8463,12 +8747,13 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
+@@ -8514,12 +8747,13 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
        SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
        SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
@@ -10842,7 +8240,7 @@ index 067e6ed..0fd258e 100644
        SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
        SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
        SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
-@@ -8480,10 +8765,20 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
+@@ -8531,10 +8765,20 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
        SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
        SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
@@ -10863,7 +8261,7 @@ index 067e6ed..0fd258e 100644
  static struct alc_config_preset alc883_presets[] = {
        [ALC883_3ST_2ch_DIG] = {
                .mixers = { alc883_3ST_2ch_mixer },
-@@ -8525,6 +8820,7 @@ static struct alc_config_preset alc883_presets[] = {
+@@ -8576,6 +8820,7 @@ static struct alc_config_preset alc883_presets[] = {
                .dac_nids = alc883_dac_nids,
                .dig_out_nid = ALC883_DIGOUT_NID,
                .dig_in_nid = ALC883_DIGIN_NID,
@@ -10871,7 +8269,7 @@ index 067e6ed..0fd258e 100644
                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
                .channel_mode = alc883_3ST_6ch_intel_modes,
                .need_dac_fix = 1,
-@@ -8559,6 +8855,8 @@ static struct alc_config_preset alc883_presets[] = {
+@@ -8610,6 +8855,8 @@ static struct alc_config_preset alc883_presets[] = {
                .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
                .dac_nids = alc883_dac_nids,
@@ -10880,7 +8278,7 @@ index 067e6ed..0fd258e 100644
                .dig_out_nid = ALC883_DIGOUT_NID,
                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
                .channel_mode = alc883_3ST_2ch_modes,
-@@ -8592,6 +8890,26 @@ static struct alc_config_preset alc883_presets[] = {
+@@ -8643,6 +8890,26 @@ static struct alc_config_preset alc883_presets[] = {
                .unsol_event = alc883_acer_aspire_unsol_event,
                .init_hook = alc883_acer_aspire_automute,
        },
@@ -10907,7 +8305,7 @@ index 067e6ed..0fd258e 100644
        [ALC883_MEDION] = {
                .mixers = { alc883_fivestack_mixer,
                            alc883_chmode_mixer },
-@@ -8599,6 +8917,8 @@ static struct alc_config_preset alc883_presets[] = {
+@@ -8650,6 +8917,8 @@ static struct alc_config_preset alc883_presets[] = {
                                alc883_medion_eapd_verbs },
                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
                .dac_nids = alc883_dac_nids,
@@ -10916,7 +8314,7 @@ index 067e6ed..0fd258e 100644
                .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
                .channel_mode = alc883_sixstack_modes,
                .input_mux = &alc883_capture_source,
-@@ -8641,6 +8961,8 @@ static struct alc_config_preset alc883_presets[] = {
+@@ -8692,6 +8961,8 @@ static struct alc_config_preset alc883_presets[] = {
                .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
                .dac_nids = alc883_dac_nids,
@@ -10925,16 +8323,7 @@ index 067e6ed..0fd258e 100644
                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
                .channel_mode = alc883_3ST_2ch_modes,
                .input_mux = &alc883_lenovo_101e_capture_source,
-@@ -8693,6 +9015,8 @@ static struct alc_config_preset alc883_presets[] = {
-               .channel_mode = alc888_3st_hp_modes,
-               .need_dac_fix = 1,
-               .input_mux = &alc883_capture_source,
-+              .unsol_event = alc888_3st_hp_unsol_event,
-+              .init_hook = alc888_3st_hp_front_automute,
-       },
-       [ALC888_6ST_DELL] = {
-               .mixers = { alc883_base_mixer, alc883_chmode_mixer },
-@@ -8731,14 +9055,30 @@ static struct alc_config_preset alc883_presets[] = {
+@@ -8784,14 +9055,30 @@ static struct alc_config_preset alc883_presets[] = {
                .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
                .init_hook = alc883_2ch_fujitsu_pi2515_automute,
        },
@@ -10967,7 +8356,7 @@ index 067e6ed..0fd258e 100644
                .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
                .channel_mode = alc883_sixstack_modes,
                .need_dac_fix = 1,
-@@ -8762,6 +9102,7 @@ static struct alc_config_preset alc883_presets[] = {
+@@ -8815,6 +9102,7 @@ static struct alc_config_preset alc883_presets[] = {
        },
        [ALC888_ASUS_EEE1601] = {
                .mixers = { alc883_asus_eee1601_mixer },
@@ -10975,7 +8364,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
                .dac_nids = alc883_dac_nids,
-@@ -8774,6 +9115,18 @@ static struct alc_config_preset alc883_presets[] = {
+@@ -8827,6 +9115,18 @@ static struct alc_config_preset alc883_presets[] = {
                .unsol_event = alc883_eee1601_unsol_event,
                .init_hook = alc883_eee1601_inithook,
        },
@@ -10994,7 +8383,7 @@ index 067e6ed..0fd258e 100644
  };
  
  
-@@ -8837,11 +9190,9 @@ static void alc883_auto_init_analog_input(struct hda_codec *codec)
+@@ -8890,11 +9190,9 @@ static void alc883_auto_init_analog_input(struct hda_codec *codec)
        for (i = 0; i < AUTO_PIN_LAST; i++) {
                hda_nid_t nid = spec->autocfg.input_pins[i];
                if (alc883_is_input_pin(nid)) {
@@ -11009,7 +8398,7 @@ index 067e6ed..0fd258e 100644
                                snd_hda_codec_write(codec, nid, 0,
                                                    AC_VERB_SET_AMP_GAIN_MUTE,
                                                    AMP_OUT_MUTE);
-@@ -8856,6 +9207,8 @@ static int alc883_parse_auto_config(struct hda_codec *codec)
+@@ -8909,6 +9207,8 @@ static int alc883_parse_auto_config(struct hda_codec *codec)
  {
        struct alc_spec *spec = codec->spec;
        int err = alc880_parse_auto_config(codec);
@@ -11018,7 +8407,7 @@ index 067e6ed..0fd258e 100644
  
        if (err < 0)
                return err;
-@@ -8868,8 +9221,26 @@ static int alc883_parse_auto_config(struct hda_codec *codec)
+@@ -8921,8 +9221,26 @@ static int alc883_parse_auto_config(struct hda_codec *codec)
  
        /* hack - override the init verbs */
        spec->init_verbs[0] = alc883_auto_init_verbs;
@@ -11047,7 +8436,7 @@ index 067e6ed..0fd258e 100644
  
        return 1; /* config found */
  }
-@@ -8922,6 +9293,12 @@ static int patch_alc883(struct hda_codec *codec)
+@@ -8975,6 +9293,12 @@ static int patch_alc883(struct hda_codec *codec)
                }
        }
  
@@ -11060,7 +8449,7 @@ index 067e6ed..0fd258e 100644
        if (board_config != ALC883_AUTO)
                setup_preset(spec, &alc883_presets[board_config]);
  
-@@ -8934,14 +9311,36 @@ static int patch_alc883(struct hda_codec *codec)
+@@ -8987,14 +9311,36 @@ static int patch_alc883(struct hda_codec *codec)
                        spec->stream_name_analog = "ALC888 Analog";
                        spec->stream_name_digital = "ALC888 Digital";
                }
@@ -11097,7 +8486,7 @@ index 067e6ed..0fd258e 100644
                break;
        }
  
-@@ -8952,9 +9351,9 @@ static int patch_alc883(struct hda_codec *codec)
+@@ -9005,9 +9351,9 @@ static int patch_alc883(struct hda_codec *codec)
        spec->stream_digital_playback = &alc883_pcm_digital_playback;
        spec->stream_digital_capture = &alc883_pcm_digital_capture;
  
@@ -11110,7 +8499,7 @@ index 067e6ed..0fd258e 100644
  
        spec->vmaster_nid = 0x0c;
  
-@@ -8966,6 +9365,7 @@ static int patch_alc883(struct hda_codec *codec)
+@@ -9019,6 +9365,7 @@ static int patch_alc883(struct hda_codec *codec)
        if (!spec->loopback.amplist)
                spec->loopback.amplist = alc883_loopbacks;
  #endif
@@ -11118,7 +8507,7 @@ index 067e6ed..0fd258e 100644
  
        return 0;
  }
-@@ -9006,8 +9406,6 @@ static struct snd_kcontrol_new alc262_base_mixer[] = {
+@@ -9059,8 +9406,6 @@ static struct snd_kcontrol_new alc262_base_mixer[] = {
        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
@@ -11127,7 +8516,7 @@ index 067e6ed..0fd258e 100644
        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-@@ -9028,8 +9426,6 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
+@@ -9081,8 +9426,6 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
@@ -11136,7 +8525,7 @@ index 067e6ed..0fd258e 100644
        /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
        { } /* end */
-@@ -9138,8 +9534,6 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
+@@ -9191,8 +9534,6 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
@@ -11145,7 +8534,7 @@ index 067e6ed..0fd258e 100644
        HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
        HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
        { } /* end */
-@@ -9168,8 +9562,6 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
+@@ -9221,8 +9562,6 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
@@ -11154,7 +8543,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -9317,6 +9709,67 @@ static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
+@@ -9370,6 +9709,67 @@ static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
        { } /* end */
  };
  
@@ -11222,7 +8611,7 @@ index 067e6ed..0fd258e 100644
  #define alc262_capture_mixer          alc882_capture_mixer
  #define alc262_capture_alt_mixer      alc882_capture_alt_mixer
  
-@@ -9445,20 +9898,6 @@ static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
+@@ -9498,20 +9898,6 @@ static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
@@ -11243,7 +8632,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -9797,8 +10236,6 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
+@@ -9850,8 +10236,6 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
        },
        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
@@ -11252,7 +8641,7 @@ index 067e6ed..0fd258e 100644
        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-@@ -9975,7 +10412,7 @@ static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
+@@ -10028,7 +10412,7 @@ static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
        struct alc_spec *spec = codec->spec;
        int ret;
  
@@ -11261,7 +8650,7 @@ index 067e6ed..0fd258e 100644
        if (!ret)
                return 0;
        /* reprogram the HP pin as mic or HP according to the input source */
-@@ -9992,8 +10429,8 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
+@@ -10045,8 +10429,8 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Capture Source",
@@ -11272,7 +8661,7 @@ index 067e6ed..0fd258e 100644
                .put = alc262_ultra_mux_enum_put,
        },
        { } /* end */
-@@ -10370,8 +10807,14 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
+@@ -10423,8 +10807,14 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
                                           alc262_ignore);
        if (err < 0)
                return err;
@@ -11288,7 +8677,7 @@ index 067e6ed..0fd258e 100644
        err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
        if (err < 0)
                return err;
-@@ -10381,23 +10824,25 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
+@@ -10434,23 +10824,25 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
  
        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  
@@ -11320,7 +8709,7 @@ index 067e6ed..0fd258e 100644
        return 1;
  }
  
-@@ -10439,20 +10884,19 @@ static const char *alc262_models[ALC262_MODEL_LAST] = {
+@@ -10492,21 +10884,19 @@ static const char *alc262_models[ALC262_MODEL_LAST] = {
        [ALC262_ULTRA]          = "ultra",
        [ALC262_LENOVO_3000]    = "lenovo-3000",
        [ALC262_NEC]            = "nec",
@@ -11339,6 +8728,7 @@ index 067e6ed..0fd258e 100644
 -      SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
 -      SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
 -      SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
+-      SND_PCI_QUIRK(0x103c, 0x170b, "HP xw*", ALC262_HP_BPC),
 +      SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
 +                         ALC262_HP_BPC),
 +      SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
@@ -11348,7 +8738,7 @@ index 067e6ed..0fd258e 100644
        SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
        SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
        SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
-@@ -10470,17 +10914,17 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
+@@ -10524,17 +10914,17 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
        SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
        SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
        SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
@@ -11372,7 +8762,7 @@ index 067e6ed..0fd258e 100644
        SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
        SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
        SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
-@@ -10633,7 +11077,8 @@ static struct alc_config_preset alc262_presets[] = {
+@@ -10687,7 +11077,8 @@ static struct alc_config_preset alc262_presets[] = {
                .init_hook = alc262_hippo_automute,
        },
        [ALC262_ULTRA] = {
@@ -11382,24 +8772,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc262_ultra_verbs },
                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
                .dac_nids = alc262_dac_nids,
-@@ -10669,16 +11114,6 @@ static struct alc_config_preset alc262_presets[] = {
-               .channel_mode = alc262_modes,
-               .input_mux = &alc262_capture_source,
-       },
--      [ALC262_NEC] = {
--              .mixers = { alc262_nec_mixer },
--              .init_verbs = { alc262_nec_verbs },
--              .num_dacs = ARRAY_SIZE(alc262_dac_nids),
--              .dac_nids = alc262_dac_nids,
--              .hp_nid = 0x03,
--              .num_channel_mode = ARRAY_SIZE(alc262_modes),
--              .channel_mode = alc262_modes,
--              .input_mux = &alc262_capture_source,
--      },
-       [ALC262_TOSHIBA_S06] = {
-               .mixers = { alc262_toshiba_s06_mixer },
-               .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
-@@ -10706,6 +11141,19 @@ static struct alc_config_preset alc262_presets[] = {
+@@ -10750,6 +11141,19 @@ static struct alc_config_preset alc262_presets[] = {
                .unsol_event = alc262_hippo_unsol_event,
                .init_hook = alc262_hippo_automute,
        },
@@ -11419,7 +8792,7 @@ index 067e6ed..0fd258e 100644
  };
  
  static int patch_alc262(struct hda_codec *codec)
-@@ -10758,6 +11206,14 @@ static int patch_alc262(struct hda_codec *codec)
+@@ -10802,6 +11206,14 @@ static int patch_alc262(struct hda_codec *codec)
                }
        }
  
@@ -11434,7 +8807,7 @@ index 067e6ed..0fd258e 100644
        if (board_config != ALC262_AUTO)
                setup_preset(spec, &alc262_presets[board_config]);
  
-@@ -10769,6 +11225,7 @@ static int patch_alc262(struct hda_codec *codec)
+@@ -10813,6 +11225,7 @@ static int patch_alc262(struct hda_codec *codec)
        spec->stream_digital_playback = &alc262_pcm_digital_playback;
        spec->stream_digital_capture = &alc262_pcm_digital_capture;
  
@@ -11442,7 +8815,7 @@ index 067e6ed..0fd258e 100644
        if (!spec->adc_nids && spec->input_mux) {
                /* check whether NID 0x07 is valid */
                unsigned int wcap = get_wcaps(codec, 0x07);
-@@ -10779,17 +11236,16 @@ static int patch_alc262(struct hda_codec *codec)
+@@ -10823,17 +11236,16 @@ static int patch_alc262(struct hda_codec *codec)
                        spec->adc_nids = alc262_adc_nids_alt;
                        spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
                        spec->capsrc_nids = alc262_capsrc_nids_alt;
@@ -11464,7 +8837,7 @@ index 067e6ed..0fd258e 100644
  
        spec->vmaster_nid = 0x0c;
  
-@@ -10800,6 +11256,7 @@ static int patch_alc262(struct hda_codec *codec)
+@@ -10844,6 +11256,7 @@ static int patch_alc262(struct hda_codec *codec)
        if (!spec->loopback.amplist)
                spec->loopback.amplist = alc262_loopbacks;
  #endif
@@ -11472,7 +8845,7 @@ index 067e6ed..0fd258e 100644
  
        return 0;
  }
-@@ -11168,19 +11625,13 @@ static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
+@@ -11212,19 +11625,13 @@ static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
  static struct hda_verb alc268_base_init_verbs[] = {
        /* Unmute DAC0-1 and set vol = 0 */
        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
@@ -11492,7 +8865,7 @@ index 067e6ed..0fd258e 100644
          {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
  
        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-@@ -11199,9 +11650,7 @@ static struct hda_verb alc268_base_init_verbs[] = {
+@@ -11243,9 +11650,7 @@ static struct hda_verb alc268_base_init_verbs[] = {
        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
@@ -11502,7 +8875,7 @@ index 067e6ed..0fd258e 100644
  
        /* set PCBEEP vol = 0, mute connections */
        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-@@ -11223,10 +11672,8 @@ static struct hda_verb alc268_base_init_verbs[] = {
+@@ -11267,10 +11672,8 @@ static struct hda_verb alc268_base_init_verbs[] = {
   */
  static struct hda_verb alc268_volume_init_verbs[] = {
        /* set output DAC */
@@ -11515,7 +8888,7 @@ index 067e6ed..0fd258e 100644
  
        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-@@ -11234,16 +11681,12 @@ static struct hda_verb alc268_volume_init_verbs[] = {
+@@ -11278,16 +11681,12 @@ static struct hda_verb alc268_volume_init_verbs[] = {
        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  
@@ -11532,7 +8905,7 @@ index 067e6ed..0fd258e 100644
  
        /* set PCBEEP vol = 0, mute connections */
        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-@@ -11253,10 +11696,6 @@ static struct hda_verb alc268_volume_init_verbs[] = {
+@@ -11297,10 +11696,6 @@ static struct hda_verb alc268_volume_init_verbs[] = {
        { }
  };
  
@@ -11543,7 +8916,7 @@ index 067e6ed..0fd258e 100644
  static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
        HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
-@@ -11268,9 +11707,9 @@ static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
+@@ -11312,9 +11707,9 @@ static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
                /* .name = "Capture Source", */
                .name = "Input Source",
                .count = 1,
@@ -11556,7 +8929,7 @@ index 067e6ed..0fd258e 100644
        },
        { } /* end */
  };
-@@ -11288,9 +11727,9 @@ static struct snd_kcontrol_new alc268_capture_mixer[] = {
+@@ -11332,9 +11727,9 @@ static struct snd_kcontrol_new alc268_capture_mixer[] = {
                /* .name = "Capture Source", */
                .name = "Input Source",
                .count = 2,
@@ -11569,7 +8942,7 @@ index 067e6ed..0fd258e 100644
        },
        { } /* end */
  };
-@@ -11446,7 +11885,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
+@@ -11490,7 +11885,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
  static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
                                                const struct auto_pin_cfg *cfg)
  {
@@ -11578,7 +8951,7 @@ index 067e6ed..0fd258e 100644
        int i, idx1;
  
        for (i = 0; i < AUTO_PIN_LAST; i++) {
-@@ -11540,9 +11979,14 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
+@@ -11584,9 +11979,14 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
                                           alc268_ignore);
        if (err < 0)
                return err;
@@ -11595,7 +8968,7 @@ index 067e6ed..0fd258e 100644
        err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
        if (err < 0)
                return err;
-@@ -11552,25 +11996,26 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
+@@ -11596,25 +11996,26 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
  
        spec->multiout.max_channels = 2;
  
@@ -11631,7 +9004,7 @@ index 067e6ed..0fd258e 100644
        return 1;
  }
  
-@@ -11617,7 +12062,9 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
+@@ -11661,7 +12062,9 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
                                                ALC268_ACER_ASPIRE_ONE),
        SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
@@ -11641,7 +9014,7 @@ index 067e6ed..0fd258e 100644
        SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
        SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
        SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
-@@ -11631,7 +12078,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
+@@ -11675,7 +12078,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
  
  static struct alc_config_preset alc268_presets[] = {
        [ALC267_QUANTA_IL1] = {
@@ -11650,7 +9023,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
                                alc267_quanta_il1_verbs },
                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
-@@ -11713,7 +12160,8 @@ static struct alc_config_preset alc268_presets[] = {
+@@ -11757,7 +12160,8 @@ static struct alc_config_preset alc268_presets[] = {
        },
        [ALC268_ACER_ASPIRE_ONE] = {
                .mixers = { alc268_acer_aspire_one_mixer,
@@ -11660,7 +9033,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
                                alc268_acer_aspire_one_verbs },
                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
-@@ -11782,7 +12230,7 @@ static int patch_alc268(struct hda_codec *codec)
+@@ -11826,7 +12230,7 @@ static int patch_alc268(struct hda_codec *codec)
  {
        struct alc_spec *spec;
        int board_config;
@@ -11669,7 +9042,7 @@ index 067e6ed..0fd258e 100644
  
        spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
-@@ -11831,15 +12279,30 @@ static int patch_alc268(struct hda_codec *codec)
+@@ -11875,15 +12279,30 @@ static int patch_alc268(struct hda_codec *codec)
  
        spec->stream_digital_playback = &alc268_pcm_digital_playback;
  
@@ -11704,7 +9077,7 @@ index 067e6ed..0fd258e 100644
                /* check whether NID 0x07 is valid */
                unsigned int wcap = get_wcaps(codec, 0x07);
                int i;
-@@ -11849,15 +12312,11 @@ static int patch_alc268(struct hda_codec *codec)
+@@ -11893,15 +12312,11 @@ static int patch_alc268(struct hda_codec *codec)
                if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
                        spec->adc_nids = alc268_adc_nids_alt;
                        spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
@@ -11722,7 +9095,7 @@ index 067e6ed..0fd258e 100644
                }
                spec->capsrc_nids = alc268_capsrc_nids;
                /* set default input source */
-@@ -11873,6 +12332,8 @@ static int patch_alc268(struct hda_codec *codec)
+@@ -11917,6 +12332,8 @@ static int patch_alc268(struct hda_codec *codec)
        if (board_config == ALC268_AUTO)
                spec->init_hook = alc268_auto_init;
  
@@ -11731,7 +9104,7 @@ index 067e6ed..0fd258e 100644
        return 0;
  }
  
-@@ -11922,8 +12383,6 @@ static struct snd_kcontrol_new alc269_base_mixer[] = {
+@@ -11966,8 +12383,6 @@ static struct snd_kcontrol_new alc269_base_mixer[] = {
        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),
@@ -11740,7 +9113,7 @@ index 067e6ed..0fd258e 100644
        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
-@@ -11950,8 +12409,29 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
+@@ -11994,8 +12409,29 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
        HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
@@ -11772,7 +9145,7 @@ index 067e6ed..0fd258e 100644
        { }
  };
  
-@@ -11973,25 +12453,6 @@ static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
+@@ -12017,25 +12453,6 @@ static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
  };
  
  /* capture mixer elements */
@@ -11798,7 +9171,7 @@ index 067e6ed..0fd258e 100644
  static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
-@@ -12007,18 +12468,25 @@ static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
+@@ -12051,18 +12468,25 @@ static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
        { } /* end */
  };
  
@@ -11830,7 +9203,7 @@ index 067e6ed..0fd258e 100644
        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
        { }
-@@ -12049,6 +12517,37 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
+@@ -12093,6 +12517,37 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
                        AC_VERB_SET_PROC_COEF, 0x480);
  }
  
@@ -11868,7 +9241,7 @@ index 067e6ed..0fd258e 100644
  static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
  {
        unsigned int present;
-@@ -12059,6 +12558,29 @@ static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
+@@ -12103,6 +12558,29 @@ static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
                            AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
  }
  
@@ -11898,7 +9271,7 @@ index 067e6ed..0fd258e 100644
  static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
                                    unsigned int res)
  {
-@@ -12068,12 +12590,27 @@ static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
+@@ -12112,12 +12590,27 @@ static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
                alc269_quanta_fl1_mic_automute(codec);
  }
  
@@ -11926,7 +9299,7 @@ index 067e6ed..0fd258e 100644
  static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
        {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
-@@ -12330,7 +12867,7 @@ static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
+@@ -12374,7 +12867,7 @@ static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
         */
        if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
            cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
@@ -11935,34 +9308,7 @@ index 067e6ed..0fd258e 100644
                imux->items[imux->num_items].label = "Int Mic";
                imux->items[imux->num_items].index = 0x05;
                imux->num_items++;
-@@ -12348,13 +12885,34 @@ static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
- #define alc269_pcm_digital_playback   alc880_pcm_digital_playback
- #define alc269_pcm_digital_capture    alc880_pcm_digital_capture
-+static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
-+      .substreams = 1,
-+      .channels_min = 2,
-+      .channels_max = 8,
-+      .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
-+      /* NID is set in alc_build_pcms */
-+      .ops = {
-+              .open = alc880_playback_pcm_open,
-+              .prepare = alc880_playback_pcm_prepare,
-+              .cleanup = alc880_playback_pcm_cleanup
-+      },
-+};
-+
-+static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
-+      .substreams = 1,
-+      .channels_min = 2,
-+      .channels_max = 2,
-+      .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
-+      /* NID is set in alc_build_pcms */
-+};
-+
- /*
-  * BIOS auto configuration
-  */
+@@ -12419,7 +12912,7 @@ static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
  static int alc269_parse_auto_config(struct hda_codec *codec)
  {
        struct alc_spec *spec = codec->spec;
@@ -11971,7 +9317,7 @@ index 067e6ed..0fd258e 100644
        static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
  
        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
-@@ -12371,22 +12929,15 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
+@@ -12436,22 +12929,15 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
  
        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  
@@ -11981,16 +9327,16 @@ index 067e6ed..0fd258e 100644
  
 -      if (spec->kctl_alloc)
 -              spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
--
++      if (spec->kctls.list)
++              add_mixer(spec, spec->kctls.list);
 -      /* create a beep mixer control if the pin 0x1d isn't assigned */
 -      for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
 -              if (spec->autocfg.input_pins[i] == 0x1d)
 -                      break;
 -      if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
 -              spec->mixers[spec->num_mixers++] = alc269_beep_mixer;
-+      if (spec->kctls.list)
-+              add_mixer(spec, spec->kctls.list);
+-
 -      spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
 +      add_verb(spec, alc269_init_verbs);
        spec->num_mux_defs = 1;
@@ -11999,7 +9345,7 @@ index 067e6ed..0fd258e 100644
        /* set default input source */
        snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
                                  0, AC_VERB_SET_CONNECT_SEL,
-@@ -12396,10 +12947,9 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
+@@ -12461,10 +12947,9 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
        if (err < 0)
                return err;
  
@@ -12012,7 +9358,7 @@ index 067e6ed..0fd258e 100644
        return 1;
  }
  
-@@ -12427,24 +12977,33 @@ static const char *alc269_models[ALC269_MODEL_LAST] = {
+@@ -12492,24 +12977,33 @@ static const char *alc269_models[ALC269_MODEL_LAST] = {
        [ALC269_QUANTA_FL1]             = "quanta",
        [ALC269_ASUS_EEEPC_P703]        = "eeepc-p703",
        [ALC269_ASUS_EEEPC_P901]        = "eeepc-p901",
@@ -12048,7 +9394,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc269_init_verbs },
                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
                .dac_nids = alc269_dac_nids,
-@@ -12466,7 +13025,8 @@ static struct alc_config_preset alc269_presets[] = {
+@@ -12531,7 +13025,8 @@ static struct alc_config_preset alc269_presets[] = {
                .init_hook = alc269_quanta_fl1_init_hook,
        },
        [ALC269_ASUS_EEEPC_P703] = {
@@ -12058,7 +9404,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc269_init_verbs,
                                alc269_eeepc_amic_init_verbs },
                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
-@@ -12479,7 +13039,8 @@ static struct alc_config_preset alc269_presets[] = {
+@@ -12544,7 +13039,8 @@ static struct alc_config_preset alc269_presets[] = {
                .init_hook = alc269_eeepc_amic_inithook,
        },
        [ALC269_ASUS_EEEPC_P901] = {
@@ -12068,7 +9414,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc269_init_verbs,
                                alc269_eeepc_dmic_init_verbs },
                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
-@@ -12492,8 +13053,8 @@ static struct alc_config_preset alc269_presets[] = {
+@@ -12557,8 +13053,8 @@ static struct alc_config_preset alc269_presets[] = {
                .init_hook = alc269_eeepc_dmic_inithook,
        },
        [ALC269_FUJITSU] = {
@@ -12079,7 +9425,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc269_init_verbs,
                                alc269_eeepc_dmic_init_verbs },
                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
-@@ -12505,6 +13066,18 @@ static struct alc_config_preset alc269_presets[] = {
+@@ -12570,6 +13066,18 @@ static struct alc_config_preset alc269_presets[] = {
                .unsol_event = alc269_eeepc_dmic_unsol_event,
                .init_hook = alc269_eeepc_dmic_inithook,
        },
@@ -12098,7 +9444,7 @@ index 067e6ed..0fd258e 100644
  };
  
  static int patch_alc269(struct hda_codec *codec)
-@@ -12545,13 +13118,26 @@ static int patch_alc269(struct hda_codec *codec)
+@@ -12610,6 +13118,12 @@ static int patch_alc269(struct hda_codec *codec)
                }
        }
  
@@ -12111,24 +9457,7 @@ index 067e6ed..0fd258e 100644
        if (board_config != ALC269_AUTO)
                setup_preset(spec, &alc269_presets[board_config]);
  
-       spec->stream_name_analog = "ALC269 Analog";
--      spec->stream_analog_playback = &alc269_pcm_analog_playback;
--      spec->stream_analog_capture = &alc269_pcm_analog_capture;
--
-+      if (codec->subsystem_id == 0x17aa3bf8) {
-+              /* Due to a hardware problem on Lenovo Ideadpad, we need to
-+               * fix the sample rate of analog I/O to 44.1kHz
-+               */
-+              spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
-+              spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
-+      } else {
-+              spec->stream_analog_playback = &alc269_pcm_analog_playback;
-+              spec->stream_analog_capture = &alc269_pcm_analog_capture;
-+      }
-       spec->stream_name_digital = "ALC269 Digital";
-       spec->stream_digital_playback = &alc269_pcm_digital_playback;
-       spec->stream_digital_capture = &alc269_pcm_digital_capture;
-@@ -12559,6 +13145,9 @@ static int patch_alc269(struct hda_codec *codec)
+@@ -12631,6 +13145,9 @@ static int patch_alc269(struct hda_codec *codec)
        spec->adc_nids = alc269_adc_nids;
        spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
        spec->capsrc_nids = alc269_capsrc_nids;
@@ -12138,7 +9467,7 @@ index 067e6ed..0fd258e 100644
  
        codec->patch_ops = alc_patch_ops;
        if (board_config == ALC269_AUTO)
-@@ -12567,6 +13156,7 @@ static int patch_alc269(struct hda_codec *codec)
+@@ -12639,6 +13156,7 @@ static int patch_alc269(struct hda_codec *codec)
        if (!spec->loopback.amplist)
                spec->loopback.amplist = alc269_loopbacks;
  #endif
@@ -12146,7 +9475,7 @@ index 067e6ed..0fd258e 100644
  
        return 0;
  }
-@@ -12699,17 +13289,6 @@ static struct snd_kcontrol_new alc861_base_mixer[] = {
+@@ -12771,17 +13289,6 @@ static struct snd_kcontrol_new alc861_base_mixer[] = {
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
  
@@ -12164,7 +9493,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -12733,17 +13312,6 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = {
+@@ -12805,17 +13312,6 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = {
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
  
@@ -12182,7 +9511,7 @@ index 067e6ed..0fd258e 100644
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Channel Mode",
-@@ -12761,18 +13329,6 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
+@@ -12833,18 +13329,6 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
  
@@ -12201,7 +9530,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -12796,17 +13352,6 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
+@@ -12868,17 +13352,6 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
  
@@ -12219,7 +9548,7 @@ index 067e6ed..0fd258e 100644
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Channel Mode",
-@@ -12838,17 +13383,6 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = {
+@@ -12910,17 +13383,6 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = {
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
  
@@ -12237,7 +9566,7 @@ index 067e6ed..0fd258e 100644
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Channel Mode",
-@@ -12864,8 +13398,6 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = {
+@@ -12936,8 +13398,6 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = {
  static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
@@ -12246,7 +9575,7 @@ index 067e6ed..0fd258e 100644
        { }
  };
  
-@@ -13339,7 +13871,7 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
+@@ -13411,7 +13871,7 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
  static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
                                                const struct auto_pin_cfg *cfg)
  {
@@ -12255,7 +9584,7 @@ index 067e6ed..0fd258e 100644
        int i, err, idx, idx1;
  
        for (i = 0; i < AUTO_PIN_LAST; i++) {
-@@ -13380,25 +13912,6 @@ static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
+@@ -13452,25 +13912,6 @@ static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
        return 0;
  }
  
@@ -12281,7 +9610,7 @@ index 067e6ed..0fd258e 100644
  static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
                                              hda_nid_t nid,
                                              int pin_type, int dac_idx)
-@@ -13445,12 +13958,8 @@ static void alc861_auto_init_analog_input(struct hda_codec *codec)
+@@ -13517,12 +13958,8 @@ static void alc861_auto_init_analog_input(struct hda_codec *codec)
  
        for (i = 0; i < AUTO_PIN_LAST; i++) {
                hda_nid_t nid = spec->autocfg.input_pins[i];
@@ -12296,7 +9625,7 @@ index 067e6ed..0fd258e 100644
        }
  }
  
-@@ -13486,23 +13995,21 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
+@@ -13558,23 +13995,21 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
  
        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  
@@ -12326,7 +9655,7 @@ index 067e6ed..0fd258e 100644
        return 1;
  }
  
-@@ -13711,6 +14218,12 @@ static int patch_alc861(struct hda_codec *codec)
+@@ -13783,6 +14218,12 @@ static int patch_alc861(struct hda_codec *codec)
                }
        }
  
@@ -12339,7 +9668,7 @@ index 067e6ed..0fd258e 100644
        if (board_config != ALC861_AUTO)
                setup_preset(spec, &alc861_presets[board_config]);
  
-@@ -13722,6 +14235,8 @@ static int patch_alc861(struct hda_codec *codec)
+@@ -13794,6 +14235,8 @@ static int patch_alc861(struct hda_codec *codec)
        spec->stream_digital_playback = &alc861_pcm_digital_playback;
        spec->stream_digital_capture = &alc861_pcm_digital_capture;
  
@@ -12348,7 +9677,7 @@ index 067e6ed..0fd258e 100644
        spec->vmaster_nid = 0x03;
  
        codec->patch_ops = alc_patch_ops;
-@@ -13731,6 +14246,7 @@ static int patch_alc861(struct hda_codec *codec)
+@@ -13803,6 +14246,7 @@ static int patch_alc861(struct hda_codec *codec)
        if (!spec->loopback.amplist)
                spec->loopback.amplist = alc861_loopbacks;
  #endif
@@ -12356,7 +9685,7 @@ index 067e6ed..0fd258e 100644
  
        return 0;
  }
-@@ -13796,11 +14312,6 @@ static struct hda_input_mux alc861vd_hp_capture_source = {
+@@ -13868,11 +14312,6 @@ static struct hda_input_mux alc861vd_hp_capture_source = {
        },
  };
  
@@ -12368,7 +9697,7 @@ index 067e6ed..0fd258e 100644
  /*
   * 2ch mode
   */
-@@ -13846,25 +14357,6 @@ static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
+@@ -13918,25 +14357,6 @@ static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
        { } /* end */
  };
  
@@ -12394,7 +9723,7 @@ index 067e6ed..0fd258e 100644
  /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
   *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
   */
-@@ -13901,9 +14393,6 @@ static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
+@@ -13973,9 +14393,6 @@ static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  
@@ -12404,7 +9733,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -13927,9 +14416,6 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
+@@ -13999,9 +14416,6 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  
@@ -12414,7 +9743,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -13968,8 +14454,6 @@ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
+@@ -14040,8 +14454,6 @@ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
@@ -12423,7 +9752,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -14256,6 +14740,7 @@ static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int re
+@@ -14328,6 +14740,7 @@ static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int re
  static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
        [ALC660VD_3ST]          = "3stack-660",
        [ALC660VD_3ST_DIG]      = "3stack-660-digout",
@@ -12431,7 +9760,7 @@ index 067e6ed..0fd258e 100644
        [ALC861VD_3ST]          = "3stack",
        [ALC861VD_3ST_DIG]      = "3stack-digout",
        [ALC861VD_6ST_DIG]      = "6stack-digout",
-@@ -14270,7 +14755,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
+@@ -14342,7 +14755,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
        SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
        SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
@@ -12440,7 +9769,7 @@ index 067e6ed..0fd258e 100644
        SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
        SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
        SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
-@@ -14279,9 +14764,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
+@@ -14351,9 +14764,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
        SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
        SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
@@ -12451,7 +9780,7 @@ index 067e6ed..0fd258e 100644
        SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
        {}
  };
-@@ -14377,6 +14860,21 @@ static struct alc_config_preset alc861vd_presets[] = {
+@@ -14449,6 +14860,21 @@ static struct alc_config_preset alc861vd_presets[] = {
                .unsol_event = alc861vd_dallas_unsol_event,
                .init_hook = alc861vd_dallas_automute,
        },
@@ -12473,7 +9802,7 @@ index 067e6ed..0fd258e 100644
  };
  
  /*
-@@ -14428,11 +14926,9 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
+@@ -14500,11 +14926,9 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
        for (i = 0; i < AUTO_PIN_LAST; i++) {
                hda_nid_t nid = spec->autocfg.input_pins[i];
                if (alc861vd_is_input_pin(nid)) {
@@ -12488,7 +9817,7 @@ index 067e6ed..0fd258e 100644
                                snd_hda_codec_write(codec, nid, 0,
                                                AC_VERB_SET_AMP_GAIN_MUTE,
                                                AMP_OUT_MUTE);
-@@ -14598,23 +15094,21 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
+@@ -14670,23 +15094,21 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
  
        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  
@@ -12517,7 +9846,7 @@ index 067e6ed..0fd258e 100644
        return 1;
  }
  
-@@ -14665,6 +15159,12 @@ static int patch_alc861vd(struct hda_codec *codec)
+@@ -14737,6 +15159,12 @@ static int patch_alc861vd(struct hda_codec *codec)
                }
        }
  
@@ -12530,7 +9859,7 @@ index 067e6ed..0fd258e 100644
        if (board_config != ALC861VD_AUTO)
                setup_preset(spec, &alc861vd_presets[board_config]);
  
-@@ -14672,7 +15172,7 @@ static int patch_alc861vd(struct hda_codec *codec)
+@@ -14744,7 +15172,7 @@ static int patch_alc861vd(struct hda_codec *codec)
                spec->stream_name_analog = "ALC660-VD Analog";
                spec->stream_name_digital = "ALC660-VD Digital";
                /* always turn on EAPD */
@@ -12539,7 +9868,7 @@ index 067e6ed..0fd258e 100644
        } else {
                spec->stream_name_analog = "ALC861VD Analog";
                spec->stream_name_digital = "ALC861VD Digital";
-@@ -14687,9 +15187,10 @@ static int patch_alc861vd(struct hda_codec *codec)
+@@ -14759,9 +15187,10 @@ static int patch_alc861vd(struct hda_codec *codec)
        spec->adc_nids = alc861vd_adc_nids;
        spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
        spec->capsrc_nids = alc861vd_capsrc_nids;
@@ -12552,7 +9881,7 @@ index 067e6ed..0fd258e 100644
  
        spec->vmaster_nid = 0x02;
  
-@@ -14701,6 +15202,7 @@ static int patch_alc861vd(struct hda_codec *codec)
+@@ -14773,6 +15202,7 @@ static int patch_alc861vd(struct hda_codec *codec)
        if (!spec->loopback.amplist)
                spec->loopback.amplist = alc861vd_loopbacks;
  #endif
@@ -12560,7 +9889,7 @@ index 067e6ed..0fd258e 100644
  
        return 0;
  }
-@@ -14724,12 +15226,23 @@ static hda_nid_t alc662_dac_nids[4] = {
+@@ -14796,12 +15226,23 @@ static hda_nid_t alc662_dac_nids[4] = {
        0x02, 0x03, 0x04
  };
  
@@ -12584,7 +9913,7 @@ index 067e6ed..0fd258e 100644
  
  /* input MUX */
  /* FIXME: should be a matrix-type input source selection */
-@@ -14776,10 +15289,6 @@ static struct hda_input_mux alc663_m51va_capture_source = {
+@@ -14848,10 +15289,6 @@ static struct hda_input_mux alc663_m51va_capture_source = {
        },
  };
  
@@ -12595,7 +9924,7 @@ index 067e6ed..0fd258e 100644
  /*
   * 2ch mode
   */
-@@ -14881,8 +15390,6 @@ static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
+@@ -14953,8 +15390,6 @@ static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
        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),
@@ -12604,7 +9933,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -14904,8 +15411,6 @@ static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
+@@ -14976,8 +15411,6 @@ static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
        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),
@@ -12613,7 +9942,7 @@ index 067e6ed..0fd258e 100644
        { } /* end */
  };
  
-@@ -15163,14 +15668,7 @@ static struct hda_verb alc662_init_verbs[] = {
+@@ -15235,14 +15668,7 @@ static struct hda_verb alc662_init_verbs[] = {
        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
        /* Input mixer */
        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -12628,7 +9957,7 @@ index 067e6ed..0fd258e 100644
  
        /* always trun on EAPD */
        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
-@@ -15365,23 +15863,34 @@ static struct hda_verb alc662_ecs_init_verbs[] = {
+@@ -15437,23 +15863,34 @@ static struct hda_verb alc662_ecs_init_verbs[] = {
        {}
  };
  
@@ -12680,7 +10009,7 @@ index 067e6ed..0fd258e 100644
  };
  
  static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
-@@ -15390,6 +15899,12 @@ static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
+@@ -15462,6 +15899,12 @@ static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
        { } /* end */
  };
  
@@ -12693,7 +10022,7 @@ index 067e6ed..0fd258e 100644
  static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
  {
        unsigned int present;
-@@ -15900,62 +16415,74 @@ static const char *alc662_models[ALC662_MODEL_LAST] = {
+@@ -15972,47 +16415,59 @@ static const char *alc662_models[ALC662_MODEL_LAST] = {
  };
  
  static struct snd_pci_quirk alc662_cfg_tbl[] = {
@@ -12778,14 +10107,13 @@ index 067e6ed..0fd258e 100644
 +      SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
        SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
                      ALC662_3ST_6ch_DIG),
--      SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
 -      SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
 -      SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
        SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
                      ALC662_3ST_6ch_DIG),
        SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
-+      SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
-+      SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
+@@ -16020,15 +16475,14 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
+       SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
        SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
                                        ALC662_3ST_6ch_DIG),
 -      SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
@@ -12803,7 +10131,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc662_init_verbs },
                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
                .dac_nids = alc662_dac_nids,
-@@ -15966,8 +16493,7 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16039,8 +16493,7 @@ static struct alc_config_preset alc662_presets[] = {
                .input_mux = &alc662_capture_source,
        },
        [ALC662_3ST_6ch_DIG] = {
@@ -12813,7 +10141,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc662_init_verbs },
                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
                .dac_nids = alc662_dac_nids,
-@@ -15979,8 +16505,7 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16052,8 +16505,7 @@ static struct alc_config_preset alc662_presets[] = {
                .input_mux = &alc662_capture_source,
        },
        [ALC662_3ST_6ch] = {
@@ -12823,7 +10151,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc662_init_verbs },
                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
                .dac_nids = alc662_dac_nids,
-@@ -15990,8 +16515,7 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16063,8 +16515,7 @@ static struct alc_config_preset alc662_presets[] = {
                .input_mux = &alc662_capture_source,
        },
        [ALC662_5ST_DIG] = {
@@ -12833,7 +10161,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc662_init_verbs },
                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
                .dac_nids = alc662_dac_nids,
-@@ -16002,7 +16526,7 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16075,7 +16526,7 @@ static struct alc_config_preset alc662_presets[] = {
                .input_mux = &alc662_capture_source,
        },
        [ALC662_LENOVO_101E] = {
@@ -12842,7 +10170,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
                .dac_nids = alc662_dac_nids,
-@@ -16013,7 +16537,7 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16086,7 +16537,7 @@ static struct alc_config_preset alc662_presets[] = {
                .init_hook = alc662_lenovo_101e_all_automute,
        },
        [ALC662_ASUS_EEEPC_P701] = {
@@ -12851,7 +10179,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc662_init_verbs,
                                alc662_eeepc_sue_init_verbs },
                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-@@ -16025,7 +16549,7 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16098,7 +16549,7 @@ static struct alc_config_preset alc662_presets[] = {
                .init_hook = alc662_eeepc_inithook,
        },
        [ALC662_ASUS_EEEPC_EP20] = {
@@ -12860,7 +10188,7 @@ index 067e6ed..0fd258e 100644
                            alc662_chmode_mixer },
                .init_verbs = { alc662_init_verbs,
                                alc662_eeepc_ep20_sue_init_verbs },
-@@ -16038,7 +16562,7 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16111,7 +16562,7 @@ static struct alc_config_preset alc662_presets[] = {
                .init_hook = alc662_eeepc_ep20_inithook,
        },
        [ALC662_ECS] = {
@@ -12869,7 +10197,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc662_init_verbs,
                                alc662_ecs_init_verbs },
                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-@@ -16050,7 +16574,7 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16123,7 +16574,7 @@ static struct alc_config_preset alc662_presets[] = {
                .init_hook = alc662_eeepc_inithook,
        },
        [ALC663_ASUS_M51VA] = {
@@ -12878,7 +10206,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
                .dac_nids = alc662_dac_nids,
-@@ -16062,7 +16586,7 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16135,7 +16586,7 @@ static struct alc_config_preset alc662_presets[] = {
                .init_hook = alc663_m51va_inithook,
        },
        [ALC663_ASUS_G71V] = {
@@ -12887,7 +10215,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
                .dac_nids = alc662_dac_nids,
-@@ -16074,7 +16598,7 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16147,7 +16598,7 @@ static struct alc_config_preset alc662_presets[] = {
                .init_hook = alc663_g71v_inithook,
        },
        [ALC663_ASUS_H13] = {
@@ -12896,7 +10224,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
                .dac_nids = alc662_dac_nids,
-@@ -16085,7 +16609,7 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16158,7 +16609,7 @@ static struct alc_config_preset alc662_presets[] = {
                .init_hook = alc663_m51va_inithook,
        },
        [ALC663_ASUS_G50V] = {
@@ -12905,7 +10233,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
                .dac_nids = alc662_dac_nids,
-@@ -16097,7 +16621,8 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16170,7 +16621,8 @@ static struct alc_config_preset alc662_presets[] = {
                .init_hook = alc663_g50v_inithook,
        },
        [ALC663_ASUS_MODE1] = {
@@ -12915,7 +10243,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc662_init_verbs,
                                alc663_21jd_amic_init_verbs },
                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-@@ -16111,7 +16636,8 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16184,7 +16636,8 @@ static struct alc_config_preset alc662_presets[] = {
                .init_hook = alc663_mode1_inithook,
        },
        [ALC662_ASUS_MODE2] = {
@@ -12925,7 +10253,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc662_init_verbs,
                                alc662_1bjd_amic_init_verbs },
                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-@@ -16124,7 +16650,8 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16197,7 +16650,8 @@ static struct alc_config_preset alc662_presets[] = {
                .init_hook = alc662_mode2_inithook,
        },
        [ALC663_ASUS_MODE3] = {
@@ -12935,7 +10263,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc662_init_verbs,
                                alc663_two_hp_amic_m1_init_verbs },
                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-@@ -16138,8 +16665,8 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16211,8 +16665,8 @@ static struct alc_config_preset alc662_presets[] = {
                .init_hook = alc663_mode3_inithook,
        },
        [ALC663_ASUS_MODE4] = {
@@ -12946,7 +10274,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc662_init_verbs,
                                alc663_21jd_amic_init_verbs},
                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-@@ -16153,8 +16680,8 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16226,8 +16680,8 @@ static struct alc_config_preset alc662_presets[] = {
                .init_hook = alc663_mode4_inithook,
        },
        [ALC663_ASUS_MODE5] = {
@@ -12957,7 +10285,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc662_init_verbs,
                                alc663_15jd_amic_init_verbs },
                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-@@ -16168,7 +16695,8 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16241,7 +16695,8 @@ static struct alc_config_preset alc662_presets[] = {
                .init_hook = alc663_mode5_inithook,
        },
        [ALC663_ASUS_MODE6] = {
@@ -12967,7 +10295,7 @@ index 067e6ed..0fd258e 100644
                .init_verbs = { alc662_init_verbs,
                                alc663_two_hp_amic_m2_init_verbs },
                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-@@ -16181,6 +16709,36 @@ static struct alc_config_preset alc662_presets[] = {
+@@ -16254,6 +16709,36 @@ static struct alc_config_preset alc662_presets[] = {
                .unsol_event = alc663_mode6_unsol_event,
                .init_hook = alc663_mode6_inithook,
        },
@@ -13004,7 +10332,7 @@ index 067e6ed..0fd258e 100644
  };
  
  
-@@ -16268,7 +16826,7 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
+@@ -16341,7 +16826,7 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
  
        if (alc880_is_fixed_pin(pin)) {
                nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
@@ -13013,7 +10341,7 @@ index 067e6ed..0fd258e 100644
                /* specify the DAC as the extra output */
                if (!spec->multiout.hp_nid)
                        spec->multiout.hp_nid = nid;
-@@ -16298,26 +16856,58 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
+@@ -16371,26 +16856,58 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
        return 0;
  }
  
@@ -13086,7 +10414,7 @@ index 067e6ed..0fd258e 100644
                }
        }
        return 0;
-@@ -16367,7 +16957,6 @@ static void alc662_auto_init_hp_out(struct hda_codec *codec)
+@@ -16440,7 +16957,6 @@ static void alc662_auto_init_hp_out(struct hda_codec *codec)
                alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
  }
  
@@ -13094,7 +10422,7 @@ index 067e6ed..0fd258e 100644
  #define ALC662_PIN_CD_NID             ALC880_PIN_CD_NID
  
  static void alc662_auto_init_analog_input(struct hda_codec *codec)
-@@ -16377,12 +16966,10 @@ static void alc662_auto_init_analog_input(struct hda_codec *codec)
+@@ -16450,12 +16966,10 @@ static void alc662_auto_init_analog_input(struct hda_codec *codec)
  
        for (i = 0; i < AUTO_PIN_LAST; i++) {
                hda_nid_t nid = spec->autocfg.input_pins[i];
@@ -13111,7 +10439,7 @@ index 067e6ed..0fd258e 100644
                                snd_hda_codec_write(codec, nid, 0,
                                                    AC_VERB_SET_AMP_GAIN_MUTE,
                                                    AMP_OUT_MUTE);
-@@ -16420,34 +17007,29 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
+@@ -16493,34 +17007,29 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
                                           "Headphone");
        if (err < 0)
                return err;
@@ -13153,7 +10481,7 @@ index 067e6ed..0fd258e 100644
        return 1;
  }
  
-@@ -16499,6 +17081,12 @@ static int patch_alc662(struct hda_codec *codec)
+@@ -16572,6 +17081,12 @@ static int patch_alc662(struct hda_codec *codec)
                }
        }
  
@@ -13166,7 +10494,7 @@ index 067e6ed..0fd258e 100644
        if (board_config != ALC662_AUTO)
                setup_preset(spec, &alc662_presets[board_config]);
  
-@@ -16522,6 +17110,14 @@ static int patch_alc662(struct hda_codec *codec)
+@@ -16595,6 +17110,14 @@ static int patch_alc662(struct hda_codec *codec)
        spec->adc_nids = alc662_adc_nids;
        spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
        spec->capsrc_nids = alc662_capsrc_nids;
@@ -13181,7 +10509,7 @@ index 067e6ed..0fd258e 100644
  
        spec->vmaster_nid = 0x02;
  
-@@ -16532,6 +17128,7 @@ static int patch_alc662(struct hda_codec *codec)
+@@ -16605,6 +17128,7 @@ static int patch_alc662(struct hda_codec *codec)
        if (!spec->loopback.amplist)
                spec->loopback.amplist = alc662_loopbacks;
  #endif
@@ -13189,7 +10517,7 @@ index 067e6ed..0fd258e 100644
  
        return 0;
  }
-@@ -16539,7 +17136,7 @@ static int patch_alc662(struct hda_codec *codec)
+@@ -16612,7 +17136,7 @@ static int patch_alc662(struct hda_codec *codec)
  /*
   * patch entries
   */
@@ -13198,7 +10526,7 @@ index 067e6ed..0fd258e 100644
        { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
        { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
        { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
-@@ -16565,9 +17162,32 @@ struct hda_codec_preset snd_hda_preset_realtek[] = {
+@@ -16638,9 +17162,32 @@ struct hda_codec_preset snd_hda_preset_realtek[] = {
          .patch = patch_alc882 }, /* should be patch_alc883() in future */
        { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
        { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
@@ -13290,7 +10618,7 @@ index 9332b63..43b436c 100644
 +module_init(patch_si3054_init)
 +module_exit(patch_si3054_exit)
 diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
-index 5e89424..d2fd8ef 100644
+index bdd6964..d2fd8ef 100644
 --- a/sound/pci/hda/patch_sigmatel.c
 +++ b/sound/pci/hda/patch_sigmatel.c
 @@ -30,19 +30,20 @@
@@ -13337,13 +10665,13 @@ index 5e89424..d2fd8ef 100644
        STAC_92HD73XX_NO_JD, /* no jack-detection */
        STAC_92HD73XX_REF,
        STAC_DELL_M6_AMIC,
-@@ -81,21 +84,27 @@ enum {
+@@ -81,22 +84,27 @@ enum {
  };
  
  enum {
 +      STAC_92HD83XXX_AUTO,
        STAC_92HD83XXX_REF,
-+      STAC_92HD83XXX_PWR_REF,
+       STAC_92HD83XXX_PWR_REF,
 +      STAC_DELL_S14,
        STAC_92HD83XXX_MODELS
  };
@@ -13365,7 +10693,7 @@ index 5e89424..d2fd8ef 100644
        STAC_925x_REF,
        STAC_M1,
        STAC_M1_2,
-@@ -108,6 +117,7 @@ enum {
+@@ -109,6 +117,7 @@ enum {
  };
  
  enum {
@@ -13373,7 +10701,7 @@ index 5e89424..d2fd8ef 100644
        STAC_D945_REF,
        STAC_D945GTP3,
        STAC_D945GTP5,
-@@ -135,15 +145,36 @@ enum {
+@@ -136,15 +145,23 @@ enum {
  };
  
  enum {
@@ -13394,13 +10722,13 @@ index 5e89424..d2fd8ef 100644
 +      STAC_9872_MODELS
 +};
 +
-+struct sigmatel_event {
-+      hda_nid_t nid;
-+      unsigned char type;
-+      unsigned char tag;
-+      int data;
-+};
-+
+ struct sigmatel_event {
+       hda_nid_t nid;
+       unsigned char type;
+@@ -152,6 +169,12 @@ struct sigmatel_event {
+       int data;
+ };
 +struct sigmatel_jack {
 +      hda_nid_t nid;
 +      int type;
@@ -13410,16 +10738,7 @@ index 5e89424..d2fd8ef 100644
  struct sigmatel_spec {
        struct snd_kcontrol_new *mixers[4];
        unsigned int num_mixers;
-@@ -151,8 +182,6 @@ struct sigmatel_spec {
-       int board_config;
-       unsigned int eapd_switch: 1;
-       unsigned int surr_switch: 1;
--      unsigned int line_switch: 1;
--      unsigned int mic_switch: 1;
-       unsigned int alt_switch: 1;
-       unsigned int hp_detect: 1;
-       unsigned int spdif_mute: 1;
-@@ -169,6 +198,7 @@ struct sigmatel_spec {
+@@ -175,6 +198,7 @@ struct sigmatel_spec {
        unsigned int stream_delay;
  
        /* analog loopback */
@@ -13427,28 +10746,21 @@ index 5e89424..d2fd8ef 100644
        unsigned char aloopback_mask;
        unsigned char aloopback_shift;
  
-@@ -178,12 +208,20 @@ struct sigmatel_spec {
+@@ -184,9 +208,11 @@ struct sigmatel_spec {
        hda_nid_t *pwr_nids;
        hda_nid_t *dac_list;
  
 +      /* jack detection */
 +      struct snd_array jacks;
 +
-+      /* events */
+       /* events */
+-      int num_events;
+-      struct sigmatel_event events[32];
 +      struct snd_array events;
-+
        /* playback */
        struct hda_input_mux *mono_mux;
-       struct hda_input_mux *amp_mux;
-       unsigned int cur_mmux;
-       struct hda_multi_out multiout;
-       hda_nid_t dac_nids[5];
-+      hda_nid_t hp_dacs[5];
-+      hda_nid_t speaker_dacs[5];
-       int volume_offset;
-@@ -208,8 +246,6 @@ struct sigmatel_spec {
+@@ -220,8 +246,6 @@ struct sigmatel_spec {
        /* pin widgets */
        hda_nid_t *pin_nids;
        unsigned int num_pins;
@@ -13457,17 +10769,7 @@ index 5e89424..d2fd8ef 100644
  
        /* codec specific stuff */
        struct hda_verb *init;
-@@ -230,15 +266,16 @@ struct sigmatel_spec {
-       /* i/o switches */
-       unsigned int io_switch[2];
-       unsigned int clfe_swap;
--      unsigned int hp_switch; /* NID of HP as line-out */
-+      hda_nid_t line_switch;  /* shared line-in for input and output */
-+      hda_nid_t mic_switch;   /* shared mic-in for input and output */
-+      hda_nid_t hp_switch; /* NID of HP as line-out */
-       unsigned int aloopback;
-       struct hda_pcm pcm_rec[2];      /* PCM information */
+@@ -251,8 +275,7 @@ struct sigmatel_spec {
  
        /* dynamic controls and input_mux */
        struct auto_pin_cfg autocfg;
@@ -13477,53 +10779,7 @@ index 5e89424..d2fd8ef 100644
        struct hda_input_mux private_dimux;
        struct hda_input_mux private_imux;
        struct hda_input_mux private_smux;
-@@ -282,9 +319,6 @@ static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
- };
- #define STAC92HD73_DAC_COUNT 5
--static hda_nid_t stac92hd73xx_dac_nids[STAC92HD73_DAC_COUNT] = {
--      0x15, 0x16, 0x17, 0x18, 0x19,
--};
- static hda_nid_t stac92hd73xx_mux_nids[4] = {
-       0x28, 0x29, 0x2a, 0x2b,
-@@ -303,11 +337,7 @@ static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = {
-       0x11, 0x12, 0
- };
--#define STAC92HD81_DAC_COUNT 2
- #define STAC92HD83_DAC_COUNT 3
--static hda_nid_t stac92hd83xxx_dac_nids[STAC92HD73_DAC_COUNT] = {
--      0x13, 0x14, 0x22,
--};
- static hda_nid_t stac92hd83xxx_dmux_nids[2] = {
-       0x17, 0x18,
-@@ -326,7 +356,11 @@ static hda_nid_t stac92hd83xxx_slave_dig_outs[2] = {
- };
- static unsigned int stac92hd83xxx_pwr_mapping[4] = {
--      0x03, 0x0c, 0x10, 0x40,
-+      0x03, 0x0c, 0x20, 0x40,
-+};
-+
-+static hda_nid_t stac92hd83xxx_amp_nids[1] = {
-+      0xc,
- };
- static hda_nid_t stac92hd71bxx_pwr_nids[3] = {
-@@ -349,10 +383,6 @@ static hda_nid_t stac92hd71bxx_smux_nids[2] = {
-       0x24, 0x25,
- };
--static hda_nid_t stac92hd71bxx_dac_nids[1] = {
--      0x10, /*0x11, */
--};
--
- #define STAC92HD71BXX_NUM_DMICS       2
- static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
-       0x18, 0x19, 0
-@@ -391,6 +421,10 @@ static hda_nid_t stac922x_mux_nids[2] = {
+@@ -398,6 +421,10 @@ static hda_nid_t stac922x_mux_nids[2] = {
          0x12, 0x13,
  };
  
@@ -13534,7 +10790,7 @@ index 5e89424..d2fd8ef 100644
  static hda_nid_t stac927x_adc_nids[3] = {
          0x07, 0x08, 0x09
  };
-@@ -463,15 +497,21 @@ static hda_nid_t stac92hd73xx_pin_nids[13] = {
+@@ -470,15 +497,21 @@ static hda_nid_t stac92hd73xx_pin_nids[13] = {
        0x14, 0x22, 0x23
  };
  
@@ -13544,15 +10800,15 @@ index 5e89424..d2fd8ef 100644
 -      0x0f, 0x10, 0x11, 0x12, 0x13,
 -      0x1d, 0x1e, 0x1f, 0x20
 +      0x0f, 0x10, 0x11, 0x1f, 0x20,
-+};
+ };
+-static hda_nid_t stac92hd71bxx_pin_nids[11] = {
 +
 +#define STAC92HD71BXX_NUM_PINS 13
 +static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = {
 +      0x0a, 0x0b, 0x0c, 0x0d, 0x00,
 +      0x00, 0x14, 0x18, 0x19, 0x1e,
 +      0x1f, 0x20, 0x27
- };
--static hda_nid_t stac92hd71bxx_pin_nids[11] = {
++};
 +static hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = {
        0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
        0x0f, 0x14, 0x18, 0x19, 0x1e,
@@ -13561,94 +10817,10 @@ index 5e89424..d2fd8ef 100644
  };
  
  static hda_nid_t stac927x_pin_nids[14] = {
-@@ -584,12 +624,12 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
-               else
-                       nid = codec->slave_dig_outs[smux_idx - 1];
-               if (spec->cur_smux[smux_idx] == smux->num_items - 1)
--                      val = AMP_OUT_MUTE;
-+                      val = HDA_AMP_MUTE;
-               else
--                      val = AMP_OUT_UNMUTE;
-+                      val = 0;
-               /* un/mute SPDIF out */
--              snd_hda_codec_write_cache(codec, nid, 0,
--                      AC_VERB_SET_AMP_GAIN_MUTE, val);
-+              snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
-+                                       HDA_AMP_MUTE, val);
-       }
-       return 0;
- }
-@@ -754,10 +794,6 @@ static struct hda_verb stac9200_eapd_init[] = {
- static struct hda_verb stac92hd73xx_6ch_core_init[] = {
-       /* set master volume and direct control */
-       { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
--      /* setup audio connections */
--      { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
--      { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
--      { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
-       /* setup adcs to point to mixer */
-       { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
-       { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
-@@ -776,10 +812,6 @@ static struct hda_verb dell_eq_core_init[] = {
-       /* set master volume to max value without distortion
-        * and direct control */
-       { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
--      /* setup audio connections */
--      { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
--      { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x02},
--      { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01},
-       /* setup adcs to point to mixer */
-       { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
-       { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
-@@ -793,10 +825,6 @@ static struct hda_verb dell_eq_core_init[] = {
- static struct hda_verb dell_m6_core_init[] = {
-       { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
--      /* setup audio connections */
--      { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
--      { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
--      { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02},
-       /* setup adcs to point to mixer */
-       { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
-       { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
-@@ -811,13 +839,6 @@ static struct hda_verb dell_m6_core_init[] = {
- static struct hda_verb stac92hd73xx_8ch_core_init[] = {
-       /* set master volume and direct control */
-       { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
--      /* setup audio connections */
--      { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
--      { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
--      { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
--      /* connect hp ports to dac3 */
--      { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x03},
--      { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x03},
-       /* setup adcs to point to mixer */
-       { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
-       { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
-@@ -835,15 +856,8 @@ static struct hda_verb stac92hd73xx_8ch_core_init[] = {
- static struct hda_verb stac92hd73xx_10ch_core_init[] = {
-       /* set master volume and direct control */
-       { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
--      /* setup audio connections */
--      { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
--      { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01 },
--      { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02 },
-       /* dac3 is connected to import3 mux */
-       { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f},
--      /* connect hp ports to dac4 */
--      { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x04},
--      { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x04},
-       /* setup adcs to point to mixer */
-       { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
-       { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
-@@ -859,13 +873,9 @@ static struct hda_verb stac92hd73xx_10ch_core_init[] = {
+@@ -840,9 +873,9 @@ static struct hda_verb stac92hd73xx_10ch_core_init[] = {
  };
  
  static struct hda_verb stac92hd83xxx_core_init[] = {
--      /* start of config #1 */
--      { 0xe, AC_VERB_SET_CONNECT_SEL, 0x3},
--
--      /* start of config #2 */
 -      { 0xa, AC_VERB_SET_CONNECT_SEL, 0x0},
 -      { 0xb, AC_VERB_SET_CONNECT_SEL, 0x0},
 -      { 0xd, AC_VERB_SET_CONNECT_SEL, 0x1},
@@ -13658,12 +10830,10 @@ index 5e89424..d2fd8ef 100644
  
        /* power state controls amps */
        { 0x01, AC_VERB_SET_EAPD, 1 << 2},
-@@ -875,30 +885,25 @@ static struct hda_verb stac92hd83xxx_core_init[] = {
+@@ -852,26 +885,25 @@ static struct hda_verb stac92hd83xxx_core_init[] = {
  static struct hda_verb stac92hd71bxx_core_init[] = {
        /* set master volume and direct control */
        { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
--      /* connect headphone jack to dac1 */
--      { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
 -      /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */
 -      { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 -      { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -13684,8 +10854,6 @@ index 5e89424..d2fd8ef 100644
  
        /* set master volume and direct control */
        { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
--      /* connect headphone jack to dac1 */
--      { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
 -      /* unmute right and left channels for nodes 0x0a, 0xd */
 +      {}
 +};
@@ -13696,7 +10864,7 @@ index 5e89424..d2fd8ef 100644
        { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {}
-@@ -979,16 +984,6 @@ static struct hda_verb stac9205_core_init[] = {
+@@ -952,16 +984,6 @@ static struct hda_verb stac9205_core_init[] = {
                .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \
        }
  
@@ -13713,7 +10881,7 @@ index 5e89424..d2fd8ef 100644
  #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \
        { \
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-@@ -1003,7 +998,6 @@ static struct hda_verb stac9205_core_init[] = {
+@@ -976,7 +998,6 @@ static struct hda_verb stac9205_core_init[] = {
  static struct snd_kcontrol_new stac9200_mixer[] = {
        HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
@@ -13721,7 +10889,7 @@ index 5e89424..d2fd8ef 100644
        HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
        { } /* end */
-@@ -1028,8 +1022,6 @@ static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = {
+@@ -1001,8 +1022,6 @@ static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = {
        HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
        HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
  
@@ -13730,7 +10898,7 @@ index 5e89424..d2fd8ef 100644
        HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
  
-@@ -1039,9 +1031,22 @@ static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = {
+@@ -1012,9 +1031,22 @@ static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = {
        { } /* end */
  };
  
@@ -13754,7 +10922,7 @@ index 5e89424..d2fd8ef 100644
        HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
  
-@@ -1066,8 +1071,6 @@ static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = {
+@@ -1039,8 +1071,6 @@ static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = {
  };
  
  static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = {
@@ -13763,37 +10931,7 @@ index 5e89424..d2fd8ef 100644
        HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
  
-@@ -1099,29 +1102,26 @@ static struct snd_kcontrol_new stac92hd83xxx_mixer[] = {
-       HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT),
--      HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0, HDA_INPUT),
--      HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0, HDA_INPUT),
-+      HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0x3, HDA_INPUT),
-+      HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0x3, HDA_INPUT),
--      HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x1, HDA_INPUT),
--      HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x1, HDA_INPUT),
-+      HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x4, HDA_INPUT),
-+      HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x4, HDA_INPUT),
--      HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x2, HDA_INPUT),
--      HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x2, HDA_INPUT),
-+      HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x0, HDA_INPUT),
-+      HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x0, HDA_INPUT),
--      HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x3, HDA_INPUT),
--      HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x3, HDA_INPUT),
-+      HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x2, HDA_INPUT),
-+      HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x2, HDA_INPUT),
-       /*
--      HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x4, HDA_INPUT),
--      HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x4, HDA_INPUT),
-+      HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x1, HDA_INPUT),
-+      HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x1, HDA_INPUT),
-       */
-       { } /* end */
+@@ -1092,9 +1122,6 @@ static struct snd_kcontrol_new stac92hd83xxx_mixer[] = {
  };
  
  static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = {
@@ -13803,7 +10941,7 @@ index 5e89424..d2fd8ef 100644
        HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
  
-@@ -1147,10 +1147,11 @@ static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = {
+@@ -1120,10 +1147,11 @@ static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = {
        { } /* end */
  };
  
@@ -13818,7 +10956,7 @@ index 5e89424..d2fd8ef 100644
        HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
  
-@@ -1162,16 +1163,12 @@ static struct snd_kcontrol_new stac92hd71bxx_mixer[] = {
+@@ -1135,16 +1163,12 @@ static struct snd_kcontrol_new stac92hd71bxx_mixer[] = {
  static struct snd_kcontrol_new stac925x_mixer[] = {
        HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT),
@@ -13835,7 +10973,7 @@ index 5e89424..d2fd8ef 100644
        HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT),
        HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT),
  
-@@ -1180,9 +1177,13 @@ static struct snd_kcontrol_new stac9205_mixer[] = {
+@@ -1153,9 +1177,13 @@ static struct snd_kcontrol_new stac9205_mixer[] = {
        { } /* end */
  };
  
@@ -13850,7 +10988,7 @@ index 5e89424..d2fd8ef 100644
        HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT),
        HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT),
  
-@@ -1193,9 +1194,6 @@ static struct snd_kcontrol_new stac922x_mixer[] = {
+@@ -1166,9 +1194,6 @@ static struct snd_kcontrol_new stac922x_mixer[] = {
  
  
  static struct snd_kcontrol_new stac927x_mixer[] = {
@@ -13860,7 +10998,7 @@ index 5e89424..d2fd8ef 100644
        HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT),
        HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT),
  
-@@ -1207,6 +1205,11 @@ static struct snd_kcontrol_new stac927x_mixer[] = {
+@@ -1180,6 +1205,11 @@ static struct snd_kcontrol_new stac927x_mixer[] = {
        { } /* end */
  };
  
@@ -13872,22 +11010,22 @@ index 5e89424..d2fd8ef 100644
  static struct snd_kcontrol_new stac_dmux_mixer = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "Digital Input Source",
-@@ -1232,10 +1235,7 @@ static const char *slave_vols[] = {
+@@ -1205,10 +1235,7 @@ static const char *slave_vols[] = {
        "LFE Playback Volume",
        "Side Playback Volume",
        "Headphone Playback Volume",
--      "Headphone Playback Volume",
+-      "Headphone2 Playback Volume",
        "Speaker Playback Volume",
 -      "External Speaker Playback Volume",
 -      "Speaker2 Playback Volume",
        NULL
  };
  
-@@ -1246,17 +1246,19 @@ static const char *slave_sws[] = {
+@@ -1219,17 +1246,19 @@ static const char *slave_sws[] = {
        "LFE Playback Switch",
        "Side Playback Switch",
        "Headphone Playback Switch",
--      "Headphone Playback Switch",
+-      "Headphone2 Playback Switch",
        "Speaker Playback Switch",
 -      "External Speaker Playback Switch",
 -      "Speaker2 Playback Switch",
@@ -13906,7 +11044,7 @@ index 5e89424..d2fd8ef 100644
        int err;
        int i;
  
-@@ -1271,7 +1273,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
+@@ -1244,7 +1273,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
        }
        if (spec->num_dmuxes > 0) {
                stac_dmux_mixer.count = spec->num_dmuxes;
@@ -13915,7 +11053,7 @@ index 5e89424..d2fd8ef 100644
                                  snd_ctl_new1(&stac_dmux_mixer, codec));
                if (err < 0)
                        return err;
-@@ -1287,7 +1289,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
+@@ -1260,7 +1289,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
                        spec->spdif_mute = 1;
                }
                stac_smux_mixer.count = spec->num_smuxes;
@@ -13924,7 +11062,7 @@ index 5e89424..d2fd8ef 100644
                                  snd_ctl_new1(&stac_smux_mixer, codec));
                if (err < 0)
                        return err;
-@@ -1328,6 +1330,44 @@ static int stac92xx_build_controls(struct hda_codec *codec)
+@@ -1301,6 +1330,44 @@ static int stac92xx_build_controls(struct hda_codec *codec)
                        return err;
        }
  
@@ -13969,7 +11107,7 @@ index 5e89424..d2fd8ef 100644
        return 0;       
  }
  
-@@ -1481,6 +1521,7 @@ static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
+@@ -1454,6 +1521,7 @@ static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
  };
  
  static const char *stac9200_models[STAC_9200_MODELS] = {
@@ -13977,7 +11115,7 @@ index 5e89424..d2fd8ef 100644
        [STAC_REF] = "ref",
        [STAC_9200_OQO] = "oqo",
        [STAC_9200_DELL_D21] = "dell-d21",
-@@ -1502,6 +1543,8 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = {
+@@ -1475,6 +1543,8 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = {
        /* SigmaTel reference board */
        SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
                      "DFI LanParty", STAC_REF),
@@ -13986,7 +11124,7 @@ index 5e89424..d2fd8ef 100644
        /* Dell laptops have BIOS problem */
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
                      "unknown Dell", STAC_9200_DELL_D21),
-@@ -1624,6 +1667,7 @@ static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
+@@ -1597,6 +1667,7 @@ static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
  };
  
  static const char *stac925x_models[STAC_925x_MODELS] = {
@@ -13994,7 +11132,7 @@ index 5e89424..d2fd8ef 100644
        [STAC_REF] = "ref",
        [STAC_M1] = "m1",
        [STAC_M1_2] = "m1-2",
-@@ -1651,6 +1695,7 @@ static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = {
+@@ -1624,6 +1695,7 @@ static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = {
  static struct snd_pci_quirk stac925x_cfg_tbl[] = {
        /* SigmaTel reference board */
        SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
@@ -14002,7 +11140,7 @@ index 5e89424..d2fd8ef 100644
        SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
  
        /* Default table for unknown ID */
-@@ -1682,6 +1727,7 @@ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
+@@ -1655,6 +1727,7 @@ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
  };
  
  static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
@@ -14010,7 +11148,7 @@ index 5e89424..d2fd8ef 100644
        [STAC_92HD73XX_NO_JD] = "no-jd",
        [STAC_92HD73XX_REF] = "ref",
        [STAC_DELL_M6_AMIC] = "dell-m6-amic",
-@@ -1694,6 +1740,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
+@@ -1667,6 +1740,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
        /* SigmaTel reference board */
        SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
                                "DFI LanParty", STAC_92HD73XX_REF),
@@ -14019,7 +11157,7 @@ index 5e89424..d2fd8ef 100644
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254,
                                "Dell Studio 1535", STAC_DELL_M6_DMIC),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255,
-@@ -1717,50 +1765,68 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
+@@ -1690,52 +1765,68 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
        {} /* terminator */
  };
  
@@ -14039,14 +11177,14 @@ index 5e89424..d2fd8ef 100644
 +
  static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
        [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
-+      [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs,
+       [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs,
 +      [STAC_DELL_S14] = dell_s14_pin_configs,
  };
  
  static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
 +      [STAC_92HD83XXX_AUTO] = "auto",
        [STAC_92HD83XXX_REF] = "ref",
-+      [STAC_92HD83XXX_PWR_REF] = "mic-ref",
+       [STAC_92HD83XXX_PWR_REF] = "mic-ref",
 +      [STAC_DELL_S14] = "dell-s14",
  };
  
@@ -14098,7 +11236,7 @@ index 5e89424..d2fd8ef 100644
  };
  
  static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
-@@ -1770,33 +1836,38 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
+@@ -1745,39 +1836,38 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
        [STAC_DELL_M4_3]        = dell_m4_3_pin_configs,
        [STAC_HP_M4]            = NULL,
        [STAC_HP_DV5]           = NULL,
@@ -14120,20 +11258,25 @@ index 5e89424..d2fd8ef 100644
        /* SigmaTel reference board */
        SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
                      "DFI LanParty", STAC_92HD71BXX_REF),
+-      SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x308c,
+-                    "HP", STAC_HP_DV5),
+-      SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x308d,
++      SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
++                    "DFI LanParty", STAC_92HD71BXX_REF),
++      SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
+                     "HP", STAC_HP_DV5),
 -      SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2,
--                    "HP dv5", STAC_HP_M4),
+-                    "HP dv5", STAC_HP_DV5),
 -      SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4,
--                    "HP dv7", STAC_HP_M4),
+-                    "HP dv7", STAC_HP_DV5),
 -      SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f7,
 -                    "HP dv4", STAC_HP_DV5),
 -      SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc,
--                    "HP dv7", STAC_HP_M4),
+-                    "HP dv7", STAC_HP_DV5),
+-      SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3600,
+-                    "HP dv5", STAC_HP_DV5),
 -      SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3603,
 -                    "HP dv5", STAC_HP_DV5),
-+      SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
-+                    "DFI LanParty", STAC_92HD71BXX_REF),
-+      SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
-+                    "HP", STAC_HP_DV5),
 +      SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
 +                    "HP dv4-7", STAC_HP_DV5),
 +      SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600,
@@ -14148,7 +11291,7 @@ index 5e89424..d2fd8ef 100644
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
                                "unknown Dell", STAC_DELL_M4_1),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234,
-@@ -1948,6 +2019,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
+@@ -1929,6 +2019,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
  };
  
  static const char *stac922x_models[STAC_922X_MODELS] = {
@@ -14156,7 +11299,7 @@ index 5e89424..d2fd8ef 100644
        [STAC_D945_REF] = "ref",
        [STAC_D945GTP5] = "5stack",
        [STAC_D945GTP3] = "3stack",
-@@ -1975,6 +2047,8 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = {
+@@ -1956,6 +2047,8 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = {
        /* SigmaTel reference board */
        SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
                      "DFI LanParty", STAC_D945_REF),
@@ -14165,7 +11308,7 @@ index 5e89424..d2fd8ef 100644
        /* Intel 945G based systems */
        SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
                      "Intel D945G", STAC_D945GTP3),
-@@ -2055,31 +2129,7 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = {
+@@ -2036,31 +2129,7 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = {
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
                      "Dell XPS M1210", STAC_922X_DELL_M82),
        /* ECS/PC Chips boards */
@@ -14198,7 +11341,7 @@ index 5e89424..d2fd8ef 100644
                      "ECS/PC chips", STAC_ECS_202),
        {} /* terminator */
  };
-@@ -2105,6 +2155,13 @@ static unsigned int d965_5st_pin_configs[14] = {
+@@ -2086,6 +2155,13 @@ static unsigned int d965_5st_pin_configs[14] = {
        0x40000100, 0x40000100
  };
  
@@ -14212,7 +11355,7 @@ index 5e89424..d2fd8ef 100644
  static unsigned int dell_3st_pin_configs[14] = {
        0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
        0x01111212, 0x01116211, 0x01813050, 0x01112214,
-@@ -2117,15 +2174,18 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
+@@ -2098,15 +2174,18 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
        [STAC_D965_REF]  = ref927x_pin_configs,
        [STAC_D965_3ST]  = d965_3st_pin_configs,
        [STAC_D965_5ST]  = d965_5st_pin_configs,
@@ -14231,7 +11374,7 @@ index 5e89424..d2fd8ef 100644
        [STAC_DELL_3ST]         = "dell-3stack",
        [STAC_DELL_BIOS]        = "dell-bios",
  };
-@@ -2134,26 +2194,16 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
+@@ -2115,26 +2194,16 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
        /* SigmaTel reference board */
        SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
                      "DFI LanParty", STAC_D965_REF),
@@ -14264,7 +11407,7 @@ index 5e89424..d2fd8ef 100644
        /* Dell 3 stack systems */
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x01f7, "Dell XPS M1730", STAC_DELL_3ST),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
-@@ -2169,15 +2219,10 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
+@@ -2150,15 +2219,10 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x02ff, "Dell     ", STAC_DELL_BIOS),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x0209, "Dell XPS 1330", STAC_DELL_BIOS),
        /* 965 based 5 stack systems */
@@ -14284,7 +11427,7 @@ index 5e89424..d2fd8ef 100644
        {} /* terminator */
  };
  
-@@ -2234,6 +2279,7 @@ static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
+@@ -2215,6 +2279,7 @@ static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
  };
  
  static const char *stac9205_models[STAC_9205_MODELS] = {
@@ -14292,7 +11435,7 @@ index 5e89424..d2fd8ef 100644
        [STAC_9205_REF] = "ref",
        [STAC_9205_DELL_M42] = "dell-m42",
        [STAC_9205_DELL_M43] = "dell-m43",
-@@ -2245,6 +2291,8 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = {
+@@ -2226,6 +2291,8 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = {
        /* SigmaTel reference board */
        SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
                      "DFI LanParty", STAC_9205_REF),
@@ -14301,16 +11444,14 @@ index 5e89424..d2fd8ef 100644
        /* Dell */
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
                      "unknown Dell", STAC_9205_DELL_M42),
-@@ -2281,66 +2329,19 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = {
+@@ -2262,66 +2329,19 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = {
        {} /* terminator */
  };
  
 -static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
-+static void stac92xx_set_config_regs(struct hda_codec *codec,
-+                                   unsigned int *pincfgs)
- {
-       int i;
-       struct sigmatel_spec *spec = codec->spec;
+-{
+-      int i;
+-      struct sigmatel_spec *spec = codec->spec;
 -      
 -      if (! spec->bios_pin_configs) {
 -              spec->bios_pin_configs = kcalloc(spec->num_pins,
@@ -14332,7 +11473,7 @@ index 5e89424..d2fd8ef 100644
 -      
 -      return 0;
 -}
+-
 -static void stac92xx_set_config_reg(struct hda_codec *codec,
 -                                  hda_nid_t pin_nid, unsigned int pin_config)
 -{
@@ -14357,10 +11498,12 @@ index 5e89424..d2fd8ef 100644
 -}
 -
 -static void stac92xx_set_config_regs(struct hda_codec *codec)
--{
--      int i;
--      struct sigmatel_spec *spec = codec->spec;
--
++static void stac92xx_set_config_regs(struct hda_codec *codec,
++                                   unsigned int *pincfgs)
+ {
+       int i;
+       struct sigmatel_spec *spec = codec->spec;
 -      if (!spec->pin_configs)
 -              return;
 +      if (!pincfgs)
@@ -14375,7 +11518,7 @@ index 5e89424..d2fd8ef 100644
  }
  
  /*
-@@ -2405,6 +2406,15 @@ static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+@@ -2386,6 +2406,15 @@ static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
                                             stream_tag, format, substream);
  }
  
@@ -14391,25 +11534,7 @@ index 5e89424..d2fd8ef 100644
  /*
   * Analog capture callbacks
   */
-@@ -2419,7 +2429,7 @@ static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
-       if (spec->powerdown_adcs) {
-               msleep(40);
--              snd_hda_codec_write_cache(codec, nid, 0,
-+              snd_hda_codec_write(codec, nid, 0,
-                       AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
-       }
-       snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
-@@ -2435,7 +2445,7 @@ static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
-       snd_hda_codec_cleanup_stream(codec, nid);
-       if (spec->powerdown_adcs)
--              snd_hda_codec_write_cache(codec, nid, 0,
-+              snd_hda_codec_write(codec, nid, 0,
-                       AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
-       return 0;
- }
-@@ -2448,7 +2458,8 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
+@@ -2429,7 +2458,8 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
        .ops = {
                .open = stac92xx_dig_playback_pcm_open,
                .close = stac92xx_dig_playback_pcm_close,
@@ -14419,7 +11544,7 @@ index 5e89424..d2fd8ef 100644
        },
  };
  
-@@ -2520,7 +2531,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec)
+@@ -2501,7 +2531,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec)
                codec->num_pcms++;
                info++;
                info->name = "STAC92xx Digital";
@@ -14428,7 +11553,7 @@ index 5e89424..d2fd8ef 100644
                if (spec->multiout.dig_out_nid) {
                        info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
                        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
-@@ -2536,8 +2547,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec)
+@@ -2517,8 +2547,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec)
  
  static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
  {
@@ -14438,16 +11563,7 @@ index 5e89424..d2fd8ef 100644
        pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
        if (pincap & AC_PINCAP_VREF_100)
                return AC_PINCTL_VREF_100;
-@@ -2569,19 +2579,22 @@ static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol,
-       return 0;
- }
-+static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid,
-+                                 unsigned char type);
-+
- static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
-                       struct snd_ctl_elem_value *ucontrol)
- {
+@@ -2559,13 +2588,14 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        struct sigmatel_spec *spec = codec->spec;
        int nid = kcontrol->private_value;
@@ -14458,21 +11574,12 @@ index 5e89424..d2fd8ef 100644
        /* check to be sure that the ports are upto date with
         * switch changes
         */
--      codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
-+      stac_issue_unsol_event(codec, nid, STAC_HP_EVENT);
+       stac_issue_unsol_event(codec, nid, STAC_HP_EVENT);
++
        return 1;
  }
-@@ -2621,7 +2634,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
-        * appropriately according to the pin direction
-        */
-       if (spec->hp_detect)
--              codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
-+              stac_issue_unsol_event(codec, nid, STAC_HP_EVENT);
  
-         return 1;
- }
-@@ -2709,35 +2722,38 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = {
+@@ -2692,35 +2722,38 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = {
  };
  
  /* add dynamic controls */
@@ -14533,12 +11640,10 @@ index 5e89424..d2fd8ef 100644
        return 0;
  }
  
-@@ -2758,70 +2774,75 @@ static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type,
+@@ -2741,6 +2774,29 @@ static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type,
        return stac92xx_add_control_idx(spec, type, 0, name, val);
  }
  
--/* flag inputs as additional dynamic lineouts */
--static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
 +static struct snd_kcontrol_new stac_input_src_temp = {
 +      .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 +      .name = "Input Source",
@@ -14562,151 +11667,47 @@ index 5e89424..d2fd8ef 100644
 +      return 0;
 +}
 +
-+/* check whether the line-input can be used as line-out */
-+static hda_nid_t check_line_out_switch(struct hda_codec *codec)
+ /* check whether the line-input can be used as line-out */
+ static hda_nid_t check_line_out_switch(struct hda_codec *codec)
  {
-       struct sigmatel_spec *spec = codec->spec;
--      unsigned int wcaps, wtype;
--      int i, num_dacs = 0;
--      
--      /* use the wcaps cache to count all DACs available for line-outs */
--      for (i = 0; i < codec->num_nodes; i++) {
--              wcaps = codec->wcaps[i];
--              wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
-+      struct auto_pin_cfg *cfg = &spec->autocfg;
-+      hda_nid_t nid;
-+      unsigned int pincap;
--              if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL))
--                      num_dacs++;
--      }
-+      if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
-+              return 0;
-+      nid = cfg->input_pins[AUTO_PIN_LINE];
+@@ -2752,7 +2808,7 @@ static hda_nid_t check_line_out_switch(struct hda_codec *codec)
+       if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
+               return 0;
+       nid = cfg->input_pins[AUTO_PIN_LINE];
+-      pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
 +      pincap = snd_hda_query_pin_caps(codec, nid);
-+      if (pincap & AC_PINCAP_OUT)
-+              return nid;
-+      return 0;
-+}
--      snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
--      
--      switch (cfg->line_outs) {
--      case 3:
--              /* add line-in as side */
--              if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
--                      cfg->line_out_pins[cfg->line_outs] =
--                              cfg->input_pins[AUTO_PIN_LINE];
--                      spec->line_switch = 1;
--                      cfg->line_outs++;
--              }
--              break;
--      case 2:
--              /* add line-in as clfe and mic as side */
--              if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
--                      cfg->line_out_pins[cfg->line_outs] =
--                              cfg->input_pins[AUTO_PIN_LINE];
--                      spec->line_switch = 1;
--                      cfg->line_outs++;
--              }
--              if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
--                      cfg->line_out_pins[cfg->line_outs] =
--                              cfg->input_pins[AUTO_PIN_MIC];
--                      spec->mic_switch = 1;
--                      cfg->line_outs++;
--              }
--              break;
--      case 1:
--              /* add line-in as surr and mic as clfe */
--              if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
--                      cfg->line_out_pins[cfg->line_outs] =
--                              cfg->input_pins[AUTO_PIN_LINE];
--                      spec->line_switch = 1;
--                      cfg->line_outs++;
--              }
--              if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
--                      cfg->line_out_pins[cfg->line_outs] =
--                              cfg->input_pins[AUTO_PIN_MIC];
--                      spec->mic_switch = 1;
--                      cfg->line_outs++;
-+/* check whether the mic-input can be used as line-out */
-+static hda_nid_t check_mic_out_switch(struct hda_codec *codec)
-+{
-+      struct sigmatel_spec *spec = codec->spec;
-+      struct auto_pin_cfg *cfg = &spec->autocfg;
-+      unsigned int def_conf, pincap;
-+      unsigned int mic_pin;
-+
-+      if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
-+              return 0;
-+      mic_pin = AUTO_PIN_MIC;
-+      for (;;) {
-+              hda_nid_t nid = cfg->input_pins[mic_pin];
+       if (pincap & AC_PINCAP_OUT)
+               return nid;
+       return 0;
+@@ -2771,12 +2827,11 @@ static hda_nid_t check_mic_out_switch(struct hda_codec *codec)
+       mic_pin = AUTO_PIN_MIC;
+       for (;;) {
+               hda_nid_t nid = cfg->input_pins[mic_pin];
+-              def_conf = snd_hda_codec_read(codec, nid, 0,
+-                                            AC_VERB_GET_CONFIG_DEFAULT, 0);
 +              def_conf = snd_hda_codec_get_pincfg(codec, nid);
-+              /* some laptops have an internal analog microphone
-+               * which can't be used as a output */
-+              if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) {
+               /* some laptops have an internal analog microphone
+                * which can't be used as a output */
+               if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) {
+-                      pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
 +                      pincap = snd_hda_query_pin_caps(codec, nid);
-+                      if (pincap & AC_PINCAP_OUT)
-+                              return nid;
+                       if (pincap & AC_PINCAP_OUT)
+                               return nid;
                }
--              break;
-+              if (mic_pin == AUTO_PIN_MIC)
-+                      mic_pin = AUTO_PIN_FRONT_MIC;
-+              else
-+                      break;
-       }
--
-       return 0;
- }
--
- static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
- {
-       int i;
-@@ -2834,6 +2855,61 @@ static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
-       return 0;
- }
-+static int check_all_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
-+{
-+      int i;
-+      if (is_in_dac_nids(spec, nid))
-+              return 1;
-+      for (i = 0; i < spec->autocfg.hp_outs; i++)
-+              if (spec->hp_dacs[i] == nid)
-+                      return 1;
-+      for (i = 0; i < spec->autocfg.speaker_outs; i++)
-+              if (spec->speaker_dacs[i] == nid)
-+                      return 1;
-+      return 0;
-+}
-+
-+static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
-+{
-+      struct sigmatel_spec *spec = codec->spec;
-+      int j, conn_len;
-+      hda_nid_t conn[HDA_MAX_CONNECTIONS];
-+      unsigned int wcaps, wtype;
-+
-+      conn_len = snd_hda_get_connections(codec, nid, conn,
-+                                         HDA_MAX_CONNECTIONS);
-+      for (j = 0; j < conn_len; j++) {
+@@ -2824,8 +2879,7 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
+       conn_len = snd_hda_get_connections(codec, nid, conn,
+                                          HDA_MAX_CONNECTIONS);
+       for (j = 0; j < conn_len; j++) {
+-              wcaps = snd_hda_param_read(codec, conn[j],
+-                                         AC_PAR_AUDIO_WIDGET_CAP);
 +              wcaps = get_wcaps(codec, conn[j]);
-+              wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
-+              /* we check only analog outputs */
-+              if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL))
-+                      continue;
-+              /* if this route has a free DAC, assign it */
-+              if (!check_all_dac_nids(spec, conn[j])) {
-+                      if (conn_len > 1) {
-+                              /* select this DAC in the pin's input mux */
-+                              snd_hda_codec_write_cache(codec, nid, 0,
-+                                                AC_VERB_SET_CONNECT_SEL, j);
-+                      }
-+                      return conn[j];
-+              }
-+      }
+               wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+               /* we check only analog outputs */
+               if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL))
+@@ -2840,6 +2894,16 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
+                       return conn[j];
+               }
+       }
 +      /* if all DACs are already assigned, connect to the primary DAC */
 +      if (conn_len > 1) {
 +              for (j = 0; j < conn_len; j++) {
@@ -14717,66 +11718,13 @@ index 5e89424..d2fd8ef 100644
 +                      }
 +              }
 +      }
-+      return 0;
-+}
-+
-+static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
-+static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
-+
- /*
-  * Fill in the dac_nids table from the parsed pin configuration
-  * This function only works when every pin in line_out_pins[]
-@@ -2841,31 +2917,17 @@ static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
-  * codecs are not connected directly to a DAC, such as the 9200
-  * and 9202/925x. For those, dac_nids[] must be hard-coded.
-  */
--static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
--                                     struct auto_pin_cfg *cfg)
-+static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec)
- {
-       struct sigmatel_spec *spec = codec->spec;
--      int i, j, conn_len = 0; 
--      hda_nid_t nid, conn[HDA_MAX_CONNECTIONS];
--      unsigned int wcaps, wtype;
-+      struct auto_pin_cfg *cfg = &spec->autocfg;
-+      int i;
-+      hda_nid_t nid, dac;
-       
-       for (i = 0; i < cfg->line_outs; i++) {
-               nid = cfg->line_out_pins[i];
--              conn_len = snd_hda_get_connections(codec, nid, conn,
--                                                 HDA_MAX_CONNECTIONS);
--              for (j = 0; j < conn_len; j++) {
--                      wcaps = snd_hda_param_read(codec, conn[j],
--                                                 AC_PAR_AUDIO_WIDGET_CAP);
--                      wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
--                      if (wtype != AC_WID_AUD_OUT ||
--                          (wcaps & AC_WCAP_DIGITAL))
--                              continue;
--                      /* conn[j] is a DAC routed to this line-out */
--                      if (!is_in_dac_nids(spec, conn[j]))
--                              break;
--              }
--
--              if (j == conn_len) {
-+              dac = get_unassigned_dac(codec, nid);
-+              if (!dac) {
-                       if (spec->multiout.num_dacs > 0) {
-                               /* we have already working output pins,
-                                * so let's drop the broken ones again
-@@ -2879,30 +2941,70 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
-                                  __func__, nid);
-                       return -ENODEV;
-               }
-+              add_spec_dacs(spec, dac);
-+      }
+       return 0;
+ }
+@@ -2880,6 +2944,26 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec)
+               add_spec_dacs(spec, dac);
+       }
  
--              spec->multiout.dac_nids[i] = conn[j];
--              spec->multiout.num_dacs++;
--              if (conn_len > 1) {
--                      /* select this DAC in the pin's input mux */
--                      snd_hda_codec_write_cache(codec, nid, 0,
--                                                AC_VERB_SET_CONNECT_SEL, j);
 +      for (i = 0; i < cfg->hp_outs; i++) {
 +              nid = cfg->hp_pins[i];
 +              dac = get_unassigned_dac(codec, nid);
@@ -14796,44 +11744,38 @@ index 5e89424..d2fd8ef 100644
 +                      add_spec_extra_dacs(spec, dac);
 +              spec->speaker_dacs[i] = dac;
 +      }
-+      /* add line-in as output */
-+      nid = check_line_out_switch(codec);
-+      if (nid) {
-+              dac = get_unassigned_dac(codec, nid);
-+              if (dac) {
-+                      snd_printdd("STAC: Add line-in 0x%x as output %d\n",
-+                                  nid, cfg->line_outs);
-+                      cfg->line_out_pins[cfg->line_outs] = nid;
-+                      cfg->line_outs++;
-+                      spec->line_switch = nid;
-+                      add_spec_dacs(spec, dac);
-+              }
-+      }
-+      /* add mic as output */
-+      nid = check_mic_out_switch(codec);
-+      if (nid) {
-+              dac = get_unassigned_dac(codec, nid);
-+              if (dac) {
-+                      snd_printdd("STAC: Add mic-in 0x%x as output %d\n",
-+                                  nid, cfg->line_outs);
-+                      cfg->line_out_pins[cfg->line_outs] = nid;
-+                      cfg->line_outs++;
-+                      spec->mic_switch = nid;
-+                      add_spec_dacs(spec, dac);
++
+       /* add line-in as output */
+       nid = check_line_out_switch(codec);
+       if (nid) {
+@@ -2907,26 +2991,6 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec)
                }
        }
  
--      snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
-+      snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
+-      for (i = 0; i < cfg->hp_outs; i++) {
+-              nid = cfg->hp_pins[i];
+-              dac = get_unassigned_dac(codec, nid);
+-              if (dac) {
+-                      if (!spec->multiout.hp_nid)
+-                              spec->multiout.hp_nid = dac;
+-                      else
+-                              add_spec_extra_dacs(spec, dac);
+-              }
+-              spec->hp_dacs[i] = dac;
+-      }
+-
+-      for (i = 0; i < cfg->speaker_outs; i++) {
+-              nid = cfg->speaker_pins[i];
+-              dac = get_unassigned_dac(codec, nid);
+-              if (dac)
+-                      add_spec_extra_dacs(spec, dac);
+-              spec->speaker_dacs[i] = dac;
+-      }
+-
+       snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
                   spec->multiout.num_dacs,
                   spec->multiout.dac_nids[0],
-                  spec->multiout.dac_nids[1],
-                  spec->multiout.dac_nids[2],
-                  spec->multiout.dac_nids[3],
-                  spec->multiout.dac_nids[4]);
-+
-       return 0;
+@@ -2939,8 +3003,8 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec)
  }
  
  /* create volume control/switch for the given prefx type */
@@ -14844,7 +11786,7 @@ index 5e89424..d2fd8ef 100644
  {
        struct sigmatel_spec *spec = codec->spec;
        char name[32];
-@@ -2926,24 +3028,25 @@ static int create_controls(struct hda_codec *codec, const char *pfx,
+@@ -2964,19 +3028,22 @@ static int create_controls(struct hda_codec *codec, const char *pfx,
        }
  
        sprintf(name, "%s Playback Volume", pfx);
@@ -14868,249 +11810,47 @@ index 5e89424..d2fd8ef 100644
 +
  static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
  {
--      if (!spec->multiout.hp_nid)
--              spec->multiout.hp_nid = nid;
--      else if (spec->multiout.num_dacs > 4) {
-+      if (spec->multiout.num_dacs > 4) {
-               printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
-               return 1;
-       } else {
-@@ -2953,36 +3056,45 @@ static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
-       return 0;
- }
--static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
-+static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
- {
--      if (is_in_dac_nids(spec, nid))
--              return 1;
--      if (spec->multiout.hp_nid == nid)
--              return 1;
--      return 0;
-+      int i;
-+      for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) {
-+              if (!spec->multiout.extra_out_nid[i]) {
-+                      spec->multiout.extra_out_nid[i] = nid;
-+                      return 0;
-+              }
-+      }
-+      printk(KERN_WARNING "stac92xx: No space for extra DAC 0x%x\n", nid);
-+      return 1;
- }
--/* add playback controls from the parsed DAC table */
--static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
--                                             const struct auto_pin_cfg *cfg)
-+/* Create output controls
-+ * The mixer elements are named depending on the given type (AUTO_PIN_XXX_OUT)
-+ */
-+static int create_multi_out_ctls(struct hda_codec *codec, int num_outs,
-+                               const hda_nid_t *pins,
-+                               const hda_nid_t *dac_nids,
-+                               int type)
- {
-+      struct sigmatel_spec *spec = codec->spec;
+       if (spec->multiout.num_dacs > 4) {
+@@ -3014,12 +3081,6 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs,
        static const char *chname[4] = {
                "Front", "Surround", NULL /*CLFE*/, "Side"
        };
--      hda_nid_t nid = 0;
-+      hda_nid_t nid;
+-      static const char *hp_pfxs[] = {
+-              "Headphone", "Headphone2", "Headphone3", "Headphone4"
+-      };
+-      static const char *speaker_pfxs[] = {
+-              "Speaker", "External Speaker", "Speaker2", "Speaker3"
+-      };
+       hda_nid_t nid;
        int i, err;
-+      unsigned int wid_caps;
--      struct sigmatel_spec *spec = codec->spec;
--      unsigned int wid_caps, pincap;
--
--
--      for (i = 0; i < cfg->line_outs && i < spec->multiout.num_dacs; i++) {
--              if (!spec->multiout.dac_nids[i])
-+      for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) {
-+              if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) {
-+                      wid_caps = get_wcaps(codec, pins[i]);
-+                      if (wid_caps & AC_WCAP_UNSOL_CAP)
-+                              spec->hp_detect = 1;
-+              }
-+              nid = dac_nids[i];
-+              if (!nid)
-                       continue;
--
--              nid = spec->multiout.dac_nids[i];
--
--              if (i == 2) {
-+              if (type != AUTO_PIN_HP_OUT && i == 2) {
-                       /* Center/LFE */
-                       err = create_controls(codec, "Center", nid, 1);
-                       if (err < 0)
-@@ -3003,15 +3115,42 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
-                       }
+       unsigned int wid_caps;
+@@ -3055,18 +3116,22 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs,
  
                } else {
--                      err = create_controls(codec, chname[i], nid, 3);
-+                      const char *name;
+                       const char *name;
 +                      int idx;
-+                      switch (type) {
-+                      case AUTO_PIN_HP_OUT:
+                       switch (type) {
+                       case AUTO_PIN_HP_OUT:
+-                              name = hp_pfxs[i];
 +                              name = "Headphone";
 +                              idx = i;
-+                              break;
-+                      case AUTO_PIN_SPEAKER_OUT:
+                               break;
+                       case AUTO_PIN_SPEAKER_OUT:
+-                              name = speaker_pfxs[i];
 +                              name = "Speaker";
 +                              idx = i;
-+                              break;
-+                      default:
-+                              name = chname[i];
+                               break;
+                       default:
+                               name = chname[i];
 +                              idx = 0;
-+                              break;
-+                      }
+                               break;
+                       }
+-                      err = create_controls(codec, name, nid, 3);
 +                      err = create_controls_idx(codec, name, idx, nid, 3);
                        if (err < 0)
                                return err;
                }
-       }
-+      return 0;
-+}
-+
-+/* add playback controls from the parsed DAC table */
-+static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
-+                                             const struct auto_pin_cfg *cfg)
-+{
-+      struct sigmatel_spec *spec = codec->spec;
-+      int err;
--      if ((spec->multiout.num_dacs - cfg->line_outs) > 0 &&
--          cfg->hp_outs == 1 && !spec->multiout.hp_nid)
--              spec->multiout.hp_nid = nid;
-+      err = create_multi_out_ctls(codec, cfg->line_outs, cfg->line_out_pins,
-+                                  spec->multiout.dac_nids,
-+                                  cfg->line_out_type);
-+      if (err < 0)
-+              return err;
-       if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) {
-               err = stac92xx_add_control(spec,
-@@ -3023,45 +3162,19 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
-       }
-       if (spec->line_switch) {
--              nid = cfg->input_pins[AUTO_PIN_LINE];
--              pincap = snd_hda_param_read(codec, nid,
--                                              AC_PAR_PIN_CAP);
--              if (pincap & AC_PINCAP_OUT) {
--                      err = stac92xx_add_control(spec,
--                              STAC_CTL_WIDGET_IO_SWITCH,
--                              "Line In as Output Switch", nid << 8);
--                      if (err < 0)
--                              return err;
--              }
-+              err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH,
-+                                         "Line In as Output Switch",
-+                                         spec->line_switch << 8);
-+              if (err < 0)
-+                      return err;
-       }
-       if (spec->mic_switch) {
--              unsigned int def_conf;
--              unsigned int mic_pin = AUTO_PIN_MIC;
--again:
--              nid = cfg->input_pins[mic_pin];
--              def_conf = snd_hda_codec_read(codec, nid, 0,
--                                              AC_VERB_GET_CONFIG_DEFAULT, 0);
--              /* some laptops have an internal analog microphone
--               * which can't be used as a output */
--              if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) {
--                      pincap = snd_hda_param_read(codec, nid,
--                                                      AC_PAR_PIN_CAP);
--                      if (pincap & AC_PINCAP_OUT) {
--                              err = stac92xx_add_control(spec,
--                                      STAC_CTL_WIDGET_IO_SWITCH,
--                                      "Mic as Output Switch", (nid << 8) | 1);
--                              nid = snd_hda_codec_read(codec, nid, 0,
--                                       AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
--                              if (!check_in_dac_nids(spec, nid))
--                                      add_spec_dacs(spec, nid);
--                              if (err < 0)
--                                      return err;
--                      }
--              } else if (mic_pin == AUTO_PIN_MIC) {
--                      mic_pin = AUTO_PIN_FRONT_MIC;
--                      goto again;
--              }
-+              err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH,
-+                                         "Mic as Output Switch",
-+                                         (spec->mic_switch << 8) | 1);
-+              if (err < 0)
-+                      return err;
-       }
-       return 0;
-@@ -3072,55 +3185,17 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
-                                       struct auto_pin_cfg *cfg)
- {
-       struct sigmatel_spec *spec = codec->spec;
--      hda_nid_t nid;
--      int i, old_num_dacs, err;
-+      int err;
--      old_num_dacs = spec->multiout.num_dacs;
--      for (i = 0; i < cfg->hp_outs; i++) {
--              unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]);
--              if (wid_caps & AC_WCAP_UNSOL_CAP)
--                      spec->hp_detect = 1;
--              nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
--                                       AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
--              if (check_in_dac_nids(spec, nid))
--                      nid = 0;
--              if (! nid)
--                      continue;
--              add_spec_dacs(spec, nid);
--      }
--      for (i = 0; i < cfg->speaker_outs; i++) {
--              nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
--                                       AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
--              if (check_in_dac_nids(spec, nid))
--                      nid = 0;
--              if (! nid)
--                      continue;
--              add_spec_dacs(spec, nid);
--      }
--      for (i = 0; i < cfg->line_outs; i++) {
--              nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0,
--                                      AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
--              if (check_in_dac_nids(spec, nid))
--                      nid = 0;
--              if (! nid)
--                      continue;
--              add_spec_dacs(spec, nid);
--      }
--      for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) {
--              static const char *pfxs[] = {
--                      "Speaker", "External Speaker", "Speaker2",
--              };
--              err = create_controls(codec, pfxs[i - old_num_dacs],
--                                    spec->multiout.dac_nids[i], 3);
--              if (err < 0)
--                      return err;
--      }
--      if (spec->multiout.hp_nid) {
--              err = create_controls(codec, "Headphone",
--                                    spec->multiout.hp_nid, 3);
--              if (err < 0)
--                      return err;
--      }
-+      err = create_multi_out_ctls(codec, cfg->hp_outs, cfg->hp_pins,
-+                                  spec->hp_dacs, AUTO_PIN_HP_OUT);
-+      if (err < 0)
-+              return err;
-+
-+      err = create_multi_out_ctls(codec, cfg->speaker_outs, cfg->speaker_pins,
-+                                  spec->speaker_dacs, AUTO_PIN_SPEAKER_OUT);
-+      if (err < 0)
-+              return err;
-       return 0;
- }
-@@ -3330,11 +3405,7 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
+@@ -3340,11 +3405,7 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
                unsigned int wcaps;
                unsigned int def_conf;
  
@@ -15123,85 +11863,7 @@ index 5e89424..d2fd8ef 100644
                if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
                        continue;
  
-@@ -3458,8 +3529,8 @@ static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
- static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in)
- {
-       struct sigmatel_spec *spec = codec->spec;
-+      int hp_swap = 0;
-       int err;
--      int hp_speaker_swap = 0;
-       if ((err = snd_hda_parse_pin_def_config(codec,
-                                               &spec->autocfg,
-@@ -3477,13 +3548,16 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
-                * speaker_outs so that the following routines can handle
-                * HP pins as primary outputs.
-                */
-+              snd_printdd("stac92xx: Enabling multi-HPs workaround\n");
-               memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins,
-                      sizeof(spec->autocfg.line_out_pins));
-               spec->autocfg.speaker_outs = spec->autocfg.line_outs;
-               memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins,
-                      sizeof(spec->autocfg.hp_pins));
-               spec->autocfg.line_outs = spec->autocfg.hp_outs;
--              hp_speaker_swap = 1;
-+              spec->autocfg.line_out_type = AUTO_PIN_HP_OUT;
-+              spec->autocfg.hp_outs = 0;
-+              hp_swap = 1;
-       }
-       if (spec->autocfg.mono_out_pin) {
-               int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) &
-@@ -3535,10 +3609,9 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
-                                        AC_PINCTL_OUT_EN);
-       }
--      if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
--              return err;
--      if (spec->multiout.num_dacs == 0) {
--              if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
-+      if (!spec->multiout.num_dacs) {
-+              err = stac92xx_auto_fill_dac_nids(codec);
-+              if (err < 0)
-                       return err;
-               err = stac92xx_auto_create_multi_out_ctls(codec,
-                                                         &spec->autocfg);
-@@ -3577,26 +3650,20 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
-       }
- #endif
--      if (hp_speaker_swap == 1) {
--              /* Restore the hp_outs and line_outs */
--              memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
--                     sizeof(spec->autocfg.line_out_pins));
--              spec->autocfg.hp_outs = spec->autocfg.line_outs;
--              memcpy(spec->autocfg.line_out_pins, spec->autocfg.speaker_pins,
--                     sizeof(spec->autocfg.speaker_pins));
--              spec->autocfg.line_outs = spec->autocfg.speaker_outs;
--              memset(spec->autocfg.speaker_pins, 0,
--                     sizeof(spec->autocfg.speaker_pins));
--              spec->autocfg.speaker_outs = 0;
--      }
--
-       err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
--
-       if (err < 0)
-               return err;
--      err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
-+      /* All output parsing done, now restore the swapped hp pins */
-+      if (hp_swap) {
-+              memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
-+                     sizeof(spec->autocfg.hp_pins));
-+              spec->autocfg.hp_outs = spec->autocfg.line_outs;
-+              spec->autocfg.line_out_type = AUTO_PIN_HP_OUT;
-+              spec->autocfg.line_outs = 0;
-+      }
-+      err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
-       if (err < 0)
-               return err;
-@@ -3625,20 +3692,25 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
+@@ -3631,17 +3692,21 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
                        return err;
        }
  
@@ -15225,13 +11887,8 @@ index 5e89424..d2fd8ef 100644
 +              spec->mixers[spec->num_mixers++] = spec->kctls.list;
  
        spec->input_mux = &spec->private_imux;
--      spec->dinput_mux = &spec->private_dimux;
-+      if (!spec->dinput_mux)
-+              spec->dinput_mux = &spec->private_dimux;
-       spec->sinput_mux = &spec->private_smux;
-       spec->mono_mux = &spec->private_mono_mux;
-       spec->amp_mux = &spec->private_amp_mux;
-@@ -3691,9 +3763,7 @@ static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec,
+       if (!spec->dinput_mux)
+@@ -3698,9 +3763,7 @@ static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec,
                for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) {
                        hda_nid_t pin = spec->autocfg.line_out_pins[i];
                        unsigned int defcfg;
@@ -15242,7 +11899,7 @@ index 5e89424..d2fd8ef 100644
                        if (get_defcfg_device(defcfg) == AC_JACK_SPEAKER) {
                                unsigned int wcaps = get_wcaps(codec, pin);
                                wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
-@@ -3737,13 +3807,17 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
+@@ -3744,13 +3807,17 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
                        return err;
        }
  
@@ -15263,7 +11920,7 @@ index 5e89424..d2fd8ef 100644
  
        spec->input_mux = &spec->private_imux;
        spec->dinput_mux = &spec->private_dimux;
-@@ -3787,13 +3861,115 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
+@@ -3794,17 +3861,64 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
                           AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
  }
  
@@ -15303,99 +11960,61 @@ index 5e89424..d2fd8ef 100644
 +              snd_hda_get_jack_location(def_conf));
 +
 +      err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
-+      if (err < 0) {
-+              jack->nid = 0;
-+              return err;
-+      }
-+      jack->jack->private_data = jack;
-+      jack->jack->private_free = stac92xx_free_jack_priv;
-+#endif
-+      return 0;
-+}
-+
-+static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid,
-+                        unsigned char type, int data)
-+{
-+      struct sigmatel_event *event;
-+
-+      snd_array_init(&spec->events, sizeof(*event), 32);
-+      event = snd_array_new(&spec->events);
-+      if (!event)
-+              return -ENOMEM;
-+      event->nid = nid;
-+      event->type = type;
-+      event->tag = spec->events.used;
-+      event->data = data;
-+
-+      return event->tag;
-+}
-+
-+static struct sigmatel_event *stac_get_event(struct hda_codec *codec,
-+                                           hda_nid_t nid, unsigned char type)
-+{
-+      struct sigmatel_spec *spec = codec->spec;
-+      struct sigmatel_event *event = spec->events.list;
-+      int i;
-+
-+      for (i = 0; i < spec->events.used; i++, event++) {
-+              if (event->nid == nid && event->type == type)
-+                      return event;
-+      }
-+      return NULL;
-+}
-+
-+static struct sigmatel_event *stac_get_event_from_tag(struct hda_codec *codec,
-+                                                    unsigned char tag)
-+{
-+      struct sigmatel_spec *spec = codec->spec;
-+      struct sigmatel_event *event = spec->events.list;
-+      int i;
-+
-+      for (i = 0; i < spec->events.used; i++, event++) {
-+              if (event->tag == tag)
-+                      return event;
++      if (err < 0) {
++              jack->nid = 0;
++              return err;
 +      }
-+      return NULL;
++      jack->jack->private_data = jack;
++      jack->jack->private_free = stac92xx_free_jack_priv;
++#endif
++      return 0;
 +}
 +
- static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
--                            unsigned int event)
-+                            unsigned int type)
+ static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid,
+                         unsigned char type, int data)
  {
--      if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)
--              snd_hda_codec_write_cache(codec, nid, 0,
--                                        AC_VERB_SET_UNSOLICITED_ENABLE,
--                                        (AC_USRSP_EN | event));
-+      struct sigmatel_event *event;
-+      int tag;
-+
-+      if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
-+              return;
-+      event = stac_get_event(codec, nid, type);
-+      if (event)
-+              tag = event->tag;
-+      else
-+              tag = stac_add_event(codec->spec, nid, type, 0);
-+      if (tag < 0)
-+              return;
-+      snd_hda_codec_write_cache(codec, nid, 0,
-+                                AC_VERB_SET_UNSOLICITED_ENABLE,
-+                                AC_USRSP_EN | tag);
- }
+       struct sigmatel_event *event;
  
- static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
-@@ -3813,15 +3989,44 @@ static void stac92xx_power_down(struct hda_codec *codec)
-       /* power down inactive DACs */
-       hda_nid_t *dac;
-       for (dac = spec->dac_list; *dac; dac++)
--              if (!is_in_dac_nids(spec, *dac) &&
--                      spec->multiout.hp_nid != *dac)
--                      snd_hda_codec_write_cache(codec, *dac, 0,
-+              if (!check_all_dac_nids(spec, *dac))
-+                      snd_hda_codec_write(codec, *dac, 0,
-                                       AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
- }
+-      if (spec->num_events >= ARRAY_SIZE(spec->events))
++      snd_array_init(&spec->events, sizeof(*event), 32);
++      event = snd_array_new(&spec->events);
++      if (!event)
+               return -ENOMEM;
+-      event = &spec->events[spec->num_events++];
+       event->nid = nid;
+       event->type = type;
+-      event->tag = spec->num_events;
++      event->tag = spec->events.used;
+       event->data = data;
+       return event->tag;
+@@ -3814,10 +3928,10 @@ static struct sigmatel_event *stac_get_event(struct hda_codec *codec,
+                                            hda_nid_t nid, unsigned char type)
+ {
+       struct sigmatel_spec *spec = codec->spec;
+-      struct sigmatel_event *event = spec->events;
++      struct sigmatel_event *event = spec->events.list;
+       int i;
  
+-      for (i = 0; i < spec->num_events; i++, event++) {
++      for (i = 0; i < spec->events.used; i++, event++) {
+               if (event->nid == nid && event->type == type)
+                       return event;
+       }
+@@ -3828,10 +3942,10 @@ static struct sigmatel_event *stac_get_event_from_tag(struct hda_codec *codec,
+                                                     unsigned char tag)
+ {
+       struct sigmatel_spec *spec = codec->spec;
+-      struct sigmatel_event *event = spec->events;
++      struct sigmatel_event *event = spec->events.list;
+       int i;
+-      for (i = 0; i < spec->num_events; i++, event++) {
++      for (i = 0; i < spec->events.used; i++, event++) {
+               if (event->tag == tag)
+                       return event;
+       }
+@@ -3883,6 +3997,36 @@ static void stac92xx_power_down(struct hda_codec *codec)
  static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
                                  int enable);
  
@@ -15432,12 +12051,7 @@ index 5e89424..d2fd8ef 100644
  static int stac92xx_init(struct hda_codec *codec)
  {
        struct sigmatel_spec *spec = codec->spec;
-@@ -3834,10 +4039,13 @@ static int stac92xx_init(struct hda_codec *codec)
-       /* power down adcs initially */
-       if (spec->powerdown_adcs)
-               for (i = 0; i < spec->num_adcs; i++)
--                      snd_hda_codec_write_cache(codec,
-+                      snd_hda_codec_write(codec,
+@@ -3899,6 +4043,9 @@ static int stac92xx_init(struct hda_codec *codec)
                                spec->adc_nids[i], 0,
                                AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
  
@@ -15447,72 +12061,38 @@ index 5e89424..d2fd8ef 100644
        /* set up GPIO */
        gpio = spec->gpio_data;
        /* turn on EAPD statically when spec->eapd_switch isn't set.
-@@ -3850,44 +4058,62 @@ static int stac92xx_init(struct hda_codec *codec)
-       /* set up pins */
-       if (spec->hp_detect) {
-               /* Enable unsolicited responses on the HP widget */
--              for (i = 0; i < cfg->hp_outs; i++)
--                      enable_pin_detect(codec, cfg->hp_pins[i],
--                                        STAC_HP_EVENT);
-+              for (i = 0; i < cfg->hp_outs; i++) {
-+                      hda_nid_t nid = cfg->hp_pins[i];
-+                      enable_pin_detect(codec, nid, STAC_HP_EVENT);
-+              }
-               /* force to enable the first line-out; the others are set up
+@@ -3919,7 +4066,7 @@ static int stac92xx_init(struct hda_codec *codec)
                 * in unsol_event
                 */
                stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
 -                                       AC_PINCTL_OUT_EN);
--              stac92xx_auto_init_hp_out(codec);
 +                              AC_PINCTL_OUT_EN);
                /* fake event to set up pins */
--              codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
-+              stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0],
-+                                     STAC_HP_EVENT);
-       } else {
-               stac92xx_auto_init_multi_out(codec);
-               stac92xx_auto_init_hp_out(codec);
-+              for (i = 0; i < cfg->hp_outs; i++)
-+                      stac_toggle_power_map(codec, cfg->hp_pins[i], 1);
-       }
-       for (i = 0; i < AUTO_PIN_LAST; i++) {
-               hda_nid_t nid = cfg->input_pins[i];
-               if (nid) {
--                      unsigned int pinctl;
-+                      unsigned int pinctl, conf;
-                       if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) {
-                               /* for mic pins, force to initialize */
-                               pinctl = stac92xx_get_vref(codec, nid);
-+                              pinctl |= AC_PINCTL_IN_EN;
-+                              stac92xx_auto_set_pinctl(codec, nid, pinctl);
-                       } else {
+               stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0],
+                                      STAC_HP_EVENT);
+@@ -3942,14 +4089,18 @@ static int stac92xx_init(struct hda_codec *codec)
                                pinctl = snd_hda_codec_read(codec, nid, 0,
                                        AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
                                /* if PINCTL already set then skip */
--                              if (pinctl & AC_PINCTL_IN_EN)
--                                      continue;
+-                              if (!(pinctl & AC_PINCTL_IN_EN)) {
 +                              /* Also, if both INPUT and OUTPUT are set,
 +                               * it must be a BIOS bug; need to override, too
 +                               */
 +                              if (!(pinctl & AC_PINCTL_IN_EN) ||
 +                                  (pinctl & AC_PINCTL_OUT_EN)) {
 +                                      pinctl &= ~AC_PINCTL_OUT_EN;
-+                                      pinctl |= AC_PINCTL_IN_EN;
-+                                      stac92xx_auto_set_pinctl(codec, nid,
-+                                                               pinctl);
-+                              }
-+                      }
-+                      conf = snd_hda_codec_get_pincfg(codec, nid);
-+                      if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
-+                              enable_pin_detect(codec, nid,
-+                                                STAC_INSERT_EVENT);
-+                              stac_issue_unsol_event(codec, nid,
-+                                                     STAC_INSERT_EVENT);
+                                       pinctl |= AC_PINCTL_IN_EN;
+                                       stac92xx_auto_set_pinctl(codec, nid,
+                                                                pinctl);
+                               }
                        }
--                      pinctl |= AC_PINCTL_IN_EN;
--                      stac92xx_auto_set_pinctl(codec, nid, pinctl);
-               }
-       }
+-                      conf = snd_hda_codec_read(codec, nid, 0,
+-                                            AC_VERB_GET_CONFIG_DEFAULT, 0);
++                      conf = snd_hda_codec_get_pincfg(codec, nid);
+                       if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
+                               enable_pin_detect(codec, nid,
+                                                 STAC_INSERT_EVENT);
+@@ -3961,8 +4112,8 @@ static int stac92xx_init(struct hda_codec *codec)
        for (i = 0; i < spec->num_dmics; i++)
                stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
                                        AC_PINCTL_IN_EN);
@@ -15523,51 +12103,17 @@ index 5e89424..d2fd8ef 100644
                                         AC_PINCTL_OUT_EN);
        if (cfg->dig_in_pin)
                stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
-@@ -3895,9 +4121,14 @@ static int stac92xx_init(struct hda_codec *codec)
-       for (i = 0; i < spec->num_pwrs; i++)  {
-               hda_nid_t nid = spec->pwr_nids[i];
-               int pinctl, def_conf;
--              int event = STAC_PWR_EVENT;
--              if (is_nid_hp_pin(cfg, nid) && spec->hp_detect)
-+              /* power on when no jack detection is available */
-+              if (!spec->hp_detect) {
-+                      stac_toggle_power_map(codec, nid, 1);
-+                      continue;
-+              }
-+
-+              if (is_nid_hp_pin(cfg, nid))
-                       continue; /* already has an unsol event */
-               pinctl = snd_hda_codec_read(codec, nid, 0,
-@@ -3906,10 +4137,11 @@ static int stac92xx_init(struct hda_codec *codec)
-                * any attempts on powering down a input port cause the
-                * referenced VREF to act quirky.
-                */
--              if (pinctl & AC_PINCTL_IN_EN)
-+              if (pinctl & AC_PINCTL_IN_EN) {
-+                      stac_toggle_power_map(codec, nid, 1);
+@@ -3990,8 +4141,7 @@ static int stac92xx_init(struct hda_codec *codec)
+                       stac_toggle_power_map(codec, nid, 1);
                        continue;
+               }
 -              def_conf = snd_hda_codec_read(codec, nid, 0,
 -                                            AC_VERB_GET_CONFIG_DEFAULT, 0);
-+              }
 +              def_conf = snd_hda_codec_get_pincfg(codec, nid);
                def_conf = get_defcfg_connect(def_conf);
                /* skip any ports that don't have jacks since presence
                 * detection is useless */
-@@ -3918,30 +4150,55 @@ static int stac92xx_init(struct hda_codec *codec)
-                               stac_toggle_power_map(codec, nid, 1);
-                       continue;
-               }
--              enable_pin_detect(codec, spec->pwr_nids[i], event | i);
--              codec->patch_ops.unsol_event(codec, (event | i) << 26);
-+              if (!stac_get_event(codec, nid, STAC_INSERT_EVENT)) {
-+                      enable_pin_detect(codec, nid, STAC_PWR_EVENT);
-+                      stac_issue_unsol_event(codec, nid, STAC_PWR_EVENT);
-+              }
-       }
-       if (spec->dac_list)
-               stac92xx_power_down(codec);
+@@ -4010,22 +4160,45 @@ static int stac92xx_init(struct hda_codec *codec)
        return 0;
  }
  
@@ -15622,7 +12168,7 @@ index 5e89424..d2fd8ef 100644
  
        kfree(spec);
        snd_hda_detach_beep_device(codec);
-@@ -3950,7 +4207,9 @@ static void stac92xx_free(struct hda_codec *codec)
+@@ -4034,7 +4207,9 @@ static void stac92xx_free(struct hda_codec *codec)
  static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
                                unsigned int flag)
  {
@@ -15633,16 +12179,7 @@ index 5e89424..d2fd8ef 100644
                        0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
  
        if (pin_ctl & AC_PINCTL_IN_EN) {
-@@ -3960,22 +4219,21 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
-                * "xxx as Output" mixer switch
-                */
-               struct sigmatel_spec *spec = codec->spec;
--              struct auto_pin_cfg *cfg = &spec->autocfg;
--              if ((nid == cfg->input_pins[AUTO_PIN_LINE] &&
--                   spec->line_switch) ||
--                  (nid == cfg->input_pins[AUTO_PIN_MIC] &&
--                   spec->mic_switch))
-+              if (nid == spec->line_switch || nid == spec->mic_switch)
+@@ -4048,14 +4223,17 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
                        return;
        }
  
@@ -15663,7 +12200,7 @@ index 5e89424..d2fd8ef 100644
  }
  
  static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
-@@ -3983,25 +4241,19 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
+@@ -4063,9 +4241,10 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
  {
        unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
                        0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
@@ -15676,93 +12213,11 @@ index 5e89424..d2fd8ef 100644
 +                                        pin_ctl & ~flag);
  }
  
--static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid)
-+static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
- {
-       if (!nid)
-               return 0;
-       if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00)
--          & (1 << 31)) {
--              unsigned int pinctl;
--              pinctl = snd_hda_codec_read(codec, nid, 0,
--                                          AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
--              if (pinctl & AC_PINCTL_IN_EN)
--                      return 0; /* mic- or line-input */
--              else
--                      return 1; /* HP-output */
--      }
-+          & (1 << 31))
-+              return 1;
-       return 0;
- }
-@@ -4013,11 +4265,9 @@ static int no_hp_sensing(struct sigmatel_spec *spec, int i)
-       struct auto_pin_cfg *cfg = &spec->autocfg;
-       /* ignore sensing of shared line and mic jacks */
--      if (spec->line_switch &&
--          cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_LINE])
-+      if (cfg->hp_pins[i] == spec->line_switch)
-               return 1;
--      if (spec->mic_switch &&
--          cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_MIC])
-+      if (cfg->hp_pins[i] == spec->mic_switch)
-               return 1;
-       /* ignore if the pin is set as line-out */
-       if (cfg->hp_pins[i] == spec->hp_switch)
-@@ -4025,7 +4275,7 @@ static int no_hp_sensing(struct sigmatel_spec *spec, int i)
-       return 0;
+ static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
+@@ -4210,6 +4389,33 @@ static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid)
+       stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid));
  }
  
--static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
-+static void stac92xx_hp_detect(struct hda_codec *codec)
- {
-       struct sigmatel_spec *spec = codec->spec;
-       struct auto_pin_cfg *cfg = &spec->autocfg;
-@@ -4041,7 +4291,14 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
-                       break;
-               if (no_hp_sensing(spec, i))
-                       continue;
--              presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);
-+              presence = get_pin_presence(codec, cfg->hp_pins[i]);
-+              if (presence) {
-+                      unsigned int pinctl;
-+                      pinctl = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
-+                                          AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-+                      if (pinctl & AC_PINCTL_IN_EN)
-+                              presence = 0; /* mic- or line-input */
-+              }
-       }
-       if (presence) {
-@@ -4082,8 +4339,19 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
-                       continue;
-               if (presence)
-                       stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);
-+#if 0 /* FIXME */
-+/* Resetting the pinctl like below may lead to (a sort of) regressions
-+ * on some devices since they use the HP pin actually for line/speaker
-+ * outs although the default pin config shows a different pin (that is
-+ * wrong and useless).
-+ *
-+ * So, it's basically a problem of default pin configs, likely a BIOS issue.
-+ * But, disabling the code below just works around it, and I'm too tired of
-+ * bug reports with such devices... 
-+ */
-               else
-                       stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val);
-+#endif /* FIXME */
-       }
- } 
-@@ -4118,50 +4386,193 @@ static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
- static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid)
- {
--      stac_toggle_power_map(codec, nid, get_hp_pin_presence(codec, nid));
-+      stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid));
-+}
-+
 +static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid)
 +{
 +      struct sigmatel_spec *spec = codec->spec;
@@ -15790,38 +12245,13 @@ index 5e89424..d2fd8ef 100644
 +      }
 +}
 +
-+static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid,
-+                                 unsigned char type)
-+{
-+      struct sigmatel_event *event = stac_get_event(codec, nid, type);
-+      if (!event)
-+              return;
-+      codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26);
- }
- static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
+ static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid,
+                                  unsigned char type)
  {
-       struct sigmatel_spec *spec = codec->spec;
--      int idx = res >> 26 & 0x0f;
-+      struct sigmatel_event *event;
-+      int tag, data;
--      switch ((res >> 26) & 0x70) {
-+      tag = (res >> 26) & 0x7f;
-+      event = stac_get_event_from_tag(codec, tag);
-+      if (!event)
-+              return;
-+
-+      switch (event->type) {
-       case STAC_HP_EVENT:
--              stac92xx_hp_detect(codec, res);
-+              stac92xx_hp_detect(codec);
-               /* fallthru */
-+      case STAC_INSERT_EVENT:
+@@ -4238,6 +4444,25 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
        case STAC_PWR_EVENT:
                if (spec->num_pwrs > 0)
--                      stac92xx_pin_sense(codec, idx);
-+                      stac92xx_pin_sense(codec, event->nid);
+                       stac92xx_pin_sense(codec, event->nid);
 +              stac92xx_report_jack(codec, event->nid);
 +
 +              switch (codec->subsystem_id) {
@@ -15842,18 +12272,9 @@ index 5e89424..d2fd8ef 100644
 +                      }
 +              }
                break;
--      case STAC_VREF_EVENT: {
--              int data = snd_hda_codec_read(codec, codec->afg, 0,
--                      AC_VERB_GET_GPIO_DATA, 0);
-+      case STAC_VREF_EVENT:
-+              data = snd_hda_codec_read(codec, codec->afg, 0,
-+                                        AC_VERB_GET_GPIO_DATA, 0);
-               /* toggle VREF state based on GPIOx status */
-               snd_hda_codec_write(codec, codec->afg, 0, 0x7e0,
--                      !!(data & (1 << idx)));
-+                                  !!(data & (1 << event->data)));
-               break;
--              }
+       case STAC_VREF_EVENT:
+               data = snd_hda_codec_read(codec, codec->afg, 0,
+@@ -4249,12 +4474,57 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
        }
  }
  
@@ -15909,24 +12330,13 @@ index 5e89424..d2fd8ef 100644
        struct sigmatel_spec *spec = codec->spec;
  
 -      stac92xx_set_config_regs(codec);
--      snd_hda_sequence_write(codec, spec->init);
--      stac_gpio_set(codec, spec->gpio_mask,
--              spec->gpio_dir, spec->gpio_data);
-+      stac92xx_init(codec);
+       stac92xx_init(codec);
        snd_hda_codec_resume_amp(codec);
        snd_hda_codec_resume_cache(codec);
--      /* power down inactive DACs */
--      if (spec->dac_list)
--              stac92xx_power_down(codec);
--      /* invoke unsolicited event to reset the HP state */
-+      /* fake event to set up pins again to override cached values */
-       if (spec->hp_detect)
--              codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
-+              stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0],
-+                                     STAC_HP_EVENT);
-+      return 0;
-+}
-+
+@@ -4265,6 +4535,37 @@ static int stac92xx_resume(struct hda_codec *codec)
+       return 0;
+ }
 +
 +/*
 + * using power check for controlling mute led of HP HDX notebooks
@@ -15958,25 +12368,10 @@ index 5e89424..d2fd8ef 100644
 +}
 +#endif
 +
-+static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
-+{
-+      struct sigmatel_spec *spec = codec->spec;
-+      if (spec->eapd_mask)
-+              stac_gpio_set(codec, spec->gpio_mask,
-+                              spec->gpio_dir, spec->gpio_data &
-+                              ~spec->eapd_mask);
-       return 0;
- }
- #endif
-@@ -4173,6 +4584,7 @@ static struct hda_codec_ops stac92xx_patch_ops = {
-       .free = stac92xx_free,
-       .unsol_event = stac92xx_unsol_event,
- #ifdef SND_HDA_NEEDS_RESUME
-+      .suspend = stac92xx_suspend,
-       .resume = stac92xx_resume,
- #endif
- };
-@@ -4192,18 +4604,11 @@ static int patch_stac9200(struct hda_codec *codec)
+ static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
+ {
+       struct sigmatel_spec *spec = codec->spec;
+@@ -4303,18 +4604,11 @@ static int patch_stac9200(struct hda_codec *codec)
        spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
                                                        stac9200_models,
                                                        stac9200_cfg_tbl);
@@ -15999,20 +12394,7 @@ index 5e89424..d2fd8ef 100644
  
        spec->multiout.max_channels = 2;
        spec->multiout.num_dacs = 1;
-@@ -4234,6 +4639,12 @@ static int patch_stac9200(struct hda_codec *codec)
-               return err;
-       }
-+      /* CF-74 has no headphone detection, and the driver should *NOT*
-+       * do detection and HP/speaker toggle because the hardware does it.
-+       */
-+      if (spec->board_config == STAC_9200_PANASONIC)
-+              spec->hp_detect = 0;
-+
-       codec->patch_ops = stac92xx_patch_ops;
-       return 0;
-@@ -4265,19 +4676,12 @@ static int patch_stac925x(struct hda_codec *codec)
+@@ -4382,19 +4676,12 @@ static int patch_stac925x(struct hda_codec *codec)
                                                        stac925x_models,
                                                        stac925x_cfg_tbl);
   again:
@@ -16036,15 +12418,7 @@ index 5e89424..d2fd8ef 100644
  
        spec->multiout.max_channels = 2;
        spec->multiout.num_dacs = 1;
-@@ -4340,6 +4744,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
-       struct sigmatel_spec *spec;
-       hda_nid_t conn[STAC92HD73_DAC_COUNT + 2];
-       int err = 0;
-+      int num_dacs;
-       spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
-       if (spec == NULL)
-@@ -4354,47 +4759,40 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
+@@ -4472,19 +4759,12 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
                                                        stac92hd73xx_models,
                                                        stac92hd73xx_cfg_tbl);
  again:
@@ -16066,54 +12440,28 @@ index 5e89424..d2fd8ef 100644
 +              stac92xx_set_config_regs(codec,
 +                              stac92hd73xx_brd_tbl[spec->board_config]);
  
--      spec->multiout.num_dacs = snd_hda_get_connections(codec, 0x0a,
-+      num_dacs = snd_hda_get_connections(codec, 0x0a,
+       num_dacs = snd_hda_get_connections(codec, 0x0a,
                        conn, STAC92HD73_DAC_COUNT + 2) - 1;
--      if (spec->multiout.num_dacs < 0) {
-+      if (num_dacs < 3 || num_dacs > 5) {
-               printk(KERN_WARNING "hda_codec: Could not determine "
-                      "number of channels defaulting to DAC count\n");
--              spec->multiout.num_dacs = STAC92HD73_DAC_COUNT;
-+              num_dacs = STAC92HD73_DAC_COUNT;
-       }
--
--      switch (spec->multiout.num_dacs) {
-+      switch (num_dacs) {
+@@ -4498,14 +4778,18 @@ again:
        case 0x3: /* 6 Channel */
--              spec->multiout.hp_nid = 0x17;
                spec->mixer = stac92hd73xx_6ch_mixer;
                spec->init = stac92hd73xx_6ch_core_init;
 +              spec->aloopback_ctl = stac92hd73xx_6ch_loopback;
                break;
        case 0x4: /* 8 Channel */
--              spec->multiout.hp_nid = 0x18;
                spec->mixer = stac92hd73xx_8ch_mixer;
                spec->init = stac92hd73xx_8ch_core_init;
 +              spec->aloopback_ctl = stac92hd73xx_8ch_loopback;
                break;
        case 0x5: /* 10 Channel */
--              spec->multiout.hp_nid = 0x19;
                spec->mixer = stac92hd73xx_10ch_mixer;
                spec->init = stac92hd73xx_10ch_core_init;
--      };
 +              spec->aloopback_ctl = stac92hd73xx_10ch_loopback;
 +              break;
-+      }
-+      spec->multiout.dac_nids = spec->dac_nids;
--      spec->multiout.dac_nids = stac92hd73xx_dac_nids;
-       spec->aloopback_mask = 0x01;
-       spec->aloopback_shift = 8;
-@@ -4425,24 +4823,23 @@ again:
-               spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP];
-               spec->eapd_switch = 0;
-               spec->num_amps = 1;
--              spec->multiout.hp_nid = 0; /* dual HPs */
+       }
+       spec->multiout.dac_nids = spec->dac_nids;
  
--              if (!spec->init)
-+              if (spec->board_config != STAC_DELL_EQ)
+@@ -4544,18 +4828,18 @@ again:
                        spec->init = dell_m6_core_init;
                switch (spec->board_config) {
                case STAC_DELL_M6_AMIC: /* Analog Mics */
@@ -16136,7 +12484,7 @@ index 5e89424..d2fd8ef 100644
                        spec->num_dmics = 1;
                        spec->private_dimux.num_items = 2;
                        break;
-@@ -4485,6 +4882,8 @@ again:
+@@ -4598,6 +4882,8 @@ again:
  
        codec->patch_ops = stac92xx_patch_ops;
  
@@ -16145,47 +12493,30 @@ index 5e89424..d2fd8ef 100644
        return 0;
  }
  
-@@ -4500,7 +4899,10 @@ static struct hda_input_mux stac92hd83xxx_dmux = {
- static int patch_stac92hd83xxx(struct hda_codec *codec)
- {
-       struct sigmatel_spec *spec;
-+      hda_nid_t conn[STAC92HD83_DAC_COUNT + 1];
+@@ -4616,6 +4902,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
+       hda_nid_t conn[STAC92HD83_DAC_COUNT + 1];
        int err;
-+      int num_dacs;
+       int num_dacs;
 +      hda_nid_t nid;
  
        spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
-@@ -4514,25 +4916,17 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
-       spec->dmux_nids = stac92hd83xxx_dmux_nids;
-       spec->adc_nids = stac92hd83xxx_adc_nids;
-       spec->pwr_nids = stac92hd83xxx_pwr_nids;
-+      spec->amp_nids = stac92hd83xxx_amp_nids;
-       spec->pwr_mapping = stac92hd83xxx_pwr_mapping;
+@@ -4634,14 +4921,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
        spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
--      spec->multiout.dac_nids = stac92hd83xxx_dac_nids;
-+      spec->multiout.dac_nids = spec->dac_nids;
+       spec->multiout.dac_nids = spec->dac_nids;
  
-       spec->init = stac92hd83xxx_core_init;
--      switch (codec->vendor_id) {
--      case 0x111d7605:
--              spec->multiout.num_dacs = STAC92HD81_DAC_COUNT;
--              break;
--      default:
--              spec->num_pwrs--;
--              spec->init++; /* switch to config #2 */
--              spec->multiout.num_dacs = STAC92HD83_DAC_COUNT;
--      }
+-      /* set port 0xe to select the last DAC
+-       */
+-      num_dacs = snd_hda_get_connections(codec, 0x0e,
+-              conn, STAC92HD83_DAC_COUNT + 1) - 1;
+-
+-      snd_hda_codec_write_cache(codec, 0xe, 0,
+-              AC_VERB_SET_CONNECT_SEL, num_dacs);
 -
+       spec->init = stac92hd83xxx_core_init;
        spec->mixer = stac92hd83xxx_mixer;
        spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids);
-       spec->num_dmuxes = ARRAY_SIZE(stac92hd83xxx_dmux_nids);
-       spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids);
-+      spec->num_amps = ARRAY_SIZE(stac92hd83xxx_amp_nids);
-       spec->num_dmics = STAC92HD83XXX_NUM_DMICS;
-       spec->dinput_mux = &stac92hd83xxx_dmux;
-       spec->pin_nids = stac92hd83xxx_pin_nids;
-@@ -4541,18 +4935,21 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
+@@ -4656,23 +4935,17 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
                                                        stac92hd83xxx_models,
                                                        stac92hd83xxx_cfg_tbl);
  again:
@@ -16202,22 +12533,19 @@ index 5e89424..d2fd8ef 100644
 -      } else {
 -              spec->pin_configs = stac92hd83xxx_brd_tbl[spec->board_config];
 -              stac92xx_set_config_regs(codec);
+-      }
 +      else
 +              stac92xx_set_config_regs(codec,
 +                              stac92hd83xxx_brd_tbl[spec->board_config]);
-+
-+      switch (codec->vendor_id) {
-+      case 0x111d7604:
-+      case 0x111d7605:
-+      case 0x111d76d5:
-+              if (spec->board_config == STAC_92HD83XXX_PWR_REF)
-+                      break;
-+              spec->num_pwrs = 0;
-+              break;
-       }
  
-       err = stac92xx_parse_auto_config(codec, 0x1d, 0);
-@@ -4571,73 +4968,110 @@ again:
+       switch (codec->vendor_id) {
+       case 0x111d7604:
+       case 0x111d7605:
++      case 0x111d76d5:
+               if (spec->board_config == STAC_92HD83XXX_PWR_REF)
+                       break;
+               spec->num_pwrs = 0;
+@@ -4695,12 +4968,40 @@ again:
                return err;
        }
  
@@ -16245,13 +12573,7 @@ index 5e89424..d2fd8ef 100644
        return 0;
  }
  
--#ifdef SND_HDA_NEEDS_RESUME
--static void stac92hd71xx_set_power_state(struct hda_codec *codec, int pwr)
--{
--      struct sigmatel_spec *spec = codec->spec;
--      int i;
--      snd_hda_codec_write_cache(codec, codec->afg, 0,
--              AC_VERB_SET_POWER_STATE, pwr);
+-static struct hda_input_mux stac92hd71bxx_dmux = {
 +static struct hda_input_mux stac92hd71bxx_dmux_nomixer = {
 +      .num_items = 3,
 +      .items = {
@@ -16260,50 +12582,32 @@ index 5e89424..d2fd8ef 100644
 +              { "Digital Mic 2", 0x03 },
 +      }
 +};
--      msleep(1);
--      for (i = 0; i < spec->num_adcs; i++) {
--              snd_hda_codec_write_cache(codec,
--                      spec->adc_nids[i], 0,
--                      AC_VERB_SET_POWER_STATE, pwr);
++
 +static struct hda_input_mux stac92hd71bxx_dmux_amixer = {
-+      .num_items = 4,
-+      .items = {
-+              { "Analog Inputs", 0x00 },
-+              { "Mixer", 0x01 },
-+              { "Digital Mic 1", 0x02 },
-+              { "Digital Mic 2", 0x03 },
+       .num_items = 4,
+       .items = {
+               { "Analog Inputs", 0x00 },
+@@ -4710,10 +5011,67 @@ static struct hda_input_mux stac92hd71bxx_dmux = {
        }
  };
  
--static int stac92hd71xx_resume(struct hda_codec *codec)
 +/* get the pin connection (fixed, none, etc) */
 +static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx)
- {
--      stac92hd71xx_set_power_state(codec, AC_PWRST_D0);
--      return stac92xx_resume(codec);
++{
 +      struct sigmatel_spec *spec = codec->spec;
 +      unsigned int cfg;
 +
 +      cfg = snd_hda_codec_get_pincfg(codec, spec->pin_nids[idx]);
 +      return get_defcfg_connect(cfg);
- }
--static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state)
++}
++
 +static int stac92hd71bxx_connected_ports(struct hda_codec *codec,
 +                                       hda_nid_t *nids, int num_nids)
- {
-       struct sigmatel_spec *spec = codec->spec;
++{
++      struct sigmatel_spec *spec = codec->spec;
 +      int idx, num;
 +      unsigned int def_conf;
--      stac92hd71xx_set_power_state(codec, AC_PWRST_D3);
--      if (spec->eapd_mask)
--              stac_gpio_set(codec, spec->gpio_mask,
--                              spec->gpio_dir, spec->gpio_data &
--                              ~spec->eapd_mask);
--      return 0;
--};
++
 +      for (num = 0; num < num_nids; num++) {
 +              for (idx = 0; idx < spec->num_pins; idx++)
 +                      if (spec->pin_nids[idx] == nids[num])
@@ -16316,40 +12620,19 @@ index 5e89424..d2fd8ef 100644
 +      }
 +      return num;
 +}
--#endif
++
 +static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec,
 +                                        hda_nid_t dig0pin)
 +{
 +      struct sigmatel_spec *spec = codec->spec;
 +      int idx;
--static struct hda_codec_ops stac92hd71bxx_patch_ops = {
--      .build_controls = stac92xx_build_controls,
--      .build_pcms = stac92xx_build_pcms,
--      .init = stac92xx_init,
--      .free = stac92xx_free,
--      .unsol_event = stac92xx_unsol_event,
--#ifdef SND_HDA_NEEDS_RESUME
--      .resume = stac92hd71xx_resume,
--      .suspend = stac92hd71xx_suspend,
--#endif
--};
++
 +      for (idx = 0; idx < spec->num_pins; idx++)
 +              if (spec->pin_nids[idx] == dig0pin)
 +                      break;
 +      if ((idx + 2) >= spec->num_pins)
 +              return 0;
--static struct hda_input_mux stac92hd71bxx_dmux = {
--      .num_items = 4,
--      .items = {
--              { "Analog Inputs", 0x00 },
--              { "Mixer", 0x01 },
--              { "Digital Mic 1", 0x02 },
--              { "Digital Mic 2", 0x03 },
--      }
--};
++
 +      /* dig1pin case */
 +      if (stac_get_defcfg_connect(codec, idx + 1) != AC_JACK_PORT_NONE)
 +              return 2;
@@ -16362,7 +12645,7 @@ index 5e89424..d2fd8ef 100644
 +      else
 +              return 0;
 +}
++
  static int patch_stac92hd71bxx(struct hda_codec *codec)
  {
        struct sigmatel_spec *spec;
@@ -16372,7 +12655,7 @@ index 5e89424..d2fd8ef 100644
  
        spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
-@@ -4645,29 +5079,32 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
+@@ -4721,29 +5079,32 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
  
        codec->spec = spec;
        codec->patch_ops = stac92xx_patch_ops;
@@ -16420,7 +12703,7 @@ index 5e89424..d2fd8ef 100644
  
        if (spec->board_config > STAC_92HD71BXX_REF) {
                /* GPIO0 = EAPD */
-@@ -4676,34 +5113,52 @@ again:
+@@ -4752,16 +5113,34 @@ again:
                spec->gpio_data = 0x01;
        }
  
@@ -16455,32 +12738,7 @@ index 5e89424..d2fd8ef 100644
                switch (spec->board_config) {
                case STAC_HP_M4:
                        /* Enable VREF power saving on GPIO1 detect */
-+                      err = stac_add_event(spec, codec->afg,
-+                                           STAC_VREF_EVENT, 0x02);
-+                      if (err < 0)
-+                              return err;
-                       snd_hda_codec_write_cache(codec, codec->afg, 0,
-                               AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
-                       snd_hda_codec_write_cache(codec, codec->afg, 0,
--                                      AC_VERB_SET_UNSOLICITED_ENABLE,
--                                      (AC_USRSP_EN | STAC_VREF_EVENT | 0x01));
-+                              AC_VERB_SET_UNSOLICITED_ENABLE,
-+                              AC_USRSP_EN | err);
-                       spec->gpio_mask |= 0x02;
-                       break;
-               }
-               if ((codec->revision_id & 0xf) == 0 ||
--                              (codec->revision_id & 0xf) == 1) {
--#ifdef SND_HDA_NEEDS_RESUME
--                      codec->patch_ops = stac92hd71bxx_patch_ops;
--#endif
-+                  (codec->revision_id & 0xf) == 1)
-                       spec->stream_delay = 40; /* 40 milliseconds */
--              }
-               /* no output amps */
-               spec->num_pwrs = 0;
-@@ -4712,26 +5167,41 @@ again:
+@@ -4788,7 +5167,15 @@ again:
  
                /* disable VSW */
                spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF];
@@ -16496,15 +12754,8 @@ index 5e89424..d2fd8ef 100644
 +              ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 2;
                break;
        case 0x111d7603: /* 6 Port with Analog Mixer */
--              if ((codec->revision_id & 0xf) == 1) {
--#ifdef SND_HDA_NEEDS_RESUME
--                      codec->patch_ops = stac92hd71bxx_patch_ops;
--#endif
-+              if ((codec->revision_id & 0xf) == 1)
-                       spec->stream_delay = 40; /* 40 milliseconds */
--              }
-               /* no output amps */
+               if ((codec->revision_id & 0xf) == 1)
+@@ -4798,12 +5185,23 @@ again:
                spec->num_pwrs = 0;
                /* fallthru */
        default:
@@ -16528,7 +12779,7 @@ index 5e89424..d2fd8ef 100644
        spec->aloopback_mask = 0x50;
        spec->aloopback_shift = 0;
  
-@@ -4739,18 +5209,17 @@ again:
+@@ -4811,18 +5209,17 @@ again:
        spec->digbeep_nid = 0x26;
        spec->mux_nids = stac92hd71bxx_mux_nids;
        spec->adc_nids = stac92hd71bxx_adc_nids;
@@ -16549,13 +12800,14 @@ index 5e89424..d2fd8ef 100644
                stac92xx_auto_set_pinctl(codec, 0x0e,
                        AC_PINCTL_IN_EN | AC_PINCTL_VREF_80);
                /* fallthru */
-@@ -4763,23 +5232,38 @@ again:
-       case STAC_DELL_M4_3:
-               spec->num_dmics = 1;
+@@ -4837,19 +5234,36 @@ again:
                spec->num_smuxes = 0;
--              spec->num_dmuxes = 0;
-+              spec->num_dmuxes = 1;
-+              break;
+               spec->num_dmuxes = 1;
+               break;
+-      default:
+-              spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
+-              spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids);
+-              spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
 +      case STAC_HP_DV5:
 +              snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
 +              stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN);
@@ -16578,17 +12830,10 @@ index 5e89424..d2fd8ef 100644
 +              codec->patch_ops.check_power_status =
 +                  stac92xx_hp_hdx_check_power_status;
 +#endif        
-               break;
--      default:
--              spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
--              spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids);
--              spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
++              break;
        };
  
--      spec->multiout.num_dacs = 1;
--      spec->multiout.hp_nid = 0x11;
--      spec->multiout.dac_nids = stac92hd71bxx_dac_nids;
-+      spec->multiout.dac_nids = spec->dac_nids;
+       spec->multiout.dac_nids = spec->dac_nids;
        if (spec->dinput_mux)
 -              spec->private_dimux.num_items +=
 -                      spec->num_dmics -
@@ -16600,7 +12845,7 @@ index 5e89424..d2fd8ef 100644
        if (!err) {
                if (spec->board_config < 0) {
                        printk(KERN_WARNING "hda_codec: No auto-config is "
-@@ -4795,6 +5279,8 @@ again:
+@@ -4865,6 +5279,8 @@ again:
                return err;
        }
  
@@ -16609,7 +12854,7 @@ index 5e89424..d2fd8ef 100644
        return 0;
  };
  
-@@ -4852,19 +5338,12 @@ static int patch_stac922x(struct hda_codec *codec)
+@@ -4922,19 +5338,12 @@ static int patch_stac922x(struct hda_codec *codec)
        }
  
   again:
@@ -16633,7 +12878,7 @@ index 5e89424..d2fd8ef 100644
  
        spec->adc_nids = stac922x_adc_nids;
        spec->mux_nids = stac922x_mux_nids;
-@@ -4915,26 +5394,19 @@ static int patch_stac927x(struct hda_codec *codec)
+@@ -4985,26 +5394,19 @@ static int patch_stac927x(struct hda_codec *codec)
                return -ENOMEM;
  
        codec->spec = spec;
@@ -16667,7 +12912,7 @@ index 5e89424..d2fd8ef 100644
  
        spec->digbeep_nid = 0x23;
        spec->adc_nids = stac927x_adc_nids;
-@@ -4963,15 +5435,15 @@ static int patch_stac927x(struct hda_codec *codec)
+@@ -5033,15 +5435,15 @@ static int patch_stac927x(struct hda_codec *codec)
                case 0x10280209:
                case 0x1028022e:
                        /* correct the device field to SPDIF out */
@@ -16687,7 +12932,7 @@ index 5e89424..d2fd8ef 100644
                /* fallthru */
        case STAC_DELL_3ST:
                /* GPIO2 High = Enable EAPD */
-@@ -4998,6 +5470,7 @@ static int patch_stac927x(struct hda_codec *codec)
+@@ -5068,6 +5470,7 @@ static int patch_stac927x(struct hda_codec *codec)
        }
  
        spec->num_pwrs = 0;
@@ -16695,7 +12940,7 @@ index 5e89424..d2fd8ef 100644
        spec->aloopback_mask = 0x40;
        spec->aloopback_shift = 0;
        spec->eapd_switch = 1;
-@@ -5019,6 +5492,8 @@ static int patch_stac927x(struct hda_codec *codec)
+@@ -5089,6 +5492,8 @@ static int patch_stac927x(struct hda_codec *codec)
  
        codec->patch_ops = stac92xx_patch_ops;
  
@@ -16704,7 +12949,7 @@ index 5e89424..d2fd8ef 100644
        /*
         * !!FIXME!!
         * The STAC927x seem to require fairly long delays for certain
-@@ -5054,18 +5529,11 @@ static int patch_stac9205(struct hda_codec *codec)
+@@ -5124,18 +5529,11 @@ static int patch_stac9205(struct hda_codec *codec)
                                                        stac9205_models,
                                                        stac9205_cfg_tbl);
   again:
@@ -16727,7 +12972,7 @@ index 5e89424..d2fd8ef 100644
  
        spec->digbeep_nid = 0x23;
        spec->adc_nids = stac9205_adc_nids;
-@@ -5082,6 +5550,7 @@ static int patch_stac9205(struct hda_codec *codec)
+@@ -5152,6 +5550,7 @@ static int patch_stac9205(struct hda_codec *codec)
  
        spec->init = stac9205_core_init;
        spec->mixer = stac9205_mixer;
@@ -16735,7 +12980,7 @@ index 5e89424..d2fd8ef 100644
  
        spec->aloopback_mask = 0x40;
        spec->aloopback_shift = 0;
-@@ -5093,15 +5562,18 @@ static int patch_stac9205(struct hda_codec *codec)
+@@ -5163,8 +5562,8 @@ static int patch_stac9205(struct hda_codec *codec)
        switch (spec->board_config){
        case STAC_9205_DELL_M43:
                /* Enable SPDIF in/out */
@@ -16745,19 +12990,8 @@ index 5e89424..d2fd8ef 100644
 +              snd_hda_codec_set_pincfg(codec, 0x20, 0x1c410030);
  
                /* Enable unsol response for GPIO4/Dock HP connection */
-+              err = stac_add_event(spec, codec->afg, STAC_VREF_EVENT, 0x01);
-+              if (err < 0)
-+                      return err;
-               snd_hda_codec_write_cache(codec, codec->afg, 0,
-                       AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
-               snd_hda_codec_write_cache(codec, codec->afg, 0,
-                                         AC_VERB_SET_UNSOLICITED_ENABLE,
--                                        (AC_USRSP_EN | STAC_HP_EVENT));
-+                                        AC_USRSP_EN | err);
-               spec->gpio_dir = 0x0b;
-               spec->eapd_mask = 0x01;
-@@ -5139,6 +5611,8 @@ static int patch_stac9205(struct hda_codec *codec)
+               err = stac_add_event(spec, codec->afg, STAC_VREF_EVENT, 0x01);
+@@ -5212,6 +5611,8 @@ static int patch_stac9205(struct hda_codec *codec)
  
        codec->patch_ops = stac92xx_patch_ops;
  
@@ -16766,7 +13000,7 @@ index 5e89424..d2fd8ef 100644
        return 0;
  }
  
-@@ -5146,239 +5620,87 @@ static int patch_stac9205(struct hda_codec *codec)
+@@ -5219,239 +5620,87 @@ static int patch_stac9205(struct hda_codec *codec)
   * STAC9872 hack
   */
  
@@ -16793,15 +13027,16 @@ index 5e89424..d2fd8ef 100644
 -      {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
 -      {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
 -      {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
--      {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
++static struct hda_verb stac9872_core_init[] = {
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
 -      {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
 -      {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
 -      {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
 -      {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
--      {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
--      {}
--};
--
+       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
+       {}
+ };
 -static struct hda_verb vaio_ar_init[] = {
 -      {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
 -      {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
@@ -16809,17 +13044,16 @@ index 5e89424..d2fd8ef 100644
 -      {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
 -/*    {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */
 -      {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
-+static struct hda_verb stac9872_core_init[] = {
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
+-      {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
 -      {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
 -      {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
 -/*    {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */
 -      {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
 -      {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
-       {}
- };
+-      {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
+-      {}
+-};
+-
 -/* bind volumes of both NID 0x02 and 0x05 */
 -static struct hda_bind_ctls vaio_bind_master_vol = {
 -      .ops = &snd_hda_bind_vol,
@@ -16907,7 +13141,7 @@ index 5e89424..d2fd8ef 100644
 -
 -static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
 -{
--      if (get_hp_pin_presence(codec, 0x0a)) {
+-      if (get_pin_presence(codec, 0x0a)) {
 -              stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
 -              stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
 -      } else {
@@ -17055,7 +13289,7 @@ index 5e89424..d2fd8ef 100644
        return 0;
  }
  
-@@ -5386,7 +5708,7 @@ static int patch_stac9872(struct hda_codec *codec)
+@@ -5459,7 +5708,7 @@ static int patch_stac9872(struct hda_codec *codec)
  /*
   * patch entries
   */
@@ -17064,7 +13298,7 @@ index 5e89424..d2fd8ef 100644
        { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
        { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
        { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
-@@ -5436,6 +5758,7 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = {
+@@ -5509,6 +5758,7 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = {
        { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx},
        { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx},
        { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx},
@@ -17072,7 +13306,7 @@ index 5e89424..d2fd8ef 100644
        { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx},
        { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
        { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },
-@@ -5450,3 +5773,27 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = {
+@@ -5523,3 +5773,27 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = {
        { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
        {} /* terminator */
  };
index cd6e6cbcffc615fef892ac270db89f8fde2fbe9d..06b65a6e279526db321adba24c4d9f553a8a3b36 100644 (file)
@@ -159,6 +159,7 @@ nfs-allow-0-retransmits.patch
 # ... Other.
 cdrom-sysctl-info.patch
 export-mlock
+intel-hda-2.6.30
 
 #
 # ParaVirtual Memory Management