Merge tag 'sound-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 1 Aug 2012 17:42:26 +0000 (10:42 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 1 Aug 2012 17:42:26 +0000 (10:42 -0700)
Pull sound fixes from Takashi Iwai:
 "A collection of small fixes that have been found recently.  Most of
  the commits are regression fixes in HD-audio and some other random
  drivers."

* tag 'sound-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: snd-usb: fix clock source validity index
  ALSA: hda - Fix mute-LED GPIO initialization for IDT codecs
  ALSA: hda - Add descriptions for missing IDT 92HD83x models
  ALSA: hda - Fix polarity of mute LED on HP Mini 210
  ALSA: es1688 - freeup resources on init failure
  ALSA: hda - Workaround for silent output on VAIO Z with ALC889
  ALSA: hda - Fix WARNING from HDMI/DP parser
  ALSA: hda - Detach from converter at closing in patch_hdmi.c
  ALSA: hda - Fix mute-LED GPIO setup for HP Mini 210
  ALSA: mpu401: Fix missing initialization of irq field
  ALSA: hda - Fix invalid D3 of headphone DAC on VT202x codecs

Documentation/sound/alsa/HD-Audio-Models.txt
include/sound/es1688.h
sound/drivers/mpu401/mpu401_uart.c
sound/isa/es1688/es1688_lib.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_via.c
sound/usb/clock.c

index 7456360..a92bba8 100644 (file)
@@ -53,6 +53,7 @@ ALC882/883/885/888/889
   acer-aspire-8930g    Acer Aspire 8330G/6935G
   acer-aspire          Acer Aspire others
   inv-dmic     Inverted internal mic workaround
+  no-primary-hp                VAIO Z workaround (for fixed speaker DAC)
 
 ALC861/660
 ==========
@@ -273,6 +274,10 @@ STAC92HD83*
   dell-s14     Dell laptop
   dell-vostro-3500     Dell Vostro 3500 laptop
   hp-dv7-4000  HP dv-7 4000
+  hp_cNB11_intquad HP CNB models with 4 speakers
+  hp-zephyr    HP Zephyr
+  hp-led       HP with broken BIOS for mute LED
+  hp-inv-led   HP with broken BIOS for inverted mute LED
   auto         BIOS setup (default)
 
 STAC9872
index 3ec7ecb..f752dd3 100644 (file)
@@ -29,6 +29,7 @@
 #define ES1688_HW_AUTO         0x0000
 #define ES1688_HW_688          0x0001
 #define ES1688_HW_1688         0x0002
+#define ES1688_HW_UNDEF        0x0003
 
 struct snd_es1688 {
        unsigned long port;             /* port of ESS chip */
index 1cff331..4608c2c 100644 (file)
@@ -554,6 +554,7 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
        spin_lock_init(&mpu->output_lock);
        spin_lock_init(&mpu->timer_lock);
        mpu->hardware = hardware;
+       mpu->irq = -1;
        if (! (info_flags & MPU401_INFO_INTEGRATED)) {
                int res_size = hardware == MPU401_HW_PC98II ? 4 : 2;
                mpu->res = request_region(port, res_size, "MPU401 UART");
index 1d47be8..b3b4f15 100644 (file)
@@ -612,10 +612,10 @@ static int snd_es1688_capture_close(struct snd_pcm_substream *substream)
 
 static int snd_es1688_free(struct snd_es1688 *chip)
 {
-       if (chip->res_port) {
+       if (chip->hardware != ES1688_HW_UNDEF)
                snd_es1688_init(chip, 0);
+       if (chip->res_port)
                release_and_free_resource(chip->res_port);
-       }
        if (chip->irq >= 0)
                free_irq(chip->irq, (void *) chip);
        if (chip->dma8 >= 0) {
@@ -657,19 +657,27 @@ int snd_es1688_create(struct snd_card *card,
                return -ENOMEM;
        chip->irq = -1;
        chip->dma8 = -1;
+       chip->hardware = ES1688_HW_UNDEF;
        
-       if ((chip->res_port = request_region(port + 4, 12, "ES1688")) == NULL) {
+       chip->res_port = request_region(port + 4, 12, "ES1688");
+       if (chip->res_port == NULL) {
                snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4);
-               return -EBUSY;
+               err = -EBUSY;
+               goto exit;
        }
-       if (request_irq(irq, snd_es1688_interrupt, 0, "ES1688", (void *) chip)) {
+
+       err = request_irq(irq, snd_es1688_interrupt, 0, "ES1688", (void *) chip);
+       if (err < 0) {
                snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq);
-               return -EBUSY;
+               goto exit;
        }
+
        chip->irq = irq;
-       if (request_dma(dma8, "ES1688")) {
+       err = request_dma(dma8, "ES1688");
+
+       if (err < 0) {
                snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8);
-               return -EBUSY;
+               goto exit;
        }
        chip->dma8 = dma8;
 
@@ -685,14 +693,18 @@ int snd_es1688_create(struct snd_card *card,
 
        err = snd_es1688_probe(chip);
        if (err < 0)
-               return err;
+               goto exit;
 
        err = snd_es1688_init(chip, 1);
        if (err < 0)
-               return err;
+               goto exit;
 
        /* Register device */
-       return snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+       err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+exit:
+       if (err)
+               snd_es1688_free(chip);
+       return err;
 }
 
 static struct snd_pcm_ops snd_es1688_playback_ops = {
index 641408d..69b9284 100644 (file)
@@ -877,6 +877,8 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
        struct hdmi_eld *eld;
        struct hdmi_spec_per_cvt *per_cvt = NULL;
 
+       hinfo->nid = 0; /* clear the leftover value */
+
        /* Validate hinfo */
        pin_idx = hinfo_to_pin_index(spec, hinfo);
        if (snd_BUG_ON(pin_idx < 0))
@@ -1161,9 +1163,9 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
        return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
 }
 
-static int generic_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
-                                            struct hda_codec *codec,
-                                            struct snd_pcm_substream *substream)
+static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
+                         struct hda_codec *codec,
+                         struct snd_pcm_substream *substream)
 {
        struct hdmi_spec *spec = codec->spec;
        int cvt_idx, pin_idx;
@@ -1171,8 +1173,6 @@ static int generic_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
        struct hdmi_spec_per_pin *per_pin;
        int pinctl;
 
-       snd_hda_codec_cleanup_stream(codec, hinfo->nid);
-
        if (hinfo->nid) {
                cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid);
                if (snd_BUG_ON(cvt_idx < 0))
@@ -1195,14 +1195,13 @@ static int generic_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
                                    pinctl & ~PIN_OUT);
                snd_hda_spdif_ctls_unassign(codec, pin_idx);
        }
-
        return 0;
 }
 
 static const struct hda_pcm_ops generic_ops = {
        .open = hdmi_pcm_open,
+       .close = hdmi_pcm_close,
        .prepare = generic_hdmi_playback_pcm_prepare,
-       .cleanup = generic_hdmi_playback_pcm_cleanup,
 };
 
 static int generic_hdmi_build_pcms(struct hda_codec *codec)
@@ -1221,6 +1220,7 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
                pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
                pstr->substreams = 1;
                pstr->ops = generic_ops;
+               pstr->nid = 1; /* FIXME: just for avoiding a debug WARNING */
                /* other pstr fields are set in open */
        }
 
index f141395..344b221 100644 (file)
@@ -203,6 +203,7 @@ struct alc_spec {
        unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */
        unsigned int inv_dmic_fixup:1; /* has inverted digital-mic workaround */
        unsigned int inv_dmic_muted:1; /* R-ch of inv d-mic is muted? */
+       unsigned int no_primary_hp:1; /* Don't prefer HP pins to speaker pins */
 
        /* auto-mute control */
        int automute_mode;
@@ -4323,7 +4324,8 @@ static int alc_parse_auto_config(struct hda_codec *codec,
                return 0; /* can't find valid BIOS pin config */
        }
 
-       if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
+       if (!spec->no_primary_hp &&
+           cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
            cfg->line_outs <= cfg->hp_outs) {
                /* use HP as primary out */
                cfg->speaker_outs = cfg->line_outs;
@@ -5050,6 +5052,7 @@ enum {
        ALC889_FIXUP_MBP_VREF,
        ALC889_FIXUP_IMAC91_VREF,
        ALC882_FIXUP_INV_DMIC,
+       ALC882_FIXUP_NO_PRIMARY_HP,
 };
 
 static void alc889_fixup_coef(struct hda_codec *codec,
@@ -5171,6 +5174,17 @@ static void alc889_fixup_imac91_vref(struct hda_codec *codec,
        spec->keep_vref_in_automute = 1;
 }
 
+/* Don't take HP output as primary
+ * strangely, the speaker output doesn't work on VAIO Z through DAC 0x05
+ */
+static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
+                                      const struct alc_fixup *fix, int action)
+{
+       struct alc_spec *spec = codec->spec;
+       if (action == ALC_FIXUP_ACT_PRE_PROBE)
+               spec->no_primary_hp = 1;
+}
+
 static const struct alc_fixup alc882_fixups[] = {
        [ALC882_FIXUP_ABIT_AW9D_MAX] = {
                .type = ALC_FIXUP_PINS,
@@ -5357,6 +5371,10 @@ static const struct alc_fixup alc882_fixups[] = {
                .type = ALC_FIXUP_FUNC,
                .v.func = alc_fixup_inv_dmic_0x12,
        },
+       [ALC882_FIXUP_NO_PRIMARY_HP] = {
+               .type = ALC_FIXUP_FUNC,
+               .v.func = alc882_fixup_no_primary_hp,
+       },
 };
 
 static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -5391,6 +5409,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
        SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
        SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
+       SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
 
        /* All Apple entries are in codec SSIDs */
        SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
@@ -5432,6 +5451,7 @@ static const struct alc_model_fixup alc882_fixup_models[] = {
        {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
        {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
        {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
+       {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
        {}
 };
 
index a1596a3..94040cc 100644 (file)
@@ -101,6 +101,8 @@ enum {
        STAC_92HD83XXX_HP_cNB11_INTQUAD,
        STAC_HP_DV7_4000,
        STAC_HP_ZEPHYR,
+       STAC_92HD83XXX_HP_LED,
+       STAC_92HD83XXX_HP_INV_LED,
        STAC_92HD83XXX_MODELS
 };
 
@@ -1675,6 +1677,8 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
        [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
        [STAC_HP_DV7_4000] = "hp-dv7-4000",
        [STAC_HP_ZEPHYR] = "hp-zephyr",
+       [STAC_92HD83XXX_HP_LED] = "hp-led",
+       [STAC_92HD83XXX_HP_INV_LED] = "hp-inv-led",
 };
 
 static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
@@ -1729,6 +1733,8 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
                          "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
        SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
                          "HP", STAC_HP_ZEPHYR),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3660,
+                         "HP Mini", STAC_92HD83XXX_HP_LED),
        {} /* terminator */
 };
 
@@ -4414,7 +4420,12 @@ static int stac92xx_init(struct hda_codec *codec)
        snd_hda_jack_report_sync(codec);
 
        /* sync mute LED */
-       snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
+       if (spec->gpio_led) {
+               if (spec->vmaster_mute.hook)
+                       snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
+               else /* the very first init call doesn't have vmaster yet */
+                       stac92xx_update_led_status(codec, false);
+       }
 
        /* sync the power-map */
        if (spec->num_pwrs)
@@ -5507,6 +5518,7 @@ static void stac92hd8x_fill_auto_spec(struct hda_codec *codec)
 static int patch_stac92hd83xxx(struct hda_codec *codec)
 {
        struct sigmatel_spec *spec;
+       int default_polarity = -1; /* no default cfg */
        int err;
 
        spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -5555,9 +5567,15 @@ again:
        case STAC_HP_ZEPHYR:
                spec->init = stac92hd83xxx_hp_zephyr_init;
                break;
+       case STAC_92HD83XXX_HP_LED:
+               default_polarity = 0;
+               break;
+       case STAC_92HD83XXX_HP_INV_LED:
+               default_polarity = 1;
+               break;
        }
 
-       if (find_mute_led_cfg(codec, -1/*no default cfg*/))
+       if (find_mute_led_cfg(codec, default_polarity))
                snd_printd("mute LED gpio %d polarity %d\n",
                                spec->gpio_led,
                                spec->gpio_led_polarity);
index 9064556..80d90cb 100644 (file)
@@ -3226,7 +3226,7 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
 {
        struct via_spec *spec = codec->spec;
        int imux_is_smixer;
-       unsigned int parm;
+       unsigned int parm, parm2;
        /* MUX6 (1eh) = stereo mixer */
        imux_is_smixer =
        snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
@@ -3249,7 +3249,7 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
        parm = AC_PWRST_D3;
        set_pin_power_state(codec, 0x27, &parm);
        update_power_state(codec, 0x1a, parm);
-       update_power_state(codec, 0xb, parm);
+       parm2 = parm; /* for pin 0x0b */
 
        /* PW2 (26h), AOW2 (ah) */
        parm = AC_PWRST_D3;
@@ -3264,6 +3264,9 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
        if (!spec->hp_independent_mode) /* check for redirected HP */
                set_pin_power_state(codec, 0x28, &parm);
        update_power_state(codec, 0x8, parm);
+       if (!spec->hp_independent_mode && parm2 != AC_PWRST_D3)
+               parm = parm2;
+       update_power_state(codec, 0xb, parm);
        /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
        update_power_state(codec, 0x21, imux_is_smixer ? AC_PWRST_D0 : parm);
 
index 379baad..5e634a2 100644 (file)
@@ -111,7 +111,8 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
                return 0;
 
        /* If a clock source can't tell us whether it's valid, we assume it is */
-       if (!uac2_control_is_readable(cs_desc->bmControls, UAC2_CS_CONTROL_CLOCK_VALID))
+       if (!uac2_control_is_readable(cs_desc->bmControls,
+                                     UAC2_CS_CONTROL_CLOCK_VALID - 1))
                return 1;
 
        err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,