]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'sound-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 22 Mar 2012 20:00:13 +0000 (13:00 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 22 Mar 2012 20:00:13 +0000 (13:00 -0700)
Pull updates of sound stuff from Takashi Iwai:
 "Here is the first big update chunk of sound stuff for 3.4-rc1.

  In the common sound infrastructure, there are a few changes for
  dynamic PCM support (used in ASoC) and a few clean-ups.  Majority of
  changes are found, as usual, in HD-audio and ASoC.

  Some highlights of HD-audio changes:

   - All the long-standing static quirk codes for Realtek codec were
     finally removed by fixing and extending the Realtek auto-parser.

   - The mute-LED control is standardized over all HD-audio codec
     drivers using the extended vmaster hook.

   - The vmaster slave mixer elements are initialized to 0dB as default
     so that the user won't be annoyed by the silent output after
     updates, e.g.  due to the additions of new elements.

   - Other many fix-ups for the misc HD-audio devices.

  In the ASoC side, this is a very active release, including a quite a
  few framework enhancements.  Some highlights:

   - Support for widgets not associated with a CODEC, an important part
     of the dynamic PCM framework.

   - A library factoring out the common code shared by dmaengine based
     DMA drivers contributed by Lars-Peter Clausen.  This will save a
     lot of code and make it much easier to deploy enhancements to
     dmaengine.

   - Support for binary controls, used for providing runtime
     configuration of algorithm coefficients.

   - A new DAPM widget type for regulator supplies allowing drivers for
     devices that can power down unused supplies while active to do
     without any per-driver code.

   - DAPM widgets for DAIs, initially giving a speed boost for playback
     startup and shutdown and also the basis for CODEC<->CODEC DAI link
     support.

   - Support for specifying the number of significant bits on audio
     interfaces, useful for allowing applications to know how much
     effort to put into generating data for a larger sample format.

   - Conversion of the FSI driver used on some SH processors to
     DMAEngine.

   - Conversion of EP93xx drivers to DMAEngine.

   - New CODEC drivers for Maxim MAX9768 and Wolfson Microelectronics
     WM2200.

   - Move audmux driver from arc/arm to sound/soc

   - McBSP move from arch/ to sound/ and updates

  Also, a few small updates and fixes for other drivers like au88x0,
  ymfpci, USB 6fire, USB usx2yaudio are included."

* tag 'sound-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (446 commits)
  ASoC: wm8994: Provide VMID mode control and fix default sequence
  ASoC: wm8994: Add missing break in resume
  ASoC: wm_hubs: Don't actively manage LINEOUT_VMID_BUF
  ASoC: pxa-ssp: atomically set stream active masks
  ASoC: fsl: p1022ds: tell the WM8776 codec driver that it's the master
  ASoC: Samsung: Added to support mono recording
  ALSA: hda - Fix build with CONFIG_PM=n
  ALSA: au88x0 - Avoid possible Oops at unbinding
  ALSA: usb-audio - Fix build error by consitification of rate list
  ASoC: core: Fix obscure leak of runtime array
  ALSA: pcm - Avoid GFP_ATOMIC in snd_pcm_link()
  ALSA: pcm: Constify the list in snd_pcm_hw_constraint_list
  ASoC: wm8996: Add 44.1kHz support
  ALSA: hda - Fix build of patch_sigmatel.c without CONFIG_SND_HDA_POWER_SAVE
  ASoC: mx27vis-aic32x4: Convert it to platform driver
  ALSA: hda - fix printing of high HDMI sample rates
  ALSA: ymfpci - Fix legacy registers on S3/S4 resume
  ALSA: control - Fixe a trailing white space error
  ALSA: hda - Add expose_enum_ctl flag to snd_hda_add_vmaster_hook()
  ALSA: hda - Add "Mute-LED Mode" enum control
  ...

1  2 
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/sound/alsa/ALSA-Configuration.txt
arch/arm/mach-shmobile/board-ap4evb.c
arch/arm/mach-shmobile/board-mackerel.c
arch/sh/boards/mach-ecovec24/setup.c
arch/sh/boards/mach-se/7724/setup.c
sound/pci/hda/patch_conexant.c

index a20008ab319a9d5acba2f57bdaff0a5338a1d547,ca8ee14bf00449b0fa6540c25ce11415fc532a3d..82ac057a24a948797af5575fd97d46e8161557e4
@@@ -30,10 -30,10 +30,11 @@@ national   National Semiconducto
  nintendo      Nintendo
  nvidia        NVIDIA
  nxp   NXP Semiconductors
 +picochip      Picochip Ltd
  powervr       Imagination Technologies
  qcom  Qualcomm, Inc.
  ramtron       Ramtron International
+ realtek Realtek Semiconductor Corp.
  samsung       Samsung Semiconductor
  sbs   Smart Battery System
  schindler     Schindler
index 12e3a0fb9bec3f9a358f42be1cd8ce2cb8195435,9af64c508ab44d87601ad4dae3db17e597ac7fc9..6f75ba3b8a391f634de7bd77ea2cae1392763571
@@@ -860,7 -860,8 +860,8 @@@ Prior to version 0.9.0rc4 options had 
  
      [Multiple options for each card instance]
      model     - force the model name
-     position_fix - Fix DMA pointer (0 = auto, 1 = use LPIB, 2 = POSBUF)
+     position_fix - Fix DMA pointer (0 = auto, 1 = use LPIB, 2 = POSBUF,
+                  3 = VIACOMBO, 4 = COMBO)
      probe_mask  - Bitmask to probe codecs (default = -1, meaning all slots)
                  When the bit 8 (0x100) is set, the lower 8 bits are used
                  as the "fixed" codec slots; i.e. the driver probes the
            (Usually SD_LPIB register is more accurate than the
            position buffer.)
  
+           position_fix=3 is specific to VIA devices.  The position
+           of the capture stream is checked from both LPIB and POSBUF
+           values.  position_fix=4 is a combination mode, using LPIB
+           for playback and POSBUF for capture.
      NB: If you get many "azx_get_response timeout" messages at
      loading, it's likely a problem of interrupts (e.g. ACPI irq
      routing).  Try to boot with options like "pci=noacpi".  Also, you
  
      Module supports autoprobe a chip.
  
 -    Note: the driver may have problems regarding endianess.
 +    Note: the driver may have problems regarding endianness.
  
      The power-management is supported.
  
index b4718b00e827b90e73edf01b252379cca75e4bcc,2ac08b29e2784153394b5a24b0a69175e2418a6d..8f6da7f134b35a2a1e73228c6e25b8d481116850
@@@ -295,6 -295,15 +295,6 @@@ static struct resource sh_mmcif_resourc
        },
  };
  
 -static struct sh_mmcif_dma sh_mmcif_dma = {
 -      .chan_priv_rx   = {
 -              .slave_id       = SHDMA_SLAVE_MMCIF_RX,
 -      },
 -      .chan_priv_tx   = {
 -              .slave_id       = SHDMA_SLAVE_MMCIF_TX,
 -      },
 -};
 -
  static struct sh_mmcif_plat_data sh_mmcif_plat = {
        .sup_pclk       = 0,
        .ocr            = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
                          MMC_CAP_8_BIT_DATA |
                          MMC_CAP_NEEDS_POLL,
        .get_cd         = slot_cn7_get_cd,
 -      .dma            = &sh_mmcif_dma,
 +      .slave_id_tx    = SHDMA_SLAVE_MMCIF_TX,
 +      .slave_id_rx    = SHDMA_SLAVE_MMCIF_RX,
  };
  
  static struct platform_device sh_mmcif_device = {
@@@ -737,26 -745,18 +737,18 @@@ fsi_set_rate_end
        return ret;
  }
  
- static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
- {
-       int ret;
-       if (is_porta)
-               ret = fsi_ak4642_set_rate(dev, rate, enable);
-       else
-               ret = fsi_hdmi_set_rate(dev, rate, enable);
-       return ret;
- }
  static struct sh_fsi_platform_info fsi_info = {
-       .porta_flags = SH_FSI_BRS_INV,
-       .portb_flags = SH_FSI_BRS_INV |
-                      SH_FSI_BRM_INV |
-                      SH_FSI_LRS_INV |
-                      SH_FSI_FMT_SPDIF,
-       .set_rate = fsi_set_rate,
+       .port_a = {
+               .flags          = SH_FSI_BRS_INV,
+               .set_rate       = fsi_ak4642_set_rate,
+       },
+       .port_b = {
+               .flags          = SH_FSI_BRS_INV |
+                                 SH_FSI_BRM_INV |
+                                 SH_FSI_LRS_INV |
+                                 SH_FSI_FMT_SPDIF,
+               .set_rate       = fsi_hdmi_set_rate,
+       },
  };
  
  static struct resource fsi_resources[] = {
@@@ -794,7 -794,7 +786,7 @@@ static struct fsi_ak4642_info fsi2_ak46
  static struct platform_device fsi_ak4643_device = {
        .name   = "fsi-ak4642-audio",
        .dev    = {
 -              .platform_data  = &fsi_info,
 +              .platform_data  = &fsi2_ak4643_info,
        },
  };
  
index 7b53cda418513a63f69d34a90e903aa4d7b76f1c,28d6d1f9dad4bf69f9280586faf7335d6c14fd36..d99e780dffca664e8d1b86e97a7a12cf4386526d
@@@ -43,6 -43,7 +43,6 @@@
  #include <linux/smsc911x.h>
  #include <linux/sh_intc.h>
  #include <linux/tca6416_keypad.h>
 -#include <linux/usb/r8a66597.h>
  #include <linux/usb/renesas_usbhs.h>
  #include <linux/dma-mapping.h>
  
   * 1-2 short | VBUS 5V       | Host
   * open      | external VBUS | Function
   *
 - * *1
 - * CN31 is used as
 - * CONFIG_USB_R8A66597_HCD    Host
 - * CONFIG_USB_RENESAS_USBHS   Function
 - *
   * CAUTION
   *
   * renesas_usbhs driver can use external interrupt mode
   * mackerel can not use external interrupt (IRQ7-PORT167) mode on "USB0",
   * because Touchscreen is using IRQ7-PORT40.
   * It is impossible to use IRQ7 demux on this board.
 - *
 - * We can use external interrupt mode USB-Function on "USB1".
 - * USB1 can become Host by r8a66597, and become Function by renesas_usbhs.
 - * But don't select both drivers in same time.
 - * These uses same IRQ number for request_irq(), and aren't supporting
 - * IRQF_SHARED / IORESOURCE_IRQ_SHAREABLE.
 - *
 - * Actually these are old/new version of USB driver.
 - * This mean its register will be broken if it supports shared IRQ,
   */
  
  /*
   *
   */
  
 +/*
 + * FSI - AK4642
 + *
 + * it needs amixer settings for playing
 + *
 + * amixer set "Headphone" on
 + * amixer set "HPOUTL Mixer DACH" on
 + * amixer set "HPOUTR Mixer DACH" on
 + */
 +
  /*
   * FIXME !!
   *
@@@ -671,16 -676,51 +671,16 @@@ static struct platform_device usbhs0_de
   * Use J30 to select between Host and Function. This setting
   * can however not be detected by software. Hotplug of USBHS1
   * is provided via IRQ8.
 + *
 + * Current USB1 works as "USB Host".
 + *  - set J30 "short"
 + *
 + * If you want to use it as "USB gadget",
 + *  - J30 "open"
 + *  - modify usbhs1_get_id() USBHS_HOST -> USBHS_GADGET
 + *  - add .get_vbus = usbhs_get_vbus in usbhs1_private
   */
  #define IRQ8 evt2irq(0x0300)
 -
 -/* USBHS1 USB Host support via r8a66597_hcd */
 -static void usb1_host_port_power(int port, int power)
 -{
 -      if (!power) /* only power-on is supported for now */
 -              return;
 -
 -      /* set VBOUT/PWEN and EXTLP1 in DVSTCTR */
 -      __raw_writew(__raw_readw(0xE68B0008) | 0x600, 0xE68B0008);
 -}
 -
 -static struct r8a66597_platdata usb1_host_data = {
 -      .on_chip        = 1,
 -      .port_power     = usb1_host_port_power,
 -};
 -
 -static struct resource usb1_host_resources[] = {
 -      [0] = {
 -              .name   = "USBHS1",
 -              .start  = 0xe68b0000,
 -              .end    = 0xe68b00e6 - 1,
 -              .flags  = IORESOURCE_MEM,
 -      },
 -      [1] = {
 -              .start  = evt2irq(0x1ce0) /* USB1_USB1I0 */,
 -              .flags  = IORESOURCE_IRQ,
 -      },
 -};
 -
 -static struct platform_device usb1_host_device = {
 -      .name   = "r8a66597_hcd",
 -      .id     = 1,
 -      .dev = {
 -              .dma_mask               = NULL,         /*  not use dma */
 -              .coherent_dma_mask      = 0xffffffff,
 -              .platform_data          = &usb1_host_data,
 -      },
 -      .num_resources  = ARRAY_SIZE(usb1_host_resources),
 -      .resource       = usb1_host_resources,
 -};
 -
 -/* USBHS1 USB Function support via renesas_usbhs */
 -
  #define USB_PHY_MODE          (1 << 4)
  #define USB_PHY_INT_EN                ((1 << 3) | (1 << 2))
  #define USB_PHY_ON            (1 << 1)
@@@ -736,7 -776,7 +736,7 @@@ static void usbhs1_hardware_exit(struc
  
  static int usbhs1_get_id(struct platform_device *pdev)
  {
 -      return USBHS_GADGET;
 +      return USBHS_HOST;
  }
  
  static u32 usbhs1_pipe_cfg[] = {
@@@ -767,6 -807,7 +767,6 @@@ static struct usbhs_private usbhs1_priv
                        .hardware_exit  = usbhs1_hardware_exit,
                        .get_id         = usbhs1_get_id,
                        .phy_reset      = usbhs_phy_reset,
 -                      .get_vbus       = usbhs_get_vbus,
                },
                .driver_param = {
                        .buswait_bwait  = 4,
@@@ -860,7 -901,7 +860,7 @@@ static int __fsi_set_round_rate(struct 
        return clk_enable(clk);
  }
  
- static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
+ static int fsi_b_set_rate(struct device *dev, int rate, int enable)
  {
        struct clk *fsib_clk;
        struct clk *fdiv_clk = &sh7372_fsidivb_clk;
        int ackmd_bpfmd;
        int ret;
  
-       /* FSIA is slave mode. nothing to do here */
-       if (is_porta)
-               return 0;
        /* clock start */
        switch (rate) {
        case 44100:
@@@ -916,14 -953,16 +912,16 @@@ fsi_set_rate_end
  }
  
  static struct sh_fsi_platform_info fsi_info = {
-       .porta_flags =  SH_FSI_BRS_INV,
-       .portb_flags =  SH_FSI_BRS_INV  |
+       .port_a = {
+               .flags = SH_FSI_BRS_INV,
+       },
+       .port_b = {
+               .flags = SH_FSI_BRS_INV |
                        SH_FSI_BRM_INV  |
                        SH_FSI_LRS_INV  |
                        SH_FSI_FMT_SPDIF,
-       .set_rate = fsi_set_rate,
+               .set_rate = fsi_b_set_rate,
+       }
  };
  
  static struct resource fsi_resources[] = {
@@@ -1143,6 -1182,15 +1141,6 @@@ static struct resource sh_mmcif_resourc
        },
  };
  
 -static struct sh_mmcif_dma sh_mmcif_dma = {
 -      .chan_priv_rx   = {
 -              .slave_id       = SHDMA_SLAVE_MMCIF_RX,
 -      },
 -      .chan_priv_tx   = {
 -              .slave_id       = SHDMA_SLAVE_MMCIF_TX,
 -      },
 -};
 -
  static struct sh_mmcif_plat_data sh_mmcif_plat = {
        .sup_pclk       = 0,
        .ocr            = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
                          MMC_CAP_8_BIT_DATA |
                          MMC_CAP_NEEDS_POLL,
        .get_cd         = slot_cn7_get_cd,
 -      .dma            = &sh_mmcif_dma,
 +      .slave_id_tx    = SHDMA_SLAVE_MMCIF_TX,
 +      .slave_id_rx    = SHDMA_SLAVE_MMCIF_RX,
  };
  
  static struct platform_device sh_mmcif_device = {
@@@ -1262,6 -1309,7 +1260,6 @@@ static struct platform_device *mackerel
        &nor_flash_device,
        &smc911x_device,
        &lcdc_device,
 -      &usb1_host_device,
        &usbhs1_device,
        &usbhs0_device,
        &leds_device,
@@@ -1352,10 -1400,6 +1350,10 @@@ static struct map_desc mackerel_io_desc
  static void __init mackerel_map_io(void)
  {
        iotable_init(mackerel_io_desc, ARRAY_SIZE(mackerel_io_desc));
 +      /* DMA memory at 0xff200000 - 0xffdfffff. The default 2MB size isn't
 +       * enough to allocate the frame buffer memory.
 +       */
 +      init_consistent_dma_size(12 << 20);
  
        /* setup early devices and console here as well */
        sh7372_add_early_devices();
@@@ -1427,6 -1471,9 +1425,6 @@@ static void __init mackerel_init(void
        gpio_pull_down(GPIO_PORT167CR); /* VBUS0_1 pull down */
        gpio_request(GPIO_FN_IDIN_1_113, NULL);
  
 -      /* USB phy tweak to make the r8a66597_hcd host driver work */
 -      __raw_writew(0x8a0a, 0xe6058130);       /* USBCR4 */
 -
        /* enable FSI2 port A (ak4643) */
        gpio_request(GPIO_FN_FSIAIBT,   NULL);
        gpio_request(GPIO_FN_FSIAILR,   NULL);
index cde7c0085cedf4b239e79cddaee05d5dcc9e81b7,1e146fcdb8a0e6a619b39a29de1dad6fd811468f..59daae2f29db6514b47612e840ea2d0913d8ff4b
  #include <linux/input.h>
  #include <linux/input/sh_keysc.h>
  #include <linux/sh_eth.h>
 +#include <linux/videodev2.h>
  #include <video/sh_mobile_lcdc.h>
  #include <sound/sh_fsi.h>
  #include <media/sh_mobile_ceu.h>
 +#include <media/soc_camera.h>
  #include <media/tw9910.h>
  #include <media/mt9t112.h>
  #include <asm/heartbeat.h>
@@@ -769,7 -767,9 +769,9 @@@ static struct platform_device camera_de
  
  /* FSI */
  static struct sh_fsi_platform_info fsi_info = {
-       .portb_flags = SH_FSI_BRS_INV,
+       .port_b = {
+               .flags = SH_FSI_BRS_INV,
+       },
  };
  
  static struct resource fsi_resources[] = {
index 2b07fc0169500aab4405b18e9e2a6f024def3f3f,1fc5d47a5687024a1048fd93d8d7c552a56bb4a4..59f4db829e91be6b745acd0f7cccc525d8ef60b0
@@@ -24,7 -24,6 +24,7 @@@
  #include <linux/input/sh_keysc.h>
  #include <linux/usb/r8a66597.h>
  #include <linux/sh_eth.h>
 +#include <linux/videodev2.h>
  #include <video/sh_mobile_lcdc.h>
  #include <media/sh_mobile_ceu.h>
  #include <sound/sh_fsi.h>
@@@ -278,7 -277,9 +278,9 @@@ static struct platform_device ceu1_devi
  /* FSI */
  /* change J20, J21, J22 pin to 1-2 connection to use slave mode */
  static struct sh_fsi_platform_info fsi_info = {
-       .porta_flags = SH_FSI_BRS_INV,
+       .port_a = {
+               .flags = SH_FSI_BRS_INV,
+       },
  };
  
  static struct resource fsi_resources[] = {
index f584f6d8ffcccfe1237e8495289cec805b91b9bb,e6eafb18c8f54871265c142c61e14ea939cacc64..8c6523bbc797f8c3a22bbbeedc4a19194e26027e
@@@ -70,6 -70,8 +70,8 @@@ struct conexant_spec 
        const struct snd_kcontrol_new *mixers[5];
        int num_mixers;
        hda_nid_t vmaster_nid;
+       struct hda_vmaster_mute_hook vmaster_mute;
+       bool vmaster_mute_led;
  
        const struct hda_verb *init_verbs[5];   /* initialization verbs
                                                 * don't forget NULL
@@@ -465,21 -467,8 +467,8 @@@ static const struct snd_kcontrol_new cx
  };
  #endif
  
- static const char * const slave_vols[] = {
-       "Headphone Playback Volume",
-       "Speaker Playback Volume",
-       "Front Playback Volume",
-       "Surround Playback Volume",
-       "CLFE Playback Volume",
-       NULL
- };
- static const char * const slave_sws[] = {
-       "Headphone Playback Switch",
-       "Speaker Playback Switch",
-       "Front Playback Switch",
-       "Surround Playback Switch",
-       "CLFE Playback Switch",
+ static const char * const slave_pfxs[] = {
+       "Headphone", "Speaker", "Front", "Surround", "CLFE",
        NULL
  };
  
@@@ -519,14 -508,17 +508,17 @@@ static int conexant_build_controls(stru
                snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
                                        HDA_OUTPUT, vmaster_tlv);
                err = snd_hda_add_vmaster(codec, "Master Playback Volume",
-                                         vmaster_tlv, slave_vols);
+                                         vmaster_tlv, slave_pfxs,
+                                         "Playback Volume");
                if (err < 0)
                        return err;
        }
        if (spec->vmaster_nid &&
            !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
-               err = snd_hda_add_vmaster(codec, "Master Playback Switch",
-                                         NULL, slave_sws);
+               err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
+                                           NULL, slave_pfxs,
+                                           "Playback Switch", true,
+                                           &spec->vmaster_mute.sw_kctl);
                if (err < 0)
                        return err;
        }
@@@ -1643,7 -1635,7 +1635,7 @@@ static void cxt5051_update_speaker(stru
        pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
        snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
                            pinctl);
 -      /* on ideapad there is an aditional speaker (subwoofer) to mute */
 +      /* on ideapad there is an additional speaker (subwoofer) to mute */
        if (spec->ideapad)
                snd_hda_codec_write(codec, 0x1b, 0,
                                    AC_VERB_SET_PIN_WIDGET_CONTROL,
@@@ -3034,7 -3026,6 +3026,6 @@@ static const struct snd_pci_quirk cxt50
        SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),
        SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
        SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO),
-       SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */
        SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO),
        {}
  };
@@@ -3943,6 -3934,63 +3934,63 @@@ static void enable_unsol_pins(struct hd
                snd_hda_jack_detect_enable(codec, pins[i], action);
  }
  
+ static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
+ {
+       int i;
+       for (i = 0; i < nums; i++)
+               if (list[i] == nid)
+                       return true;
+       return false;
+ }
+ /* is the given NID found in any of autocfg items? */
+ static bool found_in_autocfg(struct auto_pin_cfg *cfg, hda_nid_t nid)
+ {
+       int i;
+       if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
+           found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
+           found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs) ||
+           found_in_nid_list(nid, cfg->dig_out_pins, cfg->dig_outs))
+               return true;
+       for (i = 0; i < cfg->num_inputs; i++)
+               if (cfg->inputs[i].pin == nid)
+                       return true;
+       if (cfg->dig_in_pin == nid)
+               return true;
+       return false;
+ }
+ /* clear unsol-event tags on unused pins; Conexant codecs seem to leave
+  * invalid unsol tags by some reason
+  */
+ static void clear_unsol_on_unused_pins(struct hda_codec *codec)
+ {
+       struct conexant_spec *spec = codec->spec;
+       struct auto_pin_cfg *cfg = &spec->autocfg;
+       int i;
+       for (i = 0; i < codec->init_pins.used; i++) {
+               struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
+               if (!found_in_autocfg(cfg, pin->nid))
+                       snd_hda_codec_write(codec, pin->nid, 0,
+                                           AC_VERB_SET_UNSOLICITED_ENABLE, 0);
+       }
+ }
+ /* turn on/off EAPD according to Master switch */
+ static void cx_auto_vmaster_hook(void *private_data, int enabled)
+ {
+       struct hda_codec *codec = private_data;
+       struct conexant_spec *spec = codec->spec;
+       if (enabled && spec->pin_eapd_ctrls) {
+               cx_auto_update_speakers(codec);
+               return;
+       }
+       cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled);
+ }
  static void cx_auto_init_output(struct hda_codec *codec)
  {
        struct conexant_spec *spec = codec->spec;
        /* turn on all EAPDs if no individual EAPD control is available */
        if (!spec->pin_eapd_ctrls)
                cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
+       clear_unsol_on_unused_pins(codec);
  }
  
  static void cx_auto_init_input(struct hda_codec *codec)
@@@ -4046,11 -4095,13 +4095,13 @@@ static void cx_auto_init_digital(struc
  
  static int cx_auto_init(struct hda_codec *codec)
  {
+       struct conexant_spec *spec = codec->spec;
        /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/
        cx_auto_init_output(codec);
        cx_auto_init_input(codec);
        cx_auto_init_digital(codec);
        snd_hda_jack_report_sync(codec);
+       snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
        return 0;
  }
  
@@@ -4296,6 -4347,13 +4347,13 @@@ static int cx_auto_build_controls(struc
        err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
        if (err < 0)
                return err;
+       if (spec->vmaster_mute.sw_kctl) {
+               spec->vmaster_mute.hook = cx_auto_vmaster_hook;
+               err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute,
+                                              spec->vmaster_mute_led);
+               if (err < 0)
+                       return err;
+       }
        return 0;
  }
  
@@@ -4320,7 -4378,6 +4378,6 @@@ static int cx_auto_search_adcs(struct h
        return 0;
  }
  
  static const struct hda_codec_ops cx_auto_patch_ops = {
        .build_controls = cx_auto_build_controls,
        .build_pcms = conexant_build_pcms,
@@@ -4368,6 -4425,7 +4425,7 @@@ static const struct cxt_pincfg cxt_pinc
        { 0x16, 0x042140ff }, /* HP (seq# overridden) */
        { 0x17, 0x21a11000 }, /* dock-mic */
        { 0x19, 0x2121103f }, /* dock-HP */
+       { 0x1c, 0x21440100 }, /* dock SPDIF out */
        {}
  };
  
@@@ -4421,6 -4479,18 +4479,18 @@@ static int patch_conexant_auto(struct h
  
        apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
  
+       /* Show mute-led control only on HP laptops
+        * This is a sort of white-list: on HP laptops, EAPD corresponds
+        * only to the mute-LED without actualy amp function.  Meanwhile,
+        * others may use EAPD really as an amp switch, so it might be
+        * not good to expose it blindly.
+        */
+       switch (codec->subsystem_id >> 16) {
+       case 0x103c:
+               spec->vmaster_mute_led = 1;
+               break;
+       }
        err = cx_auto_search_adcs(codec);
        if (err < 0)
                return err;
        codec->patch_ops = cx_auto_patch_ops;
        if (spec->beep_amp)
                snd_hda_attach_beep_device(codec, spec->beep_amp);
+       /* Some laptops with Conexant chips show stalls in S3 resume,
+        * which falls into the single-cmd mode.
+        * Better to make reset, then.
+        */
+       if (!codec->bus->sync_write) {
+               snd_printd("hda_codec: "
+                          "Enable sync_write for stable communication\n");
+               codec->bus->sync_write = 1;
+               codec->bus->allow_bus_reset = 1;
+       }
        return 0;
  }