From patchwork Thu Mar 23 11:41:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 13185558 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5A809C76195 for ; Thu, 23 Mar 2023 11:41:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231470AbjCWLlf (ORCPT ); Thu, 23 Mar 2023 07:41:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35816 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229532AbjCWLld (ORCPT ); Thu, 23 Mar 2023 07:41:33 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BA65E193F0 for ; Thu, 23 Mar 2023 04:41:32 -0700 (PDT) Received: from dude05.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::54]) by metis.ext.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1pfJJy-0007OB-L7; Thu, 23 Mar 2023 12:41:30 +0100 From: Michael Tretter Date: Thu, 23 Mar 2023 12:41:09 +0100 Subject: [PATCH 1/8] usb: gadget: uvc: use fourcc printk helper MIME-Version: 1.0 Message-Id: <20230323-uvc-gadget-cleanup-v1-1-e41f0c5d9d8e@pengutronix.de> References: <20230323-uvc-gadget-cleanup-v1-0-e41f0c5d9d8e@pengutronix.de> In-Reply-To: <20230323-uvc-gadget-cleanup-v1-0-e41f0c5d9d8e@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman Cc: Michael Grzeschik , linux-usb@vger.kernel.org, linux-media@vger.kernel.org, kernel@pengutronix.de, Michael Tretter X-Mailer: b4 0.11.2 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::54 X-SA-Exim-Mail-From: m.tretter@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org There is a format helper for printing fourcc codes. Use that one instead of manually formatting the pixelformat for printing. Signed-off-by: Michael Tretter Reviewed-by: Daniel Scally Reviewed-by: Laurent Pinchart --- drivers/usb/gadget/function/uvc_v4l2.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index 3f0a9795c0d4..13c7ba06f994 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -240,16 +240,13 @@ uvc_v4l2_try_format(struct file *file, void *fh, struct v4l2_format *fmt) struct uvc_video *video = &uvc->video; struct uvcg_format *uformat; struct uvcg_frame *uframe; - u8 *fcc; if (fmt->type != video->queue.queue.type) return -EINVAL; - fcc = (u8 *)&fmt->fmt.pix.pixelformat; - uvcg_dbg(&uvc->func, "Trying format 0x%08x (%c%c%c%c): %ux%u\n", - fmt->fmt.pix.pixelformat, - fcc[0], fcc[1], fcc[2], fcc[3], - fmt->fmt.pix.width, fmt->fmt.pix.height); + uvcg_dbg(&uvc->func, "Trying format %p4cc: %ux%u\n", + &fmt->fmt.pix.pixelformat, + fmt->fmt.pix.width, fmt->fmt.pix.height); uformat = find_format_by_pix(uvc, fmt->fmt.pix.pixelformat); if (!uformat) From patchwork Thu Mar 23 11:41:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 13185557 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 39446C7619A for ; Thu, 23 Mar 2023 11:41:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231495AbjCWLlg (ORCPT ); Thu, 23 Mar 2023 07:41:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35832 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229451AbjCWLld (ORCPT ); Thu, 23 Mar 2023 07:41:33 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1BDA31A978 for ; Thu, 23 Mar 2023 04:41:33 -0700 (PDT) Received: from dude05.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::54]) by metis.ext.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1pfJJz-0007OB-0Q; Thu, 23 Mar 2023 12:41:31 +0100 From: Michael Tretter Date: Thu, 23 Mar 2023 12:41:10 +0100 Subject: [PATCH 2/8] usb: gadget: uvc: fix return code of REQBUFS MIME-Version: 1.0 Message-Id: <20230323-uvc-gadget-cleanup-v1-2-e41f0c5d9d8e@pengutronix.de> References: <20230323-uvc-gadget-cleanup-v1-0-e41f0c5d9d8e@pengutronix.de> In-Reply-To: <20230323-uvc-gadget-cleanup-v1-0-e41f0c5d9d8e@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman Cc: Michael Grzeschik , linux-usb@vger.kernel.org, linux-media@vger.kernel.org, kernel@pengutronix.de, Michael Tretter X-Mailer: b4 0.11.2 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::54 X-SA-Exim-Mail-From: m.tretter@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org On success, VIDIOC_REQBUFS should return 0, not the number of allocated buffers. As uvcg_alloc_buffers() is directly called by regbufs, it has to return the correct error codes. Signed-off-by: Michael Tretter Reviewed-by: Daniel Scally Reviewed-by: Laurent Pinchart --- drivers/usb/gadget/function/uvc_queue.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index 0aa3d7e1f3cc..f14f75b93aaa 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -179,11 +179,7 @@ void uvcg_free_buffers(struct uvc_video_queue *queue) int uvcg_alloc_buffers(struct uvc_video_queue *queue, struct v4l2_requestbuffers *rb) { - int ret; - - ret = vb2_reqbufs(&queue->queue, rb); - - return ret ? ret : rb->count; + return vb2_reqbufs(&queue->queue, rb); } int uvcg_query_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf) From patchwork Thu Mar 23 11:41:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 13185559 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A2586C77B60 for ; Thu, 23 Mar 2023 11:41:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231531AbjCWLlh (ORCPT ); Thu, 23 Mar 2023 07:41:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35832 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230455AbjCWLle (ORCPT ); Thu, 23 Mar 2023 07:41:34 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7EE501B327 for ; Thu, 23 Mar 2023 04:41:33 -0700 (PDT) Received: from dude05.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::54]) by metis.ext.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1pfJJz-0007OB-Bx; Thu, 23 Mar 2023 12:41:31 +0100 From: Michael Tretter Date: Thu, 23 Mar 2023 12:41:11 +0100 Subject: [PATCH 3/8] usb: gadget: uvc: implement s/g_output ioctl MIME-Version: 1.0 Message-Id: <20230323-uvc-gadget-cleanup-v1-3-e41f0c5d9d8e@pengutronix.de> References: <20230323-uvc-gadget-cleanup-v1-0-e41f0c5d9d8e@pengutronix.de> In-Reply-To: <20230323-uvc-gadget-cleanup-v1-0-e41f0c5d9d8e@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman Cc: Michael Grzeschik , linux-usb@vger.kernel.org, linux-media@vger.kernel.org, kernel@pengutronix.de, Michael Tretter X-Mailer: b4 0.11.2 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::54 X-SA-Exim-Mail-From: m.tretter@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org V4L2 OUTPUT devices should implement ENUM_OUTPUT, G_OUTPUT, and S_OUTPUT. The UVC gadget provides only a single output. Therefore, allow only a single output 0. According to the documentation, "_TYPE_ANALOG" is historical and should be read as "_TYPE_VIDEO". Signed-off-by: Michael Tretter --- drivers/usb/gadget/function/uvc_v4l2.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index 13c7ba06f994..4b8bf94e06fc 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -377,6 +377,31 @@ uvc_v4l2_enum_format(struct file *file, void *fh, struct v4l2_fmtdesc *f) return 0; } +static int +uvc_v4l2_enum_output(struct file *file, void *priv_fh, struct v4l2_output *out) +{ + if (out->index != 0) + return -EINVAL; + + out->type = V4L2_OUTPUT_TYPE_ANALOG; + snprintf(out->name, sizeof(out->name), "UVC"); + + return 0; +} + +static int +uvc_v4l2_g_output(struct file *file, void *priv_fh, unsigned int *i) +{ + *i = 0; + return 0; +} + +static int +uvc_v4l2_s_output(struct file *file, void *priv_fh, unsigned int i) +{ + return i ? -EINVAL : 0; +} + static int uvc_v4l2_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *b) { @@ -547,6 +572,9 @@ const struct v4l2_ioctl_ops uvc_v4l2_ioctl_ops = { .vidioc_enum_frameintervals = uvc_v4l2_enum_frameintervals, .vidioc_enum_framesizes = uvc_v4l2_enum_framesizes, .vidioc_enum_fmt_vid_out = uvc_v4l2_enum_format, + .vidioc_enum_output = uvc_v4l2_enum_output, + .vidioc_g_output = uvc_v4l2_g_output, + .vidioc_s_output = uvc_v4l2_s_output, .vidioc_reqbufs = uvc_v4l2_reqbufs, .vidioc_querybuf = uvc_v4l2_querybuf, .vidioc_qbuf = uvc_v4l2_qbuf, From patchwork Thu Mar 23 11:41:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 13185560 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 909F0C77B61 for ; Thu, 23 Mar 2023 11:41:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231528AbjCWLli (ORCPT ); Thu, 23 Mar 2023 07:41:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35816 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231274AbjCWLle (ORCPT ); Thu, 23 Mar 2023 07:41:34 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DF7B41043F for ; Thu, 23 Mar 2023 04:41:33 -0700 (PDT) Received: from dude05.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::54]) by metis.ext.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1pfJJz-0007OB-Oi; Thu, 23 Mar 2023 12:41:31 +0100 From: Michael Tretter Date: Thu, 23 Mar 2023 12:41:12 +0100 Subject: [PATCH 4/8] usb: gadget: uvc: move video format initialization to uvc_v4l2 MIME-Version: 1.0 Message-Id: <20230323-uvc-gadget-cleanup-v1-4-e41f0c5d9d8e@pengutronix.de> References: <20230323-uvc-gadget-cleanup-v1-0-e41f0c5d9d8e@pengutronix.de> In-Reply-To: <20230323-uvc-gadget-cleanup-v1-0-e41f0c5d9d8e@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman Cc: Michael Grzeschik , linux-usb@vger.kernel.org, linux-media@vger.kernel.org, kernel@pengutronix.de, Michael Tretter X-Mailer: b4 0.11.2 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::54 X-SA-Exim-Mail-From: m.tretter@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Move the setup of the initial video format to uvc_v4l2.c that handles all the format negotiation. This keeps all format setup and configuration code in uvc_v4l2.c and avoids scattering the format setup across multiple files. Furthermore, it allows to setup the default format using the format configured in the configfs. Signed-off-by: Michael Tretter --- drivers/usb/gadget/function/f_uvc.c | 2 ++ drivers/usb/gadget/function/uvc_v4l2.c | 11 +++++++++++ drivers/usb/gadget/function/uvc_v4l2.h | 3 +++ drivers/usb/gadget/function/uvc_video.c | 5 ----- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 5e919fb65833..a16c8f80a50a 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -434,6 +434,8 @@ uvc_register_video(struct uvc_device *uvc) struct usb_composite_dev *cdev = uvc->func.config->cdev; int ret; + uvc_init_default_format(uvc); + /* TODO reference counting. */ memset(&uvc->vdev, 0, sizeof(uvc->vdev)); uvc->vdev.v4l2_dev = &uvc->v4l2_dev; diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index 4b8bf94e06fc..5620546eb43b 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -130,6 +130,17 @@ static struct uvcg_format *find_format_by_pix(struct uvc_device *uvc, return uformat; } +void uvc_init_default_format(struct uvc_device *uvc) +{ + struct uvc_video *video = &uvc->video; + + video->fcc = V4L2_PIX_FMT_YUYV; + video->bpp = 16; + video->width = 320; + video->height = 240; + video->imagesize = 320 * 240 * 2; +} + static struct uvcg_frame *find_closest_frame_by_size(struct uvc_device *uvc, struct uvcg_format *uformat, u16 rw, u16 rh) diff --git a/drivers/usb/gadget/function/uvc_v4l2.h b/drivers/usb/gadget/function/uvc_v4l2.h index 1576005b61fd..5c3a97de0776 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.h +++ b/drivers/usb/gadget/function/uvc_v4l2.h @@ -16,4 +16,7 @@ extern const struct v4l2_ioctl_ops uvc_v4l2_ioctl_ops; extern const struct v4l2_file_operations uvc_v4l2_fops; +struct uvc_device; +void uvc_init_default_format(struct uvc_device *uvc); + #endif /* __UVC_V4L2_H__ */ diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index dd1c6b2ca7c6..27ff9ef49e16 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -516,11 +516,6 @@ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc) return -EINVAL; video->uvc = uvc; - video->fcc = V4L2_PIX_FMT_YUYV; - video->bpp = 16; - video->width = 320; - video->height = 240; - video->imagesize = 320 * 240 * 2; /* Initialize the video buffers queue. */ uvcg_queue_init(&video->queue, uvc->v4l2_dev.dev->parent, From patchwork Thu Mar 23 11:41:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 13185561 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9B3F3C6FD1D for ; Thu, 23 Mar 2023 11:41:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231540AbjCWLlj (ORCPT ); Thu, 23 Mar 2023 07:41:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35896 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229463AbjCWLlf (ORCPT ); Thu, 23 Mar 2023 07:41:35 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3EF171A978 for ; Thu, 23 Mar 2023 04:41:34 -0700 (PDT) Received: from dude05.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::54]) by metis.ext.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1pfJK0-0007OB-44; Thu, 23 Mar 2023 12:41:32 +0100 From: Michael Tretter Date: Thu, 23 Mar 2023 12:41:13 +0100 Subject: [PATCH 5/8] usb: gadget: uvc: initialize video format using configfs MIME-Version: 1.0 Message-Id: <20230323-uvc-gadget-cleanup-v1-5-e41f0c5d9d8e@pengutronix.de> References: <20230323-uvc-gadget-cleanup-v1-0-e41f0c5d9d8e@pengutronix.de> In-Reply-To: <20230323-uvc-gadget-cleanup-v1-0-e41f0c5d9d8e@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman Cc: Michael Grzeschik , linux-usb@vger.kernel.org, linux-media@vger.kernel.org, kernel@pengutronix.de, Michael Tretter X-Mailer: b4 0.11.2 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::54 X-SA-Exim-Mail-From: m.tretter@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The configfs is supported to get a list of valid formats, which will be checked in TRY_FMT and ENUM_FMT. The device should be initialized with a valid format instead of some arbitrary format that the user space won't be able to set. Signed-off-by: Michael Tretter --- drivers/usb/gadget/function/uvc_v4l2.c | 67 +++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index 5620546eb43b..3f728f451ed5 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -90,6 +90,15 @@ static struct uvcg_format *find_format_by_index(struct uvc_device *uvc, int inde return uformat; } +static struct uvcg_format *get_default_format(struct uvc_device *uvc) +{ + /* + * UVC does not specify which format index shall be used as default. + * Use the first format of the descriptor as default. + */ + return find_format_by_index(uvc, 1); +} + static struct uvcg_frame *find_frame_by_index(struct uvc_device *uvc, struct uvcg_format *uformat, int index) @@ -112,6 +121,29 @@ static struct uvcg_frame *find_frame_by_index(struct uvc_device *uvc, return uframe; } +static struct uvcg_frame *get_default_frame(struct uvc_device *uvc, + struct uvcg_format *uformat) +{ + struct uvcg_frame *frame = NULL; + int frame_index = 0; + + if (uformat->type == UVCG_UNCOMPRESSED) { + struct uvcg_uncompressed *u; + + u = to_uvcg_uncompressed(&uformat->group.cg_item); + frame_index = u->desc.bDefaultFrameIndex; + } else if (uformat->type == UVCG_MJPEG) { + struct uvcg_mjpeg *u; + + u = to_uvcg_mjpeg(&uformat->group.cg_item); + frame_index = u->desc.bDefaultFrameIndex; + } + if (frame_index != 0) + frame = find_frame_by_index(uvc, uformat, frame_index); + + return frame; +} + static struct uvcg_format *find_format_by_pix(struct uvc_device *uvc, u32 pixelformat) { @@ -133,12 +165,37 @@ static struct uvcg_format *find_format_by_pix(struct uvc_device *uvc, void uvc_init_default_format(struct uvc_device *uvc) { struct uvc_video *video = &uvc->video; + struct uvcg_format *uformat; + struct uvcg_frame *uframe = NULL; - video->fcc = V4L2_PIX_FMT_YUYV; - video->bpp = 16; - video->width = 320; - video->height = 240; - video->imagesize = 320 * 240 * 2; + uformat = get_default_format(uvc); + if (uformat) + uframe = get_default_frame(uvc, uformat); + + /* Fallback on some arbitrary default */ + if (!uframe) { + video->fcc = V4L2_PIX_FMT_YUYV; + video->bpp = 16; + video->width = 320; + video->height = 240; + video->imagesize = 320 * 240 * 2; + + return; + } + + video->fcc = to_uvc_format(uformat)->fcc; + + if (uformat->type == UVCG_UNCOMPRESSED) { + struct uvcg_uncompressed *u; + + u = to_uvcg_uncompressed(&uformat->group.cg_item); + video->bpp = u->desc.bBitsPerPixel; + } else { + video->bpp = 0; + } + video->width = uframe->frame.w_width; + video->height = uframe->frame.w_height; + video->imagesize = uvc_get_frame_size(uformat, uframe); } static struct uvcg_frame *find_closest_frame_by_size(struct uvc_device *uvc, From patchwork Thu Mar 23 11:41:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 13185562 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9E879C6FD1C for ; Thu, 23 Mar 2023 11:41:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231546AbjCWLlk (ORCPT ); Thu, 23 Mar 2023 07:41:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35918 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231393AbjCWLlf (ORCPT ); Thu, 23 Mar 2023 07:41:35 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A02A01E1CB for ; Thu, 23 Mar 2023 04:41:34 -0700 (PDT) Received: from dude05.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::54]) by metis.ext.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1pfJK0-0007OB-Fn; Thu, 23 Mar 2023 12:41:32 +0100 From: Michael Tretter Date: Thu, 23 Mar 2023 12:41:14 +0100 Subject: [PATCH 6/8] usb: gadget: uvc: try harder to find a valid format MIME-Version: 1.0 Message-Id: <20230323-uvc-gadget-cleanup-v1-6-e41f0c5d9d8e@pengutronix.de> References: <20230323-uvc-gadget-cleanup-v1-0-e41f0c5d9d8e@pengutronix.de> In-Reply-To: <20230323-uvc-gadget-cleanup-v1-0-e41f0c5d9d8e@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman Cc: Michael Grzeschik , linux-usb@vger.kernel.org, linux-media@vger.kernel.org, kernel@pengutronix.de, Michael Tretter X-Mailer: b4 0.11.2 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::54 X-SA-Exim-Mail-From: m.tretter@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The TRY_FMT call should try to avoid returning EINVAL. If the requested pixelformat is not supported by the driver, the driver should fall back to it's own default and only then fail the request. Signed-off-by: Michael Tretter --- drivers/usb/gadget/function/uvc_v4l2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index 3f728f451ed5..c5983bb0a8d1 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -317,11 +317,15 @@ uvc_v4l2_try_format(struct file *file, void *fh, struct v4l2_format *fmt) fmt->fmt.pix.width, fmt->fmt.pix.height); uformat = find_format_by_pix(uvc, fmt->fmt.pix.pixelformat); + if (!uformat) + uformat = get_default_format(uvc); if (!uformat) return -EINVAL; uframe = find_closest_frame_by_size(uvc, uformat, fmt->fmt.pix.width, fmt->fmt.pix.height); + if (!uframe) + uframe = get_default_frame(uvc, uformat); if (!uframe) return -EINVAL; From patchwork Thu Mar 23 11:41:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 13185563 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 66C5EC761AF for ; Thu, 23 Mar 2023 11:41:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231393AbjCWLll (ORCPT ); Thu, 23 Mar 2023 07:41:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35852 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231494AbjCWLlg (ORCPT ); Thu, 23 Mar 2023 07:41:36 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E61D0F746 for ; Thu, 23 Mar 2023 04:41:34 -0700 (PDT) Received: from dude05.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::54]) by metis.ext.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1pfJK0-0007OB-RV; Thu, 23 Mar 2023 12:41:32 +0100 From: Michael Tretter Date: Thu, 23 Mar 2023 12:41:15 +0100 Subject: [PATCH 7/8] usb: gadget: uvc: add colorspace handling MIME-Version: 1.0 Message-Id: <20230323-uvc-gadget-cleanup-v1-7-e41f0c5d9d8e@pengutronix.de> References: <20230323-uvc-gadget-cleanup-v1-0-e41f0c5d9d8e@pengutronix.de> In-Reply-To: <20230323-uvc-gadget-cleanup-v1-0-e41f0c5d9d8e@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman Cc: Michael Grzeschik , linux-usb@vger.kernel.org, linux-media@vger.kernel.org, kernel@pengutronix.de, Michael Tretter X-Mailer: b4 0.11.2 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::54 X-SA-Exim-Mail-From: m.tretter@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Store the values of the configured color space in the driver. This allows the user space to set the color space and re-read the set values later. UVC allows to announce the colorspace in the USB descriptors. The values of the descriptors are not evaluated by the driver, yet. Thus, the default is always the default specified by UVC and not the configured default. Signed-off-by: Michael Tretter --- drivers/usb/gadget/function/uvc.h | 4 ++++ drivers/usb/gadget/function/uvc_v4l2.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index 100475b1363e..6b4ab3e07173 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -96,6 +96,10 @@ struct uvc_video { unsigned int width; unsigned int height; unsigned int imagesize; + enum v4l2_colorspace colorspace; + enum v4l2_ycbcr_encoding ycbcr_enc; + enum v4l2_quantization quantization; + enum v4l2_xfer_func xfer_func; struct mutex mutex; /* protects frame parameters */ unsigned int uvc_num_requests; diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index c5983bb0a8d1..673532ff0faa 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -180,6 +180,11 @@ void uvc_init_default_format(struct uvc_device *uvc) video->height = 240; video->imagesize = 320 * 240 * 2; + video->colorspace = V4L2_COLORSPACE_SRGB; + video->quantization = V4L2_QUANTIZATION_FULL_RANGE; + video->xfer_func = V4L2_XFER_FUNC_SRGB; + video->ycbcr_enc = V4L2_YCBCR_ENC_601; + return; } @@ -196,6 +201,14 @@ void uvc_init_default_format(struct uvc_device *uvc) video->width = uframe->frame.w_width; video->height = uframe->frame.w_height; video->imagesize = uvc_get_frame_size(uformat, uframe); + + if (uformat->type == UVCG_UNCOMPRESSED) + video->colorspace = V4L2_COLORSPACE_SRGB; + else + video->colorspace = V4L2_COLORSPACE_JPEG; + video->quantization = V4L2_QUANTIZATION_FULL_RANGE; + video->xfer_func = V4L2_XFER_FUNC_SRGB; + video->ycbcr_enc = V4L2_YCBCR_ENC_601; } static struct uvcg_frame *find_closest_frame_by_size(struct uvc_device *uvc, @@ -294,7 +307,12 @@ uvc_v4l2_get_format(struct file *file, void *fh, struct v4l2_format *fmt) fmt->fmt.pix.field = V4L2_FIELD_NONE; fmt->fmt.pix.bytesperline = video->bpp * video->width / 8; fmt->fmt.pix.sizeimage = video->imagesize; - fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; + + fmt->fmt.pix.colorspace = video->colorspace; + fmt->fmt.pix.ycbcr_enc = video->ycbcr_enc; + fmt->fmt.pix.quantization = video->quantization; + fmt->fmt.pix.xfer_func = video->xfer_func; + fmt->fmt.pix.priv = 0; return 0; @@ -335,7 +353,12 @@ uvc_v4l2_try_format(struct file *file, void *fh, struct v4l2_format *fmt) fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(uformat, uframe); fmt->fmt.pix.sizeimage = uvc_get_frame_size(uformat, uframe); fmt->fmt.pix.pixelformat = to_uvc_format(uformat)->fcc; - fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; + + fmt->fmt.pix.colorspace = video->colorspace; + fmt->fmt.pix.ycbcr_enc = video->ycbcr_enc; + fmt->fmt.pix.quantization = video->quantization; + fmt->fmt.pix.xfer_func = video->xfer_func; + fmt->fmt.pix.priv = 0; return 0; @@ -359,6 +382,11 @@ uvc_v4l2_set_format(struct file *file, void *fh, struct v4l2_format *fmt) video->height = fmt->fmt.pix.height; video->imagesize = fmt->fmt.pix.sizeimage; + video->colorspace = fmt->fmt.pix.colorspace; + video->ycbcr_enc = fmt->fmt.pix.ycbcr_enc; + video->quantization = fmt->fmt.pix.quantization; + video->xfer_func = fmt->fmt.pix.xfer_func; + return ret; } From patchwork Thu Mar 23 11:41:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 13185564 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 82B05C76195 for ; Thu, 23 Mar 2023 11:41:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231560AbjCWLlm (ORCPT ); Thu, 23 Mar 2023 07:41:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35994 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231513AbjCWLlg (ORCPT ); Thu, 23 Mar 2023 07:41:36 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5438E1B327 for ; Thu, 23 Mar 2023 04:41:35 -0700 (PDT) Received: from dude05.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::54]) by metis.ext.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1pfJK1-0007OB-6p; Thu, 23 Mar 2023 12:41:33 +0100 From: Michael Tretter Date: Thu, 23 Mar 2023 12:41:16 +0100 Subject: [PATCH 8/8] usb: gadget: uvc: implement s/g_parm MIME-Version: 1.0 Message-Id: <20230323-uvc-gadget-cleanup-v1-8-e41f0c5d9d8e@pengutronix.de> References: <20230323-uvc-gadget-cleanup-v1-0-e41f0c5d9d8e@pengutronix.de> In-Reply-To: <20230323-uvc-gadget-cleanup-v1-0-e41f0c5d9d8e@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman Cc: Michael Grzeschik , linux-usb@vger.kernel.org, linux-media@vger.kernel.org, kernel@pengutronix.de, Michael Tretter X-Mailer: b4 0.11.2 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::54 X-SA-Exim-Mail-From: m.tretter@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org As the UVC gadget implements ENUM_FRAMEINTERVALS it should also implement S_PARM and G_PARM to allow to get and set the frame interval. While the driver doesn't actually do something with the frame interval, it should still handle and store the interval correctly, if the user space request it. Signed-off-by: Michael Tretter --- drivers/usb/gadget/function/uvc.h | 1 + drivers/usb/gadget/function/uvc_v4l2.c | 94 ++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index 6b4ab3e07173..a9a5a9d2f554 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -96,6 +96,7 @@ struct uvc_video { unsigned int width; unsigned int height; unsigned int imagesize; + struct v4l2_fract timeperframe; enum v4l2_colorspace colorspace; enum v4l2_ycbcr_encoding ycbcr_enc; enum v4l2_quantization quantization; diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index 673532ff0faa..a9564dc2445d 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -185,6 +185,9 @@ void uvc_init_default_format(struct uvc_device *uvc) video->xfer_func = V4L2_XFER_FUNC_SRGB; video->ycbcr_enc = V4L2_YCBCR_ENC_601; + video->timeperframe.numerator = 1; + video->timeperframe.denominator = 30; + return; } @@ -209,6 +212,11 @@ void uvc_init_default_format(struct uvc_device *uvc) video->quantization = V4L2_QUANTIZATION_FULL_RANGE; video->xfer_func = V4L2_XFER_FUNC_SRGB; video->ycbcr_enc = V4L2_YCBCR_ENC_601; + + video->timeperframe.numerator = uframe->frame.dw_default_frame_interval; + video->timeperframe.denominator = 10000000; + v4l2_simplify_fraction(&video->timeperframe.numerator, + &video->timeperframe.denominator, 8, 333); } static struct uvcg_frame *find_closest_frame_by_size(struct uvc_device *uvc, @@ -255,6 +263,46 @@ static struct uvcg_frame *find_closest_frame_by_size(struct uvc_device *uvc, return uframe; } +static void find_closest_timeperframe(struct uvc_device *uvc, + struct v4l2_fract *timeperframe) +{ + struct uvc_video *video = &uvc->video; + struct uvcg_format *uformat; + struct uvcg_frame *uframe; + unsigned long interval; + unsigned int best_interval; + unsigned int curr; + unsigned int dist; + unsigned int best_dist = UINT_MAX; + int i; + + if (timeperframe->denominator == 0) + timeperframe->denominator = video->timeperframe.denominator; + if (timeperframe->numerator == 0) + timeperframe->numerator = video->timeperframe.numerator; + + uformat = find_format_by_pix(uvc, video->fcc); + uframe = find_closest_frame_by_size(uvc, uformat, + video->width, video->height); + + interval = timeperframe->numerator * 10000000; + do_div(interval, timeperframe->denominator); + + for (i = 0; i < uframe->frame.b_frame_interval_type; i++) { + curr = uframe->dw_frame_interval[i]; + dist = interval > curr ? interval - curr : curr - interval; + if (dist < best_dist) { + best_dist = dist; + best_interval = curr; + } + } + + timeperframe->numerator = best_interval; + timeperframe->denominator = 10000000; + v4l2_simplify_fraction(&timeperframe->numerator, + &timeperframe->denominator, 8, 333); +} + /* -------------------------------------------------------------------------- * Requests handling */ @@ -456,6 +504,50 @@ uvc_v4l2_enum_framesizes(struct file *file, void *fh, return 0; } +static int +uvc_v4l2_s_parm(struct file *file, void *fh, struct v4l2_streamparm *parm) +{ + struct video_device *vdev = video_devdata(file); + struct uvc_device *uvc = video_get_drvdata(vdev); + struct uvc_video *video = &uvc->video; + struct v4l2_outputparm *out; + + if (parm->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && + parm->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + return -EINVAL; + + out = &parm->parm.output; + + memset(out->reserved, 0, sizeof(out->reserved)); + + out->capability = V4L2_CAP_TIMEPERFRAME; + find_closest_timeperframe(uvc, &out->timeperframe); + + video->timeperframe = out->timeperframe; + + return 0; +} + +static int +uvc_v4l2_g_parm(struct file *file, void *fh, struct v4l2_streamparm *parm) +{ + struct video_device *vdev = video_devdata(file); + struct uvc_device *uvc = video_get_drvdata(vdev); + struct uvc_video *video = &uvc->video; + struct v4l2_outputparm *out; + + if (parm->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && + parm->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + return -EINVAL; + + out = &parm->parm.output; + + out->capability |= V4L2_CAP_TIMEPERFRAME; + out->timeperframe = video->timeperframe; + + return 0; +} + static int uvc_v4l2_enum_format(struct file *file, void *fh, struct v4l2_fmtdesc *f) { @@ -671,6 +763,8 @@ const struct v4l2_ioctl_ops uvc_v4l2_ioctl_ops = { .vidioc_s_fmt_vid_out = uvc_v4l2_set_format, .vidioc_enum_frameintervals = uvc_v4l2_enum_frameintervals, .vidioc_enum_framesizes = uvc_v4l2_enum_framesizes, + .vidioc_g_parm = uvc_v4l2_g_parm, + .vidioc_s_parm = uvc_v4l2_s_parm, .vidioc_enum_fmt_vid_out = uvc_v4l2_enum_format, .vidioc_enum_output = uvc_v4l2_enum_output, .vidioc_g_output = uvc_v4l2_g_output,