diff options
Diffstat (limited to 'sound/usb/usx2y/us122l.c')
-rw-r--r-- | sound/usb/usx2y/us122l.c | 75 |
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 | ||
69 | static 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) | |||
179 | static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file) | 206 | static 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, | |||
550 | static int snd_us122l_probe(struct usb_interface *intf, | 594 | static 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 | ||