Merge tag 'sound-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 20 Dec 2012 15:52:13 +0000 (07:52 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 20 Dec 2012 15:52:13 +0000 (07:52 -0800)
Pull sound fixes from Takashi Iwai:
 "This update contains overall only driver-specific fixes.  Slightly
  large LOC are seen in usb-audio driver for a couple of new device
  quirks and cs42l71 ASoC driver for enhanced features.  The others are
  a few small (regression) fixes HD-audio, and yet other small / trival
  ASoC fixes."

* tag 'sound-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: usb-audio: Support for Digidesign Mbox 2 USB sound card:
  ALSA: HDA: Fix sound resume hang
  ALSA: hda - bug fix for invalid connection list of Haswell HDMI codec pins
  ALSA: hda - Fix the wrong pincaps set in ALC861VD dallas/hp fixup
  ALSA: hda - Set codec->single_adc_amp flag for Realtek codecs
  ASoC: atmel-ssc: change disable to disable in dts node
  ASoC: Prevent pop_wait overwrite
  ALSA: usb-audio: ignore-quirk for HP Wireless Audio
  ALSA: hda - Always turn on pins for HDMI/DP
  ALSA: hda - Fix pin configuration of HP Pavilion dv7
  ASoC: core: Fix splitting of log messages
  ASoC: cs42l73: Change VSPIN/VSPOUT to VSPINOUT
  ASoC: cs42l73: Add DAPM events for power down.
  ASoC: cs42l73: Add DMIC's as DAPM inputs.
  ASoC: sigmadsp: Fix endianness conversion issue
  ASoC: tpa6130a2: Use devm_* APIs

19 files changed:
arch/arm/boot/dts/at91sam9263.dtsi
arch/arm/boot/dts/at91sam9g45.dtsi
arch/arm/boot/dts/at91sam9x5.dtsi
include/sound/soc-dai.h
include/sound/soc.h
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/soc/codecs/cs42l73.c
sound/soc/codecs/sigmadsp.c
sound/soc/codecs/tpa6130a2.c
sound/soc/soc-compress.c
sound/soc/soc-core.c
sound/soc/soc-pcm.c
sound/usb/midi.c
sound/usb/quirks-table.h
sound/usb/quirks.c
sound/usb/usbaudio.h

index 8e6251f1f7a3d9ee36008f4ad9ee73b49f2e3cd9..32ec62cf538585bf496187e0076afabd67c7be27 100644 (file)
                                compatible = "atmel,at91rm9200-ssc";
                                reg = <0xfff98000 0x4000>;
                                interrupts = <16 4 5>;
-                               status = "disable";
+                               status = "disabled";
                        };
 
                        ssc1: ssc@fff9c000 {
                                compatible = "atmel,at91rm9200-ssc";
                                reg = <0xfff9c000 0x4000>;
                                interrupts = <17 4 5>;
-                               status = "disable";
+                               status = "disabled";
                        };
 
                        macb0: ethernet@fffbc000 {
index fa1ae0c5479c0480022fac86fe576806154da73e..231858ffd850fec57eee5a91f06aee53f4c22f7f 100644 (file)
                                compatible = "atmel,at91sam9g45-ssc";
                                reg = <0xfff9c000 0x4000>;
                                interrupts = <16 4 5>;
-                               status = "disable";
+                               status = "disabled";
                        };
 
                        ssc1: ssc@fffa0000 {
                                compatible = "atmel,at91sam9g45-ssc";
                                reg = <0xfffa0000 0x4000>;
                                interrupts = <17 4 5>;
-                               status = "disable";
+                               status = "disabled";
                        };
 
                        adc0: adc@fffb0000 {
index 617ede541ca273b76d7ca6961c6cbd6273073c3d..40ac3a4eb1abc80a3560fbf6e33183bdd9dd5e72 100644 (file)
@@ -92,7 +92,7 @@
                                compatible = "atmel,at91sam9g45-ssc";
                                reg = <0xf0010000 0x4000>;
                                interrupts = <28 4 5>;
-                               status = "disable";
+                               status = "disabled";
                        };
 
                        tcb0: timer@f8008000 {
index 628db7bca4fd0a3f8186b3e80a91adb6b48fb0dd..3953cea0ecfbf4255525bc00e821d5b031564070 100644 (file)
@@ -242,7 +242,6 @@ struct snd_soc_dai {
        unsigned int symmetric_rates:1;
        struct snd_pcm_runtime *runtime;
        unsigned int active;
-       unsigned char pop_wait:1;
        unsigned char probed:1;
 
        struct snd_soc_dapm_widget *playback_widget;
index 91244a096c190223c17272aa23d219f47b40ab71..769e27c774a3de382ec93650766621056dc78820 100644 (file)
@@ -1039,6 +1039,7 @@ struct snd_soc_pcm_runtime {
        struct snd_soc_dpcm_runtime dpcm[2];
 
        long pmdown_time;
+       unsigned char pop_wait:1;
 
        /* runtime devices */
        struct snd_pcm *pcm;
index 0f3d3db0df71a3110d48643ab0dd214ca0897cd3..cca87277baf088b273279c6b1621aa52a981a47e 100644 (file)
@@ -2876,7 +2876,7 @@ static int azx_free(struct azx *chip)
        azx_notifier_unregister(chip);
 
        chip->init_failed = 1; /* to be sure */
-       complete(&chip->probe_wait);
+       complete_all(&chip->probe_wait);
 
        if (use_vga_switcheroo(chip)) {
                if (chip->disabled && chip->bus)
@@ -3504,7 +3504,7 @@ static int azx_probe(struct pci_dev *pci,
                pm_runtime_put_noidle(&pci->dev);
 
        dev++;
-       complete(&chip->probe_wait);
+       complete_all(&chip->probe_wait);
        return 0;
 
 out_free:
index 0fcfa6f406b8ac8738ba466954cfe7a6bc6faf87..b6c21ea187ca00df7233416f516111567b6b9ca7 100644 (file)
@@ -431,9 +431,11 @@ static void hdmi_init_pin(struct hda_codec *codec, hda_nid_t pin_nid)
        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);
-       /* Disable pin out until stream is active*/
+       /* Enable pin out: some machines with GM965 gets broken output when
+        * the pin is disabled or changed while using with HDMI
+        */
        snd_hda_codec_write(codec, pin_nid, 0,
-                           AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
+                           AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
 }
 
 static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t cvt_nid)
@@ -1341,7 +1343,6 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
        struct hdmi_spec *spec = codec->spec;
        int pin_idx = hinfo_to_pin_index(spec, hinfo);
        hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid;
-       int pinctl;
        bool non_pcm;
 
        non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
@@ -1350,11 +1351,6 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
 
        hdmi_setup_audio_infoframe(codec, pin_idx, non_pcm, substream);
 
-       pinctl = snd_hda_codec_read(codec, pin_nid, 0,
-                                   AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-       snd_hda_codec_write(codec, pin_nid, 0,
-                           AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl | PIN_OUT);
-
        return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
 }
 
@@ -1374,7 +1370,6 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
        int cvt_idx, pin_idx;
        struct hdmi_spec_per_cvt *per_cvt;
        struct hdmi_spec_per_pin *per_pin;
-       int pinctl;
 
        if (hinfo->nid) {
                cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid);
@@ -1391,11 +1386,6 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
                        return -EINVAL;
                per_pin = &spec->pins[pin_idx];
 
-               pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
-                                           AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-               snd_hda_codec_write(codec, per_pin->pin_nid, 0,
-                                   AC_VERB_SET_PIN_WIDGET_CONTROL,
-                                   pinctl & ~PIN_OUT);
                snd_hda_spdif_ctls_unassign(codec, pin_idx);
                per_pin->chmap_set = false;
                memset(per_pin->chmap, 0, sizeof(per_pin->chmap));
@@ -1691,6 +1681,30 @@ static const struct hda_codec_ops generic_hdmi_patch_ops = {
        .unsol_event            = hdmi_unsol_event,
 };
 
+static void intel_haswell_fixup_connect_list(struct hda_codec *codec)
+{
+       unsigned int vendor_param;
+       hda_nid_t list[3] = {0x2, 0x3, 0x4};
+
+       vendor_param = snd_hda_codec_read(codec, 0x08, 0, 0xf81, 0);
+       if (vendor_param == -1 || vendor_param & 0x02)
+               return;
+
+       /* enable DP1.2 mode */
+       vendor_param |= 0x02;
+       snd_hda_codec_read(codec, 0x08, 0, 0x781, vendor_param);
+
+       vendor_param = snd_hda_codec_read(codec, 0x08, 0, 0xf81, 0);
+       if (vendor_param == -1 || !(vendor_param & 0x02))
+               return;
+
+       /* override 3 pins connection list */
+       snd_hda_override_conn_list(codec, 0x05, 3, list);
+       snd_hda_override_conn_list(codec, 0x06, 3, list);
+       snd_hda_override_conn_list(codec, 0x07, 3, list);
+}
+
+
 static int patch_generic_hdmi(struct hda_codec *codec)
 {
        struct hdmi_spec *spec;
@@ -1700,6 +1714,10 @@ static int patch_generic_hdmi(struct hda_codec *codec)
                return -ENOMEM;
 
        codec->spec = spec;
+
+       if (codec->vendor_id == 0x80862807)
+               intel_haswell_fixup_connect_list(codec);
+
        if (hdmi_parse_codec(codec) < 0) {
                codec->spec = NULL;
                kfree(spec);
index 7743775f6abb34b3babf5a1bf44c3b1f5ef308cc..6ee34593774a4d155cd595ab96bbc7318f2dc6d9 100644 (file)
@@ -4373,6 +4373,7 @@ static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
        if (!spec)
                return -ENOMEM;
        codec->spec = spec;
+       codec->single_adc_amp = 1;
        spec->mixer_nid = mixer_nid;
        snd_hda_gen_init(&spec->gen);
        snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
@@ -6569,8 +6570,8 @@ static void alc861vd_fixup_dallas(struct hda_codec *codec,
                                  const struct alc_fixup *fix, int action)
 {
        if (action == ALC_FIXUP_ACT_PRE_PROBE) {
-               snd_hda_override_pin_caps(codec, 0x18, 0x00001714);
-               snd_hda_override_pin_caps(codec, 0x19, 0x0000171c);
+               snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
+               snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
        }
 }
 
index df13c0f84899773e7b40f3b25a23ffe60943fcb6..a86547ca17c861f51ce815eeb5e918e8f57fcc42 100644 (file)
@@ -1725,7 +1725,7 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
        SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658,
                          "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
        SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659,
-                         "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+                         "HP Pavilion dv7", STAC_HP_DV7_4000),
        SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A,
                          "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
        SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
index a0791ecf6d95e64514b5320717b586f83c32d7ac..6361dab48bd103c147454bef68025aff7298a381 100644 (file)
@@ -40,6 +40,7 @@ struct  cs42l73_private {
        u32 sysclk;
        u8 mclksel;
        u32 mclk;
+       int shutdwn_delay;
 };
 
 static const struct reg_default cs42l73_reg_defaults[] = {
@@ -588,7 +589,60 @@ static const struct snd_kcontrol_new cs42l73_snd_controls[] = {
        SOC_ENUM("XSPOUT Mono/Stereo Select", xsp_output_mux_enum),
 };
 
+static int cs42l73_spklo_spk_amp_event(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+       struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMD:
+               /* 150 ms delay between setting PDN and MCLKDIS */
+               priv->shutdwn_delay = 150;
+               break;
+       default:
+               pr_err("Invalid event = 0x%x\n", event);
+       }
+       return 0;
+}
+
+static int cs42l73_ear_amp_event(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+       struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMD:
+               /* 50 ms delay between setting PDN and MCLKDIS */
+               if (priv->shutdwn_delay < 50)
+                       priv->shutdwn_delay = 50;
+               break;
+       default:
+               pr_err("Invalid event = 0x%x\n", event);
+       }
+       return 0;
+}
+
+
+static int cs42l73_hp_amp_event(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+       struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMD:
+               /* 30 ms delay between setting PDN and MCLKDIS */
+               if (priv->shutdwn_delay < 30)
+                       priv->shutdwn_delay = 30;
+               break;
+       default:
+               pr_err("Invalid event = 0x%x\n", event);
+       }
+       return 0;
+}
+
 static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
+       SND_SOC_DAPM_INPUT("DMICA"),
+       SND_SOC_DAPM_INPUT("DMICB"),
        SND_SOC_DAPM_INPUT("LINEINA"),
        SND_SOC_DAPM_INPUT("LINEINB"),
        SND_SOC_DAPM_INPUT("MIC1"),
@@ -604,9 +658,7 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
                        CS42L73_PWRCTL2, 3, 1),
        SND_SOC_DAPM_AIF_OUT("ASPOUTR", NULL,  0,
                        CS42L73_PWRCTL2, 3, 1),
-       SND_SOC_DAPM_AIF_OUT("VSPOUTL", NULL,  0,
-                       CS42L73_PWRCTL2, 4, 1),
-       SND_SOC_DAPM_AIF_OUT("VSPOUTR", NULL,  0,
+       SND_SOC_DAPM_AIF_OUT("VSPINOUT", NULL,  0,
                        CS42L73_PWRCTL2, 4, 1),
 
        SND_SOC_DAPM_PGA("PGA Left", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -632,8 +684,7 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
        SND_SOC_DAPM_MIXER("ASPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
        SND_SOC_DAPM_MIXER("XSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
        SND_SOC_DAPM_MIXER("XSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-       SND_SOC_DAPM_MIXER("VSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-       SND_SOC_DAPM_MIXER("VSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_MIXER("VSP Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
 
        SND_SOC_DAPM_AIF_IN("XSPINL", NULL, 0,
                                CS42L73_PWRCTL2, 0, 1),
@@ -649,7 +700,7 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
        SND_SOC_DAPM_AIF_IN("ASPINM", NULL, 0,
                                CS42L73_PWRCTL2, 2, 1),
 
-       SND_SOC_DAPM_AIF_IN("VSPIN", NULL, 0,
+       SND_SOC_DAPM_AIF_IN("VSPINOUT", NULL, 0,
                                CS42L73_PWRCTL2, 4, 1),
 
        SND_SOC_DAPM_MIXER("HL Left Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -674,16 +725,20 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
        SND_SOC_DAPM_PGA("SPK DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
        SND_SOC_DAPM_PGA("ESL DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
 
-       SND_SOC_DAPM_SWITCH("HP Amp", CS42L73_PWRCTL3, 0, 1,
-                           &hp_amp_ctl),
+       SND_SOC_DAPM_SWITCH_E("HP Amp",  CS42L73_PWRCTL3, 0, 1,
+                           &hp_amp_ctl, cs42l73_hp_amp_event,
+                       SND_SOC_DAPM_POST_PMD),
        SND_SOC_DAPM_SWITCH("LO Amp", CS42L73_PWRCTL3, 1, 1,
                            &lo_amp_ctl),
-       SND_SOC_DAPM_SWITCH("SPK Amp", CS42L73_PWRCTL3, 2, 1,
-                           &spk_amp_ctl),
-       SND_SOC_DAPM_SWITCH("EAR Amp", CS42L73_PWRCTL3, 3, 1,
-                           &ear_amp_ctl),
-       SND_SOC_DAPM_SWITCH("SPKLO Amp", CS42L73_PWRCTL3, 4, 1,
-                           &spklo_amp_ctl),
+       SND_SOC_DAPM_SWITCH_E("SPK Amp", CS42L73_PWRCTL3, 2, 1,
+                       &spk_amp_ctl, cs42l73_spklo_spk_amp_event,
+                       SND_SOC_DAPM_POST_PMD),
+       SND_SOC_DAPM_SWITCH_E("EAR Amp", CS42L73_PWRCTL3, 3, 1,
+                           &ear_amp_ctl, cs42l73_ear_amp_event,
+                       SND_SOC_DAPM_POST_PMD),
+       SND_SOC_DAPM_SWITCH_E("SPKLO Amp", CS42L73_PWRCTL3, 4, 1,
+                           &spklo_amp_ctl, cs42l73_spklo_spk_amp_event,
+                       SND_SOC_DAPM_POST_PMD),
 
        SND_SOC_DAPM_OUTPUT("HPOUTA"),
        SND_SOC_DAPM_OUTPUT("HPOUTB"),
@@ -705,7 +760,7 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
 
        {"ESL DAC", "ESL-ASP Mono Volume", "ESL Mixer"},
        {"ESL DAC", "ESL-XSP Mono Volume", "ESL Mixer"},
-       {"ESL DAC", "ESL-VSP Mono Volume", "VSPIN"},
+       {"ESL DAC", "ESL-VSP Mono Volume", "VSPINOUT"},
        /* Loopback */
        {"ESL DAC", "ESL-IP Mono Volume", "Input Left Capture"},
        {"ESL DAC", "ESL-IP Mono Volume", "Input Right Capture"},
@@ -727,7 +782,7 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
 
        {"SPK DAC", "SPK-ASP Mono Volume", "SPK Mixer"},
        {"SPK DAC", "SPK-XSP Mono Volume", "SPK Mixer"},
-       {"SPK DAC", "SPK-VSP Mono Volume", "VSPIN"},
+       {"SPK DAC", "SPK-VSP Mono Volume", "VSPINOUT"},
        /* Loopback */
        {"SPK DAC", "SPK-IP Mono Volume", "Input Left Capture"},
        {"SPK DAC", "SPK-IP Mono Volume", "Input Right Capture"},
@@ -770,8 +825,8 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
        {"HL Right Mixer", NULL, "ASPINR"},
        {"HL Left Mixer", NULL, "XSPINL"},
        {"HL Right Mixer", NULL, "XSPINR"},
-       {"HL Left Mixer", NULL, "VSPIN"},
-       {"HL Right Mixer", NULL, "VSPIN"},
+       {"HL Left Mixer", NULL, "VSPINOUT"},
+       {"HL Right Mixer", NULL, "VSPINOUT"},
 
        {"ASPINL", NULL, "ASP Playback"},
        {"ASPINM", NULL, "ASP Playback"},
@@ -779,7 +834,7 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
        {"XSPINL", NULL, "XSP Playback"},
        {"XSPINM", NULL, "XSP Playback"},
        {"XSPINR", NULL, "XSP Playback"},
-       {"VSPIN", NULL, "VSP Playback"},
+       {"VSPINOUT", NULL, "VSP Playback"},
 
        /* Capture Paths */
        {"MIC1", NULL, "MIC1 Bias"},
@@ -795,6 +850,8 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
 
        {"ADC Left", NULL, "PGA Left"},
        {"ADC Right", NULL, "PGA Right"},
+       {"DMIC Left", NULL, "DMICA"},
+       {"DMIC Right", NULL, "DMICB"},
 
        {"Input Left Capture", "ADC Left Input", "ADC Left"},
        {"Input Right Capture", "ADC Right Input", "ADC Right"},
@@ -819,21 +876,18 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
        {"XSPOUTR", NULL, "XSPR Output Mixer"},
 
        /* Voice Capture */
-       {"VSPL Output Mixer", NULL, "Input Left Capture"},
-       {"VSPR Output Mixer", NULL, "Input Left Capture"},
+       {"VSP Output Mixer", NULL, "Input Left Capture"},
+       {"VSP Output Mixer", NULL, "Input Right Capture"},
 
-       {"VSPOUTL", "VSP-IP Volume", "VSPL Output Mixer"},
-       {"VSPOUTR", "VSP-IP Volume", "VSPR Output Mixer"},
+       {"VSPINOUT", "VSP-IP Volume", "VSP Output Mixer"},
 
-       {"VSPOUTL", NULL, "VSPL Output Mixer"},
-       {"VSPOUTR", NULL, "VSPR Output Mixer"},
+       {"VSPINOUT", NULL, "VSP Output Mixer"},
 
        {"ASP Capture", NULL, "ASPOUTL"},
        {"ASP Capture", NULL, "ASPOUTR"},
        {"XSP Capture", NULL, "XSPOUTL"},
        {"XSP Capture", NULL, "XSPOUTR"},
-       {"VSP Capture", NULL, "VSPOUTL"},
-       {"VSP Capture", NULL, "VSPOUTR"},
+       {"VSP Capture", NULL, "VSPINOUT"},
 };
 
 struct cs42l73_mclk_div {
@@ -1167,6 +1221,14 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec,
 
        case SND_SOC_BIAS_OFF:
                snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1);
+               if (cs42l73->shutdwn_delay > 0) {
+                       mdelay(cs42l73->shutdwn_delay);
+                       cs42l73->shutdwn_delay = 0;
+               } else {
+                       mdelay(15); /* Min amount of time requred to power
+                                    * down.
+                                    */
+               }
                snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 1);
                break;
        }
index 5be42bf5699653f9ce6adc437921ba929a1c0f59..4068f24912322b5e53f7ad90f5e4d562b5360cef 100644 (file)
@@ -225,7 +225,7 @@ EXPORT_SYMBOL(process_sigma_firmware);
 static int sigma_action_write_regmap(void *control_data,
        const struct sigma_action *sa, size_t len)
 {
-       return regmap_raw_write(control_data, le16_to_cpu(sa->addr),
+       return regmap_raw_write(control_data, be16_to_cpu(sa->addr),
                sa->payload, len - 2);
 }
 
index 8d75aa152c8cd29dab7133791db83955d5a6bd14..c58bee8346cef2223e4b0cb5b15cbc76991ccca5 100644 (file)
@@ -398,7 +398,8 @@ static int tpa6130a2_probe(struct i2c_client *client,
                                                TPA6130A2_MUTE_L;
 
        if (data->power_gpio >= 0) {
-               ret = gpio_request(data->power_gpio, "tpa6130a2 enable");
+               ret = devm_gpio_request(dev, data->power_gpio,
+                                       "tpa6130a2 enable");
                if (ret < 0) {
                        dev_err(dev, "Failed to request power GPIO (%d)\n",
                                data->power_gpio);
@@ -419,16 +420,16 @@ static int tpa6130a2_probe(struct i2c_client *client,
                break;
        }
 
-       data->supply = regulator_get(dev, regulator);
+       data->supply = devm_regulator_get(dev, regulator);
        if (IS_ERR(data->supply)) {
                ret = PTR_ERR(data->supply);
                dev_err(dev, "Failed to request supply: %d\n", ret);
-               goto err_regulator;
+               goto err_gpio;
        }
 
        ret = tpa6130a2_power(1);
        if (ret != 0)
-               goto err_power;
+               goto err_gpio;
 
 
        /* Read version */
@@ -440,15 +441,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
        /* Disable the chip */
        ret = tpa6130a2_power(0);
        if (ret != 0)
-               goto err_power;
+               goto err_gpio;
 
        return 0;
 
-err_power:
-       regulator_put(data->supply);
-err_regulator:
-       if (data->power_gpio >= 0)
-               gpio_free(data->power_gpio);
 err_gpio:
        tpa6130a2_client = NULL;
 
@@ -457,14 +453,7 @@ err_gpio:
 
 static int tpa6130a2_remove(struct i2c_client *client)
 {
-       struct tpa6130a2_data *data = i2c_get_clientdata(client);
-
        tpa6130a2_power(0);
-
-       if (data->power_gpio >= 0)
-               gpio_free(data->power_gpio);
-
-       regulator_put(data->supply);
        tpa6130a2_client = NULL;
 
        return 0;
index 967d0e173e1b8a0d8711b24addb05f68d9487ed1..5fbfb06e80831ed97cc42bb91df52568f779fd7f 100644 (file)
@@ -113,7 +113,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
                                        SNDRV_PCM_STREAM_PLAYBACK,
                                        SND_SOC_DAPM_STREAM_STOP);
                } else
-                       codec_dai->pop_wait = 1;
+                       rtd->pop_wait = 1;
                        schedule_delayed_work(&rtd->delayed_work,
                                msecs_to_jiffies(rtd->pmdown_time));
        } else {
index 9c768bcb98a6460640577688b2f7f9d71d5a8106..91d592ff67b7914cdbeec98c24eb3b4c1cb6a364 100644 (file)
@@ -4155,9 +4155,9 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
                ret = of_property_read_string_index(np, propname,
                        2 * i, &routes[i].sink);
                if (ret) {
-                       dev_err(card->dev, "ASoC: Property '%s' index %d"
-                               " could not be read: %d\n", propname, 2 * i,
-                               ret);
+                       dev_err(card->dev,
+                               "ASoC: Property '%s' index %d could not be read: %d\n",
+                               propname, 2 * i, ret);
                        kfree(routes);
                        return -EINVAL;
                }
@@ -4165,8 +4165,8 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
                        (2 * i) + 1, &routes[i].source);
                if (ret) {
                        dev_err(card->dev,
-                               "ASoC: Property '%s' index %d could not be"
-                               " read: %d\n", propname, (2 * i) + 1, ret);
+                               "ASoC: Property '%s' index %d could not be read: %d\n",
+                               propname, (2 * i) + 1, ret);
                        kfree(routes);
                        return -EINVAL;
                }
index 5c3ca2a3466170cd132464760dffd9b63155ebe9..d7711fce119b7b949bc521759b2f13e177dd657d 100644 (file)
@@ -334,11 +334,11 @@ static void close_delayed_work(struct work_struct *work)
        dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n",
                 codec_dai->driver->playback.stream_name,
                 codec_dai->playback_active ? "active" : "inactive",
-                codec_dai->pop_wait ? "yes" : "no");
+                rtd->pop_wait ? "yes" : "no");
 
        /* are we waiting on this codec DAI stream */
-       if (codec_dai->pop_wait == 1) {
-               codec_dai->pop_wait = 0;
+       if (rtd->pop_wait == 1) {
+               rtd->pop_wait = 0;
                snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
                                          SND_SOC_DAPM_STREAM_STOP);
        }
@@ -408,7 +408,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
                                                  SND_SOC_DAPM_STREAM_STOP);
                } else {
                        /* start delayed pop wq here for playback streams */
-                       codec_dai->pop_wait = 1;
+                       rtd->pop_wait = 1;
                        schedule_delayed_work(&rtd->delayed_work,
                                msecs_to_jiffies(rtd->pmdown_time));
                }
@@ -480,8 +480,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
 
        /* cancel any delayed stream shutdown that is pending */
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
-           codec_dai->pop_wait) {
-               codec_dai->pop_wait = 0;
+           rtd->pop_wait) {
+               rtd->pop_wait = 0;
                cancel_delayed_work(&rtd->delayed_work);
        }
 
index 34b9bb7fe87c8eabed83df8b7b77f510bedbc2b1..c183d34842accdc69ac8b1dec5424bb4373b1bbc 100644 (file)
@@ -2181,6 +2181,10 @@ int snd_usbmidi_create(struct snd_card *card,
                umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
                err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
                break;
+       case QUIRK_MIDI_MBOX2:
+               umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops;
+               err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+               break;
        case QUIRK_MIDI_RAW_BYTES:
                umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
                /*
index 49f9af995d7af3cf6fda51ef8d76102e8e40177a..cdcf6b45e8a887746a2f087e680b2c45a3198462 100644 (file)
        .bInterfaceClass = USB_CLASS_AUDIO,
 },
 
+/*
+ * HP Wireless Audio
+ * When not ignored, causes instability issues for some users, forcing them to
+ * blacklist the entire module.
+ */
+{
+       USB_DEVICE(0x0424, 0xb832),
+       .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+               .vendor_name = "Standard Microsystems Corp.",
+               .product_name = "HP Wireless Audio",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_COMPOSITE,
+               .data = (const struct snd_usb_audio_quirk[]) {
+                       /* Mixer */
+                       {
+                               .ifnum = 0,
+                               .type = QUIRK_IGNORE_INTERFACE,
+                       },
+                       /* Playback */
+                       {
+                               .ifnum = 1,
+                               .type = QUIRK_IGNORE_INTERFACE,
+                       },
+                       /* Capture */
+                       {
+                               .ifnum = 2,
+                               .type = QUIRK_IGNORE_INTERFACE,
+                       },
+                       /* HID Device, .ifnum = 3 */
+                       {
+                               .ifnum = -1,
+                       }
+               }
+       }
+},
+
 /*
  * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface
  * class matches do not take effect without an explicit ID match.
@@ -2885,6 +2921,93 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 
        }
 },
+
+/* DIGIDESIGN MBOX 2 */
+{
+       USB_DEVICE(0x0dba, 0x3000),
+       .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+               .vendor_name = "Digidesign",
+               .product_name = "Mbox 2",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_COMPOSITE,
+               .data = (const struct snd_usb_audio_quirk[]) {
+                       {
+                               .ifnum = 0,
+                               .type = QUIRK_IGNORE_INTERFACE
+                       },
+                       {
+                               .ifnum = 1,
+                               .type = QUIRK_IGNORE_INTERFACE
+                       },
+                       {
+                               .ifnum = 2,
+                               .type = QUIRK_AUDIO_FIXED_ENDPOINT,
+                               .data = &(const struct audioformat) {
+                                       .formats = SNDRV_PCM_FMTBIT_S24_3BE,
+                                       .channels = 2,
+                                       .iface = 2,
+                                       .altsetting = 2,
+                                       .altset_idx = 1,
+                                       .attributes = 0x00,
+                                       .endpoint = 0x03,
+                                       .ep_attr = USB_ENDPOINT_SYNC_ASYNC,
+                                       .maxpacksize = 0x128,
+                                       .rates = SNDRV_PCM_RATE_48000,
+                                       .rate_min = 48000,
+                                       .rate_max = 48000,
+                                       .nr_rates = 1,
+                                       .rate_table = (unsigned int[]) {
+                                               48000
+                                       }
+                               }
+                       },
+                       {
+                               .ifnum = 3,
+                               .type = QUIRK_IGNORE_INTERFACE
+                       },
+                       {
+                               .ifnum = 4,
+                               .type = QUIRK_AUDIO_FIXED_ENDPOINT,
+                               .data = &(const struct audioformat) {
+                               .formats = SNDRV_PCM_FMTBIT_S24_3BE,
+                                       .channels = 2,
+                                       .iface = 4,
+                                       .altsetting = 2,
+                                       .altset_idx = 1,
+                                       .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
+                                       .endpoint = 0x85,
+                                       .ep_attr = USB_ENDPOINT_SYNC_SYNC,
+                                       .maxpacksize = 0x128,
+                                       .rates = SNDRV_PCM_RATE_48000,
+                                       .rate_min = 48000,
+                                       .rate_max = 48000,
+                                       .nr_rates = 1,
+                                       .rate_table = (unsigned int[]) {
+                                               48000
+                                       }
+                               }
+                       },
+                       {
+                               .ifnum = 5,
+                               .type = QUIRK_IGNORE_INTERFACE
+                       },
+                       {
+                               .ifnum = 6,
+                               .type = QUIRK_MIDI_MBOX2,
+                               .data = &(const struct snd_usb_midi_endpoint_info) {
+                                       .out_ep =  0x02,
+                                       .out_cables = 0x0001,
+                                       .in_ep = 0x81,
+                                       .in_interval = 0x01,
+                                       .in_cables = 0x0001
+                               }
+                       },
+                       {
+                               .ifnum = -1
+                       }
+               }
+       }
+},
 {
        /* Tascam US122 MKII - playback-only support */
        .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
index 007fcecdf5cd1fa9536a24d6cac9059071393c69..f104c68fe1e0546bfbc43bdb51dc635a8ad642af 100644 (file)
@@ -306,6 +306,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
                [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
                [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
                [QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
+               [QUIRK_MIDI_MBOX2] = create_any_midi_quirk,
                [QUIRK_MIDI_RAW_BYTES] = create_any_midi_quirk,
                [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
                [QUIRK_MIDI_CME] = create_any_midi_quirk,
@@ -497,6 +498,92 @@ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev)
        return -EAGAIN;
 }
 
+static void mbox2_setup_48_24_magic(struct usb_device *dev)
+{
+       u8 srate[3];
+       u8 temp[12];
+
+       /* Choose 48000Hz permanently */
+       srate[0] = 0x80;
+       srate[1] = 0xbb;
+       srate[2] = 0x00;
+
+       /* Send the magic! */
+       snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
+               0x01, 0x22, 0x0100, 0x0085, &temp, 0x0003);
+       snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
+               0x81, 0xa2, 0x0100, 0x0085, &srate, 0x0003);
+       snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
+               0x81, 0xa2, 0x0100, 0x0086, &srate, 0x0003);
+       snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
+               0x81, 0xa2, 0x0100, 0x0003, &srate, 0x0003);
+       return;
+}
+
+/* Digidesign Mbox 2 needs to load firmware onboard
+ * and driver must wait a few seconds for initialisation.
+ */
+
+#define MBOX2_FIRMWARE_SIZE    646
+#define MBOX2_BOOT_LOADING     0x01 /* Hard coded into the device */
+#define MBOX2_BOOT_READY       0x02 /* Hard coded into the device */
+
+int snd_usb_mbox2_boot_quirk(struct usb_device *dev)
+{
+       struct usb_host_config *config = dev->actconfig;
+       int err;
+       u8 bootresponse;
+       int fwsize;
+       int count;
+
+       fwsize = le16_to_cpu(get_cfg_desc(config)->wTotalLength);
+
+       if (fwsize != MBOX2_FIRMWARE_SIZE) {
+               snd_printk(KERN_ERR "usb-audio: Invalid firmware size=%d.\n", fwsize);
+               return -ENODEV;
+       }
+
+       snd_printd("usb-audio: Sending Digidesign Mbox 2 boot sequence...\n");
+
+       count = 0;
+       bootresponse = MBOX2_BOOT_LOADING;
+       while ((bootresponse == MBOX2_BOOT_LOADING) && (count < 10)) {
+               msleep(500); /* 0.5 second delay */
+               snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
+                       /* Control magic - load onboard firmware */
+                       0x85, 0xc0, 0x0001, 0x0000, &bootresponse, 0x0012);
+               if (bootresponse == MBOX2_BOOT_READY)
+                       break;
+               snd_printd("usb-audio: device not ready, resending boot sequence...\n");
+               count++;
+       }
+
+       if (bootresponse != MBOX2_BOOT_READY) {
+               snd_printk(KERN_ERR "usb-audio: Unknown bootresponse=%d, or timed out, ignoring device.\n", bootresponse);
+               return -ENODEV;
+       }
+
+       snd_printdd("usb-audio: device initialised!\n");
+
+       err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
+               &dev->descriptor, sizeof(dev->descriptor));
+       config = dev->actconfig;
+       if (err < 0)
+               snd_printd("error usb_get_descriptor: %d\n", err);
+
+       err = usb_reset_configuration(dev);
+       if (err < 0)
+               snd_printd("error usb_reset_configuration: %d\n", err);
+       snd_printdd("mbox2_boot: new boot length = %d\n",
+               le16_to_cpu(get_cfg_desc(config)->wTotalLength));
+
+       mbox2_setup_48_24_magic(dev);
+
+       snd_printk(KERN_INFO "usb-audio: Digidesign Mbox 2: 24bit 48kHz");
+
+       return 0; /* Successful boot */
+}
+
 /*
  * Setup quirks
  */
@@ -655,6 +742,10 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
        case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */
                return snd_usb_cm6206_boot_quirk(dev);
 
+       case USB_ID(0x0dba, 0x3000):
+               /* Digidesign Mbox 2 */
+               return snd_usb_mbox2_boot_quirk(dev);
+
        case USB_ID(0x133e, 0x0815):
                /* Access Music VirusTI Desktop */
                return snd_usb_accessmusic_boot_quirk(dev);
index 1ac3fd9cc5a625e89cc1290ab3274ebac6982793..a8172c119796015fa2edd0a675d4568c27f83ba7 100644 (file)
@@ -76,6 +76,7 @@ enum quirk_type {
        QUIRK_MIDI_YAMAHA,
        QUIRK_MIDI_MIDIMAN,
        QUIRK_MIDI_NOVATION,
+       QUIRK_MIDI_MBOX2,
        QUIRK_MIDI_RAW_BYTES,
        QUIRK_MIDI_EMAGIC,
        QUIRK_MIDI_CME,