diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-27 14:59:02 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-27 14:59:02 -0500 |
commit | 172473407962df19d0344fcdba90b02d16fe98d0 (patch) | |
tree | 756bb9c189423dfa155ee6a17f005cb649a8ed56 /sound | |
parent | 5d8686276a5acc0a3d8055028a6e9d990c9c4fbd (diff) | |
parent | 0c25ad80408e95e0a4fbaf0056950206e95f726f (diff) |
Merge tag 'sound-4.4-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai:
"Here are no big surprises but just all small fixes, mostly
device-specific quirks for HD-audio and USB-audio:
- Fix for detection of FireWire DICE Loud devices
- Intel Broxton HDMI/DP PCI IDs and relevant quirks
- Noise fixes: Dell XPS13 2015 model, Dell Latitude E6440, Gigabyte
Z170X mobo
- Fix the headphone mixer assignment on HP laptops for PulseAudio
- USB-MIDI fixes for Medeli DD305 and CH345
- Apply fixup for Acer Aspire One Cloudbook 14"
* tag 'sound-4.4-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
ALSA: hda - Fix noise on Gigabyte Z170X mobo
ALSA: hda - Fix headphone noise after Dell XPS 13 resume back from S3
ALSA: hda - Apply HP headphone fixups more generically
ALSA: hda - Add fixup for Acer Aspire One Cloudbook 14
ALSA: hda - apply SKL display power request/release patch to BXT
ALSA: hda - add PCI IDs for Intel Broxton
ALSA: usb-audio: work around CH345 input SysEx corruption
ALSA: usb-audio: prevent CH345 multiport output SysEx corruption
ALSA: usb-audio: add packet size quirk for the Medeli DD305
ALSA: dice: fix detection of Loud devices
ALSA: hda - Fix noise on Dell Latitude E6440
Diffstat (limited to 'sound')
-rw-r--r-- | sound/firewire/dice/dice.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 7 | ||||
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 3 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 23 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 45 | ||||
-rw-r--r-- | sound/usb/midi.c | 46 | ||||
-rw-r--r-- | sound/usb/quirks-table.h | 11 | ||||
-rw-r--r-- | sound/usb/quirks.c | 1 | ||||
-rw-r--r-- | sound/usb/usbaudio.h | 1 |
9 files changed, 124 insertions, 17 deletions
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c index 5d99436dfcae..0cda05c72f50 100644 --- a/sound/firewire/dice/dice.c +++ b/sound/firewire/dice/dice.c | |||
@@ -12,9 +12,11 @@ MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | |||
12 | MODULE_LICENSE("GPL v2"); | 12 | MODULE_LICENSE("GPL v2"); |
13 | 13 | ||
14 | #define OUI_WEISS 0x001c6a | 14 | #define OUI_WEISS 0x001c6a |
15 | #define OUI_LOUD 0x000ff2 | ||
15 | 16 | ||
16 | #define DICE_CATEGORY_ID 0x04 | 17 | #define DICE_CATEGORY_ID 0x04 |
17 | #define WEISS_CATEGORY_ID 0x00 | 18 | #define WEISS_CATEGORY_ID 0x00 |
19 | #define LOUD_CATEGORY_ID 0x10 | ||
18 | 20 | ||
19 | static int dice_interface_check(struct fw_unit *unit) | 21 | static int dice_interface_check(struct fw_unit *unit) |
20 | { | 22 | { |
@@ -57,6 +59,8 @@ static int dice_interface_check(struct fw_unit *unit) | |||
57 | } | 59 | } |
58 | if (vendor == OUI_WEISS) | 60 | if (vendor == OUI_WEISS) |
59 | category = WEISS_CATEGORY_ID; | 61 | category = WEISS_CATEGORY_ID; |
62 | else if (vendor == OUI_LOUD) | ||
63 | category = LOUD_CATEGORY_ID; | ||
60 | else | 64 | else |
61 | category = DICE_CATEGORY_ID; | 65 | category = DICE_CATEGORY_ID; |
62 | if (device->config_rom[3] != ((vendor << 8) | category) || | 66 | if (device->config_rom[3] != ((vendor << 8) | category) || |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 8a7fbdcb4072..963f82430938 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -312,6 +312,10 @@ enum { | |||
312 | (AZX_DCAPS_INTEL_PCH | AZX_DCAPS_SEPARATE_STREAM_TAG |\ | 312 | (AZX_DCAPS_INTEL_PCH | AZX_DCAPS_SEPARATE_STREAM_TAG |\ |
313 | AZX_DCAPS_I915_POWERWELL) | 313 | AZX_DCAPS_I915_POWERWELL) |
314 | 314 | ||
315 | #define AZX_DCAPS_INTEL_BROXTON \ | ||
316 | (AZX_DCAPS_INTEL_PCH | AZX_DCAPS_SEPARATE_STREAM_TAG |\ | ||
317 | AZX_DCAPS_I915_POWERWELL) | ||
318 | |||
315 | /* quirks for ATI SB / AMD Hudson */ | 319 | /* quirks for ATI SB / AMD Hudson */ |
316 | #define AZX_DCAPS_PRESET_ATI_SB \ | 320 | #define AZX_DCAPS_PRESET_ATI_SB \ |
317 | (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB |\ | 321 | (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB |\ |
@@ -2124,6 +2128,9 @@ static const struct pci_device_id azx_ids[] = { | |||
2124 | /* Sunrise Point-LP */ | 2128 | /* Sunrise Point-LP */ |
2125 | { PCI_DEVICE(0x8086, 0x9d70), | 2129 | { PCI_DEVICE(0x8086, 0x9d70), |
2126 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE }, | 2130 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE }, |
2131 | /* Broxton-P(Apollolake) */ | ||
2132 | { PCI_DEVICE(0x8086, 0x5a98), | ||
2133 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON }, | ||
2127 | /* Haswell */ | 2134 | /* Haswell */ |
2128 | { PCI_DEVICE(0x8086, 0x0a0c), | 2135 | { PCI_DEVICE(0x8086, 0x0a0c), |
2129 | .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL }, | 2136 | .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL }, |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 60cd9e700909..bdb6f226d006 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -2378,7 +2378,8 @@ static int patch_generic_hdmi(struct hda_codec *codec) | |||
2378 | * can cover the codec power request, and so need not set this flag. | 2378 | * can cover the codec power request, and so need not set this flag. |
2379 | * For previous platforms, there is no such power well feature. | 2379 | * For previous platforms, there is no such power well feature. |
2380 | */ | 2380 | */ |
2381 | if (is_valleyview_plus(codec) || is_skylake(codec)) | 2381 | if (is_valleyview_plus(codec) || is_skylake(codec) || |
2382 | is_broxton(codec)) | ||
2382 | codec->core.link_power_control = 1; | 2383 | codec->core.link_power_control = 1; |
2383 | 2384 | ||
2384 | if (is_haswell_plus(codec) || is_valleyview_plus(codec)) { | 2385 | if (is_haswell_plus(codec) || is_valleyview_plus(codec)) { |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 2f7b065f9ac4..9bedf7c85e29 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -1759,6 +1759,7 @@ enum { | |||
1759 | ALC882_FIXUP_NO_PRIMARY_HP, | 1759 | ALC882_FIXUP_NO_PRIMARY_HP, |
1760 | ALC887_FIXUP_ASUS_BASS, | 1760 | ALC887_FIXUP_ASUS_BASS, |
1761 | ALC887_FIXUP_BASS_CHMAP, | 1761 | ALC887_FIXUP_BASS_CHMAP, |
1762 | ALC882_FIXUP_DISABLE_AAMIX, | ||
1762 | }; | 1763 | }; |
1763 | 1764 | ||
1764 | static void alc889_fixup_coef(struct hda_codec *codec, | 1765 | static void alc889_fixup_coef(struct hda_codec *codec, |
@@ -1920,6 +1921,8 @@ static void alc882_fixup_no_primary_hp(struct hda_codec *codec, | |||
1920 | 1921 | ||
1921 | static void alc_fixup_bass_chmap(struct hda_codec *codec, | 1922 | static void alc_fixup_bass_chmap(struct hda_codec *codec, |
1922 | const struct hda_fixup *fix, int action); | 1923 | const struct hda_fixup *fix, int action); |
1924 | static void alc_fixup_disable_aamix(struct hda_codec *codec, | ||
1925 | const struct hda_fixup *fix, int action); | ||
1923 | 1926 | ||
1924 | static const struct hda_fixup alc882_fixups[] = { | 1927 | static const struct hda_fixup alc882_fixups[] = { |
1925 | [ALC882_FIXUP_ABIT_AW9D_MAX] = { | 1928 | [ALC882_FIXUP_ABIT_AW9D_MAX] = { |
@@ -2151,6 +2154,10 @@ static const struct hda_fixup alc882_fixups[] = { | |||
2151 | .type = HDA_FIXUP_FUNC, | 2154 | .type = HDA_FIXUP_FUNC, |
2152 | .v.func = alc_fixup_bass_chmap, | 2155 | .v.func = alc_fixup_bass_chmap, |
2153 | }, | 2156 | }, |
2157 | [ALC882_FIXUP_DISABLE_AAMIX] = { | ||
2158 | .type = HDA_FIXUP_FUNC, | ||
2159 | .v.func = alc_fixup_disable_aamix, | ||
2160 | }, | ||
2154 | }; | 2161 | }; |
2155 | 2162 | ||
2156 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { | 2163 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { |
@@ -2218,6 +2225,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { | |||
2218 | SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), | 2225 | SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), |
2219 | SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), | 2226 | SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), |
2220 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), | 2227 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), |
2228 | SND_PCI_QUIRK(0x1458, 0xa182, "Gigabyte Z170X-UD3", ALC882_FIXUP_DISABLE_AAMIX), | ||
2221 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), | 2229 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), |
2222 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), | 2230 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), |
2223 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), | 2231 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), |
@@ -4587,6 +4595,7 @@ enum { | |||
4587 | ALC292_FIXUP_DISABLE_AAMIX, | 4595 | ALC292_FIXUP_DISABLE_AAMIX, |
4588 | ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, | 4596 | ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, |
4589 | ALC275_FIXUP_DELL_XPS, | 4597 | ALC275_FIXUP_DELL_XPS, |
4598 | ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE, | ||
4590 | }; | 4599 | }; |
4591 | 4600 | ||
4592 | static const struct hda_fixup alc269_fixups[] = { | 4601 | static const struct hda_fixup alc269_fixups[] = { |
@@ -5167,6 +5176,17 @@ static const struct hda_fixup alc269_fixups[] = { | |||
5167 | {} | 5176 | {} |
5168 | } | 5177 | } |
5169 | }, | 5178 | }, |
5179 | [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE] = { | ||
5180 | .type = HDA_FIXUP_VERBS, | ||
5181 | .v.verbs = (const struct hda_verb[]) { | ||
5182 | /* Disable pass-through path for FRONT 14h */ | ||
5183 | {0x20, AC_VERB_SET_COEF_INDEX, 0x36}, | ||
5184 | {0x20, AC_VERB_SET_PROC_COEF, 0x1737}, | ||
5185 | {} | ||
5186 | }, | ||
5187 | .chained = true, | ||
5188 | .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE | ||
5189 | }, | ||
5170 | }; | 5190 | }; |
5171 | 5191 | ||
5172 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 5192 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
@@ -5180,8 +5200,10 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
5180 | SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), | 5200 | SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), |
5181 | SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), | 5201 | SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), |
5182 | SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS), | 5202 | SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS), |
5203 | SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK), | ||
5183 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), | 5204 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), |
5184 | SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS), | 5205 | SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS), |
5206 | SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X), | ||
5185 | SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X), | 5207 | SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X), |
5186 | SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X), | 5208 | SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X), |
5187 | SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER), | 5209 | SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER), |
@@ -5204,6 +5226,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
5204 | SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC292_FIXUP_DISABLE_AAMIX), | 5226 | SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC292_FIXUP_DISABLE_AAMIX), |
5205 | SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC292_FIXUP_DISABLE_AAMIX), | 5227 | SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC292_FIXUP_DISABLE_AAMIX), |
5206 | SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC292_FIXUP_DISABLE_AAMIX), | 5228 | SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC292_FIXUP_DISABLE_AAMIX), |
5229 | SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), | ||
5207 | SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), | 5230 | SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), |
5208 | SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), | 5231 | SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), |
5209 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), | 5232 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 826122d8acee..2c7c5eb8b1e9 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -3110,6 +3110,29 @@ static void stac92hd71bxx_fixup_hp_hdx(struct hda_codec *codec, | |||
3110 | spec->gpio_led = 0x08; | 3110 | spec->gpio_led = 0x08; |
3111 | } | 3111 | } |
3112 | 3112 | ||
3113 | static bool is_hp_output(struct hda_codec *codec, hda_nid_t pin) | ||
3114 | { | ||
3115 | unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, pin); | ||
3116 | |||
3117 | /* count line-out, too, as BIOS sets often so */ | ||
3118 | return get_defcfg_connect(pin_cfg) != AC_JACK_PORT_NONE && | ||
3119 | (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT || | ||
3120 | get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT); | ||
3121 | } | ||
3122 | |||
3123 | static void fixup_hp_headphone(struct hda_codec *codec, hda_nid_t pin) | ||
3124 | { | ||
3125 | unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, pin); | ||
3126 | |||
3127 | /* It was changed in the BIOS to just satisfy MS DTM. | ||
3128 | * Lets turn it back into slaved HP | ||
3129 | */ | ||
3130 | pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE)) | | ||
3131 | (AC_JACK_HP_OUT << AC_DEFCFG_DEVICE_SHIFT); | ||
3132 | pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC | AC_DEFCFG_SEQUENCE))) | | ||
3133 | 0x1f; | ||
3134 | snd_hda_codec_set_pincfg(codec, pin, pin_cfg); | ||
3135 | } | ||
3113 | 3136 | ||
3114 | static void stac92hd71bxx_fixup_hp(struct hda_codec *codec, | 3137 | static void stac92hd71bxx_fixup_hp(struct hda_codec *codec, |
3115 | const struct hda_fixup *fix, int action) | 3138 | const struct hda_fixup *fix, int action) |
@@ -3119,22 +3142,12 @@ static void stac92hd71bxx_fixup_hp(struct hda_codec *codec, | |||
3119 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | 3142 | if (action != HDA_FIXUP_ACT_PRE_PROBE) |
3120 | return; | 3143 | return; |
3121 | 3144 | ||
3122 | if (hp_blike_system(codec->core.subsystem_id)) { | 3145 | /* when both output A and F are assigned, these are supposedly |
3123 | unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f); | 3146 | * dock and built-in headphones; fix both pin configs |
3124 | if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT || | 3147 | */ |
3125 | get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER || | 3148 | if (is_hp_output(codec, 0x0a) && is_hp_output(codec, 0x0f)) { |
3126 | get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT) { | 3149 | fixup_hp_headphone(codec, 0x0a); |
3127 | /* It was changed in the BIOS to just satisfy MS DTM. | 3150 | fixup_hp_headphone(codec, 0x0f); |
3128 | * Lets turn it back into slaved HP | ||
3129 | */ | ||
3130 | pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE)) | ||
3131 | | (AC_JACK_HP_OUT << | ||
3132 | AC_DEFCFG_DEVICE_SHIFT); | ||
3133 | pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC | ||
3134 | | AC_DEFCFG_SEQUENCE))) | ||
3135 | | 0x1f; | ||
3136 | snd_hda_codec_set_pincfg(codec, 0x0f, pin_cfg); | ||
3137 | } | ||
3138 | } | 3151 | } |
3139 | 3152 | ||
3140 | if (find_mute_led_cfg(codec, 1)) | 3153 | if (find_mute_led_cfg(codec, 1)) |
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index 7661616f3636..5b4c58c3e2c5 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c | |||
@@ -174,6 +174,8 @@ struct snd_usb_midi_in_endpoint { | |||
174 | u8 running_status_length; | 174 | u8 running_status_length; |
175 | } ports[0x10]; | 175 | } ports[0x10]; |
176 | u8 seen_f5; | 176 | u8 seen_f5; |
177 | bool in_sysex; | ||
178 | u8 last_cin; | ||
177 | u8 error_resubmit; | 179 | u8 error_resubmit; |
178 | int current_port; | 180 | int current_port; |
179 | }; | 181 | }; |
@@ -468,6 +470,39 @@ static void snd_usbmidi_maudio_broken_running_status_input( | |||
468 | } | 470 | } |
469 | 471 | ||
470 | /* | 472 | /* |
473 | * QinHeng CH345 is buggy: every second packet inside a SysEx has not CIN 4 | ||
474 | * but the previously seen CIN, but still with three data bytes. | ||
475 | */ | ||
476 | static void ch345_broken_sysex_input(struct snd_usb_midi_in_endpoint *ep, | ||
477 | uint8_t *buffer, int buffer_length) | ||
478 | { | ||
479 | unsigned int i, cin, length; | ||
480 | |||
481 | for (i = 0; i + 3 < buffer_length; i += 4) { | ||
482 | if (buffer[i] == 0 && i > 0) | ||
483 | break; | ||
484 | cin = buffer[i] & 0x0f; | ||
485 | if (ep->in_sysex && | ||
486 | cin == ep->last_cin && | ||
487 | (buffer[i + 1 + (cin == 0x6)] & 0x80) == 0) | ||
488 | cin = 0x4; | ||
489 | #if 0 | ||
490 | if (buffer[i + 1] == 0x90) { | ||
491 | /* | ||
492 | * Either a corrupted running status or a real note-on | ||
493 | * message; impossible to detect reliably. | ||
494 | */ | ||
495 | } | ||
496 | #endif | ||
497 | length = snd_usbmidi_cin_length[cin]; | ||
498 | snd_usbmidi_input_data(ep, 0, &buffer[i + 1], length); | ||
499 | ep->in_sysex = cin == 0x4; | ||
500 | if (!ep->in_sysex) | ||
501 | ep->last_cin = cin; | ||
502 | } | ||
503 | } | ||
504 | |||
505 | /* | ||
471 | * CME protocol: like the standard protocol, but SysEx commands are sent as a | 506 | * CME protocol: like the standard protocol, but SysEx commands are sent as a |
472 | * single USB packet preceded by a 0x0F byte. | 507 | * single USB packet preceded by a 0x0F byte. |
473 | */ | 508 | */ |
@@ -660,6 +695,12 @@ static struct usb_protocol_ops snd_usbmidi_cme_ops = { | |||
660 | .output_packet = snd_usbmidi_output_standard_packet, | 695 | .output_packet = snd_usbmidi_output_standard_packet, |
661 | }; | 696 | }; |
662 | 697 | ||
698 | static struct usb_protocol_ops snd_usbmidi_ch345_broken_sysex_ops = { | ||
699 | .input = ch345_broken_sysex_input, | ||
700 | .output = snd_usbmidi_standard_output, | ||
701 | .output_packet = snd_usbmidi_output_standard_packet, | ||
702 | }; | ||
703 | |||
663 | /* | 704 | /* |
664 | * AKAI MPD16 protocol: | 705 | * AKAI MPD16 protocol: |
665 | * | 706 | * |
@@ -1341,6 +1382,7 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi, | |||
1341 | * Various chips declare a packet size larger than 4 bytes, but | 1382 | * Various chips declare a packet size larger than 4 bytes, but |
1342 | * do not actually work with larger packets: | 1383 | * do not actually work with larger packets: |
1343 | */ | 1384 | */ |
1385 | case USB_ID(0x0a67, 0x5011): /* Medeli DD305 */ | ||
1344 | case USB_ID(0x0a92, 0x1020): /* ESI M4U */ | 1386 | case USB_ID(0x0a92, 0x1020): /* ESI M4U */ |
1345 | case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */ | 1387 | case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */ |
1346 | case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */ | 1388 | case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */ |
@@ -2378,6 +2420,10 @@ int snd_usbmidi_create(struct snd_card *card, | |||
2378 | 2420 | ||
2379 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | 2421 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); |
2380 | break; | 2422 | break; |
2423 | case QUIRK_MIDI_CH345: | ||
2424 | umidi->usb_protocol_ops = &snd_usbmidi_ch345_broken_sysex_ops; | ||
2425 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | ||
2426 | break; | ||
2381 | default: | 2427 | default: |
2382 | dev_err(&umidi->dev->dev, "invalid quirk type %d\n", | 2428 | dev_err(&umidi->dev->dev, "invalid quirk type %d\n", |
2383 | quirk->type); | 2429 | quirk->type); |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 1a1e2e4df35e..c60a776e815d 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -2829,6 +2829,17 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2829 | .idProduct = 0x1020, | 2829 | .idProduct = 0x1020, |
2830 | }, | 2830 | }, |
2831 | 2831 | ||
2832 | /* QinHeng devices */ | ||
2833 | { | ||
2834 | USB_DEVICE(0x1a86, 0x752d), | ||
2835 | .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
2836 | .vendor_name = "QinHeng", | ||
2837 | .product_name = "CH345", | ||
2838 | .ifnum = 1, | ||
2839 | .type = QUIRK_MIDI_CH345 | ||
2840 | } | ||
2841 | }, | ||
2842 | |||
2832 | /* KeithMcMillen Stringport */ | 2843 | /* KeithMcMillen Stringport */ |
2833 | { | 2844 | { |
2834 | USB_DEVICE(0x1f38, 0x0001), | 2845 | USB_DEVICE(0x1f38, 0x0001), |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 5ca80e7d30cd..7016ad898187 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
@@ -538,6 +538,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, | |||
538 | [QUIRK_MIDI_CME] = create_any_midi_quirk, | 538 | [QUIRK_MIDI_CME] = create_any_midi_quirk, |
539 | [QUIRK_MIDI_AKAI] = create_any_midi_quirk, | 539 | [QUIRK_MIDI_AKAI] = create_any_midi_quirk, |
540 | [QUIRK_MIDI_FTDI] = create_any_midi_quirk, | 540 | [QUIRK_MIDI_FTDI] = create_any_midi_quirk, |
541 | [QUIRK_MIDI_CH345] = create_any_midi_quirk, | ||
541 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, | 542 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, |
542 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, | 543 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, |
543 | [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, | 544 | [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, |
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 15a12715bd05..b665d85555cb 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
@@ -95,6 +95,7 @@ enum quirk_type { | |||
95 | QUIRK_MIDI_AKAI, | 95 | QUIRK_MIDI_AKAI, |
96 | QUIRK_MIDI_US122L, | 96 | QUIRK_MIDI_US122L, |
97 | QUIRK_MIDI_FTDI, | 97 | QUIRK_MIDI_FTDI, |
98 | QUIRK_MIDI_CH345, | ||
98 | QUIRK_AUDIO_STANDARD_INTERFACE, | 99 | QUIRK_AUDIO_STANDARD_INTERFACE, |
99 | QUIRK_AUDIO_FIXED_ENDPOINT, | 100 | QUIRK_AUDIO_FIXED_ENDPOINT, |
100 | QUIRK_AUDIO_EDIROL_UAXX, | 101 | QUIRK_AUDIO_EDIROL_UAXX, |