Update of /cvsroot/alsa/alsa-kernel/usb
In directory usw-pr-cvs1:/tmp/cvs-serv18001
Modified Files:
usbaudio.c usbaudio.h usbmidi.c usbquirks.h
Log Message:
added the support for Yamaha and Midiman devices.
Index: usbaudio.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/usbaudio.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- usbaudio.c 4 Oct 2002 12:27:41 -0000 1.15
+++ usbaudio.c 4 Oct 2002 13:18:24 -0000 1.16
@@ -2079,7 +2079,7 @@
snd_card_t *card;
snd_usb_audio_t *chip;
- if (quirk && ifnum != quirk->ifnum)
+ if (quirk && quirk->ifnum != QUIRK_ANY_INTERFACE && ifnum != quirk->ifnum)
goto __err_val;
if (usb_set_configuration(dev, config->bConfigurationValue) < 0) {
Index: usbaudio.h
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/usbaudio.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- usbaudio.h 26 Aug 2002 16:05:43 -0000 1.2
+++ usbaudio.h 4 Oct 2002 13:18:24 -0000 1.3
@@ -58,6 +58,8 @@
#define EP_GENERAL 0x01
#define MS_GENERAL 0x01
+#define MIDI_IN_JACK 0x02
+#define MIDI_OUT_JACK 0x03
/* endpoint attributes */
#define EP_ATTR_MASK 0x0c
@@ -146,21 +148,33 @@
/*
* Information about devices with broken descriptors
*/
+#define QUIRK_ANY_INTERFACE -1
+
+#define QUIRK_MIDI_FIXED_ENDPOINT 0
+#define QUIRK_MIDI_YAMAHA 1
+#define QUIRK_MIDI_MIDIMAN 2
+
typedef struct snd_usb_audio_quirk snd_usb_audio_quirk_t;
typedef struct snd_usb_midi_endpoint_info snd_usb_midi_endpoint_info_t;
struct snd_usb_audio_quirk {
const char *vendor_name;
const char *product_name;
- int ifnum;
+ int16_t ifnum;
+ int16_t type;
+ const void *data;
+};
- /* MIDI specific */
- struct snd_usb_midi_endpoint_info {
- int16_t epnum; /* ep number, -1 autodetect */
- uint16_t out_cables; /* bitmask */
- uint16_t in_cables; /* bitmask */
- } endpoints[MIDI_MAX_ENDPOINTS];
+/* data for QUIRK_MIDI_FIXED_ENDPOINT */
+struct snd_usb_midi_endpoint_info {
+ int16_t epnum; /* ep number, -1 autodetect */
+ uint16_t out_cables; /* bitmask */
+ uint16_t in_cables; /* bitmask */
};
+
+/* for QUIRK_MIDI_YAMAHA, data is NULL */
+
+/* for QUIRK_MIDI_MIDIMAN, data is the number of ports */
/*
* USB MIDI sequencer device data
Index: usbmidi.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/usbmidi.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- usbmidi.c 3 Oct 2002 10:33:09 -0000 1.5
+++ usbmidi.c 4 Oct 2002 13:18:24 -0000 1.6
@@ -4,6 +4,10 @@
* Copyright (c) 2002 Clemens Ladisch
* All rights reserved.
*
+ * Based on the OSS usb-midi driver by NAGANO Daisuke,
+ * NetBSD's umidi driver by Takuya SHIOZAKI,
+ * the "USB Device Class Definition for MIDI Devices" by Roland
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -120,6 +124,10 @@
static void snd_usbmidi_do_output(snd_usb_midi_out_endpoint_t* ep);
+static const uint8_t snd_usbmidi_cin_length[] = {
+ 0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1
+};
+
/*
* Submits the URB, with error handling.
*/
@@ -152,9 +160,6 @@
static void snd_usbmidi_input_packet(snd_usb_midi_in_endpoint_t* ep,
uint8_t packet[4])
{
- static const uint8_t cin_length[] = {
- 0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1
- };
int cable = packet[0] >> 4;
usbmidi_in_port_t* port = &ep->ports[cable];
snd_seq_event_t ev;
@@ -163,7 +168,7 @@
return;
memset(&ev, 0, sizeof(ev));
if (snd_midi_event_encode(port->midi_event, &packet[1],
- cin_length[packet[0] & 0x0f], &ev) > 0
+ snd_usbmidi_cin_length[packet[0] & 0x0f], &ev) > 0
&& ev.type != SNDRV_SEQ_EVENT_NONE) {
ev.source.port = port->seq_port;
ev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
@@ -199,6 +204,38 @@
}
}
+/*
+ * Converts the data read from a Midiman device to standard USB MIDI packets.
+ */
+static void snd_usbmidi_in_midiman_complete(struct urb* urb)
+{
+ if (urb->status == 0) {
+ uint8_t* buffer = (uint8_t*)urb->transfer_buffer;
+ int i;
+
+ for (i = 0; i + 4 <= urb->actual_length; i += 4) {
+ if (buffer[i + 3] != 0) {
+ /*
+ * snd_usbmidi_input_packet() doesn't check the
+ * contents of the message, so we simply use
+ * some random CIN with the desired length.
+ */
+ static const uint8_t cin[4] = {
+ 0x0, 0xf, 0x2, 0x3
+ };
+ uint8_t ctl = buffer[i + 3];
+ buffer[i + 3] = buffer[i + 2];
+ buffer[i + 2] = buffer[i + 1];
+ buffer[i + 1] = buffer[i + 0];
+ buffer[i + 0] = (ctl & 0xf0) | cin[ctl & 3];
+ } else {
+ buffer[i + 0] = 0;
+ }
+ }
+ }
+ snd_usbmidi_in_urb_complete(urb);
+}
+
static void snd_usbmidi_out_urb_complete(struct urb* urb)
{
snd_usb_midi_out_endpoint_t* ep = snd_magic_cast(snd_usb_midi_out_endpoint_t,
urb->context, return);
@@ -214,6 +251,23 @@
}
/*
+ * Converts standard USB MIDI packets to what Midman devices expect.
+ */
+static void snd_usbmidi_convert_to_midiman(struct urb* urb)
+{
+ uint8_t* buffer = (uint8_t*)urb->transfer_buffer;
+ int i;
+
+ for (i = 0; i + 4 <= urb->transfer_buffer_length; i += 4) {
+ uint8_t cin = buffer[i];
+ buffer[i + 0] = buffer[i + 1];
+ buffer[i + 1] = buffer[i + 2];
+ buffer[i + 2] = buffer[i + 3];
+ buffer[i + 3] = (cin & 0xf0) | snd_usbmidi_cin_length[cin & 0x0f];
+ }
+}
+
+/*
* This is called when some data should be transferred to the device
* (after the reception of one or more sequencer events, or after completion
* of the previous transfer). ep->buffer_lock must be held.
@@ -255,6 +309,9 @@
}
if (len > 0) {
+ if (ep->umidi->quirk && ep->umidi->quirk->type == QUIRK_MIDI_MIDIMAN)
+ snd_usbmidi_convert_to_midiman(ep->urb);
+
ep->urb->dev = ep->umidi->chip->dev;
snd_usbmidi_submit_urb(ep->urb, GFP_ATOMIC);
}
@@ -528,6 +585,14 @@
return &intfd->endpoint[1];
}
+static usb_endpoint_descriptor_t* snd_usbmidi_get_midiman_int_epd(snd_usb_midi_t*
+umidi)
+{
+ usb_interface_t* intf = local_usb_ifnum_to_if(umidi->chip->dev, umidi->ifnum);
+ if (!intf)
+ return NULL;
+ return &intf->altsetting[0].endpoint[0];
+}
+
/*
* Creates an input endpoint, and initalizes input ports.
* ALSA ports are created later.
@@ -551,7 +616,10 @@
for (i = 0; i < 0x10; ++i)
ep->ports[i].seq_port = -1;
- int_epd = snd_usbmidi_get_int_epd(umidi, ep_info->epnum);
+ if (umidi->quirk && umidi->quirk->type == QUIRK_MIDI_MIDIMAN)
+ int_epd = snd_usbmidi_get_midiman_int_epd(umidi);
+ else
+ int_epd = snd_usbmidi_get_int_epd(umidi, ep_info->epnum);
ep->urb = usb_alloc_urb(0, GFP_KERNEL);
if (!ep->urb) {
@@ -697,72 +765,106 @@
}
/*
+ * Creates a sequencer port for an input/output cable pair.
+ */
+static int snd_usbmidi_create_port(snd_usb_midi_t* umidi,
+ snd_usb_midi_out_endpoint_t* out_ep,
+ snd_usb_midi_in_endpoint_t* in_ep,
+ int cable, int port_idx)
+{
+ int cap, type, port;
+ snd_seq_port_callback_t port_callback;
+ char port_name[48];
+
+ cap = 0;
+ memset(&port_callback, 0, sizeof(port_callback));
+ port_callback.owner = THIS_MODULE;
+ if (out_ep) {
+ port_callback.event_input = snd_usbmidi_event_input;
+ port_callback.private_data = &out_ep->ports[cable];
+ cap |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
+ }
+ if (in_ep) {
+ cap |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ;
+ }
+ if (out_ep && in_ep) {
+ cap |= SNDRV_SEQ_PORT_CAP_DUPLEX;
+ }
+ /* TODO: read type bits from element descriptor */
+ type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC;
+ /* TODO: read port name from jack descriptor */
+ snprintf(port_name, sizeof(port_name), "%s Port %d",
+ umidi->chip->card->shortname, port_idx);
+ port = snd_seq_event_port_attach(umidi->seq_client, &port_callback,
+ cap, type, port_name);
+ if (port < 0) {
+ snd_printk(KERN_ERR "cannot create port (error code %d)\n", port);
+ return port;
+ }
+ if (in_ep)
+ in_ep->ports[cable].seq_port = port;
+ return port;
+}
+
+/*
+ * Creates a virmidi port emulating rawmidi for the sequencer port.
+ */
+static int snd_usbmidi_create_virmidi(snd_usb_midi_t* umidi, int port,
+ int port_idx, snd_rawmidi_t** rrmidi)
+{
+ snd_rawmidi_t *rmidi;
+ snd_virmidi_dev_t *rdev;
+ int err;
+
+ *rrmidi = NULL;
+ err = snd_virmidi_new(umidi->chip->card, port_idx, &rmidi);
+ if (err < 0)
+ return err;
+ sprintf(rmidi->name, "%s MIDI %d", umidi->chip->card->shortname, port_idx);
+ rdev = snd_magic_cast(snd_virmidi_dev_t, rmidi->private_data, return -ENXIO);
+ rdev->seq_mode = SNDRV_VIRMIDI_SEQ_ATTACH;
+ rdev->client = umidi->seq_client;
+ rdev->port = port;
+ err = snd_device_register(umidi->chip->card, rmidi);
+ if (err < 0) {
+ snd_device_free(umidi->chip->card, rmidi);
+ return err;
+ }
+ *rrmidi = rmidi;
+ return 0;
+}
+
+/*
* After input and output endpoints have been initialized, create
* the ALSA port for each input/output port pair in the endpoint.
* *port_idx is the port number, which must be unique over all endpoints.
*/
-static int snd_usbmidi_create_endpoint_ports(snd_usb_midi_t* umidi, int ep, int*
port_idx,
+static int snd_usbmidi_create_endpoint_ports(snd_usb_midi_t* umidi,
+ snd_usb_midi_endpoint_t* endpoint,
+ int* port_idx,
snd_usb_midi_endpoint_info_t* ep_info)
{
- int c, err;
- int cap, type, port;
- int out, in;
- snd_seq_port_callback_t port_callback;
- char port_name[48];
+ int cable;
- for (c = 0; c < 0x10; ++c) {
- out = ep_info->out_cables & (1 << c);
- in = ep_info->in_cables & (1 << c);
+ for (cable = 0; cable < 0x10; ++cable) {
+ int port, err;
+ int out = ep_info->out_cables & (1 << cable);
+ int in = ep_info->in_cables & (1 << cable);
if (!(in || out))
continue;
- cap = 0;
- memset(&port_callback, 0, sizeof(port_callback));
- port_callback.owner = THIS_MODULE;
- if (out) {
- port_callback.event_input = snd_usbmidi_event_input;
- port_callback.private_data =
&umidi->endpoints[ep].out->ports[c];
- cap |= SNDRV_SEQ_PORT_CAP_WRITE |
- SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
- }
- if (in) {
- cap |= SNDRV_SEQ_PORT_CAP_READ |
- SNDRV_SEQ_PORT_CAP_SUBS_READ;
- }
- if (out && in) {
- cap |= SNDRV_SEQ_PORT_CAP_DUPLEX;
- }
- /* TODO: read type bits from element descriptor */
- type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC;
- /* TODO: read port name from jack descriptor */
- snprintf(port_name, sizeof(port_name), "%s Port %d",
- umidi->chip->card->shortname, *port_idx);
- port = snd_seq_event_port_attach(umidi->seq_client,
- &port_callback,
- cap, type, port_name);
- if (port < 0) {
- snd_printk(KERN_ERR "cannot create port (error code %d)\n",
port);
+
+ port = snd_usbmidi_create_port(umidi,
+ out ? endpoint->out : NULL,
+ in ? endpoint->in : NULL,
+ cable, *port_idx);
+ if (port < 0)
return port;
- }
- if (in)
- umidi->endpoints[ep].in->ports[c].seq_port = port;
if (*port_idx < SNDRV_MINOR_RAWMIDIS) {
- snd_rawmidi_t *rmidi;
- snd_virmidi_dev_t *rdev;
- err = snd_virmidi_new(umidi->chip->card, *port_idx, &rmidi);
+ err = snd_usbmidi_create_virmidi(umidi, port, *port_idx,
+ &endpoint->rmidi[cable]);
if (err < 0)
return err;
- rdev = snd_magic_cast(snd_virmidi_dev_t, rmidi->private_data,
return -ENXIO);
- strcpy(rmidi->name, port_name);
- rdev->seq_mode = SNDRV_VIRMIDI_SEQ_ATTACH;
- rdev->client = umidi->seq_client;
- rdev->port = port;
- err = snd_device_register(umidi->chip->card, rmidi);
- if (err < 0) {
- snd_device_free(umidi->chip->card, rmidi);
- return err;
- }
- umidi->endpoints[ep].rmidi[c] = rmidi;
}
++*port_idx;
}
@@ -792,8 +894,8 @@
if (err < 0)
return err;
}
- err = snd_usbmidi_create_endpoint_ports(umidi, i, &port_idx,
- &endpoints[i]);
+ err = snd_usbmidi_create_endpoint_ports(umidi, &umidi->endpoints[i],
+ &port_idx, &endpoints[i]);
if (err < 0)
return err;
printk(KERN_INFO "snd-usb-midi: endpoint %d: created %d output and %d
input ports\n",
@@ -817,8 +919,6 @@
usb_ms_endpoint_descriptor_t* ms_ep;
int i, epidx;
- memset(endpoints, 0, sizeof(*endpoints) * MIDI_MAX_ENDPOINTS);
-
intf = local_usb_ifnum_to_if(umidi->chip->dev, umidi->ifnum);
if (!intf)
return -ENXIO;
@@ -891,6 +991,120 @@
}
/*
+ * Detects the endpoints and ports of Yamaha devices.
+ */
+static int snd_usbmidi_detect_yamaha(snd_usb_midi_t* umidi,
+ snd_usb_midi_endpoint_info_t* endpoint)
+{
+ usb_interface_t* intf;
+ usb_interface_descriptor_t* intfd;
+ uint8_t* cs_desc;
+
+ intf = local_usb_ifnum_to_if(umidi->chip->dev, umidi->ifnum);
+ if (!intf)
+ return -ENOENT;
+ intfd = intf->altsetting;
+ if (intfd->bNumEndpoints < 1)
+ return -ENOENT;
+
+ for (cs_desc = intfd->extra;
+ cs_desc < intfd->extra + intfd->extralen && cs_desc[0] >= 2;
+ cs_desc += cs_desc[0]) {
+ if (cs_desc[1] == CS_AUDIO_INTERFACE) {
+ if (cs_desc[2] == MIDI_IN_JACK)
+ endpoint->in_cables = (endpoint->in_cables << 1) | 1;
+ else if (cs_desc[2] == MIDI_OUT_JACK)
+ endpoint->out_cables = (endpoint->out_cables << 1) | 1;
+ }
+ }
+ if (!endpoint->in_cables && !endpoint->out_cables)
+ return -ENOENT;
+
+ endpoint->epnum = -1;
+ return snd_usbmidi_detect_endpoint(umidi, endpoint);
+}
+
+/*
+ * Creates the endpoints and their ports for Midiman devices.
+ */
+static int snd_usbmidi_create_endpoints_midiman(snd_usb_midi_t* umidi, int ports)
+{
+ snd_usb_midi_endpoint_info_t ep_info;
+ usb_interface_t* intf;
+ usb_interface_descriptor_t* intfd;
+ usb_endpoint_descriptor_t* epd;
+ int cable, err;
+
+ intf = local_usb_ifnum_to_if(umidi->chip->dev, umidi->ifnum);
+ if (!intf)
+ return -ENOENT;
+ intfd = intf->altsetting;
+ if (intfd->bNumEndpoints < (ports > 1 ? 5 : 3)) {
+ snd_printdd(KERN_ERR "not enough endpoints\n");
+ return -ENOENT;
+ }
+
+ epd = &intfd->endpoint[0];
+ if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN ||
+ (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
+{
+ snd_printdd(KERN_ERR "endpoint[0] isn't interrupt\n");
+ return -ENXIO;
+ }
+ epd = &intfd->endpoint[2];
+ if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_OUT ||
+ (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
+USB_ENDPOINT_XFER_BULK) {
+ snd_printdd(KERN_ERR "endpoint[2] isn't bulk output\n");
+ return -ENXIO;
+ }
+ if (ports > 1) {
+ epd = &intfd->endpoint[4];
+ if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_OUT ||
+ (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
+USB_ENDPOINT_XFER_BULK) {
+ snd_printdd(KERN_ERR "endpoint[4] isn't bulk output\n");
+ return -ENXIO;
+ }
+ }
+
+ ep_info.epnum = intfd->endpoint[2].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+ ep_info.out_cables = 0x5555 & ((1 << ports) - 1);
+ err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]);
+ if (err < 0)
+ return err;
+
+ ep_info.epnum = intfd->endpoint[0].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+ ep_info.in_cables = (1 << ports) - 1;
+ err = snd_usbmidi_in_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]);
+ if (err < 0)
+ return err;
+ umidi->endpoints[0].in->urb->complete = snd_usbmidi_in_midiman_complete;
+
+ if (ports > 1) {
+ ep_info.epnum = intfd->endpoint[4].bEndpointAddress &
+USB_ENDPOINT_NUMBER_MASK;
+ ep_info.out_cables = 0xaaaa & ((1 << ports) - 1);
+ err = snd_usbmidi_out_endpoint_create(umidi, &ep_info,
+&umidi->endpoints[1]);
+ if (err < 0)
+ return err;
+ }
+
+ for (cable = 0; cable < ports; ++cable) {
+ int port = snd_usbmidi_create_port(umidi,
+ umidi->endpoints[cable & 1].out,
+ umidi->endpoints[0].in,
+ cable, cable);
+ if (port < 0)
+ return port;
+
+ if (cable < SNDRV_MINOR_RAWMIDIS) {
+ int err = snd_usbmidi_create_virmidi(umidi, port, cable,
+
+&umidi->endpoints[0].rmidi[cable]);
+ if (err < 0)
+ return err;
+ }
+ }
+ return 0;
+}
+
+/*
* Initialize the sequencer device.
*/
static int snd_usbmidi_seq_device_new(snd_seq_device_t* seq_device)
@@ -912,6 +1126,7 @@
if (umidi->seq_client < 0)
return umidi->seq_client;
+ /* set the client name */
memset(&client_info, 0, sizeof(client_info));
client_info.client = umidi->seq_client;
client_info.type = KERNEL_CLIENT;
@@ -935,17 +1150,37 @@
SNDRV_SEQ_IOCTL_SET_CLIENT_INFO,
&client_info);
- if (umidi->quirk) {
- memcpy(endpoints, umidi->quirk->endpoints, sizeof(endpoints));
- err = snd_usbmidi_detect_endpoint(umidi, &endpoints[0]);
- } else {
+ /* detect the endpoint(s) to use */
+ memset(endpoints, 0, sizeof(endpoints));
+ if (!umidi->quirk) {
err = snd_usbmidi_get_ms_info(umidi, endpoints);
+ } else {
+ switch (umidi->quirk->type) {
+ case QUIRK_MIDI_FIXED_ENDPOINT:
+ memcpy(&endpoints[0], umidi->quirk->data,
+ sizeof(snd_usb_midi_endpoint_info_t));
+ err = snd_usbmidi_detect_endpoint(umidi, &endpoints[0]);
+ break;
+ case QUIRK_MIDI_YAMAHA:
+ err = snd_usbmidi_detect_yamaha(umidi, &endpoints[0]);
+ break;
+ case QUIRK_MIDI_MIDIMAN:
+ err = 0;
+ break;
+ default:
+ snd_printd(KERN_ERR "invalid quirk type %d\n",
+umidi->quirk->type);
+ err = -ENXIO;
+ break;
+ }
}
- if (err < 0) {
- snd_usbmidi_seq_device_delete(seq_device);
- return err;
+
+ /* create ports */
+ if (err >= 0) {
+ if (umidi->quirk && umidi->quirk->type == QUIRK_MIDI_MIDIMAN)
+ err = snd_usbmidi_create_endpoints_midiman(umidi,
+(int)umidi->quirk->data);
+ else
+ err = snd_usbmidi_create_endpoints(umidi, endpoints);
}
- err = snd_usbmidi_create_endpoints(umidi, endpoints);
if (err < 0) {
snd_usbmidi_seq_device_delete(seq_device);
return err;
Index: usbquirks.h
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/usbquirks.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- usbquirks.h 26 Aug 2002 16:05:43 -0000 1.1
+++ usbquirks.h 4 Oct 2002 13:18:24 -0000 1.2
@@ -26,45 +26,143 @@
* In a perfect world, this file would be empty.
*/
+#define USB_DEVICE_VENDOR_SPEC(vend, prod) \
+ .match_flags = USB_DEVICE_ID_MATCH_VENDOR | \
+ USB_DEVICE_ID_MATCH_PRODUCT | \
+ USB_DEVICE_ID_MATCH_INT_CLASS, \
+ .idVendor = vend, \
+ .idProduct = prod, \
+ .bInterfaceClass = USB_CLASS_VENDOR_SPEC
+
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
+/* Yamaha devices */
{
- /* from NetBSD's umidi driver */
- USB_DEVICE(0x0499, 0x1000), /* Yamaha UX256 */
+ USB_DEVICE_VENDOR_SPEC(0x0499, 0x1000),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
- .ifnum = 0,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0xffff,
- .in_cables = 0x00ff
- }
- }
+ .vendor_name = "Yamaha",
+ .product_name = "UX256",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_MIDI_YAMAHA
}
},
{
- /* from Nagano Daisuke's usb-midi driver */
- USB_DEVICE(0x0499, 0x1001), /* Yamaha MU1000 */
+ USB_DEVICE_VENDOR_SPEC(0x0499, 0x1001),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
- .ifnum = 0,
- .endpoints = {
- {
- .epnum = 1,
- .out_cables = 0x000f,
- .in_cables = 0x0001
- }
- }
+ .vendor_name = "Yamaha",
+ .product_name = "MU1000",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_MIDI_YAMAHA
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0499, 0x1002),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "Yamaha",
+ .product_name = "MU2000",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_MIDI_YAMAHA
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0499, 0x1003),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "Yamaha",
+ .product_name = "MU500",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_MIDI_YAMAHA
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0499, 0x1004),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "Yamaha",
+ .product_name = "UW500",
+ .ifnum = 3,
+ .type = QUIRK_MIDI_YAMAHA
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0499, 0x1005),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "Yamaha",
+ .product_name = "MOTIF6",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_MIDI_YAMAHA
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0499, 0x1006),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "Yamaha",
+ .product_name = "MOTIF7",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_MIDI_YAMAHA
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0499, 0x1007),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "Yamaha",
+ .product_name = "MOTIF8",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_MIDI_YAMAHA
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0499, 0x1008),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "Yamaha",
+ .product_name = "UX96",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_MIDI_YAMAHA
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0499, 0x1009),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "Yamaha",
+ .product_name = "UX16",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_MIDI_YAMAHA
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0499, 0x100a),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "Yamaha",
+ .product_name = "EOS BX",
+ .ifnum = 3,
+ .type = QUIRK_MIDI_YAMAHA
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0499, 0x100e),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "Yamaha",
+ .product_name = "S08",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_MIDI_YAMAHA
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0499, 0x100f),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "Yamaha",
+ .product_name = "CLP-150",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_MIDI_YAMAHA
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0499, 0x1010),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "Yamaha",
+ .product_name = "CLP-170",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_MIDI_YAMAHA
}
},
-/*
- * I don't know whether the following Yamaha devices need entries or not:
- * 0x1002 MU2000 0x1008 UX96
- * 0x1003 MU500 0x1009 UX16
- * 0x1004 UW500 0x100e S08
- * 0x1005 MOTIF6 0x100f CLP-150
- * 0x1006 MOTIF7 0x1010 CLP-170
- * 0x1007 MOTIF8
- */
/*
* Once upon a time people thought, "Wouldn't it be nice if there was a
@@ -79,259 +177,316 @@
* class-specific descriptors.
*/
{
- USB_DEVICE(0x0582, 0x0000),
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x0000),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
.product_name = "UA-100",
.ifnum = 2,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0x0007,
- .in_cables = 0x0007
- }
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .epnum = -1,
+ .out_cables = 0x0007,
+ .in_cables = 0x0007
}
}
},
{
- USB_DEVICE(0x0582, 0x0002),
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x0002),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "UM-4",
.ifnum = 2,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0x000f,
- .in_cables = 0x000f
- }
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .epnum = -1,
+ .out_cables = 0x000f,
+ .in_cables = 0x000f
}
}
},
{
- USB_DEVICE(0x0582, 0x0003),
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x0003),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
.product_name = "SC-8850",
.ifnum = 2,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0x003f,
- .in_cables = 0x003f
- }
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .epnum = -1,
+ .out_cables = 0x003f,
+ .in_cables = 0x003f
}
}
},
{
- USB_DEVICE(0x0582, 0x0004),
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x0004),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
.product_name = "U-8",
.ifnum = 2,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0x0003,
- .in_cables = 0x0003
- }
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .epnum = -1,
+ .out_cables = 0x0003,
+ .in_cables = 0x0003
}
}
},
{
- USB_DEVICE(0x0582, 0x0005),
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x0005),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "UM-2",
.ifnum = 2,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0x0003,
- .in_cables = 0x0003
- }
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .epnum = -1,
+ .out_cables = 0x0003,
+ .in_cables = 0x0003
}
}
},
{
- USB_DEVICE(0x0582, 0x0007),
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x0007),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
.product_name = "SC-8820",
.ifnum = 2,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0x0013,
- .in_cables = 0x0013
- }
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .epnum = -1,
+ .out_cables = 0x0013,
+ .in_cables = 0x0013
}
}
},
{
- USB_DEVICE(0x0582, 0x0008),
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x0008),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
.product_name = "PC-300",
.ifnum = 2,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .epnum = -1,
+ .out_cables = 0x0001,
+ .in_cables = 0x0001
}
}
},
{
- USB_DEVICE(0x0582, 0x0009),
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x0009),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "UM-1",
.ifnum = 2,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .epnum = -1,
+ .out_cables = 0x0001,
+ .in_cables = 0x0001
}
}
},
{
- USB_DEVICE(0x0582, 0x000b),
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x000b),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
.product_name = "SK-500",
.ifnum = 2,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0x0013,
- .in_cables = 0x0013
- }
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .epnum = -1,
+ .out_cables = 0x0013,
+ .in_cables = 0x0013
}
}
},
{
- USB_DEVICE(0x0582, 0x000c),
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x000c),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
.product_name = "SC-D70",
.ifnum = 2,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0x0007,
- .in_cables = 0x0007
- }
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .epnum = -1,
+ .out_cables = 0x0007,
+ .in_cables = 0x0007
}
}
},
{
- USB_DEVICE(0x0582, 0x0012),
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x0012),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
.product_name = "XV-5050",
.ifnum = 0,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .epnum = -1,
+ .out_cables = 0x0001,
+ .in_cables = 0x0001
}
}
},
{
- USB_DEVICE(0x0582, 0x0014),
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x0014),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "UM-880",
.ifnum = 0,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0x01ff,
- .in_cables = 0x01ff
- }
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .epnum = -1,
+ .out_cables = 0x01ff,
+ .in_cables = 0x01ff
}
}
},
{
- USB_DEVICE(0x0582, 0x0016),
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x0016),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "SD-90",
.ifnum = 2,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0x000f,
- .in_cables = 0x000f
- }
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .epnum = -1,
+ .out_cables = 0x000f,
+ .in_cables = 0x000f
}
}
},
{
- USB_DEVICE(0x0582, 0x0023),
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x0023),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "UM-550",
.ifnum = 0,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0x003f,
- .in_cables = 0x003f
- }
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .epnum = -1,
+ .out_cables = 0x003f,
+ .in_cables = 0x003f
}
}
},
{
- USB_DEVICE(0x0582, 0x0027),
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x0027),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "SD-20",
.ifnum = 0,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0x0003,
- .in_cables = 0x0007
- }
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .epnum = -1,
+ .out_cables = 0x0003,
+ .in_cables = 0x0007
}
}
},
{
- USB_DEVICE(0x0582, 0x0029),
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x0029),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "SD-80",
.ifnum = 0,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0x000f,
- .in_cables = 0x000f
- }
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .epnum = -1,
+ .out_cables = 0x000f,
+ .in_cables = 0x000f
}
}
},
{
- USB_DEVICE(0x0582, 0x002b),
+ USB_DEVICE_VENDOR_SPEC(0x0582, 0x002b),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "UA-700",
.ifnum = 3,
- .endpoints = {
- {
- .epnum = -1,
- .out_cables = 0x0003,
- .in_cables = 0x0003
- }
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const snd_usb_midi_endpoint_info_t) {
+ .epnum = -1,
+ .out_cables = 0x0003,
+ .in_cables = 0x0003
}
}
},
+/* Midiman/M-Audio devices */
+{
+ USB_DEVICE_VENDOR_SPEC(0x0763, 0x1002),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "M-Audio",
+ .product_name = "MidiSport 2x2",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_MIDI_MIDIMAN,
+ .data = (void*) 2
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0763, 0x1011),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "M-Audio",
+ .product_name = "MidiSport 1x1",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_MIDI_MIDIMAN,
+ .data = (void*) 1
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0763, 0x1015),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "M-Audio",
+ .product_name = "Keystation",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_MIDI_MIDIMAN,
+ .data = (void*) 1
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0763, 0x1021),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "M-Audio",
+ .product_name = "MidiSport 4x4",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_MIDI_MIDIMAN,
+ .data = (void*) 4
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0763, 0x1033),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "M-Audio",
+ .product_name = "MidiSport 8x8",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_MIDI_MIDIMAN,
+ .data = (void*) 9
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0763, 0x2001),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "M-Audio",
+ .product_name = "Quattro",
+ .ifnum = 9,
+ .type = QUIRK_MIDI_MIDIMAN,
+ .data = (void*) 1
+ }
+},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0763, 0x2003),
+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+ .vendor_name = "M-Audio",
+ .product_name = "AudioPhile",
+ .ifnum = 9,
+ .type = QUIRK_MIDI_MIDIMAN,
+ .data = (void*) 1
+ }
+},
+
#endif /* CONFIG_SND_SEQUENCER(_MODULE) */
+
+#undef USB_DEVICE_VENDOR_SPEC
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog