|
@@ -66,6 +66,28 @@ static int us122l_create_usbmidi(struct snd_card *card)
|
|
|
iface, &quirk);
|
|
|
}
|
|
|
|
|
|
+static int us144_create_usbmidi(struct snd_card *card)
|
|
|
+{
|
|
|
+ static struct snd_usb_midi_endpoint_info quirk_data = {
|
|
|
+ .out_ep = 4,
|
|
|
+ .in_ep = 3,
|
|
|
+ .out_cables = 0x001,
|
|
|
+ .in_cables = 0x001
|
|
|
+ };
|
|
|
+ static struct snd_usb_audio_quirk quirk = {
|
|
|
+ .vendor_name = "US144",
|
|
|
+ .product_name = NAME_ALLCAPS,
|
|
|
+ .ifnum = 0,
|
|
|
+ .type = QUIRK_MIDI_US122L,
|
|
|
+ .data = &quirk_data
|
|
|
+ };
|
|
|
+ struct usb_device *dev = US122L(card)->chip.dev;
|
|
|
+ struct usb_interface *iface = usb_ifnum_to_if(dev, 0);
|
|
|
+
|
|
|
+ return snd_usb_create_midi_interface(&US122L(card)->chip,
|
|
|
+ iface, &quirk);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Wrapper for usb_control_msg().
|
|
|
* Allocates a temp buffer to prevent dmaing from/to the stack.
|
|
@@ -171,6 +193,11 @@ static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
|
|
|
|
|
|
if (!us122l->first)
|
|
|
us122l->first = file;
|
|
|
+
|
|
|
+ if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) {
|
|
|
+ iface = usb_ifnum_to_if(us122l->chip.dev, 0);
|
|
|
+ usb_autopm_get_interface(iface);
|
|
|
+ }
|
|
|
iface = usb_ifnum_to_if(us122l->chip.dev, 1);
|
|
|
usb_autopm_get_interface(iface);
|
|
|
return 0;
|
|
@@ -179,8 +206,14 @@ static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
|
|
|
static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file)
|
|
|
{
|
|
|
struct us122l *us122l = hw->private_data;
|
|
|
- struct usb_interface *iface = usb_ifnum_to_if(us122l->chip.dev, 1);
|
|
|
+ struct usb_interface *iface;
|
|
|
snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
|
|
|
+
|
|
|
+ if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) {
|
|
|
+ iface = usb_ifnum_to_if(us122l->chip.dev, 0);
|
|
|
+ usb_autopm_put_interface(iface);
|
|
|
+ }
|
|
|
+ iface = usb_ifnum_to_if(us122l->chip.dev, 1);
|
|
|
usb_autopm_put_interface(iface);
|
|
|
if (us122l->first == file)
|
|
|
us122l->first = NULL;
|
|
@@ -443,6 +476,13 @@ static bool us122l_create_card(struct snd_card *card)
|
|
|
int err;
|
|
|
struct us122l *us122l = US122L(card);
|
|
|
|
|
|
+ if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) {
|
|
|
+ err = usb_set_interface(us122l->chip.dev, 0, 1);
|
|
|
+ if (err) {
|
|
|
+ snd_printk(KERN_ERR "usb_set_interface error \n");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
err = usb_set_interface(us122l->chip.dev, 1, 1);
|
|
|
if (err) {
|
|
|
snd_printk(KERN_ERR "usb_set_interface error \n");
|
|
@@ -455,7 +495,10 @@ static bool us122l_create_card(struct snd_card *card)
|
|
|
if (!us122l_start(us122l, 44100, 256))
|
|
|
return false;
|
|
|
|
|
|
- err = us122l_create_usbmidi(card);
|
|
|
+ if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144)
|
|
|
+ err = us144_create_usbmidi(card);
|
|
|
+ else
|
|
|
+ err = us122l_create_usbmidi(card);
|
|
|
if (err < 0) {
|
|
|
snd_printk(KERN_ERR "us122l_create_usbmidi error %i \n", err);
|
|
|
us122l_stop(us122l);
|
|
@@ -542,6 +585,7 @@ static int us122l_usb_probe(struct usb_interface *intf,
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+ usb_get_intf(usb_ifnum_to_if(device, 0));
|
|
|
usb_get_dev(device);
|
|
|
*cardp = card;
|
|
|
return 0;
|
|
@@ -550,9 +594,16 @@ static int us122l_usb_probe(struct usb_interface *intf,
|
|
|
static int snd_us122l_probe(struct usb_interface *intf,
|
|
|
const struct usb_device_id *id)
|
|
|
{
|
|
|
+ struct usb_device *device = interface_to_usbdev(intf);
|
|
|
struct snd_card *card;
|
|
|
int err;
|
|
|
|
|
|
+ if (device->descriptor.idProduct == USB_ID_US144
|
|
|
+ && device->speed == USB_SPEED_HIGH) {
|
|
|
+ snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n");
|
|
|
+ return -ENOENT;
|
|
|
+ }
|
|
|
+
|
|
|
snd_printdd(KERN_DEBUG"%p:%i\n",
|
|
|
intf, intf->cur_altsetting->desc.bInterfaceNumber);
|
|
|
if (intf->cur_altsetting->desc.bInterfaceNumber != 1)
|
|
@@ -591,7 +642,8 @@ static void snd_us122l_disconnect(struct usb_interface *intf)
|
|
|
snd_usbmidi_disconnect(p);
|
|
|
}
|
|
|
|
|
|
- usb_put_intf(intf);
|
|
|
+ usb_put_intf(usb_ifnum_to_if(us122l->chip.dev, 0));
|
|
|
+ usb_put_intf(usb_ifnum_to_if(us122l->chip.dev, 1));
|
|
|
usb_put_dev(us122l->chip.dev);
|
|
|
|
|
|
while (atomic_read(&us122l->mmap_count))
|
|
@@ -642,6 +694,13 @@ static int snd_us122l_resume(struct usb_interface *intf)
|
|
|
|
|
|
mutex_lock(&us122l->mutex);
|
|
|
/* needed, doesn't restart without: */
|
|
|
+ if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) {
|
|
|
+ err = usb_set_interface(us122l->chip.dev, 0, 1);
|
|
|
+ if (err) {
|
|
|
+ snd_printk(KERN_ERR "usb_set_interface error \n");
|
|
|
+ goto unlock;
|
|
|
+ }
|
|
|
+ }
|
|
|
err = usb_set_interface(us122l->chip.dev, 1, 1);
|
|
|
if (err) {
|
|
|
snd_printk(KERN_ERR "usb_set_interface error \n");
|
|
@@ -675,11 +734,11 @@ static struct usb_device_id snd_us122l_usb_id_table[] = {
|
|
|
.idVendor = 0x0644,
|
|
|
.idProduct = USB_ID_US122L
|
|
|
},
|
|
|
-/* { */ /* US-144 maybe works when @USB1.1. Untested. */
|
|
|
-/* .match_flags = USB_DEVICE_ID_MATCH_DEVICE, */
|
|
|
-/* .idVendor = 0x0644, */
|
|
|
-/* .idProduct = USB_ID_US144 */
|
|
|
-/* }, */
|
|
|
+ { /* US-144 only works at USB1.1! Disable module ehci-hcd. */
|
|
|
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
|
|
|
+ .idVendor = 0x0644,
|
|
|
+ .idProduct = USB_ID_US144
|
|
|
+ },
|
|
|
{ /* terminator */ }
|
|
|
};
|
|
|
|