diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2012-07-17 08:58:48 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-13 15:47:56 -0300 |
commit | 6fd90db8df379e215f2d495d0b4f3d2553c00277 (patch) | |
tree | 5bdbf0da46589b4b3c2946e9a28bd15b584736be | |
parent | da2cd767f537082be0a02d83f87e0da4270e25b2 (diff) | |
download | linux-3.10-6fd90db8df379e215f2d495d0b4f3d2553c00277.tar.gz linux-3.10-6fd90db8df379e215f2d495d0b4f3d2553c00277.tar.bz2 linux-3.10-6fd90db8df379e215f2d495d0b4f3d2553c00277.zip |
[media] uvcvideo: Support super speed endpoints
Compute the maximum number of bytes per interval using the burst and
multiplier values for super speed endpoints.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/uvc/uvc_video.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 7ac4347ca09..1c15b4227bd 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -1439,6 +1439,26 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers) } /* + * Compute the maximum number of bytes per interval for an endpoint. + */ +static unsigned int uvc_endpoint_max_bpi(struct usb_device *dev, + struct usb_host_endpoint *ep) +{ + u16 psize; + + switch (dev->speed) { + case USB_SPEED_SUPER: + return ep->ss_ep_comp.wBytesPerInterval; + case USB_SPEED_HIGH: + psize = usb_endpoint_maxp(&ep->desc); + return (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); + default: + psize = usb_endpoint_maxp(&ep->desc); + return psize & 0x07ff; + } +} + +/* * Initialize isochronous URBs and allocate transfer buffers. The packet size * is given by the endpoint. */ @@ -1450,8 +1470,7 @@ static int uvc_init_video_isoc(struct uvc_streaming *stream, u16 psize; u32 size; - psize = le16_to_cpu(ep->desc.wMaxPacketSize); - psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); + psize = uvc_endpoint_max_bpi(stream->dev->udev, ep); size = stream->ctrl.dwMaxVideoFrameSize; npackets = uvc_alloc_urb_buffers(stream, size, psize, gfp_flags); @@ -1506,7 +1525,7 @@ static int uvc_init_video_bulk(struct uvc_streaming *stream, u16 psize; u32 size; - psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff; + psize = usb_endpoint_maxp(&ep->desc) & 0x7ff; size = stream->ctrl.dwMaxPayloadTransferSize; stream->bulk.max_payload_size = size; @@ -1567,7 +1586,7 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) if (intf->num_altsetting > 1) { struct usb_host_endpoint *best_ep = NULL; - unsigned int best_psize = 3 * 1024; + unsigned int best_psize = UINT_MAX; unsigned int bandwidth; unsigned int uninitialized_var(altsetting); int intfnum = stream->intfnum; @@ -1595,8 +1614,7 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) continue; /* Check if the bandwidth is high enough. */ - psize = le16_to_cpu(ep->desc.wMaxPacketSize); - psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); + psize = uvc_endpoint_max_bpi(stream->dev->udev, ep); if (psize >= bandwidth && psize <= best_psize) { altsetting = alts->desc.bAlternateSetting; best_psize = psize; |