diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2012-07-17 07:58:48 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-13 14:47:56 -0400 |
commit | 6fd90db8df379e215f2d495d0b4f3d2553c00277 (patch) | |
tree | 5bdbf0da46589b4b3c2946e9a28bd15b584736be /drivers/media/video | |
parent | da2cd767f537082be0a02d83f87e0da4270e25b2 (diff) |
[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>
Diffstat (limited to 'drivers/media/video')
-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 7ac4347ca09e..1c15b4227bdb 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) | |||
1439 | } | 1439 | } |
1440 | 1440 | ||
1441 | /* | 1441 | /* |
1442 | * Compute the maximum number of bytes per interval for an endpoint. | ||
1443 | */ | ||
1444 | static unsigned int uvc_endpoint_max_bpi(struct usb_device *dev, | ||
1445 | struct usb_host_endpoint *ep) | ||
1446 | { | ||
1447 | u16 psize; | ||
1448 | |||
1449 | switch (dev->speed) { | ||
1450 | case USB_SPEED_SUPER: | ||
1451 | return ep->ss_ep_comp.wBytesPerInterval; | ||
1452 | case USB_SPEED_HIGH: | ||
1453 | psize = usb_endpoint_maxp(&ep->desc); | ||
1454 | return (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); | ||
1455 | default: | ||
1456 | psize = usb_endpoint_maxp(&ep->desc); | ||
1457 | return psize & 0x07ff; | ||
1458 | } | ||
1459 | } | ||
1460 | |||
1461 | /* | ||
1442 | * Initialize isochronous URBs and allocate transfer buffers. The packet size | 1462 | * Initialize isochronous URBs and allocate transfer buffers. The packet size |
1443 | * is given by the endpoint. | 1463 | * is given by the endpoint. |
1444 | */ | 1464 | */ |
@@ -1450,8 +1470,7 @@ static int uvc_init_video_isoc(struct uvc_streaming *stream, | |||
1450 | u16 psize; | 1470 | u16 psize; |
1451 | u32 size; | 1471 | u32 size; |
1452 | 1472 | ||
1453 | psize = le16_to_cpu(ep->desc.wMaxPacketSize); | 1473 | psize = uvc_endpoint_max_bpi(stream->dev->udev, ep); |
1454 | psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); | ||
1455 | size = stream->ctrl.dwMaxVideoFrameSize; | 1474 | size = stream->ctrl.dwMaxVideoFrameSize; |
1456 | 1475 | ||
1457 | npackets = uvc_alloc_urb_buffers(stream, size, psize, gfp_flags); | 1476 | npackets = uvc_alloc_urb_buffers(stream, size, psize, gfp_flags); |
@@ -1506,7 +1525,7 @@ static int uvc_init_video_bulk(struct uvc_streaming *stream, | |||
1506 | u16 psize; | 1525 | u16 psize; |
1507 | u32 size; | 1526 | u32 size; |
1508 | 1527 | ||
1509 | psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff; | 1528 | psize = usb_endpoint_maxp(&ep->desc) & 0x7ff; |
1510 | size = stream->ctrl.dwMaxPayloadTransferSize; | 1529 | size = stream->ctrl.dwMaxPayloadTransferSize; |
1511 | stream->bulk.max_payload_size = size; | 1530 | stream->bulk.max_payload_size = size; |
1512 | 1531 | ||
@@ -1567,7 +1586,7 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) | |||
1567 | 1586 | ||
1568 | if (intf->num_altsetting > 1) { | 1587 | if (intf->num_altsetting > 1) { |
1569 | struct usb_host_endpoint *best_ep = NULL; | 1588 | struct usb_host_endpoint *best_ep = NULL; |
1570 | unsigned int best_psize = 3 * 1024; | 1589 | unsigned int best_psize = UINT_MAX; |
1571 | unsigned int bandwidth; | 1590 | unsigned int bandwidth; |
1572 | unsigned int uninitialized_var(altsetting); | 1591 | unsigned int uninitialized_var(altsetting); |
1573 | int intfnum = stream->intfnum; | 1592 | int intfnum = stream->intfnum; |
@@ -1595,8 +1614,7 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) | |||
1595 | continue; | 1614 | continue; |
1596 | 1615 | ||
1597 | /* Check if the bandwidth is high enough. */ | 1616 | /* Check if the bandwidth is high enough. */ |
1598 | psize = le16_to_cpu(ep->desc.wMaxPacketSize); | 1617 | psize = uvc_endpoint_max_bpi(stream->dev->udev, ep); |
1599 | psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); | ||
1600 | if (psize >= bandwidth && psize <= best_psize) { | 1618 | if (psize >= bandwidth && psize <= best_psize) { |
1601 | altsetting = alts->desc.bAlternateSetting; | 1619 | altsetting = alts->desc.bAlternateSetting; |
1602 | best_psize = psize; | 1620 | best_psize = psize; |