diff options
Diffstat (limited to 'sound/usb/endpoint.c')
-rw-r--r-- | sound/usb/endpoint.c | 139 |
1 files changed, 73 insertions, 66 deletions
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 93e970f2b3c0..b9ba0fcc45df 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include "pcm.h" | 33 | #include "pcm.h" |
34 | #include "quirks.h" | 34 | #include "quirks.h" |
35 | 35 | ||
36 | #define EP_FLAG_ACTIVATED 0 | ||
37 | #define EP_FLAG_RUNNING 1 | 36 | #define EP_FLAG_RUNNING 1 |
38 | #define EP_FLAG_STOPPING 2 | 37 | #define EP_FLAG_STOPPING 2 |
39 | 38 | ||
@@ -426,9 +425,9 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, | |||
426 | list_for_each_entry(ep, &chip->ep_list, list) { | 425 | list_for_each_entry(ep, &chip->ep_list, list) { |
427 | if (ep->ep_num == ep_num && | 426 | if (ep->ep_num == ep_num && |
428 | ep->iface == alts->desc.bInterfaceNumber && | 427 | ep->iface == alts->desc.bInterfaceNumber && |
429 | ep->alt_idx == alts->desc.bAlternateSetting) { | 428 | ep->altsetting == alts->desc.bAlternateSetting) { |
430 | snd_printdd(KERN_DEBUG "Re-using EP %x in iface %d,%d @%p\n", | 429 | snd_printdd(KERN_DEBUG "Re-using EP %x in iface %d,%d @%p\n", |
431 | ep_num, ep->iface, ep->alt_idx, ep); | 430 | ep_num, ep->iface, ep->altsetting, ep); |
432 | goto __exit_unlock; | 431 | goto __exit_unlock; |
433 | } | 432 | } |
434 | } | 433 | } |
@@ -447,7 +446,7 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, | |||
447 | ep->type = type; | 446 | ep->type = type; |
448 | ep->ep_num = ep_num; | 447 | ep->ep_num = ep_num; |
449 | ep->iface = alts->desc.bInterfaceNumber; | 448 | ep->iface = alts->desc.bInterfaceNumber; |
450 | ep->alt_idx = alts->desc.bAlternateSetting; | 449 | ep->altsetting = alts->desc.bAlternateSetting; |
451 | INIT_LIST_HEAD(&ep->ready_playback_urbs); | 450 | INIT_LIST_HEAD(&ep->ready_playback_urbs); |
452 | ep_num &= USB_ENDPOINT_NUMBER_MASK; | 451 | ep_num &= USB_ENDPOINT_NUMBER_MASK; |
453 | 452 | ||
@@ -574,11 +573,14 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, | |||
574 | snd_pcm_format_t pcm_format, | 573 | snd_pcm_format_t pcm_format, |
575 | unsigned int channels, | 574 | unsigned int channels, |
576 | unsigned int period_bytes, | 575 | unsigned int period_bytes, |
576 | unsigned int frames_per_period, | ||
577 | unsigned int periods_per_buffer, | ||
577 | struct audioformat *fmt, | 578 | struct audioformat *fmt, |
578 | struct snd_usb_endpoint *sync_ep) | 579 | struct snd_usb_endpoint *sync_ep) |
579 | { | 580 | { |
580 | unsigned int maxsize, i, urb_packs, total_packs, packs_per_ms; | 581 | unsigned int maxsize, minsize, packs_per_ms, max_packs_per_urb; |
581 | int is_playback = usb_pipeout(ep->pipe); | 582 | unsigned int max_packs_per_period, urbs_per_period, urb_packs; |
583 | unsigned int max_urbs, i; | ||
582 | int frame_bits = snd_pcm_format_physical_width(pcm_format) * channels; | 584 | int frame_bits = snd_pcm_format_physical_width(pcm_format) * channels; |
583 | 585 | ||
584 | if (pcm_format == SNDRV_PCM_FORMAT_DSD_U16_LE && fmt->dsd_dop) { | 586 | if (pcm_format == SNDRV_PCM_FORMAT_DSD_U16_LE && fmt->dsd_dop) { |
@@ -611,58 +613,67 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, | |||
611 | else | 613 | else |
612 | ep->curpacksize = maxsize; | 614 | ep->curpacksize = maxsize; |
613 | 615 | ||
614 | if (snd_usb_get_speed(ep->chip->dev) != USB_SPEED_FULL) | 616 | if (snd_usb_get_speed(ep->chip->dev) != USB_SPEED_FULL) { |
615 | packs_per_ms = 8 >> ep->datainterval; | 617 | packs_per_ms = 8 >> ep->datainterval; |
616 | else | 618 | max_packs_per_urb = MAX_PACKS_HS; |
617 | packs_per_ms = 1; | ||
618 | |||
619 | if (is_playback && !snd_usb_endpoint_implicit_feedback_sink(ep)) { | ||
620 | urb_packs = max(ep->chip->nrpacks, 1); | ||
621 | urb_packs = min(urb_packs, (unsigned int) MAX_PACKS); | ||
622 | } else { | 619 | } else { |
623 | urb_packs = 1; | 620 | packs_per_ms = 1; |
621 | max_packs_per_urb = MAX_PACKS; | ||
624 | } | 622 | } |
623 | if (sync_ep && !snd_usb_endpoint_implicit_feedback_sink(ep)) | ||
624 | max_packs_per_urb = min(max_packs_per_urb, | ||
625 | 1U << sync_ep->syncinterval); | ||
626 | max_packs_per_urb = max(1u, max_packs_per_urb >> ep->datainterval); | ||
625 | 627 | ||
626 | urb_packs *= packs_per_ms; | 628 | /* |
629 | * Capture endpoints need to use small URBs because there's no way | ||
630 | * to tell in advance where the next period will end, and we don't | ||
631 | * want the next URB to complete much after the period ends. | ||
632 | * | ||
633 | * Playback endpoints with implicit sync much use the same parameters | ||
634 | * as their corresponding capture endpoint. | ||
635 | */ | ||
636 | if (usb_pipein(ep->pipe) || | ||
637 | snd_usb_endpoint_implicit_feedback_sink(ep)) { | ||
627 | 638 | ||
628 | if (sync_ep && !snd_usb_endpoint_implicit_feedback_sink(ep)) | 639 | /* make capture URBs <= 1 ms and smaller than a period */ |
629 | urb_packs = min(urb_packs, 1U << sync_ep->syncinterval); | 640 | urb_packs = min(max_packs_per_urb, packs_per_ms); |
641 | while (urb_packs > 1 && urb_packs * maxsize >= period_bytes) | ||
642 | urb_packs >>= 1; | ||
643 | ep->nurbs = MAX_URBS; | ||
630 | 644 | ||
631 | /* decide how many packets to be used */ | 645 | /* |
632 | if (is_playback && !snd_usb_endpoint_implicit_feedback_sink(ep)) { | 646 | * Playback endpoints without implicit sync are adjusted so that |
633 | unsigned int minsize, maxpacks; | 647 | * a period fits as evenly as possible in the smallest number of |
648 | * URBs. The total number of URBs is adjusted to the size of the | ||
649 | * ALSA buffer, subject to the MAX_URBS and MAX_QUEUE limits. | ||
650 | */ | ||
651 | } else { | ||
634 | /* determine how small a packet can be */ | 652 | /* determine how small a packet can be */ |
635 | minsize = (ep->freqn >> (16 - ep->datainterval)) | 653 | minsize = (ep->freqn >> (16 - ep->datainterval)) * |
636 | * (frame_bits >> 3); | 654 | (frame_bits >> 3); |
637 | /* with sync from device, assume it can be 12% lower */ | 655 | /* with sync from device, assume it can be 12% lower */ |
638 | if (sync_ep) | 656 | if (sync_ep) |
639 | minsize -= minsize >> 3; | 657 | minsize -= minsize >> 3; |
640 | minsize = max(minsize, 1u); | 658 | minsize = max(minsize, 1u); |
641 | total_packs = (period_bytes + minsize - 1) / minsize; | ||
642 | /* we need at least two URBs for queueing */ | ||
643 | if (total_packs < 2) { | ||
644 | total_packs = 2; | ||
645 | } else { | ||
646 | /* and we don't want too long a queue either */ | ||
647 | maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2); | ||
648 | total_packs = min(total_packs, maxpacks); | ||
649 | } | ||
650 | } else { | ||
651 | while (urb_packs > 1 && urb_packs * maxsize >= period_bytes) | ||
652 | urb_packs >>= 1; | ||
653 | total_packs = MAX_URBS * urb_packs; | ||
654 | } | ||
655 | 659 | ||
656 | ep->nurbs = (total_packs + urb_packs - 1) / urb_packs; | 660 | /* how many packets will contain an entire ALSA period? */ |
657 | if (ep->nurbs > MAX_URBS) { | 661 | max_packs_per_period = DIV_ROUND_UP(period_bytes, minsize); |
658 | /* too much... */ | 662 | |
659 | ep->nurbs = MAX_URBS; | 663 | /* how many URBs will contain a period? */ |
660 | total_packs = MAX_URBS * urb_packs; | 664 | urbs_per_period = DIV_ROUND_UP(max_packs_per_period, |
661 | } else if (ep->nurbs < 2) { | 665 | max_packs_per_urb); |
662 | /* too little - we need at least two packets | 666 | /* how many packets are needed in each URB? */ |
663 | * to ensure contiguous playback/capture | 667 | urb_packs = DIV_ROUND_UP(max_packs_per_period, urbs_per_period); |
664 | */ | 668 | |
665 | ep->nurbs = 2; | 669 | /* limit the number of frames in a single URB */ |
670 | ep->max_urb_frames = DIV_ROUND_UP(frames_per_period, | ||
671 | urbs_per_period); | ||
672 | |||
673 | /* try to use enough URBs to contain an entire ALSA buffer */ | ||
674 | max_urbs = min((unsigned) MAX_URBS, | ||
675 | MAX_QUEUE * packs_per_ms / urb_packs); | ||
676 | ep->nurbs = min(max_urbs, urbs_per_period * periods_per_buffer); | ||
666 | } | 677 | } |
667 | 678 | ||
668 | /* allocate and initialize data urbs */ | 679 | /* allocate and initialize data urbs */ |
@@ -670,8 +681,7 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, | |||
670 | struct snd_urb_ctx *u = &ep->urb[i]; | 681 | struct snd_urb_ctx *u = &ep->urb[i]; |
671 | u->index = i; | 682 | u->index = i; |
672 | u->ep = ep; | 683 | u->ep = ep; |
673 | u->packets = (i + 1) * total_packs / ep->nurbs | 684 | u->packets = urb_packs; |
674 | - i * total_packs / ep->nurbs; | ||
675 | u->buffer_size = maxsize * u->packets; | 685 | u->buffer_size = maxsize * u->packets; |
676 | 686 | ||
677 | if (fmt->fmt_type == UAC_FORMAT_TYPE_II) | 687 | if (fmt->fmt_type == UAC_FORMAT_TYPE_II) |
@@ -703,8 +713,7 @@ out_of_memory: | |||
703 | /* | 713 | /* |
704 | * configure a sync endpoint | 714 | * configure a sync endpoint |
705 | */ | 715 | */ |
706 | static int sync_ep_set_params(struct snd_usb_endpoint *ep, | 716 | static int sync_ep_set_params(struct snd_usb_endpoint *ep) |
707 | struct audioformat *fmt) | ||
708 | { | 717 | { |
709 | int i; | 718 | int i; |
710 | 719 | ||
@@ -748,6 +757,8 @@ out_of_memory: | |||
748 | * @pcm_format: the audio fomat. | 757 | * @pcm_format: the audio fomat. |
749 | * @channels: the number of audio channels. | 758 | * @channels: the number of audio channels. |
750 | * @period_bytes: the number of bytes in one alsa period. | 759 | * @period_bytes: the number of bytes in one alsa period. |
760 | * @period_frames: the number of frames in one alsa period. | ||
761 | * @buffer_periods: the number of periods in one alsa buffer. | ||
751 | * @rate: the frame rate. | 762 | * @rate: the frame rate. |
752 | * @fmt: the USB audio format information | 763 | * @fmt: the USB audio format information |
753 | * @sync_ep: the sync endpoint to use, if any | 764 | * @sync_ep: the sync endpoint to use, if any |
@@ -760,6 +771,8 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, | |||
760 | snd_pcm_format_t pcm_format, | 771 | snd_pcm_format_t pcm_format, |
761 | unsigned int channels, | 772 | unsigned int channels, |
762 | unsigned int period_bytes, | 773 | unsigned int period_bytes, |
774 | unsigned int period_frames, | ||
775 | unsigned int buffer_periods, | ||
763 | unsigned int rate, | 776 | unsigned int rate, |
764 | struct audioformat *fmt, | 777 | struct audioformat *fmt, |
765 | struct snd_usb_endpoint *sync_ep) | 778 | struct snd_usb_endpoint *sync_ep) |
@@ -793,10 +806,11 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, | |||
793 | switch (ep->type) { | 806 | switch (ep->type) { |
794 | case SND_USB_ENDPOINT_TYPE_DATA: | 807 | case SND_USB_ENDPOINT_TYPE_DATA: |
795 | err = data_ep_set_params(ep, pcm_format, channels, | 808 | err = data_ep_set_params(ep, pcm_format, channels, |
796 | period_bytes, fmt, sync_ep); | 809 | period_bytes, period_frames, |
810 | buffer_periods, fmt, sync_ep); | ||
797 | break; | 811 | break; |
798 | case SND_USB_ENDPOINT_TYPE_SYNC: | 812 | case SND_USB_ENDPOINT_TYPE_SYNC: |
799 | err = sync_ep_set_params(ep, fmt); | 813 | err = sync_ep_set_params(ep); |
800 | break; | 814 | break; |
801 | default: | 815 | default: |
802 | err = -EINVAL; | 816 | err = -EINVAL; |
@@ -931,28 +945,21 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep) | |||
931 | * | 945 | * |
932 | * @ep: the endpoint to deactivate | 946 | * @ep: the endpoint to deactivate |
933 | * | 947 | * |
934 | * If the endpoint is not currently in use, this functions will select the | 948 | * If the endpoint is not currently in use, this functions will |
935 | * alternate interface setting 0 for the interface of this endpoint. | 949 | * deactivate its associated URBs. |
936 | * | 950 | * |
937 | * In case of any active users, this functions does nothing. | 951 | * In case of any active users, this functions does nothing. |
938 | * | ||
939 | * Returns an error if usb_set_interface() failed, 0 in all other | ||
940 | * cases. | ||
941 | */ | 952 | */ |
942 | int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep) | 953 | void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep) |
943 | { | 954 | { |
944 | if (!ep) | 955 | if (!ep) |
945 | return -EINVAL; | 956 | return; |
946 | |||
947 | deactivate_urbs(ep, true); | ||
948 | wait_clear_urbs(ep); | ||
949 | 957 | ||
950 | if (ep->use_count != 0) | 958 | if (ep->use_count != 0) |
951 | return 0; | 959 | return; |
952 | |||
953 | clear_bit(EP_FLAG_ACTIVATED, &ep->flags); | ||
954 | 960 | ||
955 | return 0; | 961 | deactivate_urbs(ep, true); |
962 | wait_clear_urbs(ep); | ||
956 | } | 963 | } |
957 | 964 | ||
958 | /** | 965 | /** |