diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-20 10:52:13 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-20 10:52:13 -0500 |
commit | 03c850ec327c42a97e44c448b75983e12da417d9 (patch) | |
tree | d5fe304ba4b0639b331ffe689b5aff7c524cb4da /sound | |
parent | 85d5b70d8a0681a362d075bf0d19b4ee8c6767ee (diff) | |
parent | cb99864d40e46dea9c2aa3eaa97517b776f91024 (diff) |
Merge tag 'sound-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
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
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 46 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 5 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/cs42l73.c | 116 | ||||
-rw-r--r-- | sound/soc/codecs/sigmadsp.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/tpa6130a2.c | 23 | ||||
-rw-r--r-- | sound/soc/soc-compress.c | 2 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 10 | ||||
-rw-r--r-- | sound/soc/soc-pcm.c | 12 | ||||
-rw-r--r-- | sound/usb/midi.c | 4 | ||||
-rw-r--r-- | sound/usb/quirks-table.h | 123 | ||||
-rw-r--r-- | sound/usb/quirks.c | 91 | ||||
-rw-r--r-- | sound/usb/usbaudio.h | 1 |
14 files changed, 365 insertions, 76 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 0f3d3db0df71..cca87277baf0 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -2876,7 +2876,7 @@ static int azx_free(struct azx *chip) | |||
2876 | azx_notifier_unregister(chip); | 2876 | azx_notifier_unregister(chip); |
2877 | 2877 | ||
2878 | chip->init_failed = 1; /* to be sure */ | 2878 | chip->init_failed = 1; /* to be sure */ |
2879 | complete(&chip->probe_wait); | 2879 | complete_all(&chip->probe_wait); |
2880 | 2880 | ||
2881 | if (use_vga_switcheroo(chip)) { | 2881 | if (use_vga_switcheroo(chip)) { |
2882 | if (chip->disabled && chip->bus) | 2882 | if (chip->disabled && chip->bus) |
@@ -3504,7 +3504,7 @@ static int azx_probe(struct pci_dev *pci, | |||
3504 | pm_runtime_put_noidle(&pci->dev); | 3504 | pm_runtime_put_noidle(&pci->dev); |
3505 | 3505 | ||
3506 | dev++; | 3506 | dev++; |
3507 | complete(&chip->probe_wait); | 3507 | complete_all(&chip->probe_wait); |
3508 | return 0; | 3508 | return 0; |
3509 | 3509 | ||
3510 | out_free: | 3510 | out_free: |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 0fcfa6f406b8..b6c21ea187ca 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -431,9 +431,11 @@ static void hdmi_init_pin(struct hda_codec *codec, hda_nid_t pin_nid) | |||
431 | if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP) | 431 | if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP) |
432 | snd_hda_codec_write(codec, pin_nid, 0, | 432 | snd_hda_codec_write(codec, pin_nid, 0, |
433 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | 433 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); |
434 | /* Disable pin out until stream is active*/ | 434 | /* Enable pin out: some machines with GM965 gets broken output when |
435 | * the pin is disabled or changed while using with HDMI | ||
436 | */ | ||
435 | snd_hda_codec_write(codec, pin_nid, 0, | 437 | snd_hda_codec_write(codec, pin_nid, 0, |
436 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | 438 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); |
437 | } | 439 | } |
438 | 440 | ||
439 | static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t cvt_nid) | 441 | 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, | |||
1341 | struct hdmi_spec *spec = codec->spec; | 1343 | struct hdmi_spec *spec = codec->spec; |
1342 | int pin_idx = hinfo_to_pin_index(spec, hinfo); | 1344 | int pin_idx = hinfo_to_pin_index(spec, hinfo); |
1343 | hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid; | 1345 | hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid; |
1344 | int pinctl; | ||
1345 | bool non_pcm; | 1346 | bool non_pcm; |
1346 | 1347 | ||
1347 | non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); | 1348 | 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, | |||
1350 | 1351 | ||
1351 | hdmi_setup_audio_infoframe(codec, pin_idx, non_pcm, substream); | 1352 | hdmi_setup_audio_infoframe(codec, pin_idx, non_pcm, substream); |
1352 | 1353 | ||
1353 | pinctl = snd_hda_codec_read(codec, pin_nid, 0, | ||
1354 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
1355 | snd_hda_codec_write(codec, pin_nid, 0, | ||
1356 | AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl | PIN_OUT); | ||
1357 | |||
1358 | return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); | 1354 | return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); |
1359 | } | 1355 | } |
1360 | 1356 | ||
@@ -1374,7 +1370,6 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, | |||
1374 | int cvt_idx, pin_idx; | 1370 | int cvt_idx, pin_idx; |
1375 | struct hdmi_spec_per_cvt *per_cvt; | 1371 | struct hdmi_spec_per_cvt *per_cvt; |
1376 | struct hdmi_spec_per_pin *per_pin; | 1372 | struct hdmi_spec_per_pin *per_pin; |
1377 | int pinctl; | ||
1378 | 1373 | ||
1379 | if (hinfo->nid) { | 1374 | if (hinfo->nid) { |
1380 | cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid); | 1375 | cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid); |
@@ -1391,11 +1386,6 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, | |||
1391 | return -EINVAL; | 1386 | return -EINVAL; |
1392 | per_pin = &spec->pins[pin_idx]; | 1387 | per_pin = &spec->pins[pin_idx]; |
1393 | 1388 | ||
1394 | pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0, | ||
1395 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
1396 | snd_hda_codec_write(codec, per_pin->pin_nid, 0, | ||
1397 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1398 | pinctl & ~PIN_OUT); | ||
1399 | snd_hda_spdif_ctls_unassign(codec, pin_idx); | 1389 | snd_hda_spdif_ctls_unassign(codec, pin_idx); |
1400 | per_pin->chmap_set = false; | 1390 | per_pin->chmap_set = false; |
1401 | memset(per_pin->chmap, 0, sizeof(per_pin->chmap)); | 1391 | memset(per_pin->chmap, 0, sizeof(per_pin->chmap)); |
@@ -1691,6 +1681,30 @@ static const struct hda_codec_ops generic_hdmi_patch_ops = { | |||
1691 | .unsol_event = hdmi_unsol_event, | 1681 | .unsol_event = hdmi_unsol_event, |
1692 | }; | 1682 | }; |
1693 | 1683 | ||
1684 | static void intel_haswell_fixup_connect_list(struct hda_codec *codec) | ||
1685 | { | ||
1686 | unsigned int vendor_param; | ||
1687 | hda_nid_t list[3] = {0x2, 0x3, 0x4}; | ||
1688 | |||
1689 | vendor_param = snd_hda_codec_read(codec, 0x08, 0, 0xf81, 0); | ||
1690 | if (vendor_param == -1 || vendor_param & 0x02) | ||
1691 | return; | ||
1692 | |||
1693 | /* enable DP1.2 mode */ | ||
1694 | vendor_param |= 0x02; | ||
1695 | snd_hda_codec_read(codec, 0x08, 0, 0x781, vendor_param); | ||
1696 | |||
1697 | vendor_param = snd_hda_codec_read(codec, 0x08, 0, 0xf81, 0); | ||
1698 | if (vendor_param == -1 || !(vendor_param & 0x02)) | ||
1699 | return; | ||
1700 | |||
1701 | /* override 3 pins connection list */ | ||
1702 | snd_hda_override_conn_list(codec, 0x05, 3, list); | ||
1703 | snd_hda_override_conn_list(codec, 0x06, 3, list); | ||
1704 | snd_hda_override_conn_list(codec, 0x07, 3, list); | ||
1705 | } | ||
1706 | |||
1707 | |||
1694 | static int patch_generic_hdmi(struct hda_codec *codec) | 1708 | static int patch_generic_hdmi(struct hda_codec *codec) |
1695 | { | 1709 | { |
1696 | struct hdmi_spec *spec; | 1710 | struct hdmi_spec *spec; |
@@ -1700,6 +1714,10 @@ static int patch_generic_hdmi(struct hda_codec *codec) | |||
1700 | return -ENOMEM; | 1714 | return -ENOMEM; |
1701 | 1715 | ||
1702 | codec->spec = spec; | 1716 | codec->spec = spec; |
1717 | |||
1718 | if (codec->vendor_id == 0x80862807) | ||
1719 | intel_haswell_fixup_connect_list(codec); | ||
1720 | |||
1703 | if (hdmi_parse_codec(codec) < 0) { | 1721 | if (hdmi_parse_codec(codec) < 0) { |
1704 | codec->spec = NULL; | 1722 | codec->spec = NULL; |
1705 | kfree(spec); | 1723 | kfree(spec); |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 7743775f6abb..6ee34593774a 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -4373,6 +4373,7 @@ static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid) | |||
4373 | if (!spec) | 4373 | if (!spec) |
4374 | return -ENOMEM; | 4374 | return -ENOMEM; |
4375 | codec->spec = spec; | 4375 | codec->spec = spec; |
4376 | codec->single_adc_amp = 1; | ||
4376 | spec->mixer_nid = mixer_nid; | 4377 | spec->mixer_nid = mixer_nid; |
4377 | snd_hda_gen_init(&spec->gen); | 4378 | snd_hda_gen_init(&spec->gen); |
4378 | snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); | 4379 | snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); |
@@ -6569,8 +6570,8 @@ static void alc861vd_fixup_dallas(struct hda_codec *codec, | |||
6569 | const struct alc_fixup *fix, int action) | 6570 | const struct alc_fixup *fix, int action) |
6570 | { | 6571 | { |
6571 | if (action == ALC_FIXUP_ACT_PRE_PROBE) { | 6572 | if (action == ALC_FIXUP_ACT_PRE_PROBE) { |
6572 | snd_hda_override_pin_caps(codec, 0x18, 0x00001714); | 6573 | snd_hda_override_pin_caps(codec, 0x18, 0x00000734); |
6573 | snd_hda_override_pin_caps(codec, 0x19, 0x0000171c); | 6574 | snd_hda_override_pin_caps(codec, 0x19, 0x0000073c); |
6574 | } | 6575 | } |
6575 | } | 6576 | } |
6576 | 6577 | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index df13c0f84899..a86547ca17c8 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -1725,7 +1725,7 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | |||
1725 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658, | 1725 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658, |
1726 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), | 1726 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), |
1727 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659, | 1727 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659, |
1728 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), | 1728 | "HP Pavilion dv7", STAC_HP_DV7_4000), |
1729 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A, | 1729 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A, |
1730 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), | 1730 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), |
1731 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B, | 1731 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B, |
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index a0791ecf6d95..6361dab48bd1 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c | |||
@@ -40,6 +40,7 @@ struct cs42l73_private { | |||
40 | u32 sysclk; | 40 | u32 sysclk; |
41 | u8 mclksel; | 41 | u8 mclksel; |
42 | u32 mclk; | 42 | u32 mclk; |
43 | int shutdwn_delay; | ||
43 | }; | 44 | }; |
44 | 45 | ||
45 | static const struct reg_default cs42l73_reg_defaults[] = { | 46 | static const struct reg_default cs42l73_reg_defaults[] = { |
@@ -588,7 +589,60 @@ static const struct snd_kcontrol_new cs42l73_snd_controls[] = { | |||
588 | SOC_ENUM("XSPOUT Mono/Stereo Select", xsp_output_mux_enum), | 589 | SOC_ENUM("XSPOUT Mono/Stereo Select", xsp_output_mux_enum), |
589 | }; | 590 | }; |
590 | 591 | ||
592 | static int cs42l73_spklo_spk_amp_event(struct snd_soc_dapm_widget *w, | ||
593 | struct snd_kcontrol *kcontrol, int event) | ||
594 | { | ||
595 | struct snd_soc_codec *codec = w->codec; | ||
596 | struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec); | ||
597 | switch (event) { | ||
598 | case SND_SOC_DAPM_POST_PMD: | ||
599 | /* 150 ms delay between setting PDN and MCLKDIS */ | ||
600 | priv->shutdwn_delay = 150; | ||
601 | break; | ||
602 | default: | ||
603 | pr_err("Invalid event = 0x%x\n", event); | ||
604 | } | ||
605 | return 0; | ||
606 | } | ||
607 | |||
608 | static int cs42l73_ear_amp_event(struct snd_soc_dapm_widget *w, | ||
609 | struct snd_kcontrol *kcontrol, int event) | ||
610 | { | ||
611 | struct snd_soc_codec *codec = w->codec; | ||
612 | struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec); | ||
613 | switch (event) { | ||
614 | case SND_SOC_DAPM_POST_PMD: | ||
615 | /* 50 ms delay between setting PDN and MCLKDIS */ | ||
616 | if (priv->shutdwn_delay < 50) | ||
617 | priv->shutdwn_delay = 50; | ||
618 | break; | ||
619 | default: | ||
620 | pr_err("Invalid event = 0x%x\n", event); | ||
621 | } | ||
622 | return 0; | ||
623 | } | ||
624 | |||
625 | |||
626 | static int cs42l73_hp_amp_event(struct snd_soc_dapm_widget *w, | ||
627 | struct snd_kcontrol *kcontrol, int event) | ||
628 | { | ||
629 | struct snd_soc_codec *codec = w->codec; | ||
630 | struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec); | ||
631 | switch (event) { | ||
632 | case SND_SOC_DAPM_POST_PMD: | ||
633 | /* 30 ms delay between setting PDN and MCLKDIS */ | ||
634 | if (priv->shutdwn_delay < 30) | ||
635 | priv->shutdwn_delay = 30; | ||
636 | break; | ||
637 | default: | ||
638 | pr_err("Invalid event = 0x%x\n", event); | ||
639 | } | ||
640 | return 0; | ||
641 | } | ||
642 | |||
591 | static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = { | 643 | static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = { |
644 | SND_SOC_DAPM_INPUT("DMICA"), | ||
645 | SND_SOC_DAPM_INPUT("DMICB"), | ||
592 | SND_SOC_DAPM_INPUT("LINEINA"), | 646 | SND_SOC_DAPM_INPUT("LINEINA"), |
593 | SND_SOC_DAPM_INPUT("LINEINB"), | 647 | SND_SOC_DAPM_INPUT("LINEINB"), |
594 | SND_SOC_DAPM_INPUT("MIC1"), | 648 | SND_SOC_DAPM_INPUT("MIC1"), |
@@ -604,9 +658,7 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = { | |||
604 | CS42L73_PWRCTL2, 3, 1), | 658 | CS42L73_PWRCTL2, 3, 1), |
605 | SND_SOC_DAPM_AIF_OUT("ASPOUTR", NULL, 0, | 659 | SND_SOC_DAPM_AIF_OUT("ASPOUTR", NULL, 0, |
606 | CS42L73_PWRCTL2, 3, 1), | 660 | CS42L73_PWRCTL2, 3, 1), |
607 | SND_SOC_DAPM_AIF_OUT("VSPOUTL", NULL, 0, | 661 | SND_SOC_DAPM_AIF_OUT("VSPINOUT", NULL, 0, |
608 | CS42L73_PWRCTL2, 4, 1), | ||
609 | SND_SOC_DAPM_AIF_OUT("VSPOUTR", NULL, 0, | ||
610 | CS42L73_PWRCTL2, 4, 1), | 662 | CS42L73_PWRCTL2, 4, 1), |
611 | 663 | ||
612 | SND_SOC_DAPM_PGA("PGA Left", SND_SOC_NOPM, 0, 0, NULL, 0), | 664 | 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[] = { | |||
632 | SND_SOC_DAPM_MIXER("ASPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | 684 | SND_SOC_DAPM_MIXER("ASPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), |
633 | SND_SOC_DAPM_MIXER("XSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | 685 | SND_SOC_DAPM_MIXER("XSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), |
634 | SND_SOC_DAPM_MIXER("XSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | 686 | SND_SOC_DAPM_MIXER("XSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), |
635 | SND_SOC_DAPM_MIXER("VSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | 687 | SND_SOC_DAPM_MIXER("VSP Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), |
636 | SND_SOC_DAPM_MIXER("VSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
637 | 688 | ||
638 | SND_SOC_DAPM_AIF_IN("XSPINL", NULL, 0, | 689 | SND_SOC_DAPM_AIF_IN("XSPINL", NULL, 0, |
639 | CS42L73_PWRCTL2, 0, 1), | 690 | CS42L73_PWRCTL2, 0, 1), |
@@ -649,7 +700,7 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = { | |||
649 | SND_SOC_DAPM_AIF_IN("ASPINM", NULL, 0, | 700 | SND_SOC_DAPM_AIF_IN("ASPINM", NULL, 0, |
650 | CS42L73_PWRCTL2, 2, 1), | 701 | CS42L73_PWRCTL2, 2, 1), |
651 | 702 | ||
652 | SND_SOC_DAPM_AIF_IN("VSPIN", NULL, 0, | 703 | SND_SOC_DAPM_AIF_IN("VSPINOUT", NULL, 0, |
653 | CS42L73_PWRCTL2, 4, 1), | 704 | CS42L73_PWRCTL2, 4, 1), |
654 | 705 | ||
655 | SND_SOC_DAPM_MIXER("HL Left Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | 706 | 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[] = { | |||
674 | SND_SOC_DAPM_PGA("SPK DAC", SND_SOC_NOPM, 0, 0, NULL, 0), | 725 | SND_SOC_DAPM_PGA("SPK DAC", SND_SOC_NOPM, 0, 0, NULL, 0), |
675 | SND_SOC_DAPM_PGA("ESL DAC", SND_SOC_NOPM, 0, 0, NULL, 0), | 726 | SND_SOC_DAPM_PGA("ESL DAC", SND_SOC_NOPM, 0, 0, NULL, 0), |
676 | 727 | ||
677 | SND_SOC_DAPM_SWITCH("HP Amp", CS42L73_PWRCTL3, 0, 1, | 728 | SND_SOC_DAPM_SWITCH_E("HP Amp", CS42L73_PWRCTL3, 0, 1, |
678 | &hp_amp_ctl), | 729 | &hp_amp_ctl, cs42l73_hp_amp_event, |
730 | SND_SOC_DAPM_POST_PMD), | ||
679 | SND_SOC_DAPM_SWITCH("LO Amp", CS42L73_PWRCTL3, 1, 1, | 731 | SND_SOC_DAPM_SWITCH("LO Amp", CS42L73_PWRCTL3, 1, 1, |
680 | &lo_amp_ctl), | 732 | &lo_amp_ctl), |
681 | SND_SOC_DAPM_SWITCH("SPK Amp", CS42L73_PWRCTL3, 2, 1, | 733 | SND_SOC_DAPM_SWITCH_E("SPK Amp", CS42L73_PWRCTL3, 2, 1, |
682 | &spk_amp_ctl), | 734 | &spk_amp_ctl, cs42l73_spklo_spk_amp_event, |
683 | SND_SOC_DAPM_SWITCH("EAR Amp", CS42L73_PWRCTL3, 3, 1, | 735 | SND_SOC_DAPM_POST_PMD), |
684 | &ear_amp_ctl), | 736 | SND_SOC_DAPM_SWITCH_E("EAR Amp", CS42L73_PWRCTL3, 3, 1, |
685 | SND_SOC_DAPM_SWITCH("SPKLO Amp", CS42L73_PWRCTL3, 4, 1, | 737 | &ear_amp_ctl, cs42l73_ear_amp_event, |
686 | &spklo_amp_ctl), | 738 | SND_SOC_DAPM_POST_PMD), |
739 | SND_SOC_DAPM_SWITCH_E("SPKLO Amp", CS42L73_PWRCTL3, 4, 1, | ||
740 | &spklo_amp_ctl, cs42l73_spklo_spk_amp_event, | ||
741 | SND_SOC_DAPM_POST_PMD), | ||
687 | 742 | ||
688 | SND_SOC_DAPM_OUTPUT("HPOUTA"), | 743 | SND_SOC_DAPM_OUTPUT("HPOUTA"), |
689 | SND_SOC_DAPM_OUTPUT("HPOUTB"), | 744 | SND_SOC_DAPM_OUTPUT("HPOUTB"), |
@@ -705,7 +760,7 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = { | |||
705 | 760 | ||
706 | {"ESL DAC", "ESL-ASP Mono Volume", "ESL Mixer"}, | 761 | {"ESL DAC", "ESL-ASP Mono Volume", "ESL Mixer"}, |
707 | {"ESL DAC", "ESL-XSP Mono Volume", "ESL Mixer"}, | 762 | {"ESL DAC", "ESL-XSP Mono Volume", "ESL Mixer"}, |
708 | {"ESL DAC", "ESL-VSP Mono Volume", "VSPIN"}, | 763 | {"ESL DAC", "ESL-VSP Mono Volume", "VSPINOUT"}, |
709 | /* Loopback */ | 764 | /* Loopback */ |
710 | {"ESL DAC", "ESL-IP Mono Volume", "Input Left Capture"}, | 765 | {"ESL DAC", "ESL-IP Mono Volume", "Input Left Capture"}, |
711 | {"ESL DAC", "ESL-IP Mono Volume", "Input Right Capture"}, | 766 | {"ESL DAC", "ESL-IP Mono Volume", "Input Right Capture"}, |
@@ -727,7 +782,7 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = { | |||
727 | 782 | ||
728 | {"SPK DAC", "SPK-ASP Mono Volume", "SPK Mixer"}, | 783 | {"SPK DAC", "SPK-ASP Mono Volume", "SPK Mixer"}, |
729 | {"SPK DAC", "SPK-XSP Mono Volume", "SPK Mixer"}, | 784 | {"SPK DAC", "SPK-XSP Mono Volume", "SPK Mixer"}, |
730 | {"SPK DAC", "SPK-VSP Mono Volume", "VSPIN"}, | 785 | {"SPK DAC", "SPK-VSP Mono Volume", "VSPINOUT"}, |
731 | /* Loopback */ | 786 | /* Loopback */ |
732 | {"SPK DAC", "SPK-IP Mono Volume", "Input Left Capture"}, | 787 | {"SPK DAC", "SPK-IP Mono Volume", "Input Left Capture"}, |
733 | {"SPK DAC", "SPK-IP Mono Volume", "Input Right Capture"}, | 788 | {"SPK DAC", "SPK-IP Mono Volume", "Input Right Capture"}, |
@@ -770,8 +825,8 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = { | |||
770 | {"HL Right Mixer", NULL, "ASPINR"}, | 825 | {"HL Right Mixer", NULL, "ASPINR"}, |
771 | {"HL Left Mixer", NULL, "XSPINL"}, | 826 | {"HL Left Mixer", NULL, "XSPINL"}, |
772 | {"HL Right Mixer", NULL, "XSPINR"}, | 827 | {"HL Right Mixer", NULL, "XSPINR"}, |
773 | {"HL Left Mixer", NULL, "VSPIN"}, | 828 | {"HL Left Mixer", NULL, "VSPINOUT"}, |
774 | {"HL Right Mixer", NULL, "VSPIN"}, | 829 | {"HL Right Mixer", NULL, "VSPINOUT"}, |
775 | 830 | ||
776 | {"ASPINL", NULL, "ASP Playback"}, | 831 | {"ASPINL", NULL, "ASP Playback"}, |
777 | {"ASPINM", NULL, "ASP Playback"}, | 832 | {"ASPINM", NULL, "ASP Playback"}, |
@@ -779,7 +834,7 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = { | |||
779 | {"XSPINL", NULL, "XSP Playback"}, | 834 | {"XSPINL", NULL, "XSP Playback"}, |
780 | {"XSPINM", NULL, "XSP Playback"}, | 835 | {"XSPINM", NULL, "XSP Playback"}, |
781 | {"XSPINR", NULL, "XSP Playback"}, | 836 | {"XSPINR", NULL, "XSP Playback"}, |
782 | {"VSPIN", NULL, "VSP Playback"}, | 837 | {"VSPINOUT", NULL, "VSP Playback"}, |
783 | 838 | ||
784 | /* Capture Paths */ | 839 | /* Capture Paths */ |
785 | {"MIC1", NULL, "MIC1 Bias"}, | 840 | {"MIC1", NULL, "MIC1 Bias"}, |
@@ -795,6 +850,8 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = { | |||
795 | 850 | ||
796 | {"ADC Left", NULL, "PGA Left"}, | 851 | {"ADC Left", NULL, "PGA Left"}, |
797 | {"ADC Right", NULL, "PGA Right"}, | 852 | {"ADC Right", NULL, "PGA Right"}, |
853 | {"DMIC Left", NULL, "DMICA"}, | ||
854 | {"DMIC Right", NULL, "DMICB"}, | ||
798 | 855 | ||
799 | {"Input Left Capture", "ADC Left Input", "ADC Left"}, | 856 | {"Input Left Capture", "ADC Left Input", "ADC Left"}, |
800 | {"Input Right Capture", "ADC Right Input", "ADC Right"}, | 857 | {"Input Right Capture", "ADC Right Input", "ADC Right"}, |
@@ -819,21 +876,18 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = { | |||
819 | {"XSPOUTR", NULL, "XSPR Output Mixer"}, | 876 | {"XSPOUTR", NULL, "XSPR Output Mixer"}, |
820 | 877 | ||
821 | /* Voice Capture */ | 878 | /* Voice Capture */ |
822 | {"VSPL Output Mixer", NULL, "Input Left Capture"}, | 879 | {"VSP Output Mixer", NULL, "Input Left Capture"}, |
823 | {"VSPR Output Mixer", NULL, "Input Left Capture"}, | 880 | {"VSP Output Mixer", NULL, "Input Right Capture"}, |
824 | 881 | ||
825 | {"VSPOUTL", "VSP-IP Volume", "VSPL Output Mixer"}, | 882 | {"VSPINOUT", "VSP-IP Volume", "VSP Output Mixer"}, |
826 | {"VSPOUTR", "VSP-IP Volume", "VSPR Output Mixer"}, | ||
827 | 883 | ||
828 | {"VSPOUTL", NULL, "VSPL Output Mixer"}, | 884 | {"VSPINOUT", NULL, "VSP Output Mixer"}, |
829 | {"VSPOUTR", NULL, "VSPR Output Mixer"}, | ||
830 | 885 | ||
831 | {"ASP Capture", NULL, "ASPOUTL"}, | 886 | {"ASP Capture", NULL, "ASPOUTL"}, |
832 | {"ASP Capture", NULL, "ASPOUTR"}, | 887 | {"ASP Capture", NULL, "ASPOUTR"}, |
833 | {"XSP Capture", NULL, "XSPOUTL"}, | 888 | {"XSP Capture", NULL, "XSPOUTL"}, |
834 | {"XSP Capture", NULL, "XSPOUTR"}, | 889 | {"XSP Capture", NULL, "XSPOUTR"}, |
835 | {"VSP Capture", NULL, "VSPOUTL"}, | 890 | {"VSP Capture", NULL, "VSPINOUT"}, |
836 | {"VSP Capture", NULL, "VSPOUTR"}, | ||
837 | }; | 891 | }; |
838 | 892 | ||
839 | struct cs42l73_mclk_div { | 893 | struct cs42l73_mclk_div { |
@@ -1167,6 +1221,14 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec, | |||
1167 | 1221 | ||
1168 | case SND_SOC_BIAS_OFF: | 1222 | case SND_SOC_BIAS_OFF: |
1169 | snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1); | 1223 | snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1); |
1224 | if (cs42l73->shutdwn_delay > 0) { | ||
1225 | mdelay(cs42l73->shutdwn_delay); | ||
1226 | cs42l73->shutdwn_delay = 0; | ||
1227 | } else { | ||
1228 | mdelay(15); /* Min amount of time requred to power | ||
1229 | * down. | ||
1230 | */ | ||
1231 | } | ||
1170 | snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 1); | 1232 | snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 1); |
1171 | break; | 1233 | break; |
1172 | } | 1234 | } |
diff --git a/sound/soc/codecs/sigmadsp.c b/sound/soc/codecs/sigmadsp.c index 5be42bf56996..4068f2491232 100644 --- a/sound/soc/codecs/sigmadsp.c +++ b/sound/soc/codecs/sigmadsp.c | |||
@@ -225,7 +225,7 @@ EXPORT_SYMBOL(process_sigma_firmware); | |||
225 | static int sigma_action_write_regmap(void *control_data, | 225 | static int sigma_action_write_regmap(void *control_data, |
226 | const struct sigma_action *sa, size_t len) | 226 | const struct sigma_action *sa, size_t len) |
227 | { | 227 | { |
228 | return regmap_raw_write(control_data, le16_to_cpu(sa->addr), | 228 | return regmap_raw_write(control_data, be16_to_cpu(sa->addr), |
229 | sa->payload, len - 2); | 229 | sa->payload, len - 2); |
230 | } | 230 | } |
231 | 231 | ||
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 8d75aa152c8c..c58bee8346ce 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c | |||
@@ -398,7 +398,8 @@ static int tpa6130a2_probe(struct i2c_client *client, | |||
398 | TPA6130A2_MUTE_L; | 398 | TPA6130A2_MUTE_L; |
399 | 399 | ||
400 | if (data->power_gpio >= 0) { | 400 | if (data->power_gpio >= 0) { |
401 | ret = gpio_request(data->power_gpio, "tpa6130a2 enable"); | 401 | ret = devm_gpio_request(dev, data->power_gpio, |
402 | "tpa6130a2 enable"); | ||
402 | if (ret < 0) { | 403 | if (ret < 0) { |
403 | dev_err(dev, "Failed to request power GPIO (%d)\n", | 404 | dev_err(dev, "Failed to request power GPIO (%d)\n", |
404 | data->power_gpio); | 405 | data->power_gpio); |
@@ -419,16 +420,16 @@ static int tpa6130a2_probe(struct i2c_client *client, | |||
419 | break; | 420 | break; |
420 | } | 421 | } |
421 | 422 | ||
422 | data->supply = regulator_get(dev, regulator); | 423 | data->supply = devm_regulator_get(dev, regulator); |
423 | if (IS_ERR(data->supply)) { | 424 | if (IS_ERR(data->supply)) { |
424 | ret = PTR_ERR(data->supply); | 425 | ret = PTR_ERR(data->supply); |
425 | dev_err(dev, "Failed to request supply: %d\n", ret); | 426 | dev_err(dev, "Failed to request supply: %d\n", ret); |
426 | goto err_regulator; | 427 | goto err_gpio; |
427 | } | 428 | } |
428 | 429 | ||
429 | ret = tpa6130a2_power(1); | 430 | ret = tpa6130a2_power(1); |
430 | if (ret != 0) | 431 | if (ret != 0) |
431 | goto err_power; | 432 | goto err_gpio; |
432 | 433 | ||
433 | 434 | ||
434 | /* Read version */ | 435 | /* Read version */ |
@@ -440,15 +441,10 @@ static int tpa6130a2_probe(struct i2c_client *client, | |||
440 | /* Disable the chip */ | 441 | /* Disable the chip */ |
441 | ret = tpa6130a2_power(0); | 442 | ret = tpa6130a2_power(0); |
442 | if (ret != 0) | 443 | if (ret != 0) |
443 | goto err_power; | 444 | goto err_gpio; |
444 | 445 | ||
445 | return 0; | 446 | return 0; |
446 | 447 | ||
447 | err_power: | ||
448 | regulator_put(data->supply); | ||
449 | err_regulator: | ||
450 | if (data->power_gpio >= 0) | ||
451 | gpio_free(data->power_gpio); | ||
452 | err_gpio: | 448 | err_gpio: |
453 | tpa6130a2_client = NULL; | 449 | tpa6130a2_client = NULL; |
454 | 450 | ||
@@ -457,14 +453,7 @@ err_gpio: | |||
457 | 453 | ||
458 | static int tpa6130a2_remove(struct i2c_client *client) | 454 | static int tpa6130a2_remove(struct i2c_client *client) |
459 | { | 455 | { |
460 | struct tpa6130a2_data *data = i2c_get_clientdata(client); | ||
461 | |||
462 | tpa6130a2_power(0); | 456 | tpa6130a2_power(0); |
463 | |||
464 | if (data->power_gpio >= 0) | ||
465 | gpio_free(data->power_gpio); | ||
466 | |||
467 | regulator_put(data->supply); | ||
468 | tpa6130a2_client = NULL; | 457 | tpa6130a2_client = NULL; |
469 | 458 | ||
470 | return 0; | 459 | return 0; |
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 967d0e173e1b..5fbfb06e8083 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c | |||
@@ -113,7 +113,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream) | |||
113 | SNDRV_PCM_STREAM_PLAYBACK, | 113 | SNDRV_PCM_STREAM_PLAYBACK, |
114 | SND_SOC_DAPM_STREAM_STOP); | 114 | SND_SOC_DAPM_STREAM_STOP); |
115 | } else | 115 | } else |
116 | codec_dai->pop_wait = 1; | 116 | rtd->pop_wait = 1; |
117 | schedule_delayed_work(&rtd->delayed_work, | 117 | schedule_delayed_work(&rtd->delayed_work, |
118 | msecs_to_jiffies(rtd->pmdown_time)); | 118 | msecs_to_jiffies(rtd->pmdown_time)); |
119 | } else { | 119 | } else { |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 9c768bcb98a6..91d592ff67b7 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -4155,9 +4155,9 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | |||
4155 | ret = of_property_read_string_index(np, propname, | 4155 | ret = of_property_read_string_index(np, propname, |
4156 | 2 * i, &routes[i].sink); | 4156 | 2 * i, &routes[i].sink); |
4157 | if (ret) { | 4157 | if (ret) { |
4158 | dev_err(card->dev, "ASoC: Property '%s' index %d" | 4158 | dev_err(card->dev, |
4159 | " could not be read: %d\n", propname, 2 * i, | 4159 | "ASoC: Property '%s' index %d could not be read: %d\n", |
4160 | ret); | 4160 | propname, 2 * i, ret); |
4161 | kfree(routes); | 4161 | kfree(routes); |
4162 | return -EINVAL; | 4162 | return -EINVAL; |
4163 | } | 4163 | } |
@@ -4165,8 +4165,8 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | |||
4165 | (2 * i) + 1, &routes[i].source); | 4165 | (2 * i) + 1, &routes[i].source); |
4166 | if (ret) { | 4166 | if (ret) { |
4167 | dev_err(card->dev, | 4167 | dev_err(card->dev, |
4168 | "ASoC: Property '%s' index %d could not be" | 4168 | "ASoC: Property '%s' index %d could not be read: %d\n", |
4169 | " read: %d\n", propname, (2 * i) + 1, ret); | 4169 | propname, (2 * i) + 1, ret); |
4170 | kfree(routes); | 4170 | kfree(routes); |
4171 | return -EINVAL; | 4171 | return -EINVAL; |
4172 | } | 4172 | } |
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 5c3ca2a34661..d7711fce119b 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c | |||
@@ -334,11 +334,11 @@ static void close_delayed_work(struct work_struct *work) | |||
334 | dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n", | 334 | dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n", |
335 | codec_dai->driver->playback.stream_name, | 335 | codec_dai->driver->playback.stream_name, |
336 | codec_dai->playback_active ? "active" : "inactive", | 336 | codec_dai->playback_active ? "active" : "inactive", |
337 | codec_dai->pop_wait ? "yes" : "no"); | 337 | rtd->pop_wait ? "yes" : "no"); |
338 | 338 | ||
339 | /* are we waiting on this codec DAI stream */ | 339 | /* are we waiting on this codec DAI stream */ |
340 | if (codec_dai->pop_wait == 1) { | 340 | if (rtd->pop_wait == 1) { |
341 | codec_dai->pop_wait = 0; | 341 | rtd->pop_wait = 0; |
342 | snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, | 342 | snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, |
343 | SND_SOC_DAPM_STREAM_STOP); | 343 | SND_SOC_DAPM_STREAM_STOP); |
344 | } | 344 | } |
@@ -408,7 +408,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) | |||
408 | SND_SOC_DAPM_STREAM_STOP); | 408 | SND_SOC_DAPM_STREAM_STOP); |
409 | } else { | 409 | } else { |
410 | /* start delayed pop wq here for playback streams */ | 410 | /* start delayed pop wq here for playback streams */ |
411 | codec_dai->pop_wait = 1; | 411 | rtd->pop_wait = 1; |
412 | schedule_delayed_work(&rtd->delayed_work, | 412 | schedule_delayed_work(&rtd->delayed_work, |
413 | msecs_to_jiffies(rtd->pmdown_time)); | 413 | msecs_to_jiffies(rtd->pmdown_time)); |
414 | } | 414 | } |
@@ -480,8 +480,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
480 | 480 | ||
481 | /* cancel any delayed stream shutdown that is pending */ | 481 | /* cancel any delayed stream shutdown that is pending */ |
482 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && | 482 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && |
483 | codec_dai->pop_wait) { | 483 | rtd->pop_wait) { |
484 | codec_dai->pop_wait = 0; | 484 | rtd->pop_wait = 0; |
485 | cancel_delayed_work(&rtd->delayed_work); | 485 | cancel_delayed_work(&rtd->delayed_work); |
486 | } | 486 | } |
487 | 487 | ||
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index 34b9bb7fe87c..c183d34842ac 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c | |||
@@ -2181,6 +2181,10 @@ int snd_usbmidi_create(struct snd_card *card, | |||
2181 | umidi->usb_protocol_ops = &snd_usbmidi_novation_ops; | 2181 | umidi->usb_protocol_ops = &snd_usbmidi_novation_ops; |
2182 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | 2182 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); |
2183 | break; | 2183 | break; |
2184 | case QUIRK_MIDI_MBOX2: | ||
2185 | umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops; | ||
2186 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | ||
2187 | break; | ||
2184 | case QUIRK_MIDI_RAW_BYTES: | 2188 | case QUIRK_MIDI_RAW_BYTES: |
2185 | umidi->usb_protocol_ops = &snd_usbmidi_raw_ops; | 2189 | umidi->usb_protocol_ops = &snd_usbmidi_raw_ops; |
2186 | /* | 2190 | /* |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 49f9af995d7a..cdcf6b45e8a8 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -99,6 +99,42 @@ | |||
99 | }, | 99 | }, |
100 | 100 | ||
101 | /* | 101 | /* |
102 | * HP Wireless Audio | ||
103 | * When not ignored, causes instability issues for some users, forcing them to | ||
104 | * blacklist the entire module. | ||
105 | */ | ||
106 | { | ||
107 | USB_DEVICE(0x0424, 0xb832), | ||
108 | .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
109 | .vendor_name = "Standard Microsystems Corp.", | ||
110 | .product_name = "HP Wireless Audio", | ||
111 | .ifnum = QUIRK_ANY_INTERFACE, | ||
112 | .type = QUIRK_COMPOSITE, | ||
113 | .data = (const struct snd_usb_audio_quirk[]) { | ||
114 | /* Mixer */ | ||
115 | { | ||
116 | .ifnum = 0, | ||
117 | .type = QUIRK_IGNORE_INTERFACE, | ||
118 | }, | ||
119 | /* Playback */ | ||
120 | { | ||
121 | .ifnum = 1, | ||
122 | .type = QUIRK_IGNORE_INTERFACE, | ||
123 | }, | ||
124 | /* Capture */ | ||
125 | { | ||
126 | .ifnum = 2, | ||
127 | .type = QUIRK_IGNORE_INTERFACE, | ||
128 | }, | ||
129 | /* HID Device, .ifnum = 3 */ | ||
130 | { | ||
131 | .ifnum = -1, | ||
132 | } | ||
133 | } | ||
134 | } | ||
135 | }, | ||
136 | |||
137 | /* | ||
102 | * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface | 138 | * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface |
103 | * class matches do not take effect without an explicit ID match. | 139 | * class matches do not take effect without an explicit ID match. |
104 | */ | 140 | */ |
@@ -2885,6 +2921,93 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2885 | 2921 | ||
2886 | } | 2922 | } |
2887 | }, | 2923 | }, |
2924 | |||
2925 | /* DIGIDESIGN MBOX 2 */ | ||
2926 | { | ||
2927 | USB_DEVICE(0x0dba, 0x3000), | ||
2928 | .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
2929 | .vendor_name = "Digidesign", | ||
2930 | .product_name = "Mbox 2", | ||
2931 | .ifnum = QUIRK_ANY_INTERFACE, | ||
2932 | .type = QUIRK_COMPOSITE, | ||
2933 | .data = (const struct snd_usb_audio_quirk[]) { | ||
2934 | { | ||
2935 | .ifnum = 0, | ||
2936 | .type = QUIRK_IGNORE_INTERFACE | ||
2937 | }, | ||
2938 | { | ||
2939 | .ifnum = 1, | ||
2940 | .type = QUIRK_IGNORE_INTERFACE | ||
2941 | }, | ||
2942 | { | ||
2943 | .ifnum = 2, | ||
2944 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | ||
2945 | .data = &(const struct audioformat) { | ||
2946 | .formats = SNDRV_PCM_FMTBIT_S24_3BE, | ||
2947 | .channels = 2, | ||
2948 | .iface = 2, | ||
2949 | .altsetting = 2, | ||
2950 | .altset_idx = 1, | ||
2951 | .attributes = 0x00, | ||
2952 | .endpoint = 0x03, | ||
2953 | .ep_attr = USB_ENDPOINT_SYNC_ASYNC, | ||
2954 | .maxpacksize = 0x128, | ||
2955 | .rates = SNDRV_PCM_RATE_48000, | ||
2956 | .rate_min = 48000, | ||
2957 | .rate_max = 48000, | ||
2958 | .nr_rates = 1, | ||
2959 | .rate_table = (unsigned int[]) { | ||
2960 | 48000 | ||
2961 | } | ||
2962 | } | ||
2963 | }, | ||
2964 | { | ||
2965 | .ifnum = 3, | ||
2966 | .type = QUIRK_IGNORE_INTERFACE | ||
2967 | }, | ||
2968 | { | ||
2969 | .ifnum = 4, | ||
2970 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | ||
2971 | .data = &(const struct audioformat) { | ||
2972 | .formats = SNDRV_PCM_FMTBIT_S24_3BE, | ||
2973 | .channels = 2, | ||
2974 | .iface = 4, | ||
2975 | .altsetting = 2, | ||
2976 | .altset_idx = 1, | ||
2977 | .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, | ||
2978 | .endpoint = 0x85, | ||
2979 | .ep_attr = USB_ENDPOINT_SYNC_SYNC, | ||
2980 | .maxpacksize = 0x128, | ||
2981 | .rates = SNDRV_PCM_RATE_48000, | ||
2982 | .rate_min = 48000, | ||
2983 | .rate_max = 48000, | ||
2984 | .nr_rates = 1, | ||
2985 | .rate_table = (unsigned int[]) { | ||
2986 | 48000 | ||
2987 | } | ||
2988 | } | ||
2989 | }, | ||
2990 | { | ||
2991 | .ifnum = 5, | ||
2992 | .type = QUIRK_IGNORE_INTERFACE | ||
2993 | }, | ||
2994 | { | ||
2995 | .ifnum = 6, | ||
2996 | .type = QUIRK_MIDI_MBOX2, | ||
2997 | .data = &(const struct snd_usb_midi_endpoint_info) { | ||
2998 | .out_ep = 0x02, | ||
2999 | .out_cables = 0x0001, | ||
3000 | .in_ep = 0x81, | ||
3001 | .in_interval = 0x01, | ||
3002 | .in_cables = 0x0001 | ||
3003 | } | ||
3004 | }, | ||
3005 | { | ||
3006 | .ifnum = -1 | ||
3007 | } | ||
3008 | } | ||
3009 | } | ||
3010 | }, | ||
2888 | { | 3011 | { |
2889 | /* Tascam US122 MKII - playback-only support */ | 3012 | /* Tascam US122 MKII - playback-only support */ |
2890 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 3013 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 007fcecdf5cd..f104c68fe1e0 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
@@ -306,6 +306,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, | |||
306 | [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk, | 306 | [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk, |
307 | [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk, | 307 | [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk, |
308 | [QUIRK_MIDI_NOVATION] = create_any_midi_quirk, | 308 | [QUIRK_MIDI_NOVATION] = create_any_midi_quirk, |
309 | [QUIRK_MIDI_MBOX2] = create_any_midi_quirk, | ||
309 | [QUIRK_MIDI_RAW_BYTES] = create_any_midi_quirk, | 310 | [QUIRK_MIDI_RAW_BYTES] = create_any_midi_quirk, |
310 | [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, | 311 | [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, |
311 | [QUIRK_MIDI_CME] = create_any_midi_quirk, | 312 | [QUIRK_MIDI_CME] = create_any_midi_quirk, |
@@ -497,6 +498,92 @@ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev) | |||
497 | return -EAGAIN; | 498 | return -EAGAIN; |
498 | } | 499 | } |
499 | 500 | ||
501 | static void mbox2_setup_48_24_magic(struct usb_device *dev) | ||
502 | { | ||
503 | u8 srate[3]; | ||
504 | u8 temp[12]; | ||
505 | |||
506 | /* Choose 48000Hz permanently */ | ||
507 | srate[0] = 0x80; | ||
508 | srate[1] = 0xbb; | ||
509 | srate[2] = 0x00; | ||
510 | |||
511 | /* Send the magic! */ | ||
512 | snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
513 | 0x01, 0x22, 0x0100, 0x0085, &temp, 0x0003); | ||
514 | snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), | ||
515 | 0x81, 0xa2, 0x0100, 0x0085, &srate, 0x0003); | ||
516 | snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), | ||
517 | 0x81, 0xa2, 0x0100, 0x0086, &srate, 0x0003); | ||
518 | snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), | ||
519 | 0x81, 0xa2, 0x0100, 0x0003, &srate, 0x0003); | ||
520 | return; | ||
521 | } | ||
522 | |||
523 | /* Digidesign Mbox 2 needs to load firmware onboard | ||
524 | * and driver must wait a few seconds for initialisation. | ||
525 | */ | ||
526 | |||
527 | #define MBOX2_FIRMWARE_SIZE 646 | ||
528 | #define MBOX2_BOOT_LOADING 0x01 /* Hard coded into the device */ | ||
529 | #define MBOX2_BOOT_READY 0x02 /* Hard coded into the device */ | ||
530 | |||
531 | int snd_usb_mbox2_boot_quirk(struct usb_device *dev) | ||
532 | { | ||
533 | struct usb_host_config *config = dev->actconfig; | ||
534 | int err; | ||
535 | u8 bootresponse; | ||
536 | int fwsize; | ||
537 | int count; | ||
538 | |||
539 | fwsize = le16_to_cpu(get_cfg_desc(config)->wTotalLength); | ||
540 | |||
541 | if (fwsize != MBOX2_FIRMWARE_SIZE) { | ||
542 | snd_printk(KERN_ERR "usb-audio: Invalid firmware size=%d.\n", fwsize); | ||
543 | return -ENODEV; | ||
544 | } | ||
545 | |||
546 | snd_printd("usb-audio: Sending Digidesign Mbox 2 boot sequence...\n"); | ||
547 | |||
548 | count = 0; | ||
549 | bootresponse = MBOX2_BOOT_LOADING; | ||
550 | while ((bootresponse == MBOX2_BOOT_LOADING) && (count < 10)) { | ||
551 | msleep(500); /* 0.5 second delay */ | ||
552 | snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
553 | /* Control magic - load onboard firmware */ | ||
554 | 0x85, 0xc0, 0x0001, 0x0000, &bootresponse, 0x0012); | ||
555 | if (bootresponse == MBOX2_BOOT_READY) | ||
556 | break; | ||
557 | snd_printd("usb-audio: device not ready, resending boot sequence...\n"); | ||
558 | count++; | ||
559 | } | ||
560 | |||
561 | if (bootresponse != MBOX2_BOOT_READY) { | ||
562 | snd_printk(KERN_ERR "usb-audio: Unknown bootresponse=%d, or timed out, ignoring device.\n", bootresponse); | ||
563 | return -ENODEV; | ||
564 | } | ||
565 | |||
566 | snd_printdd("usb-audio: device initialised!\n"); | ||
567 | |||
568 | err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, | ||
569 | &dev->descriptor, sizeof(dev->descriptor)); | ||
570 | config = dev->actconfig; | ||
571 | if (err < 0) | ||
572 | snd_printd("error usb_get_descriptor: %d\n", err); | ||
573 | |||
574 | err = usb_reset_configuration(dev); | ||
575 | if (err < 0) | ||
576 | snd_printd("error usb_reset_configuration: %d\n", err); | ||
577 | snd_printdd("mbox2_boot: new boot length = %d\n", | ||
578 | le16_to_cpu(get_cfg_desc(config)->wTotalLength)); | ||
579 | |||
580 | mbox2_setup_48_24_magic(dev); | ||
581 | |||
582 | snd_printk(KERN_INFO "usb-audio: Digidesign Mbox 2: 24bit 48kHz"); | ||
583 | |||
584 | return 0; /* Successful boot */ | ||
585 | } | ||
586 | |||
500 | /* | 587 | /* |
501 | * Setup quirks | 588 | * Setup quirks |
502 | */ | 589 | */ |
@@ -655,6 +742,10 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev, | |||
655 | case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */ | 742 | case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */ |
656 | return snd_usb_cm6206_boot_quirk(dev); | 743 | return snd_usb_cm6206_boot_quirk(dev); |
657 | 744 | ||
745 | case USB_ID(0x0dba, 0x3000): | ||
746 | /* Digidesign Mbox 2 */ | ||
747 | return snd_usb_mbox2_boot_quirk(dev); | ||
748 | |||
658 | case USB_ID(0x133e, 0x0815): | 749 | case USB_ID(0x133e, 0x0815): |
659 | /* Access Music VirusTI Desktop */ | 750 | /* Access Music VirusTI Desktop */ |
660 | return snd_usb_accessmusic_boot_quirk(dev); | 751 | return snd_usb_accessmusic_boot_quirk(dev); |
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 1ac3fd9cc5a6..a8172c119796 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
@@ -76,6 +76,7 @@ enum quirk_type { | |||
76 | QUIRK_MIDI_YAMAHA, | 76 | QUIRK_MIDI_YAMAHA, |
77 | QUIRK_MIDI_MIDIMAN, | 77 | QUIRK_MIDI_MIDIMAN, |
78 | QUIRK_MIDI_NOVATION, | 78 | QUIRK_MIDI_NOVATION, |
79 | QUIRK_MIDI_MBOX2, | ||
79 | QUIRK_MIDI_RAW_BYTES, | 80 | QUIRK_MIDI_RAW_BYTES, |
80 | QUIRK_MIDI_EMAGIC, | 81 | QUIRK_MIDI_EMAGIC, |
81 | QUIRK_MIDI_CME, | 82 | QUIRK_MIDI_CME, |