From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A0B10C35280 for ; Wed, 2 Oct 2019 08:55:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7BE2E215EA for ; Wed, 2 Oct 2019 08:55:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726458AbfJBIzN (ORCPT ); Wed, 2 Oct 2019 04:55:13 -0400 Received: from [68.65.227.210] ([68.65.227.210]:63382 "EHLO lan.digital-loggers.com" rhost-flags-FAIL-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1725852AbfJBIzM (ORCPT ); Wed, 2 Oct 2019 04:55:12 -0400 X-Greylist: delayed 454 seconds by postgrey-1.27 at vger.kernel.org; Wed, 02 Oct 2019 04:55:12 EDT From: Sergey Zakharchenko To: linux-media@vger.kernel.org Cc: Laurent Pinchart , Mauro Carvalho Chehab , Martin Bodo , "Logan, Peter" , Auke Kok , Sergey Zakharchenko , Sergey Zakharchenko Subject: [PATCH] media: uvcvideo: Add a quirk to force GEO GC6500 Camera bits-per-pixel value Date: Wed, 2 Oct 2019 08:47:23 +0000 Message-Id: <20191002084723.76329-1-szakharchenko@digital-loggers.com> X-Mailer: git-send-email 2.9.2 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org This device does not function correctly in raw mode in kernel versions validating buffer sizes in bulk mode. It erroneously announces 16 bits per pixel instead of 12 for NV12 format, so it needs this quirk to fix computed frame size and avoid legitimate frames getting discarded. Signed-off-by: Sergey Zakharchenko --- drivers/media/usb/uvc/uvc_driver.c | 27 +++++++++++++++++++++++++++ drivers/media/usb/uvc/uvcvideo.h | 1 + 2 files changed, 28 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 66ee168ddc7e..ffb3bc0992cc 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -446,10 +446,12 @@ static int uvc_parse_format(struct uvc_device *dev, struct usb_host_interface *alts = intf->cur_altsetting; struct uvc_format_desc *fmtdesc; struct uvc_frame *frame; + const struct v4l2_format_info *info; const unsigned char *start = buffer; unsigned int width_multiplier = 1; unsigned int interval; unsigned int i, n; + unsigned int div; u8 ftype; format->type = buffer[2]; @@ -497,6 +499,18 @@ static int uvc_parse_format(struct uvc_device *dev, } } + /* Some devices report bpp that doesn't match the format. */ + if (dev->quirks & UVC_QUIRK_FORCE_BPP) { + info = v4l2_format_info(format->fcc); + if (info) { + div = info->hdiv * info->vdiv; + n = info->bpp[i] * div; + for (i = 1; i < info->comp_planes; i++) + n += info->bpp[i]; + format->bpp = DIV_ROUND_UP(8 * n, div); + } + } + if (buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED) { ftype = UVC_VS_FRAME_UNCOMPRESSED; } else { @@ -2384,6 +2398,10 @@ static const struct uvc_device_info uvc_quirk_force_y8 = { .quirks = UVC_QUIRK_FORCE_Y8, }; +static const struct uvc_device_info uvc_quirk_force_bpp = { + .quirks = UVC_QUIRK_FORCE_BPP, +}; + #define UVC_INFO_QUIRK(q) (kernel_ulong_t)&(struct uvc_device_info){.quirks = q} #define UVC_INFO_META(m) (kernel_ulong_t)&(struct uvc_device_info) \ {.meta_format = m} @@ -2869,6 +2887,15 @@ static const struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, + /* GEO Semiconductor GC6500 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x29fe, + .idProduct = 0x4d53, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = (kernel_ulong_t)&uvc_quirk_force_bpp }, /* Generic USB Video Class */ { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) }, { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) }, diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index c7c1baa90dea..24e3d8c647e7 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -198,6 +198,7 @@ #define UVC_QUIRK_RESTRICT_FRAME_RATE 0x00000200 #define UVC_QUIRK_RESTORE_CTRLS_ON_INIT 0x00000400 #define UVC_QUIRK_FORCE_Y8 0x00000800 +#define UVC_QUIRK_FORCE_BPP 0x00001000 /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 -- 2.23.0