Commit f257f1d8 authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'for-linus' into for-next

parents 8005c49d a91e627e
...@@ -12,9 +12,11 @@ MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); ...@@ -12,9 +12,11 @@ MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
#define OUI_WEISS 0x001c6a #define OUI_WEISS 0x001c6a
#define OUI_LOUD 0x000ff2
#define DICE_CATEGORY_ID 0x04 #define DICE_CATEGORY_ID 0x04
#define WEISS_CATEGORY_ID 0x00 #define WEISS_CATEGORY_ID 0x00
#define LOUD_CATEGORY_ID 0x10
static int dice_interface_check(struct fw_unit *unit) static int dice_interface_check(struct fw_unit *unit)
{ {
...@@ -57,6 +59,8 @@ static int dice_interface_check(struct fw_unit *unit) ...@@ -57,6 +59,8 @@ static int dice_interface_check(struct fw_unit *unit)
} }
if (vendor == OUI_WEISS) if (vendor == OUI_WEISS)
category = WEISS_CATEGORY_ID; category = WEISS_CATEGORY_ID;
else if (vendor == OUI_LOUD)
category = LOUD_CATEGORY_ID;
else else
category = DICE_CATEGORY_ID; category = DICE_CATEGORY_ID;
if (device->config_rom[3] != ((vendor << 8) | category) || if (device->config_rom[3] != ((vendor << 8) | category) ||
......
...@@ -5182,6 +5182,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -5182,6 +5182,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS), SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS), SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X), SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X), SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER), SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
......
...@@ -174,6 +174,8 @@ struct snd_usb_midi_in_endpoint { ...@@ -174,6 +174,8 @@ struct snd_usb_midi_in_endpoint {
u8 running_status_length; u8 running_status_length;
} ports[0x10]; } ports[0x10];
u8 seen_f5; u8 seen_f5;
bool in_sysex;
u8 last_cin;
u8 error_resubmit; u8 error_resubmit;
int current_port; int current_port;
}; };
...@@ -467,6 +469,39 @@ static void snd_usbmidi_maudio_broken_running_status_input( ...@@ -467,6 +469,39 @@ static void snd_usbmidi_maudio_broken_running_status_input(
} }
} }
/*
* QinHeng CH345 is buggy: every second packet inside a SysEx has not CIN 4
* but the previously seen CIN, but still with three data bytes.
*/
static void ch345_broken_sysex_input(struct snd_usb_midi_in_endpoint *ep,
uint8_t *buffer, int buffer_length)
{
unsigned int i, cin, length;
for (i = 0; i + 3 < buffer_length; i += 4) {
if (buffer[i] == 0 && i > 0)
break;
cin = buffer[i] & 0x0f;
if (ep->in_sysex &&
cin == ep->last_cin &&
(buffer[i + 1 + (cin == 0x6)] & 0x80) == 0)
cin = 0x4;
#if 0
if (buffer[i + 1] == 0x90) {
/*
* Either a corrupted running status or a real note-on
* message; impossible to detect reliably.
*/
}
#endif
length = snd_usbmidi_cin_length[cin];
snd_usbmidi_input_data(ep, 0, &buffer[i + 1], length);
ep->in_sysex = cin == 0x4;
if (!ep->in_sysex)
ep->last_cin = cin;
}
}
/* /*
* CME protocol: like the standard protocol, but SysEx commands are sent as a * CME protocol: like the standard protocol, but SysEx commands are sent as a
* single USB packet preceded by a 0x0F byte. * single USB packet preceded by a 0x0F byte.
...@@ -660,6 +695,12 @@ static struct usb_protocol_ops snd_usbmidi_cme_ops = { ...@@ -660,6 +695,12 @@ static struct usb_protocol_ops snd_usbmidi_cme_ops = {
.output_packet = snd_usbmidi_output_standard_packet, .output_packet = snd_usbmidi_output_standard_packet,
}; };
static struct usb_protocol_ops snd_usbmidi_ch345_broken_sysex_ops = {
.input = ch345_broken_sysex_input,
.output = snd_usbmidi_standard_output,
.output_packet = snd_usbmidi_output_standard_packet,
};
/* /*
* AKAI MPD16 protocol: * AKAI MPD16 protocol:
* *
...@@ -1341,6 +1382,7 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi, ...@@ -1341,6 +1382,7 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi,
* Various chips declare a packet size larger than 4 bytes, but * Various chips declare a packet size larger than 4 bytes, but
* do not actually work with larger packets: * do not actually work with larger packets:
*/ */
case USB_ID(0x0a67, 0x5011): /* Medeli DD305 */
case USB_ID(0x0a92, 0x1020): /* ESI M4U */ case USB_ID(0x0a92, 0x1020): /* ESI M4U */
case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */ case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */
case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */ case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */
...@@ -2376,6 +2418,10 @@ int snd_usbmidi_create(struct snd_card *card, ...@@ -2376,6 +2418,10 @@ int snd_usbmidi_create(struct snd_card *card,
if (err < 0) if (err < 0)
break; break;
err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
break;
case QUIRK_MIDI_CH345:
umidi->usb_protocol_ops = &snd_usbmidi_ch345_broken_sysex_ops;
err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
break; break;
default: default:
......
...@@ -2829,6 +2829,17 @@ YAMAHA_DEVICE(0x7010, "UB99"), ...@@ -2829,6 +2829,17 @@ YAMAHA_DEVICE(0x7010, "UB99"),
.idProduct = 0x1020, .idProduct = 0x1020,
}, },
/* QinHeng devices */
{
USB_DEVICE(0x1a86, 0x752d),
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
.vendor_name = "QinHeng",
.product_name = "CH345",
.ifnum = 1,
.type = QUIRK_MIDI_CH345
}
},
/* KeithMcMillen Stringport */ /* KeithMcMillen Stringport */
{ {
USB_DEVICE(0x1f38, 0x0001), USB_DEVICE(0x1f38, 0x0001),
......
...@@ -538,6 +538,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, ...@@ -538,6 +538,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
[QUIRK_MIDI_CME] = create_any_midi_quirk, [QUIRK_MIDI_CME] = create_any_midi_quirk,
[QUIRK_MIDI_AKAI] = create_any_midi_quirk, [QUIRK_MIDI_AKAI] = create_any_midi_quirk,
[QUIRK_MIDI_FTDI] = create_any_midi_quirk, [QUIRK_MIDI_FTDI] = create_any_midi_quirk,
[QUIRK_MIDI_CH345] = create_any_midi_quirk,
[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
[QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
[QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
......
...@@ -95,6 +95,7 @@ enum quirk_type { ...@@ -95,6 +95,7 @@ enum quirk_type {
QUIRK_MIDI_AKAI, QUIRK_MIDI_AKAI,
QUIRK_MIDI_US122L, QUIRK_MIDI_US122L,
QUIRK_MIDI_FTDI, QUIRK_MIDI_FTDI,
QUIRK_MIDI_CH345,
QUIRK_AUDIO_STANDARD_INTERFACE, QUIRK_AUDIO_STANDARD_INTERFACE,
QUIRK_AUDIO_FIXED_ENDPOINT, QUIRK_AUDIO_FIXED_ENDPOINT,
QUIRK_AUDIO_EDIROL_UAXX, QUIRK_AUDIO_EDIROL_UAXX,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment