Merge branch 'for-linus' into for-next
This commit is contained in:
commit
f257f1d848
6 changed files with 64 additions and 0 deletions
|
@ -12,9 +12,11 @@ MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
|
|||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
#define OUI_WEISS 0x001c6a
|
||||
#define OUI_LOUD 0x000ff2
|
||||
|
||||
#define DICE_CATEGORY_ID 0x04
|
||||
#define WEISS_CATEGORY_ID 0x00
|
||||
#define LOUD_CATEGORY_ID 0x10
|
||||
|
||||
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)
|
||||
category = WEISS_CATEGORY_ID;
|
||||
else if (vendor == OUI_LOUD)
|
||||
category = LOUD_CATEGORY_ID;
|
||||
else
|
||||
category = DICE_CATEGORY_ID;
|
||||
if (device->config_rom[3] != ((vendor << 8) | category) ||
|
||||
|
|
|
@ -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(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, 0x05bd, "Dell Latitude E6440", 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, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
|
||||
|
|
|
@ -174,6 +174,8 @@ struct snd_usb_midi_in_endpoint {
|
|||
u8 running_status_length;
|
||||
} ports[0x10];
|
||||
u8 seen_f5;
|
||||
bool in_sysex;
|
||||
u8 last_cin;
|
||||
u8 error_resubmit;
|
||||
int current_port;
|
||||
};
|
||||
|
@ -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
|
||||
* single USB packet preceded by a 0x0F byte.
|
||||
|
@ -660,6 +695,12 @@ static struct usb_protocol_ops snd_usbmidi_cme_ops = {
|
|||
.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:
|
||||
*
|
||||
|
@ -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
|
||||
* do not actually work with larger packets:
|
||||
*/
|
||||
case USB_ID(0x0a67, 0x5011): /* Medeli DD305 */
|
||||
case USB_ID(0x0a92, 0x1020): /* ESI M4U */
|
||||
case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */
|
||||
case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */
|
||||
|
@ -2376,6 +2418,10 @@ int snd_usbmidi_create(struct snd_card *card,
|
|||
if (err < 0)
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -2829,6 +2829,17 @@ YAMAHA_DEVICE(0x7010, "UB99"),
|
|||
.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 */
|
||||
{
|
||||
USB_DEVICE(0x1f38, 0x0001),
|
||||
|
|
|
@ -538,6 +538,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
|
|||
[QUIRK_MIDI_CME] = create_any_midi_quirk,
|
||||
[QUIRK_MIDI_AKAI] = 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_FIXED_ENDPOINT] = create_fixed_stream_quirk,
|
||||
[QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
|
||||
|
|
|
@ -95,6 +95,7 @@ enum quirk_type {
|
|||
QUIRK_MIDI_AKAI,
|
||||
QUIRK_MIDI_US122L,
|
||||
QUIRK_MIDI_FTDI,
|
||||
QUIRK_MIDI_CH345,
|
||||
QUIRK_AUDIO_STANDARD_INTERFACE,
|
||||
QUIRK_AUDIO_FIXED_ENDPOINT,
|
||||
QUIRK_AUDIO_EDIROL_UAXX,
|
||||
|
|
Loading…
Reference in a new issue