aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/usx2y/us122l.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/usx2y/us122l.c')
-rw-r--r--sound/usb/usx2y/us122l.c75
1 files changed, 67 insertions, 8 deletions
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index fd44946ce4b3..6c7b64a23c13 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -66,6 +66,28 @@ static int us122l_create_usbmidi(struct snd_card *card)
66 iface, &quirk); 66 iface, &quirk);
67} 67}
68 68
69static int us144_create_usbmidi(struct snd_card *card)
70{
71 static struct snd_usb_midi_endpoint_info quirk_data = {
72 .out_ep = 4,
73 .in_ep = 3,
74 .out_cables = 0x001,
75 .in_cables = 0x001
76 };
77 static struct snd_usb_audio_quirk quirk = {
78 .vendor_name = "US144",
79 .product_name = NAME_ALLCAPS,
80 .ifnum = 0,
81 .type = QUIRK_MIDI_US122L,
82 .data = &quirk_data
83 };
84 struct usb_device *dev = US122L(card)->chip.dev;
85 struct usb_interface *iface = usb_ifnum_to_if(dev, 0);
86
87 return snd_usb_create_midi_interface(&US122L(card)->chip,
88 iface, &quirk);
89}
90
69/* 91/*
70 * Wrapper for usb_control_msg(). 92 * Wrapper for usb_control_msg().
71 * Allocates a temp buffer to prevent dmaing from/to the stack. 93 * 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)
171 193
172 if (!us122l->first) 194 if (!us122l->first)
173 us122l->first = file; 195 us122l->first = file;
196
197 if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) {
198 iface = usb_ifnum_to_if(us122l->chip.dev, 0);
199 usb_autopm_get_interface(iface);
200 }
174 iface = usb_ifnum_to_if(us122l->chip.dev, 1); 201 iface = usb_ifnum_to_if(us122l->chip.dev, 1);
175 usb_autopm_get_interface(iface); 202 usb_autopm_get_interface(iface);
176 return 0; 203 return 0;
@@ -179,8 +206,14 @@ static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
179static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file) 206static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file)
180{ 207{
181 struct us122l *us122l = hw->private_data; 208 struct us122l *us122l = hw->private_data;
182 struct usb_interface *iface = usb_ifnum_to_if(us122l->chip.dev, 1); 209 struct usb_interface *iface;
183 snd_printdd(KERN_DEBUG "%p %p\n", hw, file); 210 snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
211
212 if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) {
213 iface = usb_ifnum_to_if(us122l->chip.dev, 0);
214 usb_autopm_put_interface(iface);
215 }
216 iface = usb_ifnum_to_if(us122l->chip.dev, 1);
184 usb_autopm_put_interface(iface); 217 usb_autopm_put_interface(iface);
185 if (us122l->first == file) 218 if (us122l->first == file)
186 us122l->first = NULL; 219 us122l->first = NULL;
@@ -443,6 +476,13 @@ static bool us122l_create_card(struct snd_card *card)
443 int err; 476 int err;
444 struct us122l *us122l = US122L(card); 477 struct us122l *us122l = US122L(card);
445 478
479 if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) {
480 err = usb_set_interface(us122l->chip.dev, 0, 1);
481 if (err) {
482 snd_printk(KERN_ERR "usb_set_interface error \n");
483 return false;
484 }
485 }
446 err = usb_set_interface(us122l->chip.dev, 1, 1); 486 err = usb_set_interface(us122l->chip.dev, 1, 1);
447 if (err) { 487 if (err) {
448 snd_printk(KERN_ERR "usb_set_interface error \n"); 488 snd_printk(KERN_ERR "usb_set_interface error \n");
@@ -455,7 +495,10 @@ static bool us122l_create_card(struct snd_card *card)
455 if (!us122l_start(us122l, 44100, 256)) 495 if (!us122l_start(us122l, 44100, 256))
456 return false; 496 return false;
457 497
458 err = us122l_create_usbmidi(card); 498 if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144)
499 err = us144_create_usbmidi(card);
500 else
501 err = us122l_create_usbmidi(card);
459 if (err < 0) { 502 if (err < 0) {
460 snd_printk(KERN_ERR "us122l_create_usbmidi error %i \n", err); 503 snd_printk(KERN_ERR "us122l_create_usbmidi error %i \n", err);
461 us122l_stop(us122l); 504 us122l_stop(us122l);
@@ -542,6 +585,7 @@ static int us122l_usb_probe(struct usb_interface *intf,
542 return err; 585 return err;
543 } 586 }
544 587
588 usb_get_intf(usb_ifnum_to_if(device, 0));
545 usb_get_dev(device); 589 usb_get_dev(device);
546 *cardp = card; 590 *cardp = card;
547 return 0; 591 return 0;
@@ -550,9 +594,16 @@ static int us122l_usb_probe(struct usb_interface *intf,
550static int snd_us122l_probe(struct usb_interface *intf, 594static int snd_us122l_probe(struct usb_interface *intf,
551 const struct usb_device_id *id) 595 const struct usb_device_id *id)
552{ 596{
597 struct usb_device *device = interface_to_usbdev(intf);
553 struct snd_card *card; 598 struct snd_card *card;
554 int err; 599 int err;
555 600
601 if (device->descriptor.idProduct == USB_ID_US144
602 && device->speed == USB_SPEED_HIGH) {
603 snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n");
604 return -ENOENT;
605 }
606
556 snd_printdd(KERN_DEBUG"%p:%i\n", 607 snd_printdd(KERN_DEBUG"%p:%i\n",
557 intf, intf->cur_altsetting->desc.bInterfaceNumber); 608 intf, intf->cur_altsetting->desc.bInterfaceNumber);
558 if (intf->cur_altsetting->desc.bInterfaceNumber != 1) 609 if (intf->cur_altsetting->desc.bInterfaceNumber != 1)
@@ -591,7 +642,8 @@ static void snd_us122l_disconnect(struct usb_interface *intf)
591 snd_usbmidi_disconnect(p); 642 snd_usbmidi_disconnect(p);
592 } 643 }
593 644
594 usb_put_intf(intf); 645 usb_put_intf(usb_ifnum_to_if(us122l->chip.dev, 0));
646 usb_put_intf(usb_ifnum_to_if(us122l->chip.dev, 1));
595 usb_put_dev(us122l->chip.dev); 647 usb_put_dev(us122l->chip.dev);
596 648
597 while (atomic_read(&us122l->mmap_count)) 649 while (atomic_read(&us122l->mmap_count))
@@ -642,6 +694,13 @@ static int snd_us122l_resume(struct usb_interface *intf)
642 694
643 mutex_lock(&us122l->mutex); 695 mutex_lock(&us122l->mutex);
644 /* needed, doesn't restart without: */ 696 /* needed, doesn't restart without: */
697 if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) {
698 err = usb_set_interface(us122l->chip.dev, 0, 1);
699 if (err) {
700 snd_printk(KERN_ERR "usb_set_interface error \n");
701 goto unlock;
702 }
703 }
645 err = usb_set_interface(us122l->chip.dev, 1, 1); 704 err = usb_set_interface(us122l->chip.dev, 1, 1);
646 if (err) { 705 if (err) {
647 snd_printk(KERN_ERR "usb_set_interface error \n"); 706 snd_printk(KERN_ERR "usb_set_interface error \n");
@@ -675,11 +734,11 @@ static struct usb_device_id snd_us122l_usb_id_table[] = {
675 .idVendor = 0x0644, 734 .idVendor = 0x0644,
676 .idProduct = USB_ID_US122L 735 .idProduct = USB_ID_US122L
677 }, 736 },
678/* { */ /* US-144 maybe works when @USB1.1. Untested. */ 737 { /* US-144 only works at USB1.1! Disable module ehci-hcd. */
679/* .match_flags = USB_DEVICE_ID_MATCH_DEVICE, */ 738 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
680/* .idVendor = 0x0644, */ 739 .idVendor = 0x0644,
681/* .idProduct = USB_ID_US144 */ 740 .idProduct = USB_ID_US144
682/* }, */ 741 },
683 { /* terminator */ } 742 { /* terminator */ }
684}; 743};
685 744