@@ -2491,6 +2491,11 @@ static const struct uvc_device_info uvc_quirk_fix_bandwidth = {
.quirks = UVC_QUIRK_FIX_BANDWIDTH,
};
+static const struct uvc_device_info uvc_quirk_fix_bw_622 = {
+ .quirks = UVC_QUIRK_FIX_BANDWIDTH,
+ .max_bandwidth = 62208000,
+};
+
static const struct uvc_device_info uvc_quirk_probe_def = {
.quirks = UVC_QUIRK_PROBE_DEF,
};
@@ -2794,6 +2799,15 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
+ /* MacroSilicon HDMI capture */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x534d,
+ .idProduct = 0x2109,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = (kernel_ulong_t)&uvc_quirk_fix_bw_622 },
/* Genesys Logic USB 2.0 PC Camera */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -225,9 +225,32 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
if ((ctrl->dwMaxPayloadTransferSize & 0xffff0000) == 0xffff0000)
ctrl->dwMaxPayloadTransferSize &= ~0xffff0000;
- if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) &&
- stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH &&
- stream->intf->num_altsetting > 1) {
+ if (!(stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH))
+ return;
+
+ /* Handle UVC_QUIRK_FIX_BANDWIDTH */
+
+ if (format->flags & UVC_FMT_FLAG_COMPRESSED) {
+ u32 bandwidth;
+
+ if (!stream->dev->info->max_bandwidth || !frame->bFrameIntervalType)
+ return;
+
+ for (i = 0; i < frame->bFrameIntervalType; ++i) {
+ bandwidth = frame->wWidth * frame->wHeight;
+ bandwidth *= UVC_FIVAL_DENOM / frame->dwFrameInterval[i];
+
+ if (bandwidth <= stream->dev->info->max_bandwidth)
+ break;
+ }
+
+ if (ctrl->dwFrameInterval < frame->dwFrameInterval[i])
+ ctrl->dwFrameInterval = frame->dwFrameInterval[i];
+
+ return;
+ }
+
+ if (stream->intf->num_altsetting > 1) {
u32 interval;
u32 bandwidth;
@@ -535,6 +535,7 @@ static inline u32 uvc_urb_index(const struct uvc_urb *uvc_urb)
struct uvc_device_info {
u32 quirks;
+ u32 max_bandwidth; /* In pixels per second */
u32 meta_format;
u16 uvc_version;
};