diff options
Diffstat (limited to 'sound/usb/usx2y/us122l.c')
-rw-r--r-- | sound/usb/usx2y/us122l.c | 135 |
1 files changed, 96 insertions, 39 deletions
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c index 99f33766cd51..f71cd28eca6b 100644 --- a/sound/usb/usx2y/us122l.c +++ b/sound/usb/usx2y/us122l.c | |||
@@ -59,11 +59,33 @@ static int us122l_create_usbmidi(struct snd_card *card) | |||
59 | .type = QUIRK_MIDI_US122L, | 59 | .type = QUIRK_MIDI_US122L, |
60 | .data = &quirk_data | 60 | .data = &quirk_data |
61 | }; | 61 | }; |
62 | struct usb_device *dev = US122L(card)->chip.dev; | 62 | struct usb_device *dev = US122L(card)->dev; |
63 | struct usb_interface *iface = usb_ifnum_to_if(dev, 1); | 63 | struct usb_interface *iface = usb_ifnum_to_if(dev, 1); |
64 | 64 | ||
65 | return snd_usb_create_midi_interface(&US122L(card)->chip, | 65 | return snd_usbmidi_create(card, iface, |
66 | iface, &quirk); | 66 | &US122L(card)->midi_list, &quirk); |
67 | } | ||
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)->dev; | ||
85 | struct usb_interface *iface = usb_ifnum_to_if(dev, 0); | ||
86 | |||
87 | return snd_usbmidi_create(card, iface, | ||
88 | &US122L(card)->midi_list, &quirk); | ||
67 | } | 89 | } |
68 | 90 | ||
69 | /* | 91 | /* |
@@ -171,7 +193,12 @@ 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; |
174 | iface = usb_ifnum_to_if(us122l->chip.dev, 1); | 196 | |
197 | if (us122l->dev->descriptor.idProduct == USB_ID_US144) { | ||
198 | iface = usb_ifnum_to_if(us122l->dev, 0); | ||
199 | usb_autopm_get_interface(iface); | ||
200 | } | ||
201 | iface = usb_ifnum_to_if(us122l->dev, 1); | ||
175 | usb_autopm_get_interface(iface); | 202 | usb_autopm_get_interface(iface); |
176 | return 0; | 203 | return 0; |
177 | } | 204 | } |
@@ -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->dev->descriptor.idProduct == USB_ID_US144) { | ||
213 | iface = usb_ifnum_to_if(us122l->dev, 0); | ||
214 | usb_autopm_put_interface(iface); | ||
215 | } | ||
216 | iface = usb_ifnum_to_if(us122l->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; |
@@ -264,7 +297,7 @@ static unsigned int usb_stream_hwdep_poll(struct snd_hwdep *hw, | |||
264 | static void us122l_stop(struct us122l *us122l) | 297 | static void us122l_stop(struct us122l *us122l) |
265 | { | 298 | { |
266 | struct list_head *p; | 299 | struct list_head *p; |
267 | list_for_each(p, &us122l->chip.midi_list) | 300 | list_for_each(p, &us122l->midi_list) |
268 | snd_usbmidi_input_stop(p); | 301 | snd_usbmidi_input_stop(p); |
269 | 302 | ||
270 | usb_stream_stop(&us122l->sk); | 303 | usb_stream_stop(&us122l->sk); |
@@ -297,7 +330,7 @@ static bool us122l_start(struct us122l *us122l, | |||
297 | unsigned use_packsize = 0; | 330 | unsigned use_packsize = 0; |
298 | bool success = false; | 331 | bool success = false; |
299 | 332 | ||
300 | if (us122l->chip.dev->speed == USB_SPEED_HIGH) { | 333 | if (us122l->dev->speed == USB_SPEED_HIGH) { |
301 | /* The us-122l's descriptor defaults to iso max_packsize 78, | 334 | /* The us-122l's descriptor defaults to iso max_packsize 78, |
302 | which isn't needed for samplerates <= 48000. | 335 | which isn't needed for samplerates <= 48000. |
303 | Lets save some memory: | 336 | Lets save some memory: |
@@ -314,11 +347,11 @@ static bool us122l_start(struct us122l *us122l, | |||
314 | break; | 347 | break; |
315 | } | 348 | } |
316 | } | 349 | } |
317 | if (!usb_stream_new(&us122l->sk, us122l->chip.dev, 1, 2, | 350 | if (!usb_stream_new(&us122l->sk, us122l->dev, 1, 2, |
318 | rate, use_packsize, period_frames, 6)) | 351 | rate, use_packsize, period_frames, 6)) |
319 | goto out; | 352 | goto out; |
320 | 353 | ||
321 | err = us122l_set_sample_rate(us122l->chip.dev, rate); | 354 | err = us122l_set_sample_rate(us122l->dev, rate); |
322 | if (err < 0) { | 355 | if (err < 0) { |
323 | us122l_stop(us122l); | 356 | us122l_stop(us122l); |
324 | snd_printk(KERN_ERR "us122l_set_sample_rate error \n"); | 357 | snd_printk(KERN_ERR "us122l_set_sample_rate error \n"); |
@@ -330,7 +363,7 @@ static bool us122l_start(struct us122l *us122l, | |||
330 | snd_printk(KERN_ERR "us122l_start error %i \n", err); | 363 | snd_printk(KERN_ERR "us122l_start error %i \n", err); |
331 | goto out; | 364 | goto out; |
332 | } | 365 | } |
333 | list_for_each(p, &us122l->chip.midi_list) | 366 | list_for_each(p, &us122l->midi_list) |
334 | snd_usbmidi_input_start(p); | 367 | snd_usbmidi_input_start(p); |
335 | success = true; | 368 | success = true; |
336 | out: | 369 | out: |
@@ -357,7 +390,7 @@ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, | |||
357 | err = -ENXIO; | 390 | err = -ENXIO; |
358 | goto free; | 391 | goto free; |
359 | } | 392 | } |
360 | high_speed = us122l->chip.dev->speed == USB_SPEED_HIGH; | 393 | high_speed = us122l->dev->speed == USB_SPEED_HIGH; |
361 | if ((cfg->sample_rate != 44100 && cfg->sample_rate != 48000 && | 394 | if ((cfg->sample_rate != 44100 && cfg->sample_rate != 48000 && |
362 | (!high_speed || | 395 | (!high_speed || |
363 | (cfg->sample_rate != 88200 && cfg->sample_rate != 96000))) || | 396 | (cfg->sample_rate != 88200 && cfg->sample_rate != 96000))) || |
@@ -417,7 +450,7 @@ static int usb_stream_hwdep_new(struct snd_card *card) | |||
417 | { | 450 | { |
418 | int err; | 451 | int err; |
419 | struct snd_hwdep *hw; | 452 | struct snd_hwdep *hw; |
420 | struct usb_device *dev = US122L(card)->chip.dev; | 453 | struct usb_device *dev = US122L(card)->dev; |
421 | 454 | ||
422 | err = snd_hwdep_new(card, SND_USB_STREAM_ID, 0, &hw); | 455 | err = snd_hwdep_new(card, SND_USB_STREAM_ID, 0, &hw); |
423 | if (err < 0) | 456 | if (err < 0) |
@@ -443,19 +476,29 @@ 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 | ||
446 | err = usb_set_interface(us122l->chip.dev, 1, 1); | 479 | if (us122l->dev->descriptor.idProduct == USB_ID_US144) { |
480 | err = usb_set_interface(us122l->dev, 0, 1); | ||
481 | if (err) { | ||
482 | snd_printk(KERN_ERR "usb_set_interface error \n"); | ||
483 | return false; | ||
484 | } | ||
485 | } | ||
486 | err = usb_set_interface(us122l->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"); |
449 | return false; | 489 | return false; |
450 | } | 490 | } |
451 | 491 | ||
452 | pt_info_set(us122l->chip.dev, 0x11); | 492 | pt_info_set(us122l->dev, 0x11); |
453 | pt_info_set(us122l->chip.dev, 0x10); | 493 | pt_info_set(us122l->dev, 0x10); |
454 | 494 | ||
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->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); |
@@ -465,7 +508,7 @@ static bool us122l_create_card(struct snd_card *card) | |||
465 | if (err < 0) { | 508 | if (err < 0) { |
466 | /* release the midi resources */ | 509 | /* release the midi resources */ |
467 | struct list_head *p; | 510 | struct list_head *p; |
468 | list_for_each(p, &us122l->chip.midi_list) | 511 | list_for_each(p, &us122l->midi_list) |
469 | snd_usbmidi_disconnect(p); | 512 | snd_usbmidi_disconnect(p); |
470 | 513 | ||
471 | us122l_stop(us122l); | 514 | us122l_stop(us122l); |
@@ -477,7 +520,7 @@ static bool us122l_create_card(struct snd_card *card) | |||
477 | static void snd_us122l_free(struct snd_card *card) | 520 | static void snd_us122l_free(struct snd_card *card) |
478 | { | 521 | { |
479 | struct us122l *us122l = US122L(card); | 522 | struct us122l *us122l = US122L(card); |
480 | int index = us122l->chip.index; | 523 | int index = us122l->card_index; |
481 | if (index >= 0 && index < SNDRV_CARDS) | 524 | if (index >= 0 && index < SNDRV_CARDS) |
482 | snd_us122l_card_used[index] = 0; | 525 | snd_us122l_card_used[index] = 0; |
483 | } | 526 | } |
@@ -497,13 +540,12 @@ static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp) | |||
497 | sizeof(struct us122l), &card); | 540 | sizeof(struct us122l), &card); |
498 | if (err < 0) | 541 | if (err < 0) |
499 | return err; | 542 | return err; |
500 | snd_us122l_card_used[US122L(card)->chip.index = dev] = 1; | 543 | snd_us122l_card_used[US122L(card)->card_index = dev] = 1; |
501 | card->private_free = snd_us122l_free; | 544 | card->private_free = snd_us122l_free; |
502 | US122L(card)->chip.dev = device; | 545 | US122L(card)->dev = device; |
503 | US122L(card)->chip.card = card; | ||
504 | mutex_init(&US122L(card)->mutex); | 546 | mutex_init(&US122L(card)->mutex); |
505 | init_waitqueue_head(&US122L(card)->sk.sleep); | 547 | init_waitqueue_head(&US122L(card)->sk.sleep); |
506 | INIT_LIST_HEAD(&US122L(card)->chip.midi_list); | 548 | INIT_LIST_HEAD(&US122L(card)->midi_list); |
507 | strcpy(card->driver, "USB "NAME_ALLCAPS""); | 549 | strcpy(card->driver, "USB "NAME_ALLCAPS""); |
508 | sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); | 550 | sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); |
509 | sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)", | 551 | sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)", |
@@ -511,8 +553,8 @@ static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp) | |||
511 | le16_to_cpu(device->descriptor.idVendor), | 553 | le16_to_cpu(device->descriptor.idVendor), |
512 | le16_to_cpu(device->descriptor.idProduct), | 554 | le16_to_cpu(device->descriptor.idProduct), |
513 | 0, | 555 | 0, |
514 | US122L(card)->chip.dev->bus->busnum, | 556 | US122L(card)->dev->bus->busnum, |
515 | US122L(card)->chip.dev->devnum | 557 | US122L(card)->dev->devnum |
516 | ); | 558 | ); |
517 | *cardp = card; | 559 | *cardp = card; |
518 | return 0; | 560 | return 0; |
@@ -542,6 +584,7 @@ static int us122l_usb_probe(struct usb_interface *intf, | |||
542 | return err; | 584 | return err; |
543 | } | 585 | } |
544 | 586 | ||
587 | usb_get_intf(usb_ifnum_to_if(device, 0)); | ||
545 | usb_get_dev(device); | 588 | usb_get_dev(device); |
546 | *cardp = card; | 589 | *cardp = card; |
547 | return 0; | 590 | return 0; |
@@ -550,9 +593,16 @@ static int us122l_usb_probe(struct usb_interface *intf, | |||
550 | static int snd_us122l_probe(struct usb_interface *intf, | 593 | static int snd_us122l_probe(struct usb_interface *intf, |
551 | const struct usb_device_id *id) | 594 | const struct usb_device_id *id) |
552 | { | 595 | { |
596 | struct usb_device *device = interface_to_usbdev(intf); | ||
553 | struct snd_card *card; | 597 | struct snd_card *card; |
554 | int err; | 598 | int err; |
555 | 599 | ||
600 | if (device->descriptor.idProduct == USB_ID_US144 | ||
601 | && device->speed == USB_SPEED_HIGH) { | ||
602 | snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n"); | ||
603 | return -ENODEV; | ||
604 | } | ||
605 | |||
556 | snd_printdd(KERN_DEBUG"%p:%i\n", | 606 | snd_printdd(KERN_DEBUG"%p:%i\n", |
557 | intf, intf->cur_altsetting->desc.bInterfaceNumber); | 607 | intf, intf->cur_altsetting->desc.bInterfaceNumber); |
558 | if (intf->cur_altsetting->desc.bInterfaceNumber != 1) | 608 | if (intf->cur_altsetting->desc.bInterfaceNumber != 1) |
@@ -584,15 +634,15 @@ static void snd_us122l_disconnect(struct usb_interface *intf) | |||
584 | mutex_lock(&us122l->mutex); | 634 | mutex_lock(&us122l->mutex); |
585 | us122l_stop(us122l); | 635 | us122l_stop(us122l); |
586 | mutex_unlock(&us122l->mutex); | 636 | mutex_unlock(&us122l->mutex); |
587 | us122l->chip.shutdown = 1; | ||
588 | 637 | ||
589 | /* release the midi resources */ | 638 | /* release the midi resources */ |
590 | list_for_each(p, &us122l->chip.midi_list) { | 639 | list_for_each(p, &us122l->midi_list) { |
591 | snd_usbmidi_disconnect(p); | 640 | snd_usbmidi_disconnect(p); |
592 | } | 641 | } |
593 | 642 | ||
594 | usb_put_intf(intf); | 643 | usb_put_intf(usb_ifnum_to_if(us122l->dev, 0)); |
595 | usb_put_dev(us122l->chip.dev); | 644 | usb_put_intf(usb_ifnum_to_if(us122l->dev, 1)); |
645 | usb_put_dev(us122l->dev); | ||
596 | 646 | ||
597 | while (atomic_read(&us122l->mmap_count)) | 647 | while (atomic_read(&us122l->mmap_count)) |
598 | msleep(500); | 648 | msleep(500); |
@@ -615,7 +665,7 @@ static int snd_us122l_suspend(struct usb_interface *intf, pm_message_t message) | |||
615 | if (!us122l) | 665 | if (!us122l) |
616 | return 0; | 666 | return 0; |
617 | 667 | ||
618 | list_for_each(p, &us122l->chip.midi_list) | 668 | list_for_each(p, &us122l->midi_list) |
619 | snd_usbmidi_input_stop(p); | 669 | snd_usbmidi_input_stop(p); |
620 | 670 | ||
621 | mutex_lock(&us122l->mutex); | 671 | mutex_lock(&us122l->mutex); |
@@ -642,16 +692,23 @@ static int snd_us122l_resume(struct usb_interface *intf) | |||
642 | 692 | ||
643 | mutex_lock(&us122l->mutex); | 693 | mutex_lock(&us122l->mutex); |
644 | /* needed, doesn't restart without: */ | 694 | /* needed, doesn't restart without: */ |
645 | err = usb_set_interface(us122l->chip.dev, 1, 1); | 695 | if (us122l->dev->descriptor.idProduct == USB_ID_US144) { |
696 | err = usb_set_interface(us122l->dev, 0, 1); | ||
697 | if (err) { | ||
698 | snd_printk(KERN_ERR "usb_set_interface error \n"); | ||
699 | goto unlock; | ||
700 | } | ||
701 | } | ||
702 | err = usb_set_interface(us122l->dev, 1, 1); | ||
646 | if (err) { | 703 | if (err) { |
647 | snd_printk(KERN_ERR "usb_set_interface error \n"); | 704 | snd_printk(KERN_ERR "usb_set_interface error \n"); |
648 | goto unlock; | 705 | goto unlock; |
649 | } | 706 | } |
650 | 707 | ||
651 | pt_info_set(us122l->chip.dev, 0x11); | 708 | pt_info_set(us122l->dev, 0x11); |
652 | pt_info_set(us122l->chip.dev, 0x10); | 709 | pt_info_set(us122l->dev, 0x10); |
653 | 710 | ||
654 | err = us122l_set_sample_rate(us122l->chip.dev, | 711 | err = us122l_set_sample_rate(us122l->dev, |
655 | us122l->sk.s->cfg.sample_rate); | 712 | us122l->sk.s->cfg.sample_rate); |
656 | if (err < 0) { | 713 | if (err < 0) { |
657 | snd_printk(KERN_ERR "us122l_set_sample_rate error \n"); | 714 | snd_printk(KERN_ERR "us122l_set_sample_rate error \n"); |
@@ -661,7 +718,7 @@ static int snd_us122l_resume(struct usb_interface *intf) | |||
661 | if (err) | 718 | if (err) |
662 | goto unlock; | 719 | goto unlock; |
663 | 720 | ||
664 | list_for_each(p, &us122l->chip.midi_list) | 721 | list_for_each(p, &us122l->midi_list) |
665 | snd_usbmidi_input_start(p); | 722 | snd_usbmidi_input_start(p); |
666 | unlock: | 723 | unlock: |
667 | mutex_unlock(&us122l->mutex); | 724 | mutex_unlock(&us122l->mutex); |
@@ -675,11 +732,11 @@ static struct usb_device_id snd_us122l_usb_id_table[] = { | |||
675 | .idVendor = 0x0644, | 732 | .idVendor = 0x0644, |
676 | .idProduct = USB_ID_US122L | 733 | .idProduct = USB_ID_US122L |
677 | }, | 734 | }, |
678 | /* { */ /* US-144 maybe works when @USB1.1. Untested. */ | 735 | { /* US-144 only works at USB1.1! Disable module ehci-hcd. */ |
679 | /* .match_flags = USB_DEVICE_ID_MATCH_DEVICE, */ | 736 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
680 | /* .idVendor = 0x0644, */ | 737 | .idVendor = 0x0644, |
681 | /* .idProduct = USB_ID_US144 */ | 738 | .idProduct = USB_ID_US144 |
682 | /* }, */ | 739 | }, |
683 | { /* terminator */ } | 740 | { /* terminator */ } |
684 | }; | 741 | }; |
685 | 742 | ||