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: 13185568 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 6F99CC7619A for ; Thu, 23 Mar 2023 11:41:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231527AbjCWLli (ORCPT ); Thu, 23 Mar 2023 07:41:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35862 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231182AbjCWLle (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 380911B2FA 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 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-usb@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@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: 13185566 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 BAFB9C6FD1D for ; Thu, 23 Mar 2023 11:41:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231496AbjCWLlg (ORCPT ); Thu, 23 Mar 2023 07:41:36 -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 S230459AbjCWLle (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 AF301F746 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-usb@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@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: 13185567 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 7DB11C6FD1C for ; Thu, 23 Mar 2023 11:41:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231526AbjCWLlh (ORCPT ); Thu, 23 Mar 2023 07:41:37 -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 S231265AbjCWLle (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 06302193F0 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 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-usb@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@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: 13185569 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 AB739C76195 for ; Thu, 23 Mar 2023 11:41:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231532AbjCWLlj (ORCPT ); Thu, 23 Mar 2023 07:41:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35916 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231340AbjCWLlf (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 5F77519F20 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 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-usb@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@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: 13185570 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 E718BC7619A for ; Thu, 23 Mar 2023 11:41:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231542AbjCWLlk (ORCPT ); Thu, 23 Mar 2023 07:41:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35930 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229532AbjCWLlf (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 A8BAF1E1E0 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-usb@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@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: 13185571 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 8BFC8C77B60 for ; Thu, 23 Mar 2023 11:41:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231550AbjCWLll (ORCPT ); Thu, 23 Mar 2023 07:41:41 -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 S231485AbjCWLlg (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 117601043F 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 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-usb@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@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: 13185572 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 D372BC6FD1C for ; Thu, 23 Mar 2023 11:41:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231572AbjCWLlm (ORCPT ); Thu, 23 Mar 2023 07:41:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36036 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230459AbjCWLlg (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 613E6222F8 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 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-usb@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@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: 13185573 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 5E674C6FD1D for ; Thu, 23 Mar 2023 11:41:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231580AbjCWLln (ORCPT ); Thu, 23 Mar 2023 07:41:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36038 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229451AbjCWLlg (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 E2F602CFD6 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-usb@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@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,