aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-27 14:59:02 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-27 14:59:02 -0500
commit172473407962df19d0344fcdba90b02d16fe98d0 (patch)
tree756bb9c189423dfa155ee6a17f005cb649a8ed56 /sound
parent5d8686276a5acc0a3d8055028a6e9d990c9c4fbd (diff)
parent0c25ad80408e95e0a4fbaf0056950206e95f726f (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.c4
-rw-r--r--sound/pci/hda/hda_intel.c7
-rw-r--r--sound/pci/hda/patch_hdmi.c3
-rw-r--r--sound/pci/hda/patch_realtek.c23
-rw-r--r--sound/pci/hda/patch_sigmatel.c45
-rw-r--r--sound/usb/midi.c46
-rw-r--r--sound/usb/quirks-table.h11
-rw-r--r--sound/usb/quirks.c1
-rw-r--r--sound/usb/usbaudio.h1
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>");
12MODULE_LICENSE("GPL v2"); 12MODULE_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
19static int dice_interface_check(struct fw_unit *unit) 21static 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
1764static void alc889_fixup_coef(struct hda_codec *codec, 1765static 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
1921static void alc_fixup_bass_chmap(struct hda_codec *codec, 1922static 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);
1924static void alc_fixup_disable_aamix(struct hda_codec *codec,
1925 const struct hda_fixup *fix, int action);
1923 1926
1924static const struct hda_fixup alc882_fixups[] = { 1927static 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
2156static const struct snd_pci_quirk alc882_fixup_tbl[] = { 2163static 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
4592static const struct hda_fixup alc269_fixups[] = { 4601static 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
5172static const struct snd_pci_quirk alc269_fixup_tbl[] = { 5192static 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
3113static 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
3123static 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
3114static void stac92hd71bxx_fixup_hp(struct hda_codec *codec, 3137static 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 */
476static 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
698static 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,