diff options
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/caiaq/audio.c | 37 | ||||
-rw-r--r-- | sound/usb/caiaq/device.h | 1 | ||||
-rw-r--r-- | sound/usb/caiaq/input.c | 2 | ||||
-rw-r--r-- | sound/usb/card.c | 23 | ||||
-rw-r--r-- | sound/usb/endpoint.c | 4 | ||||
-rw-r--r-- | sound/usb/misc/ua101.c | 30 | ||||
-rw-r--r-- | sound/usb/mixer.c | 148 | ||||
-rw-r--r-- | sound/usb/mixer.h | 1 | ||||
-rw-r--r-- | sound/usb/quirks-table.h | 70 | ||||
-rw-r--r-- | sound/usb/quirks.c | 161 | ||||
-rw-r--r-- | sound/usb/usx2y/usb_stream.c | 6 |
11 files changed, 363 insertions, 120 deletions
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index d0d493ca28a..2cf87f5afed 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c | |||
@@ -139,8 +139,12 @@ static void stream_stop(struct snd_usb_caiaqdev *dev) | |||
139 | 139 | ||
140 | for (i = 0; i < N_URBS; i++) { | 140 | for (i = 0; i < N_URBS; i++) { |
141 | usb_kill_urb(dev->data_urbs_in[i]); | 141 | usb_kill_urb(dev->data_urbs_in[i]); |
142 | usb_kill_urb(dev->data_urbs_out[i]); | 142 | |
143 | if (test_bit(i, &dev->outurb_active_mask)) | ||
144 | usb_kill_urb(dev->data_urbs_out[i]); | ||
143 | } | 145 | } |
146 | |||
147 | dev->outurb_active_mask = 0; | ||
144 | } | 148 | } |
145 | 149 | ||
146 | static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream) | 150 | static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream) |
@@ -612,8 +616,9 @@ static void read_completed(struct urb *urb) | |||
612 | { | 616 | { |
613 | struct snd_usb_caiaq_cb_info *info = urb->context; | 617 | struct snd_usb_caiaq_cb_info *info = urb->context; |
614 | struct snd_usb_caiaqdev *dev; | 618 | struct snd_usb_caiaqdev *dev; |
615 | struct urb *out; | 619 | struct urb *out = NULL; |
616 | int frame, len, send_it = 0, outframe = 0; | 620 | int i, frame, len, send_it = 0, outframe = 0; |
621 | size_t offset = 0; | ||
617 | 622 | ||
618 | if (urb->status || !info) | 623 | if (urb->status || !info) |
619 | return; | 624 | return; |
@@ -623,7 +628,17 @@ static void read_completed(struct urb *urb) | |||
623 | if (!dev->streaming) | 628 | if (!dev->streaming) |
624 | return; | 629 | return; |
625 | 630 | ||
626 | out = dev->data_urbs_out[info->index]; | 631 | /* find an unused output urb that is unused */ |
632 | for (i = 0; i < N_URBS; i++) | ||
633 | if (test_and_set_bit(i, &dev->outurb_active_mask) == 0) { | ||
634 | out = dev->data_urbs_out[i]; | ||
635 | break; | ||
636 | } | ||
637 | |||
638 | if (!out) { | ||
639 | log("Unable to find an output urb to use\n"); | ||
640 | goto requeue; | ||
641 | } | ||
627 | 642 | ||
628 | /* read the recently received packet and send back one which has | 643 | /* read the recently received packet and send back one which has |
629 | * the same layout */ | 644 | * the same layout */ |
@@ -634,7 +649,8 @@ static void read_completed(struct urb *urb) | |||
634 | len = urb->iso_frame_desc[outframe].actual_length; | 649 | len = urb->iso_frame_desc[outframe].actual_length; |
635 | out->iso_frame_desc[outframe].length = len; | 650 | out->iso_frame_desc[outframe].length = len; |
636 | out->iso_frame_desc[outframe].actual_length = 0; | 651 | out->iso_frame_desc[outframe].actual_length = 0; |
637 | out->iso_frame_desc[outframe].offset = BYTES_PER_FRAME * frame; | 652 | out->iso_frame_desc[outframe].offset = offset; |
653 | offset += len; | ||
638 | 654 | ||
639 | if (len > 0) { | 655 | if (len > 0) { |
640 | spin_lock(&dev->spinlock); | 656 | spin_lock(&dev->spinlock); |
@@ -650,11 +666,15 @@ static void read_completed(struct urb *urb) | |||
650 | } | 666 | } |
651 | 667 | ||
652 | if (send_it) { | 668 | if (send_it) { |
653 | out->number_of_packets = FRAMES_PER_URB; | 669 | out->number_of_packets = outframe; |
654 | out->transfer_flags = URB_ISO_ASAP; | 670 | out->transfer_flags = URB_ISO_ASAP; |
655 | usb_submit_urb(out, GFP_ATOMIC); | 671 | usb_submit_urb(out, GFP_ATOMIC); |
672 | } else { | ||
673 | struct snd_usb_caiaq_cb_info *oinfo = out->context; | ||
674 | clear_bit(oinfo->index, &dev->outurb_active_mask); | ||
656 | } | 675 | } |
657 | 676 | ||
677 | requeue: | ||
658 | /* re-submit inbound urb */ | 678 | /* re-submit inbound urb */ |
659 | for (frame = 0; frame < FRAMES_PER_URB; frame++) { | 679 | for (frame = 0; frame < FRAMES_PER_URB; frame++) { |
660 | urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame; | 680 | urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame; |
@@ -676,6 +696,8 @@ static void write_completed(struct urb *urb) | |||
676 | dev->output_running = 1; | 696 | dev->output_running = 1; |
677 | wake_up(&dev->prepare_wait_queue); | 697 | wake_up(&dev->prepare_wait_queue); |
678 | } | 698 | } |
699 | |||
700 | clear_bit(info->index, &dev->outurb_active_mask); | ||
679 | } | 701 | } |
680 | 702 | ||
681 | static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) | 703 | static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) |
@@ -827,6 +849,9 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev) | |||
827 | if (!dev->data_cb_info) | 849 | if (!dev->data_cb_info) |
828 | return -ENOMEM; | 850 | return -ENOMEM; |
829 | 851 | ||
852 | dev->outurb_active_mask = 0; | ||
853 | BUILD_BUG_ON(N_URBS > (sizeof(dev->outurb_active_mask) * 8)); | ||
854 | |||
830 | for (i = 0; i < N_URBS; i++) { | 855 | for (i = 0; i < N_URBS; i++) { |
831 | dev->data_cb_info[i].dev = dev; | 856 | dev->data_cb_info[i].dev = dev; |
832 | dev->data_cb_info[i].index = i; | 857 | dev->data_cb_info[i].index = i; |
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h index b2b310194ff..3f9c6339ae9 100644 --- a/sound/usb/caiaq/device.h +++ b/sound/usb/caiaq/device.h | |||
@@ -96,6 +96,7 @@ struct snd_usb_caiaqdev { | |||
96 | int input_panic, output_panic, warned; | 96 | int input_panic, output_panic, warned; |
97 | char *audio_in_buf, *audio_out_buf; | 97 | char *audio_in_buf, *audio_out_buf; |
98 | unsigned int samplerates, bpp; | 98 | unsigned int samplerates, bpp; |
99 | unsigned long outurb_active_mask; | ||
99 | 100 | ||
100 | struct snd_pcm_substream *sub_playback[MAX_STREAMS]; | 101 | struct snd_pcm_substream *sub_playback[MAX_STREAMS]; |
101 | struct snd_pcm_substream *sub_capture[MAX_STREAMS]; | 102 | struct snd_pcm_substream *sub_capture[MAX_STREAMS]; |
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c index 4432ef7a70a..a213813487b 100644 --- a/sound/usb/caiaq/input.c +++ b/sound/usb/caiaq/input.c | |||
@@ -30,7 +30,7 @@ static unsigned short keycode_ak1[] = { KEY_C, KEY_B, KEY_A }; | |||
30 | static unsigned short keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4, | 30 | static unsigned short keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4, |
31 | KEY_5, KEY_6, KEY_7 }; | 31 | KEY_5, KEY_6, KEY_7 }; |
32 | static unsigned short keycode_rk3[] = { KEY_1, KEY_2, KEY_3, KEY_4, | 32 | static unsigned short keycode_rk3[] = { KEY_1, KEY_2, KEY_3, KEY_4, |
33 | KEY_5, KEY_6, KEY_7, KEY_5, KEY_6 }; | 33 | KEY_5, KEY_6, KEY_7, KEY_8, KEY_9 }; |
34 | 34 | ||
35 | static unsigned short keycode_kore[] = { | 35 | static unsigned short keycode_kore[] = { |
36 | KEY_FN_F1, /* "menu" */ | 36 | KEY_FN_F1, /* "menu" */ |
diff --git a/sound/usb/card.c b/sound/usb/card.c index 220c6167dd8..d8f2bf40145 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
@@ -433,9 +433,10 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, | |||
433 | * only at the first time. the successive calls of this function will | 433 | * only at the first time. the successive calls of this function will |
434 | * append the pcm interface to the corresponding card. | 434 | * append the pcm interface to the corresponding card. |
435 | */ | 435 | */ |
436 | static void *snd_usb_audio_probe(struct usb_device *dev, | 436 | static struct snd_usb_audio * |
437 | struct usb_interface *intf, | 437 | snd_usb_audio_probe(struct usb_device *dev, |
438 | const struct usb_device_id *usb_id) | 438 | struct usb_interface *intf, |
439 | const struct usb_device_id *usb_id) | ||
439 | { | 440 | { |
440 | const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info; | 441 | const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info; |
441 | int i, err; | 442 | int i, err; |
@@ -529,8 +530,11 @@ static void *snd_usb_audio_probe(struct usb_device *dev, | |||
529 | return chip; | 530 | return chip; |
530 | 531 | ||
531 | __error: | 532 | __error: |
532 | if (chip && !chip->num_interfaces) | 533 | if (chip) { |
533 | snd_card_free(chip->card); | 534 | if (!chip->num_interfaces) |
535 | snd_card_free(chip->card); | ||
536 | chip->probing = 0; | ||
537 | } | ||
534 | mutex_unlock(®ister_mutex); | 538 | mutex_unlock(®ister_mutex); |
535 | __err_val: | 539 | __err_val: |
536 | return NULL; | 540 | return NULL; |
@@ -540,16 +544,15 @@ static void *snd_usb_audio_probe(struct usb_device *dev, | |||
540 | * we need to take care of counter, since disconnection can be called also | 544 | * we need to take care of counter, since disconnection can be called also |
541 | * many times as well as usb_audio_probe(). | 545 | * many times as well as usb_audio_probe(). |
542 | */ | 546 | */ |
543 | static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) | 547 | static void snd_usb_audio_disconnect(struct usb_device *dev, |
548 | struct snd_usb_audio *chip) | ||
544 | { | 549 | { |
545 | struct snd_usb_audio *chip; | ||
546 | struct snd_card *card; | 550 | struct snd_card *card; |
547 | struct list_head *p; | 551 | struct list_head *p; |
548 | 552 | ||
549 | if (ptr == (void *)-1L) | 553 | if (chip == (void *)-1L) |
550 | return; | 554 | return; |
551 | 555 | ||
552 | chip = ptr; | ||
553 | card = chip->card; | 556 | card = chip->card; |
554 | mutex_lock(®ister_mutex); | 557 | mutex_lock(®ister_mutex); |
555 | mutex_lock(&chip->shutdown_mutex); | 558 | mutex_lock(&chip->shutdown_mutex); |
@@ -585,7 +588,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) | |||
585 | static int usb_audio_probe(struct usb_interface *intf, | 588 | static int usb_audio_probe(struct usb_interface *intf, |
586 | const struct usb_device_id *id) | 589 | const struct usb_device_id *id) |
587 | { | 590 | { |
588 | void *chip; | 591 | struct snd_usb_audio *chip; |
589 | chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id); | 592 | chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id); |
590 | if (chip) { | 593 | if (chip) { |
591 | usb_set_intfdata(intf, chip); | 594 | usb_set_intfdata(intf, chip); |
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index b0ef9f50189..7d46e482375 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -352,7 +352,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
352 | continue; | 352 | continue; |
353 | } | 353 | } |
354 | if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || | 354 | if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || |
355 | ((protocol == UAC_VERSION_2) && (fmt->bLength != 6))) { | 355 | ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) { |
356 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", | 356 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", |
357 | dev->devnum, iface_no, altno); | 357 | dev->devnum, iface_no, altno); |
358 | continue; | 358 | continue; |
@@ -408,6 +408,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
408 | /* doesn't set the sample rate attribute, but supports it */ | 408 | /* doesn't set the sample rate attribute, but supports it */ |
409 | fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE; | 409 | fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE; |
410 | break; | 410 | break; |
411 | case USB_ID(0x0763, 0x2001): /* M-Audio Quattro USB */ | ||
412 | case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */ | ||
411 | case USB_ID(0x047f, 0x0ca1): /* plantronics headset */ | 413 | case USB_ID(0x047f, 0x0ca1): /* plantronics headset */ |
412 | case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is | 414 | case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is |
413 | an older model 77d:223) */ | 415 | an older model 77d:223) */ |
diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c index fb5d68fa7ff..c0609c21030 100644 --- a/sound/usb/misc/ua101.c +++ b/sound/usb/misc/ua101.c | |||
@@ -459,7 +459,8 @@ static void kill_stream_urbs(struct ua101_stream *stream) | |||
459 | unsigned int i; | 459 | unsigned int i; |
460 | 460 | ||
461 | for (i = 0; i < stream->queue_length; ++i) | 461 | for (i = 0; i < stream->queue_length; ++i) |
462 | usb_kill_urb(&stream->urbs[i]->urb); | 462 | if (stream->urbs[i]) |
463 | usb_kill_urb(&stream->urbs[i]->urb); | ||
463 | } | 464 | } |
464 | 465 | ||
465 | static int enable_iso_interface(struct ua101 *ua, unsigned int intf_index) | 466 | static int enable_iso_interface(struct ua101 *ua, unsigned int intf_index) |
@@ -484,6 +485,9 @@ static void disable_iso_interface(struct ua101 *ua, unsigned int intf_index) | |||
484 | { | 485 | { |
485 | struct usb_host_interface *alts; | 486 | struct usb_host_interface *alts; |
486 | 487 | ||
488 | if (!ua->intf[intf_index]) | ||
489 | return; | ||
490 | |||
487 | alts = ua->intf[intf_index]->cur_altsetting; | 491 | alts = ua->intf[intf_index]->cur_altsetting; |
488 | if (alts->desc.bAlternateSetting != 0) { | 492 | if (alts->desc.bAlternateSetting != 0) { |
489 | int err = usb_set_interface(ua->dev, | 493 | int err = usb_set_interface(ua->dev, |
@@ -645,7 +649,7 @@ static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream, | |||
645 | err = snd_pcm_hw_constraint_minmax(substream->runtime, | 649 | err = snd_pcm_hw_constraint_minmax(substream->runtime, |
646 | SNDRV_PCM_HW_PARAM_PERIOD_TIME, | 650 | SNDRV_PCM_HW_PARAM_PERIOD_TIME, |
647 | 1500000 / ua->packets_per_second, | 651 | 1500000 / ua->packets_per_second, |
648 | 8192000); | 652 | UINT_MAX); |
649 | if (err < 0) | 653 | if (err < 0) |
650 | return err; | 654 | return err; |
651 | err = snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24); | 655 | err = snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24); |
@@ -1144,27 +1148,37 @@ static void free_stream_urbs(struct ua101_stream *stream) | |||
1144 | { | 1148 | { |
1145 | unsigned int i; | 1149 | unsigned int i; |
1146 | 1150 | ||
1147 | for (i = 0; i < stream->queue_length; ++i) | 1151 | for (i = 0; i < stream->queue_length; ++i) { |
1148 | kfree(stream->urbs[i]); | 1152 | kfree(stream->urbs[i]); |
1153 | stream->urbs[i] = NULL; | ||
1154 | } | ||
1149 | } | 1155 | } |
1150 | 1156 | ||
1151 | static void free_usb_related_resources(struct ua101 *ua, | 1157 | static void free_usb_related_resources(struct ua101 *ua, |
1152 | struct usb_interface *interface) | 1158 | struct usb_interface *interface) |
1153 | { | 1159 | { |
1154 | unsigned int i; | 1160 | unsigned int i; |
1161 | struct usb_interface *intf; | ||
1155 | 1162 | ||
1163 | mutex_lock(&ua->mutex); | ||
1156 | free_stream_urbs(&ua->capture); | 1164 | free_stream_urbs(&ua->capture); |
1157 | free_stream_urbs(&ua->playback); | 1165 | free_stream_urbs(&ua->playback); |
1166 | mutex_unlock(&ua->mutex); | ||
1158 | free_stream_buffers(ua, &ua->capture); | 1167 | free_stream_buffers(ua, &ua->capture); |
1159 | free_stream_buffers(ua, &ua->playback); | 1168 | free_stream_buffers(ua, &ua->playback); |
1160 | 1169 | ||
1161 | for (i = 0; i < ARRAY_SIZE(ua->intf); ++i) | 1170 | for (i = 0; i < ARRAY_SIZE(ua->intf); ++i) { |
1162 | if (ua->intf[i]) { | 1171 | mutex_lock(&ua->mutex); |
1163 | usb_set_intfdata(ua->intf[i], NULL); | 1172 | intf = ua->intf[i]; |
1164 | if (ua->intf[i] != interface) | 1173 | ua->intf[i] = NULL; |
1174 | mutex_unlock(&ua->mutex); | ||
1175 | if (intf) { | ||
1176 | usb_set_intfdata(intf, NULL); | ||
1177 | if (intf != interface) | ||
1165 | usb_driver_release_interface(&ua101_driver, | 1178 | usb_driver_release_interface(&ua101_driver, |
1166 | ua->intf[i]); | 1179 | intf); |
1167 | } | 1180 | } |
1181 | } | ||
1168 | } | 1182 | } |
1169 | 1183 | ||
1170 | static void ua101_card_free(struct snd_card *card) | 1184 | static void ua101_card_free(struct snd_card *card) |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index c22fa76e363..0de7cbd99ea 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
@@ -152,6 +152,7 @@ static inline void check_mapped_dB(const struct usbmix_name_map *p, | |||
152 | if (p && p->dB) { | 152 | if (p && p->dB) { |
153 | cval->dBmin = p->dB->min; | 153 | cval->dBmin = p->dB->min; |
154 | cval->dBmax = p->dB->max; | 154 | cval->dBmax = p->dB->max; |
155 | cval->initialized = 1; | ||
155 | } | 156 | } |
156 | } | 157 | } |
157 | 158 | ||
@@ -764,10 +765,60 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl) | |||
764 | * interface to ALSA control for feature/mixer units | 765 | * interface to ALSA control for feature/mixer units |
765 | */ | 766 | */ |
766 | 767 | ||
768 | /* volume control quirks */ | ||
769 | static void volume_control_quirks(struct usb_mixer_elem_info *cval, | ||
770 | struct snd_kcontrol *kctl) | ||
771 | { | ||
772 | switch (cval->mixer->chip->usb_id) { | ||
773 | case USB_ID(0x0471, 0x0101): | ||
774 | case USB_ID(0x0471, 0x0104): | ||
775 | case USB_ID(0x0471, 0x0105): | ||
776 | case USB_ID(0x0672, 0x1041): | ||
777 | /* quirk for UDA1321/N101. | ||
778 | * note that detection between firmware 2.1.1.7 (N101) | ||
779 | * and later 2.1.1.21 is not very clear from datasheets. | ||
780 | * I hope that the min value is -15360 for newer firmware --jk | ||
781 | */ | ||
782 | if (!strcmp(kctl->id.name, "PCM Playback Volume") && | ||
783 | cval->min == -15616) { | ||
784 | snd_printk(KERN_INFO | ||
785 | "set volume quirk for UDA1321/N101 chip\n"); | ||
786 | cval->max = -256; | ||
787 | } | ||
788 | break; | ||
789 | |||
790 | case USB_ID(0x046d, 0x09a4): | ||
791 | if (!strcmp(kctl->id.name, "Mic Capture Volume")) { | ||
792 | snd_printk(KERN_INFO | ||
793 | "set volume quirk for QuickCam E3500\n"); | ||
794 | cval->min = 6080; | ||
795 | cval->max = 8768; | ||
796 | cval->res = 192; | ||
797 | } | ||
798 | break; | ||
799 | |||
800 | case USB_ID(0x046d, 0x0808): | ||
801 | case USB_ID(0x046d, 0x0809): | ||
802 | case USB_ID(0x046d, 0x0991): | ||
803 | /* Most audio usb devices lie about volume resolution. | ||
804 | * Most Logitech webcams have res = 384. | ||
805 | * Proboly there is some logitech magic behind this number --fishor | ||
806 | */ | ||
807 | if (!strcmp(kctl->id.name, "Mic Capture Volume")) { | ||
808 | snd_printk(KERN_INFO | ||
809 | "set resolution quirk: cval->res = 384\n"); | ||
810 | cval->res = 384; | ||
811 | } | ||
812 | break; | ||
813 | |||
814 | } | ||
815 | } | ||
816 | |||
767 | /* | 817 | /* |
768 | * retrieve the minimum and maximum values for the specified control | 818 | * retrieve the minimum and maximum values for the specified control |
769 | */ | 819 | */ |
770 | static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) | 820 | static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, |
821 | int default_min, struct snd_kcontrol *kctl) | ||
771 | { | 822 | { |
772 | /* for failsafe */ | 823 | /* for failsafe */ |
773 | cval->min = default_min; | 824 | cval->min = default_min; |
@@ -843,6 +894,9 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) | |||
843 | cval->initialized = 1; | 894 | cval->initialized = 1; |
844 | } | 895 | } |
845 | 896 | ||
897 | if (kctl) | ||
898 | volume_control_quirks(cval, kctl); | ||
899 | |||
846 | /* USB descriptions contain the dB scale in 1/256 dB unit | 900 | /* USB descriptions contain the dB scale in 1/256 dB unit |
847 | * while ALSA TLV contains in 1/100 dB unit | 901 | * while ALSA TLV contains in 1/100 dB unit |
848 | */ | 902 | */ |
@@ -863,6 +917,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) | |||
863 | return 0; | 917 | return 0; |
864 | } | 918 | } |
865 | 919 | ||
920 | #define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL) | ||
866 | 921 | ||
867 | /* get a feature/mixer unit info */ | 922 | /* get a feature/mixer unit info */ |
868 | static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 923 | static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
@@ -880,8 +935,17 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
880 | uinfo->value.integer.min = 0; | 935 | uinfo->value.integer.min = 0; |
881 | uinfo->value.integer.max = 1; | 936 | uinfo->value.integer.max = 1; |
882 | } else { | 937 | } else { |
883 | if (! cval->initialized) | 938 | if (!cval->initialized) { |
884 | get_min_max(cval, 0); | 939 | get_min_max_with_quirks(cval, 0, kcontrol); |
940 | if (cval->initialized && cval->dBmin >= cval->dBmax) { | ||
941 | kcontrol->vd[0].access &= | ||
942 | ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ | | ||
943 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK); | ||
944 | snd_ctl_notify(cval->mixer->chip->card, | ||
945 | SNDRV_CTL_EVENT_MASK_INFO, | ||
946 | &kcontrol->id); | ||
947 | } | ||
948 | } | ||
885 | uinfo->value.integer.min = 0; | 949 | uinfo->value.integer.min = 0; |
886 | uinfo->value.integer.max = | 950 | uinfo->value.integer.max = |
887 | (cval->max - cval->min + cval->res - 1) / cval->res; | 951 | (cval->max - cval->min + cval->res - 1) / cval->res; |
@@ -1035,9 +1099,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1035 | cval->ch_readonly = readonly_mask; | 1099 | cval->ch_readonly = readonly_mask; |
1036 | } | 1100 | } |
1037 | 1101 | ||
1038 | /* get min/max values */ | ||
1039 | get_min_max(cval, 0); | ||
1040 | |||
1041 | /* if all channels in the mask are marked read-only, make the control | 1102 | /* if all channels in the mask are marked read-only, make the control |
1042 | * read-only. set_cur_mix_value() will check the mask again and won't | 1103 | * read-only. set_cur_mix_value() will check the mask again and won't |
1043 | * issue write commands to read-only channels. */ | 1104 | * issue write commands to read-only channels. */ |
@@ -1059,6 +1120,9 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1059 | len = snd_usb_copy_string_desc(state, nameid, | 1120 | len = snd_usb_copy_string_desc(state, nameid, |
1060 | kctl->id.name, sizeof(kctl->id.name)); | 1121 | kctl->id.name, sizeof(kctl->id.name)); |
1061 | 1122 | ||
1123 | /* get min/max values */ | ||
1124 | get_min_max_with_quirks(cval, 0, kctl); | ||
1125 | |||
1062 | switch (control) { | 1126 | switch (control) { |
1063 | case UAC_FU_MUTE: | 1127 | case UAC_FU_MUTE: |
1064 | case UAC_FU_VOLUME: | 1128 | case UAC_FU_VOLUME: |
@@ -1092,7 +1156,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1092 | " Switch" : " Volume"); | 1156 | " Switch" : " Volume"); |
1093 | if (control == UAC_FU_VOLUME) { | 1157 | if (control == UAC_FU_VOLUME) { |
1094 | check_mapped_dB(map, cval); | 1158 | check_mapped_dB(map, cval); |
1095 | if (cval->dBmin < cval->dBmax) { | 1159 | if (cval->dBmin < cval->dBmax || !cval->initialized) { |
1096 | kctl->tlv.c = mixer_vol_tlv; | 1160 | kctl->tlv.c = mixer_vol_tlv; |
1097 | kctl->vd[0].access |= | 1161 | kctl->vd[0].access |= |
1098 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | | 1162 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | |
@@ -1108,51 +1172,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1108 | break; | 1172 | break; |
1109 | } | 1173 | } |
1110 | 1174 | ||
1111 | /* volume control quirks */ | ||
1112 | switch (state->chip->usb_id) { | ||
1113 | case USB_ID(0x0471, 0x0101): | ||
1114 | case USB_ID(0x0471, 0x0104): | ||
1115 | case USB_ID(0x0471, 0x0105): | ||
1116 | case USB_ID(0x0672, 0x1041): | ||
1117 | /* quirk for UDA1321/N101. | ||
1118 | * note that detection between firmware 2.1.1.7 (N101) | ||
1119 | * and later 2.1.1.21 is not very clear from datasheets. | ||
1120 | * I hope that the min value is -15360 for newer firmware --jk | ||
1121 | */ | ||
1122 | if (!strcmp(kctl->id.name, "PCM Playback Volume") && | ||
1123 | cval->min == -15616) { | ||
1124 | snd_printk(KERN_INFO | ||
1125 | "set volume quirk for UDA1321/N101 chip\n"); | ||
1126 | cval->max = -256; | ||
1127 | } | ||
1128 | break; | ||
1129 | |||
1130 | case USB_ID(0x046d, 0x09a4): | ||
1131 | if (!strcmp(kctl->id.name, "Mic Capture Volume")) { | ||
1132 | snd_printk(KERN_INFO | ||
1133 | "set volume quirk for QuickCam E3500\n"); | ||
1134 | cval->min = 6080; | ||
1135 | cval->max = 8768; | ||
1136 | cval->res = 192; | ||
1137 | } | ||
1138 | break; | ||
1139 | |||
1140 | case USB_ID(0x046d, 0x0808): | ||
1141 | case USB_ID(0x046d, 0x0809): | ||
1142 | case USB_ID(0x046d, 0x0991): | ||
1143 | /* Most audio usb devices lie about volume resolution. | ||
1144 | * Most Logitech webcams have res = 384. | ||
1145 | * Proboly there is some logitech magic behind this number --fishor | ||
1146 | */ | ||
1147 | if (!strcmp(kctl->id.name, "Mic Capture Volume")) { | ||
1148 | snd_printk(KERN_INFO | ||
1149 | "set resolution quirk: cval->res = 384\n"); | ||
1150 | cval->res = 384; | ||
1151 | } | ||
1152 | break; | ||
1153 | |||
1154 | } | ||
1155 | |||
1156 | range = (cval->max - cval->min) / cval->res; | 1175 | range = (cval->max - cval->min) / cval->res; |
1157 | /* Are there devices with volume range more than 255? I use a bit more | 1176 | /* Are there devices with volume range more than 255? I use a bit more |
1158 | * to be sure. 384 is a resolution magic number found on Logitech | 1177 | * to be sure. 384 is a resolution magic number found on Logitech |
@@ -1191,6 +1210,11 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void | |||
1191 | 1210 | ||
1192 | if (state->mixer->protocol == UAC_VERSION_1) { | 1211 | if (state->mixer->protocol == UAC_VERSION_1) { |
1193 | csize = hdr->bControlSize; | 1212 | csize = hdr->bControlSize; |
1213 | if (!csize) { | ||
1214 | snd_printdd(KERN_ERR "usbaudio: unit %u: " | ||
1215 | "invalid bControlSize == 0\n", unitid); | ||
1216 | return -EINVAL; | ||
1217 | } | ||
1194 | channels = (hdr->bLength - 7) / csize - 1; | 1218 | channels = (hdr->bLength - 7) / csize - 1; |
1195 | bmaControls = hdr->bmaControls; | 1219 | bmaControls = hdr->bmaControls; |
1196 | } else { | 1220 | } else { |
@@ -1934,15 +1958,13 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) | |||
1934 | struct mixer_build state; | 1958 | struct mixer_build state; |
1935 | int err; | 1959 | int err; |
1936 | const struct usbmix_ctl_map *map; | 1960 | const struct usbmix_ctl_map *map; |
1937 | struct usb_host_interface *hostif; | ||
1938 | void *p; | 1961 | void *p; |
1939 | 1962 | ||
1940 | hostif = mixer->chip->ctrl_intf; | ||
1941 | memset(&state, 0, sizeof(state)); | 1963 | memset(&state, 0, sizeof(state)); |
1942 | state.chip = mixer->chip; | 1964 | state.chip = mixer->chip; |
1943 | state.mixer = mixer; | 1965 | state.mixer = mixer; |
1944 | state.buffer = hostif->extra; | 1966 | state.buffer = mixer->hostif->extra; |
1945 | state.buflen = hostif->extralen; | 1967 | state.buflen = mixer->hostif->extralen; |
1946 | 1968 | ||
1947 | /* check the mapping table */ | 1969 | /* check the mapping table */ |
1948 | for (map = usbmix_ctl_maps; map->id; map++) { | 1970 | for (map = usbmix_ctl_maps; map->id; map++) { |
@@ -1955,7 +1977,8 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) | |||
1955 | } | 1977 | } |
1956 | 1978 | ||
1957 | p = NULL; | 1979 | p = NULL; |
1958 | while ((p = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, p, UAC_OUTPUT_TERMINAL)) != NULL) { | 1980 | while ((p = snd_usb_find_csint_desc(mixer->hostif->extra, mixer->hostif->extralen, |
1981 | p, UAC_OUTPUT_TERMINAL)) != NULL) { | ||
1959 | if (mixer->protocol == UAC_VERSION_1) { | 1982 | if (mixer->protocol == UAC_VERSION_1) { |
1960 | struct uac1_output_terminal_descriptor *desc = p; | 1983 | struct uac1_output_terminal_descriptor *desc = p; |
1961 | 1984 | ||
@@ -2162,17 +2185,15 @@ int snd_usb_mixer_activate(struct usb_mixer_interface *mixer) | |||
2162 | /* create the handler for the optional status interrupt endpoint */ | 2185 | /* create the handler for the optional status interrupt endpoint */ |
2163 | static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer) | 2186 | static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer) |
2164 | { | 2187 | { |
2165 | struct usb_host_interface *hostif; | ||
2166 | struct usb_endpoint_descriptor *ep; | 2188 | struct usb_endpoint_descriptor *ep; |
2167 | void *transfer_buffer; | 2189 | void *transfer_buffer; |
2168 | int buffer_length; | 2190 | int buffer_length; |
2169 | unsigned int epnum; | 2191 | unsigned int epnum; |
2170 | 2192 | ||
2171 | hostif = mixer->chip->ctrl_intf; | ||
2172 | /* we need one interrupt input endpoint */ | 2193 | /* we need one interrupt input endpoint */ |
2173 | if (get_iface_desc(hostif)->bNumEndpoints < 1) | 2194 | if (get_iface_desc(mixer->hostif)->bNumEndpoints < 1) |
2174 | return 0; | 2195 | return 0; |
2175 | ep = get_endpoint(hostif, 0); | 2196 | ep = get_endpoint(mixer->hostif, 0); |
2176 | if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_int(ep)) | 2197 | if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_int(ep)) |
2177 | return 0; | 2198 | return 0; |
2178 | 2199 | ||
@@ -2202,7 +2223,6 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, | |||
2202 | }; | 2223 | }; |
2203 | struct usb_mixer_interface *mixer; | 2224 | struct usb_mixer_interface *mixer; |
2204 | struct snd_info_entry *entry; | 2225 | struct snd_info_entry *entry; |
2205 | struct usb_host_interface *host_iface; | ||
2206 | int err; | 2226 | int err; |
2207 | 2227 | ||
2208 | strcpy(chip->card->mixername, "USB Mixer"); | 2228 | strcpy(chip->card->mixername, "USB Mixer"); |
@@ -2219,8 +2239,8 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, | |||
2219 | return -ENOMEM; | 2239 | return -ENOMEM; |
2220 | } | 2240 | } |
2221 | 2241 | ||
2222 | host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; | 2242 | mixer->hostif = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; |
2223 | switch (get_iface_desc(host_iface)->bInterfaceProtocol) { | 2243 | switch (get_iface_desc(mixer->hostif)->bInterfaceProtocol) { |
2224 | case UAC_VERSION_1: | 2244 | case UAC_VERSION_1: |
2225 | default: | 2245 | default: |
2226 | mixer->protocol = UAC_VERSION_1; | 2246 | mixer->protocol = UAC_VERSION_1; |
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h index ae1a14dcfe8..81b2d8a32fb 100644 --- a/sound/usb/mixer.h +++ b/sound/usb/mixer.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | struct usb_mixer_interface { | 4 | struct usb_mixer_interface { |
5 | struct snd_usb_audio *chip; | 5 | struct snd_usb_audio *chip; |
6 | struct usb_host_interface *hostif; | ||
6 | struct list_head list; | 7 | struct list_head list; |
7 | unsigned int ignore_ctl_error; | 8 | unsigned int ignore_ctl_error; |
8 | struct urb *urb; | 9 | struct urb *urb; |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 0b2ae8e1c02..a42e3ef3832 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -1677,6 +1677,70 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1677 | } | 1677 | } |
1678 | } | 1678 | } |
1679 | }, | 1679 | }, |
1680 | { | ||
1681 | USB_DEVICE(0x0582, 0x011e), | ||
1682 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1683 | /* .vendor_name = "BOSS", */ | ||
1684 | /* .product_name = "BR-800", */ | ||
1685 | .ifnum = QUIRK_ANY_INTERFACE, | ||
1686 | .type = QUIRK_COMPOSITE, | ||
1687 | .data = (const struct snd_usb_audio_quirk[]) { | ||
1688 | { | ||
1689 | .ifnum = 0, | ||
1690 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1691 | }, | ||
1692 | { | ||
1693 | .ifnum = 1, | ||
1694 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1695 | }, | ||
1696 | { | ||
1697 | .ifnum = 2, | ||
1698 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
1699 | .data = & (const struct snd_usb_midi_endpoint_info) { | ||
1700 | .out_cables = 0x0001, | ||
1701 | .in_cables = 0x0001 | ||
1702 | } | ||
1703 | }, | ||
1704 | { | ||
1705 | .ifnum = -1 | ||
1706 | } | ||
1707 | } | ||
1708 | } | ||
1709 | }, | ||
1710 | { | ||
1711 | USB_DEVICE(0x0582, 0x0130), | ||
1712 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1713 | /* .vendor_name = "BOSS", */ | ||
1714 | /* .product_name = "MICRO BR-80", */ | ||
1715 | .ifnum = QUIRK_ANY_INTERFACE, | ||
1716 | .type = QUIRK_COMPOSITE, | ||
1717 | .data = (const struct snd_usb_audio_quirk[]) { | ||
1718 | { | ||
1719 | .ifnum = 0, | ||
1720 | .type = QUIRK_IGNORE_INTERFACE | ||
1721 | }, | ||
1722 | { | ||
1723 | .ifnum = 1, | ||
1724 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1725 | }, | ||
1726 | { | ||
1727 | .ifnum = 2, | ||
1728 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1729 | }, | ||
1730 | { | ||
1731 | .ifnum = 3, | ||
1732 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
1733 | .data = & (const struct snd_usb_midi_endpoint_info) { | ||
1734 | .out_cables = 0x0001, | ||
1735 | .in_cables = 0x0001 | ||
1736 | } | ||
1737 | }, | ||
1738 | { | ||
1739 | .ifnum = -1 | ||
1740 | } | ||
1741 | } | ||
1742 | } | ||
1743 | }, | ||
1680 | 1744 | ||
1681 | /* Guillemot devices */ | 1745 | /* Guillemot devices */ |
1682 | { | 1746 | { |
@@ -2387,6 +2451,12 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2387 | .idProduct = 0x1020, | 2451 | .idProduct = 0x1020, |
2388 | }, | 2452 | }, |
2389 | 2453 | ||
2454 | /* KeithMcMillen Stringport */ | ||
2455 | { | ||
2456 | USB_DEVICE(0x1f38, 0x0001), | ||
2457 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
2458 | }, | ||
2459 | |||
2390 | /* Miditech devices */ | 2460 | /* Miditech devices */ |
2391 | { | 2461 | { |
2392 | USB_DEVICE(0x4752, 0x0011), | 2462 | USB_DEVICE(0x4752, 0x0011), |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 090e1930dfd..81e07d84258 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
@@ -369,6 +369,30 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev) | |||
369 | return 0; | 369 | return 0; |
370 | } | 370 | } |
371 | 371 | ||
372 | static int snd_usb_fasttrackpro_boot_quirk(struct usb_device *dev) | ||
373 | { | ||
374 | int err; | ||
375 | |||
376 | if (dev->actconfig->desc.bConfigurationValue == 1) { | ||
377 | snd_printk(KERN_INFO "usb-audio: " | ||
378 | "Fast Track Pro switching to config #2\n"); | ||
379 | /* This function has to be available by the usb core module. | ||
380 | * if it is not avialable the boot quirk has to be left out | ||
381 | * and the configuration has to be set by udev or hotplug | ||
382 | * rules | ||
383 | */ | ||
384 | err = usb_driver_set_configuration(dev, 2); | ||
385 | if (err < 0) { | ||
386 | snd_printdd("error usb_driver_set_configuration: %d\n", | ||
387 | err); | ||
388 | return -ENODEV; | ||
389 | } | ||
390 | } else | ||
391 | snd_printk(KERN_INFO "usb-audio: Fast Track Pro config OK\n"); | ||
392 | |||
393 | return 0; | ||
394 | } | ||
395 | |||
372 | /* | 396 | /* |
373 | * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely | 397 | * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely |
374 | * documented in the device's data sheet. | 398 | * documented in the device's data sheet. |
@@ -402,7 +426,7 @@ static int snd_usb_cm106_boot_quirk(struct usb_device *dev) | |||
402 | */ | 426 | */ |
403 | static int snd_usb_cm6206_boot_quirk(struct usb_device *dev) | 427 | static int snd_usb_cm6206_boot_quirk(struct usb_device *dev) |
404 | { | 428 | { |
405 | int err, reg; | 429 | int err = 0, reg; |
406 | int val[] = {0x2004, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000}; | 430 | int val[] = {0x2004, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000}; |
407 | 431 | ||
408 | for (reg = 0; reg < ARRAY_SIZE(val); reg++) { | 432 | for (reg = 0; reg < ARRAY_SIZE(val); reg++) { |
@@ -471,16 +495,49 @@ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev) | |||
471 | /* | 495 | /* |
472 | * Setup quirks | 496 | * Setup quirks |
473 | */ | 497 | */ |
474 | #define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */ | 498 | #define MAUDIO_SET 0x01 /* parse device_setup */ |
475 | #define AUDIOPHILE_SET_DTS 0x02 /* if set, enable DTS Digital Output */ | 499 | #define MAUDIO_SET_COMPATIBLE 0x80 /* use only "win-compatible" interfaces */ |
476 | #define AUDIOPHILE_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */ | 500 | #define MAUDIO_SET_DTS 0x02 /* enable DTS Digital Output */ |
477 | #define AUDIOPHILE_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */ | 501 | #define MAUDIO_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */ |
478 | #define AUDIOPHILE_SET_DI 0x10 /* if set, enable Digital Input */ | 502 | #define MAUDIO_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */ |
479 | #define AUDIOPHILE_SET_MASK 0x1F /* bit mask for setup value */ | 503 | #define MAUDIO_SET_DI 0x10 /* enable Digital Input */ |
480 | #define AUDIOPHILE_SET_24B_48K_DI 0x19 /* value for 24bits+48KHz+Digital Input */ | 504 | #define MAUDIO_SET_MASK 0x1f /* bit mask for setup value */ |
481 | #define AUDIOPHILE_SET_24B_48K_NOTDI 0x09 /* value for 24bits+48KHz+No Digital Input */ | 505 | #define MAUDIO_SET_24B_48K_DI 0x19 /* 24bits+48KHz+Digital Input */ |
482 | #define AUDIOPHILE_SET_16B_48K_DI 0x11 /* value for 16bits+48KHz+Digital Input */ | 506 | #define MAUDIO_SET_24B_48K_NOTDI 0x09 /* 24bits+48KHz+No Digital Input */ |
483 | #define AUDIOPHILE_SET_16B_48K_NOTDI 0x01 /* value for 16bits+48KHz+No Digital Input */ | 507 | #define MAUDIO_SET_16B_48K_DI 0x11 /* 16bits+48KHz+Digital Input */ |
508 | #define MAUDIO_SET_16B_48K_NOTDI 0x01 /* 16bits+48KHz+No Digital Input */ | ||
509 | |||
510 | static int quattro_skip_setting_quirk(struct snd_usb_audio *chip, | ||
511 | int iface, int altno) | ||
512 | { | ||
513 | /* Reset ALL ifaces to 0 altsetting. | ||
514 | * Call it for every possible altsetting of every interface. | ||
515 | */ | ||
516 | usb_set_interface(chip->dev, iface, 0); | ||
517 | if (chip->setup & MAUDIO_SET) { | ||
518 | if (chip->setup & MAUDIO_SET_COMPATIBLE) { | ||
519 | if (iface != 1 && iface != 2) | ||
520 | return 1; /* skip all interfaces but 1 and 2 */ | ||
521 | } else { | ||
522 | unsigned int mask; | ||
523 | if (iface == 1 || iface == 2) | ||
524 | return 1; /* skip interfaces 1 and 2 */ | ||
525 | if ((chip->setup & MAUDIO_SET_96K) && altno != 1) | ||
526 | return 1; /* skip this altsetting */ | ||
527 | mask = chip->setup & MAUDIO_SET_MASK; | ||
528 | if (mask == MAUDIO_SET_24B_48K_DI && altno != 2) | ||
529 | return 1; /* skip this altsetting */ | ||
530 | if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3) | ||
531 | return 1; /* skip this altsetting */ | ||
532 | if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 4) | ||
533 | return 1; /* skip this altsetting */ | ||
534 | } | ||
535 | } | ||
536 | snd_printdd(KERN_INFO | ||
537 | "using altsetting %d for interface %d config %d\n", | ||
538 | altno, iface, chip->setup); | ||
539 | return 0; /* keep this altsetting */ | ||
540 | } | ||
484 | 541 | ||
485 | static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, | 542 | static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, |
486 | int iface, | 543 | int iface, |
@@ -491,30 +548,65 @@ static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, | |||
491 | */ | 548 | */ |
492 | usb_set_interface(chip->dev, iface, 0); | 549 | usb_set_interface(chip->dev, iface, 0); |
493 | 550 | ||
494 | if (chip->setup & AUDIOPHILE_SET) { | 551 | if (chip->setup & MAUDIO_SET) { |
495 | if ((chip->setup & AUDIOPHILE_SET_DTS) | 552 | unsigned int mask; |
496 | && altno != 6) | 553 | if ((chip->setup & MAUDIO_SET_DTS) && altno != 6) |
497 | return 1; /* skip this altsetting */ | 554 | return 1; /* skip this altsetting */ |
498 | if ((chip->setup & AUDIOPHILE_SET_96K) | 555 | if ((chip->setup & MAUDIO_SET_96K) && altno != 1) |
499 | && altno != 1) | ||
500 | return 1; /* skip this altsetting */ | 556 | return 1; /* skip this altsetting */ |
501 | if ((chip->setup & AUDIOPHILE_SET_MASK) == | 557 | mask = chip->setup & MAUDIO_SET_MASK; |
502 | AUDIOPHILE_SET_24B_48K_DI && altno != 2) | 558 | if (mask == MAUDIO_SET_24B_48K_DI && altno != 2) |
503 | return 1; /* skip this altsetting */ | 559 | return 1; /* skip this altsetting */ |
504 | if ((chip->setup & AUDIOPHILE_SET_MASK) == | 560 | if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3) |
505 | AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3) | ||
506 | return 1; /* skip this altsetting */ | 561 | return 1; /* skip this altsetting */ |
507 | if ((chip->setup & AUDIOPHILE_SET_MASK) == | 562 | if (mask == MAUDIO_SET_16B_48K_DI && altno != 4) |
508 | AUDIOPHILE_SET_16B_48K_DI && altno != 4) | ||
509 | return 1; /* skip this altsetting */ | 563 | return 1; /* skip this altsetting */ |
510 | if ((chip->setup & AUDIOPHILE_SET_MASK) == | 564 | if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 5) |
511 | AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5) | ||
512 | return 1; /* skip this altsetting */ | 565 | return 1; /* skip this altsetting */ |
513 | } | 566 | } |
514 | 567 | ||
515 | return 0; /* keep this altsetting */ | 568 | return 0; /* keep this altsetting */ |
516 | } | 569 | } |
517 | 570 | ||
571 | |||
572 | static int fasttrackpro_skip_setting_quirk(struct snd_usb_audio *chip, | ||
573 | int iface, int altno) | ||
574 | { | ||
575 | /* Reset ALL ifaces to 0 altsetting. | ||
576 | * Call it for every possible altsetting of every interface. | ||
577 | */ | ||
578 | usb_set_interface(chip->dev, iface, 0); | ||
579 | |||
580 | /* possible configuration where both inputs and only one output is | ||
581 | *used is not supported by the current setup | ||
582 | */ | ||
583 | if (chip->setup & (MAUDIO_SET | MAUDIO_SET_24B)) { | ||
584 | if (chip->setup & MAUDIO_SET_96K) { | ||
585 | if (altno != 3 && altno != 6) | ||
586 | return 1; | ||
587 | } else if (chip->setup & MAUDIO_SET_DI) { | ||
588 | if (iface == 4) | ||
589 | return 1; /* no analog input */ | ||
590 | if (altno != 2 && altno != 5) | ||
591 | return 1; /* enable only altsets 2 and 5 */ | ||
592 | } else { | ||
593 | if (iface == 5) | ||
594 | return 1; /* disable digialt input */ | ||
595 | if (altno != 2 && altno != 5) | ||
596 | return 1; /* enalbe only altsets 2 and 5 */ | ||
597 | } | ||
598 | } else { | ||
599 | /* keep only 16-Bit mode */ | ||
600 | if (altno != 1) | ||
601 | return 1; | ||
602 | } | ||
603 | |||
604 | snd_printdd(KERN_INFO | ||
605 | "using altsetting %d for interface %d config %d\n", | ||
606 | altno, iface, chip->setup); | ||
607 | return 0; /* keep this altsetting */ | ||
608 | } | ||
609 | |||
518 | int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip, | 610 | int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip, |
519 | int iface, | 611 | int iface, |
520 | int altno) | 612 | int altno) |
@@ -522,6 +614,12 @@ int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip, | |||
522 | /* audiophile usb: skip altsets incompatible with device_setup */ | 614 | /* audiophile usb: skip altsets incompatible with device_setup */ |
523 | if (chip->usb_id == USB_ID(0x0763, 0x2003)) | 615 | if (chip->usb_id == USB_ID(0x0763, 0x2003)) |
524 | return audiophile_skip_setting_quirk(chip, iface, altno); | 616 | return audiophile_skip_setting_quirk(chip, iface, altno); |
617 | /* quattro usb: skip altsets incompatible with device_setup */ | ||
618 | if (chip->usb_id == USB_ID(0x0763, 0x2001)) | ||
619 | return quattro_skip_setting_quirk(chip, iface, altno); | ||
620 | /* fasttrackpro usb: skip altsets incompatible with device_setup */ | ||
621 | if (chip->usb_id == USB_ID(0x0763, 0x2012)) | ||
622 | return fasttrackpro_skip_setting_quirk(chip, iface, altno); | ||
525 | 623 | ||
526 | return 0; | 624 | return 0; |
527 | } | 625 | } |
@@ -560,6 +658,8 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev, | |||
560 | case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */ | 658 | case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */ |
561 | case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */ | 659 | case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */ |
562 | return snd_usb_nativeinstruments_boot_quirk(dev); | 660 | return snd_usb_nativeinstruments_boot_quirk(dev); |
661 | case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */ | ||
662 | return snd_usb_fasttrackpro_boot_quirk(dev); | ||
563 | } | 663 | } |
564 | 664 | ||
565 | return 0; | 665 | return 0; |
@@ -570,15 +670,24 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev, | |||
570 | */ | 670 | */ |
571 | int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp) | 671 | int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp) |
572 | { | 672 | { |
673 | /* it depends on altsetting wether the device is big-endian or not */ | ||
573 | switch (chip->usb_id) { | 674 | switch (chip->usb_id) { |
574 | case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */ | 675 | case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */ |
575 | if (fp->endpoint & USB_DIR_IN) | 676 | if (fp->altsetting == 2 || fp->altsetting == 3 || |
677 | fp->altsetting == 5 || fp->altsetting == 6) | ||
576 | return 1; | 678 | return 1; |
577 | break; | 679 | break; |
578 | case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ | 680 | case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ |
579 | if (chip->setup == 0x00 || | 681 | if (chip->setup == 0x00 || |
580 | fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3) | 682 | fp->altsetting == 1 || fp->altsetting == 2 || |
683 | fp->altsetting == 3) | ||
684 | return 1; | ||
685 | break; | ||
686 | case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro */ | ||
687 | if (fp->altsetting == 2 || fp->altsetting == 3 || | ||
688 | fp->altsetting == 5 || fp->altsetting == 6) | ||
581 | return 1; | 689 | return 1; |
690 | break; | ||
582 | } | 691 | } |
583 | return 0; | 692 | return 0; |
584 | } | 693 | } |
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c index c400ade3ff0..1e7a47a8660 100644 --- a/sound/usb/usx2y/usb_stream.c +++ b/sound/usb/usx2y/usb_stream.c | |||
@@ -674,7 +674,7 @@ dotry: | |||
674 | inurb->transfer_buffer_length = | 674 | inurb->transfer_buffer_length = |
675 | inurb->number_of_packets * | 675 | inurb->number_of_packets * |
676 | inurb->iso_frame_desc[0].length; | 676 | inurb->iso_frame_desc[0].length; |
677 | preempt_disable(); | 677 | |
678 | if (u == 0) { | 678 | if (u == 0) { |
679 | int now; | 679 | int now; |
680 | struct usb_device *dev = inurb->dev; | 680 | struct usb_device *dev = inurb->dev; |
@@ -686,19 +686,17 @@ dotry: | |||
686 | } | 686 | } |
687 | err = usb_submit_urb(inurb, GFP_ATOMIC); | 687 | err = usb_submit_urb(inurb, GFP_ATOMIC); |
688 | if (err < 0) { | 688 | if (err < 0) { |
689 | preempt_enable(); | ||
690 | snd_printk(KERN_ERR"usb_submit_urb(sk->inurb[%i])" | 689 | snd_printk(KERN_ERR"usb_submit_urb(sk->inurb[%i])" |
691 | " returned %i\n", u, err); | 690 | " returned %i\n", u, err); |
692 | return err; | 691 | return err; |
693 | } | 692 | } |
694 | err = usb_submit_urb(outurb, GFP_ATOMIC); | 693 | err = usb_submit_urb(outurb, GFP_ATOMIC); |
695 | if (err < 0) { | 694 | if (err < 0) { |
696 | preempt_enable(); | ||
697 | snd_printk(KERN_ERR"usb_submit_urb(sk->outurb[%i])" | 695 | snd_printk(KERN_ERR"usb_submit_urb(sk->outurb[%i])" |
698 | " returned %i\n", u, err); | 696 | " returned %i\n", u, err); |
699 | return err; | 697 | return err; |
700 | } | 698 | } |
701 | preempt_enable(); | 699 | |
702 | if (inurb->start_frame != outurb->start_frame) { | 700 | if (inurb->start_frame != outurb->start_frame) { |
703 | snd_printd(KERN_DEBUG | 701 | snd_printd(KERN_DEBUG |
704 | "u[%i] start_frames differ in:%u out:%u\n", | 702 | "u[%i] start_frames differ in:%u out:%u\n", |