diff options
Diffstat (limited to 'sound/usb/endpoint.c')
-rw-r--r-- | sound/usb/endpoint.c | 106 |
1 files changed, 61 insertions, 45 deletions
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 93e970f2b3c0..21dc6422d747 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -574,11 +574,14 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, | |||
574 | snd_pcm_format_t pcm_format, | 574 | snd_pcm_format_t pcm_format, |
575 | unsigned int channels, | 575 | unsigned int channels, |
576 | unsigned int period_bytes, | 576 | unsigned int period_bytes, |
577 | unsigned int frames_per_period, | ||
578 | unsigned int periods_per_buffer, | ||
577 | struct audioformat *fmt, | 579 | struct audioformat *fmt, |
578 | struct snd_usb_endpoint *sync_ep) | 580 | struct snd_usb_endpoint *sync_ep) |
579 | { | 581 | { |
580 | unsigned int maxsize, i, urb_packs, total_packs, packs_per_ms; | 582 | unsigned int maxsize, minsize, packs_per_ms, max_packs_per_urb; |
581 | int is_playback = usb_pipeout(ep->pipe); | 583 | unsigned int max_packs_per_period, urbs_per_period, urb_packs; |
584 | unsigned int max_urbs, i; | ||
582 | int frame_bits = snd_pcm_format_physical_width(pcm_format) * channels; | 585 | int frame_bits = snd_pcm_format_physical_width(pcm_format) * channels; |
583 | 586 | ||
584 | if (pcm_format == SNDRV_PCM_FORMAT_DSD_U16_LE && fmt->dsd_dop) { | 587 | if (pcm_format == SNDRV_PCM_FORMAT_DSD_U16_LE && fmt->dsd_dop) { |
@@ -611,58 +614,67 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, | |||
611 | else | 614 | else |
612 | ep->curpacksize = maxsize; | 615 | ep->curpacksize = maxsize; |
613 | 616 | ||
614 | if (snd_usb_get_speed(ep->chip->dev) != USB_SPEED_FULL) | 617 | if (snd_usb_get_speed(ep->chip->dev) != USB_SPEED_FULL) { |
615 | packs_per_ms = 8 >> ep->datainterval; | 618 | packs_per_ms = 8 >> ep->datainterval; |
616 | else | 619 | 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 { | 620 | } else { |
623 | urb_packs = 1; | 621 | packs_per_ms = 1; |
622 | max_packs_per_urb = MAX_PACKS; | ||
624 | } | 623 | } |
624 | if (sync_ep && !snd_usb_endpoint_implicit_feedback_sink(ep)) | ||
625 | max_packs_per_urb = min(max_packs_per_urb, | ||
626 | 1U << sync_ep->syncinterval); | ||
627 | max_packs_per_urb = max(1u, max_packs_per_urb >> ep->datainterval); | ||
625 | 628 | ||
626 | urb_packs *= packs_per_ms; | 629 | /* |
630 | * Capture endpoints need to use small URBs because there's no way | ||
631 | * to tell in advance where the next period will end, and we don't | ||
632 | * want the next URB to complete much after the period ends. | ||
633 | * | ||
634 | * Playback endpoints with implicit sync much use the same parameters | ||
635 | * as their corresponding capture endpoint. | ||
636 | */ | ||
637 | if (usb_pipein(ep->pipe) || | ||
638 | snd_usb_endpoint_implicit_feedback_sink(ep)) { | ||
627 | 639 | ||
628 | if (sync_ep && !snd_usb_endpoint_implicit_feedback_sink(ep)) | 640 | /* make capture URBs <= 1 ms and smaller than a period */ |
629 | urb_packs = min(urb_packs, 1U << sync_ep->syncinterval); | 641 | urb_packs = min(max_packs_per_urb, packs_per_ms); |
642 | while (urb_packs > 1 && urb_packs * maxsize >= period_bytes) | ||
643 | urb_packs >>= 1; | ||
644 | ep->nurbs = MAX_URBS; | ||
630 | 645 | ||
631 | /* decide how many packets to be used */ | 646 | /* |
632 | if (is_playback && !snd_usb_endpoint_implicit_feedback_sink(ep)) { | 647 | * Playback endpoints without implicit sync are adjusted so that |
633 | unsigned int minsize, maxpacks; | 648 | * a period fits as evenly as possible in the smallest number of |
649 | * URBs. The total number of URBs is adjusted to the size of the | ||
650 | * ALSA buffer, subject to the MAX_URBS and MAX_QUEUE limits. | ||
651 | */ | ||
652 | } else { | ||
634 | /* determine how small a packet can be */ | 653 | /* determine how small a packet can be */ |
635 | minsize = (ep->freqn >> (16 - ep->datainterval)) | 654 | minsize = (ep->freqn >> (16 - ep->datainterval)) * |
636 | * (frame_bits >> 3); | 655 | (frame_bits >> 3); |
637 | /* with sync from device, assume it can be 12% lower */ | 656 | /* with sync from device, assume it can be 12% lower */ |
638 | if (sync_ep) | 657 | if (sync_ep) |
639 | minsize -= minsize >> 3; | 658 | minsize -= minsize >> 3; |
640 | minsize = max(minsize, 1u); | 659 | 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 | 660 | ||
656 | ep->nurbs = (total_packs + urb_packs - 1) / urb_packs; | 661 | /* how many packets will contain an entire ALSA period? */ |
657 | if (ep->nurbs > MAX_URBS) { | 662 | max_packs_per_period = DIV_ROUND_UP(period_bytes, minsize); |
658 | /* too much... */ | 663 | |
659 | ep->nurbs = MAX_URBS; | 664 | /* how many URBs will contain a period? */ |
660 | total_packs = MAX_URBS * urb_packs; | 665 | urbs_per_period = DIV_ROUND_UP(max_packs_per_period, |
661 | } else if (ep->nurbs < 2) { | 666 | max_packs_per_urb); |
662 | /* too little - we need at least two packets | 667 | /* how many packets are needed in each URB? */ |
663 | * to ensure contiguous playback/capture | 668 | urb_packs = DIV_ROUND_UP(max_packs_per_period, urbs_per_period); |
664 | */ | 669 | |
665 | ep->nurbs = 2; | 670 | /* limit the number of frames in a single URB */ |
671 | ep->max_urb_frames = DIV_ROUND_UP(frames_per_period, | ||
672 | urbs_per_period); | ||
673 | |||
674 | /* try to use enough URBs to contain an entire ALSA buffer */ | ||
675 | max_urbs = min((unsigned) MAX_URBS, | ||
676 | MAX_QUEUE * packs_per_ms / urb_packs); | ||
677 | ep->nurbs = min(max_urbs, urbs_per_period * periods_per_buffer); | ||
666 | } | 678 | } |
667 | 679 | ||
668 | /* allocate and initialize data urbs */ | 680 | /* allocate and initialize data urbs */ |
@@ -670,8 +682,7 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, | |||
670 | struct snd_urb_ctx *u = &ep->urb[i]; | 682 | struct snd_urb_ctx *u = &ep->urb[i]; |
671 | u->index = i; | 683 | u->index = i; |
672 | u->ep = ep; | 684 | u->ep = ep; |
673 | u->packets = (i + 1) * total_packs / ep->nurbs | 685 | u->packets = urb_packs; |
674 | - i * total_packs / ep->nurbs; | ||
675 | u->buffer_size = maxsize * u->packets; | 686 | u->buffer_size = maxsize * u->packets; |
676 | 687 | ||
677 | if (fmt->fmt_type == UAC_FORMAT_TYPE_II) | 688 | if (fmt->fmt_type == UAC_FORMAT_TYPE_II) |
@@ -748,6 +759,8 @@ out_of_memory: | |||
748 | * @pcm_format: the audio fomat. | 759 | * @pcm_format: the audio fomat. |
749 | * @channels: the number of audio channels. | 760 | * @channels: the number of audio channels. |
750 | * @period_bytes: the number of bytes in one alsa period. | 761 | * @period_bytes: the number of bytes in one alsa period. |
762 | * @period_frames: the number of frames in one alsa period. | ||
763 | * @buffer_periods: the number of periods in one alsa buffer. | ||
751 | * @rate: the frame rate. | 764 | * @rate: the frame rate. |
752 | * @fmt: the USB audio format information | 765 | * @fmt: the USB audio format information |
753 | * @sync_ep: the sync endpoint to use, if any | 766 | * @sync_ep: the sync endpoint to use, if any |
@@ -760,6 +773,8 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, | |||
760 | snd_pcm_format_t pcm_format, | 773 | snd_pcm_format_t pcm_format, |
761 | unsigned int channels, | 774 | unsigned int channels, |
762 | unsigned int period_bytes, | 775 | unsigned int period_bytes, |
776 | unsigned int period_frames, | ||
777 | unsigned int buffer_periods, | ||
763 | unsigned int rate, | 778 | unsigned int rate, |
764 | struct audioformat *fmt, | 779 | struct audioformat *fmt, |
765 | struct snd_usb_endpoint *sync_ep) | 780 | struct snd_usb_endpoint *sync_ep) |
@@ -793,7 +808,8 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, | |||
793 | switch (ep->type) { | 808 | switch (ep->type) { |
794 | case SND_USB_ENDPOINT_TYPE_DATA: | 809 | case SND_USB_ENDPOINT_TYPE_DATA: |
795 | err = data_ep_set_params(ep, pcm_format, channels, | 810 | err = data_ep_set_params(ep, pcm_format, channels, |
796 | period_bytes, fmt, sync_ep); | 811 | period_bytes, period_frames, |
812 | buffer_periods, fmt, sync_ep); | ||
797 | break; | 813 | break; |
798 | case SND_USB_ENDPOINT_TYPE_SYNC: | 814 | case SND_USB_ENDPOINT_TYPE_SYNC: |
799 | err = sync_ep_set_params(ep, fmt); | 815 | err = sync_ep_set_params(ep, fmt); |