From patchwork Thu Nov 14 19:10:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Ribalda X-Patchwork-Id: 843397 Received: from mail-qv1-f51.google.com (mail-qv1-f51.google.com [209.85.219.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 86F0F19CCF9 for ; Thu, 14 Nov 2024 19:10:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611451; cv=none; b=N2xCjHAGLx5fVSXdAl+dQMo4UzMe6eg0nVDKuwV/TRjOiLp6tquQcnXqzuyC6obeo21JELZtMKCnhc/iiCkqZU8EmDG6acQabjzFNQTdRC64hofAAJOxA8CRKiY/saG4KjIdTHAyt8QwnmZTP+yKcoxbk/m8EOQwn13pU/r9Uqg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611451; c=relaxed/simple; bh=HxxCa8aCZqw7+XgedrXryM3g+ejWKITG5YuSOaGTAys=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=I6ESn8ZI47x/3yBHfFOOlFBUhgh4d27BXaX2Cd2bJqdLuPhD7C6x2wF7vFoygeakC/2ItIGcTHPsKCZay47b/m7awmXVglve5h6xgwaahKTq0+e27Aj+ZzPwyhpg/z1ulqVIbgGSIJ8ASJTKeiHmXQFSDufJFiKM/zrUOfyip04= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=e+YQAeE0; arc=none smtp.client-ip=209.85.219.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="e+YQAeE0" Received: by mail-qv1-f51.google.com with SMTP id 6a1803df08f44-6cbd00dd21cso4884526d6.3 for ; Thu, 14 Nov 2024 11:10:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1731611448; x=1732216248; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=1HI5lZXxKp42G1HCdhF2Z7i3opylcCsNhfoyIRTMS9o=; b=e+YQAeE0PLo4F9YV3TD5LJIvY1VTrmme8XYxDMNERysNMNkGySY2lHKmFW7fNSjvV0 Z91JUB1DM1GIs909S9FyvXqyanWhFAXctr+aTQfFMCFCXcqvuTP4evGstko+WJp88K5w 3xegb1di8HLTGCB8+i2YoT6dFxHNIxFd9ROJQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731611448; x=1732216248; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1HI5lZXxKp42G1HCdhF2Z7i3opylcCsNhfoyIRTMS9o=; b=WPtmPK2ykF8ACJcmbD5EUcY9cwe1ME3Xue+TmEZYXFzdJqJ5utLEA9KasmjMobBWOA gK1RHgKveXRcvsGvlwz7bgBIy2+VJ8DJY9WM9WGqvxUH4s0UjlVkGU9Q7ST/gwTg32WR N3vfq+LffWjZLC2Z78vd6AQg5SWqIYtDlOufLxWCAmeqY0jp0ZBydOPQi0UonEJpBR5C lkMCdVrU3rGxK6v18w39/VYcDCXeMewNDVVGVl5FdJbgqQqPJxlr12dWJ/9ZVgBuZRxQ KaJLIo6L61vCsx2SgwVbZ600sEKP1Xas1i9mxM0pEYeLZ/oqeegnNYdkqgx2yKr3BHlE lV8w== X-Forwarded-Encrypted: i=1; AJvYcCUXE6EeuK9+TaLVJo7InaUw/6X8gEAwnNPqGUuHtziRIyjEnebmJJcVdeVNeNcmW3mDjbGi3HLB5Mq2tg==@vger.kernel.org X-Gm-Message-State: AOJu0YxGp1E1wOltX60HkBUImDXl7u+hZEnIxyeVB6jmZyz+vDrLlGg3 OdHkc9mjBFFFRARI+/KwIhUquoFIWKYR9SvPoDdzP3a6BRyxA6loVB3njABWUw== X-Google-Smtp-Source: AGHT+IG2l3VxNXtNXIcocUyYR/QdBi0pnQ7Ege9NiZqMMQCPuL9w1s2C20GN87XZMBlYsQpbVArMSQ== X-Received: by 2002:a05:6214:3bc7:b0:6d3:9b88:db62 with SMTP id 6a1803df08f44-6d3d00bfd7dmr154515706d6.17.1731611446897; Thu, 14 Nov 2024 11:10:46 -0800 (PST) Received: from denia.c.googlers.com (189.216.85.34.bc.googleusercontent.com. [34.85.216.189]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-6d3ee7cc7e1sm8857766d6.53.2024.11.14.11.10.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Nov 2024 11:10:46 -0800 (PST) From: Ricardo Ribalda Date: Thu, 14 Nov 2024 19:10:31 +0000 Subject: [PATCH v15 02/19] media: v4l2_ctrl: Add V4L2_CTRL_TYPE_RECT Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241114-uvc-roi-v15-2-64cfeb56b6f8@chromium.org> References: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> In-Reply-To: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> To: Laurent Pinchart , Mauro Carvalho Chehab , Hans de Goede , Ricardo Ribalda , Sakari Ailus , Hans Verkuil Cc: Yunke Cao , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Ricardo Ribalda , Yunke Cao , Sergey Senozhatsky , Daniel Scally , Hans Verkuil X-Mailer: b4 0.13.0 From: Yunke Cao Add p_rect to struct v4l2_ext_control with basic support in v4l2-ctrls. Reviewed-by: Laurent Pinchart Reviewed-by: Ricardo Ribalda Reviewed-by: Sergey Senozhatsky Reviewed-by: Daniel Scally Signed-off-by: Yunke Cao Reviewed-by: Hans Verkuil Signed-off-by: Ricardo Ribalda --- .../userspace-api/media/v4l/vidioc-g-ext-ctrls.rst | 4 ++++ .../userspace-api/media/v4l/vidioc-queryctrl.rst | 7 +++++++ .../userspace-api/media/videodev2.h.rst.exceptions | 1 + drivers/media/v4l2-core/v4l2-ctrls-core.c | 16 +++++++++++++++- include/media/v4l2-ctrls.h | 2 ++ include/uapi/linux/videodev2.h | 2 ++ 6 files changed, 31 insertions(+), 1 deletion(-) diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst index 4d56c0528ad7..b74a74ac06fc 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst @@ -199,6 +199,10 @@ still cause this situation. - ``p_area`` - A pointer to a struct :c:type:`v4l2_area`. Valid if this control is of type ``V4L2_CTRL_TYPE_AREA``. + * - struct :c:type:`v4l2_rect` * + - ``p_rect`` + - A pointer to a struct :c:type:`v4l2_rect`. Valid if this control is + of type ``V4L2_CTRL_TYPE_RECT``. * - struct :c:type:`v4l2_ctrl_h264_sps` * - ``p_h264_sps`` - A pointer to a struct :c:type:`v4l2_ctrl_h264_sps`. Valid if this control is diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst index 4d38acafe8e1..56d5c8b0b88b 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst @@ -441,6 +441,13 @@ See also the examples in :ref:`control`. - n/a - A struct :c:type:`v4l2_area`, containing the width and the height of a rectangular area. Units depend on the use case. + * - ``V4L2_CTRL_TYPE_RECT`` + - n/a + - n/a + - n/a + - A struct :c:type:`v4l2_rect`, containing a rectangle described by + the position of its top-left corner, the width and the height. Units + depend on the use case. * - ``V4L2_CTRL_TYPE_H264_SPS`` - n/a - n/a diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions index 429b5cdf05c3..3cf1380b52b0 100644 --- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions +++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions @@ -150,6 +150,7 @@ replace symbol V4L2_CTRL_TYPE_HEVC_SPS :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_HEVC_PPS :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_AREA :c:type:`v4l2_ctrl_type` +replace symbol V4L2_CTRL_TYPE_RECT :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_FWHT_PARAMS :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_VP8_FRAME :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR :c:type:`v4l2_ctrl_type` diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c index eeab6a5eb7ba..4c8744c8cd96 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c @@ -370,7 +370,11 @@ void v4l2_ctrl_type_op_log(const struct v4l2_ctrl *ctrl) case V4L2_CTRL_TYPE_AV1_FILM_GRAIN: pr_cont("AV1_FILM_GRAIN"); break; - + case V4L2_CTRL_TYPE_RECT: + pr_cont("%ux%u@%dx%d", + ptr.p_rect->width, ptr.p_rect->height, + ptr.p_rect->left, ptr.p_rect->top); + break; default: pr_cont("unknown type %d", ctrl->type); break; @@ -815,6 +819,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering; struct v4l2_ctrl_hevc_decode_params *p_hevc_decode_params; struct v4l2_area *area; + struct v4l2_rect *rect; void *p = ptr.p + idx * ctrl->elem_size; unsigned int i; @@ -1172,6 +1177,12 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, return -EINVAL; break; + case V4L2_CTRL_TYPE_RECT: + rect = p; + if (!rect->width || !rect->height) + return -EINVAL; + break; + default: return -EINVAL; } @@ -1872,6 +1883,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, case V4L2_CTRL_TYPE_AREA: elem_size = sizeof(struct v4l2_area); break; + case V4L2_CTRL_TYPE_RECT: + elem_size = sizeof(struct v4l2_rect); + break; default: if (type < V4L2_CTRL_COMPOUND_TYPES) elem_size = sizeof(s32); diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index 59679a42b3e7..b0db167a3ac4 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -56,6 +56,7 @@ struct video_device; * @p_av1_tile_group_entry: Pointer to an AV1 tile group entry structure. * @p_av1_frame: Pointer to an AV1 frame structure. * @p_av1_film_grain: Pointer to an AV1 film grain structure. + * @p_rect: Pointer to a rectangle. * @p: Pointer to a compound value. * @p_const: Pointer to a constant compound value. */ @@ -89,6 +90,7 @@ union v4l2_ctrl_ptr { struct v4l2_ctrl_av1_tile_group_entry *p_av1_tile_group_entry; struct v4l2_ctrl_av1_frame *p_av1_frame; struct v4l2_ctrl_av1_film_grain *p_av1_film_grain; + struct v4l2_rect *p_rect; void *p; const void *p_const; }; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index e7c4dce39007..c1c2ae150d30 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1859,6 +1859,7 @@ struct v4l2_ext_control { __s32 __user *p_s32; __s64 __user *p_s64; struct v4l2_area __user *p_area; + struct v4l2_rect __user *p_rect; struct v4l2_ctrl_h264_sps __user *p_h264_sps; struct v4l2_ctrl_h264_pps __user *p_h264_pps; struct v4l2_ctrl_h264_scaling_matrix __user *p_h264_scaling_matrix; @@ -1929,6 +1930,7 @@ enum v4l2_ctrl_type { V4L2_CTRL_TYPE_U16 = 0x0101, V4L2_CTRL_TYPE_U32 = 0x0102, V4L2_CTRL_TYPE_AREA = 0x0106, + V4L2_CTRL_TYPE_RECT = 0x0107, V4L2_CTRL_TYPE_HDR10_CLL_INFO = 0x0110, V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY = 0x0111, From patchwork Thu Nov 14 19:10:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Ribalda X-Patchwork-Id: 843396 Received: from mail-qv1-f48.google.com (mail-qv1-f48.google.com [209.85.219.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1A1711A0AFB for ; Thu, 14 Nov 2024 19:10:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611452; cv=none; b=OR9rNimXx7tJja7VDZWeesGFgrrycqZQFNnCVjL+tXil29UbWyYfGH4VIoIqE44AZj4VZ6Sun4mAoLjaPzU7o/ImsqfzxBQHcClaH5Ld3ID1we6NtYcVRAGsyzBca+YmEfOcR1BfWAumfw7/h53sq5nLKrEHz1YDB/h3MrDpJnI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611452; c=relaxed/simple; bh=UYqmDYSRM45RrMYLdKAGuJZQsXVdmxTn5VBRrCL3DkA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=d9wi2W8B9AsQMuFCLVykeKVBsBcmJzFtAslHTYca6+sasfpDnTbrus2qC4acHzn/xBL55o9RS1Wi78Lvv02gkDTMYKyWbACtt2Xvn3Z1TxSy7GiPSKJH63j4/+YGAouriSGub9u3aPmzqx4E03VHm72r2HXeerzvlKYn/Js2tJI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=H/CfJtWv; arc=none smtp.client-ip=209.85.219.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="H/CfJtWv" Received: by mail-qv1-f48.google.com with SMTP id 6a1803df08f44-6cbceb321b3so6652766d6.3 for ; Thu, 14 Nov 2024 11:10:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1731611448; x=1732216248; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=SIEI9lOfs+bzPcK/C41IbD2ivUvc8o2wxWUbZzCDwRI=; b=H/CfJtWvB43Po4UpxlNnGQfAyAsHXpWqhAz42n8SiQ9EfIDLEDz14UO2GNlh1aKbmH SeAGSCUF7FP4CYbby5XxNPgaFTUUcSuju03VHToqm8SaY50l8MxbzaSC53PMrcY7PvRy 8eY42l+AU+gt4W6RtgTkwM5omS6Pu9v+av4IQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731611448; x=1732216248; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=SIEI9lOfs+bzPcK/C41IbD2ivUvc8o2wxWUbZzCDwRI=; b=pWL7gdvNRmypW4+ZMTTTrWAyFqcMo6AV9D7EHKDA0a9UpUOZuYx/H8ZXX424F+N0kA 29MBhs39tOKXPH+GM+mXXo206DrmH81CagaiNADRw+YnKkRvSjt7YSaIbT6DrB2ZniSD bOB+GlFZ5pwT3IWUIUtINnjV1+EmTcmHq+sBzwdd6OgKn1wYFSL1Uu82E9jnKOVbBRjO beLVRFgFECx2pYw9Ni6SaCczWgPRT1URW0RP0avgft7J/9OrdiHpImLexzKoMKNg4yoJ ZpqXh2tbyLcTeUNQM+yph0HBd7S2zgtFJVVA5MvyAau+E/C3qFS/Mxzd1BwqXQNymHt2 t7lw== X-Forwarded-Encrypted: i=1; AJvYcCUeJej9+POfW/MkfFi46Us+QX8moSXoFvYhvOkiAdoX3049BVdvrVyZSwLv/0o21hDyav0saD9g52OIdQ==@vger.kernel.org X-Gm-Message-State: AOJu0YxR9wxqJEtNMevNIv4JEKCnkjRL2QhPZsGdEjzEstb4sP+2fE6+ EWA71XS1WUu7m0aj9GmRMY6j0XpX+2Qpd1PFLdWLrA4H2SpJpz2H8cn/HYQYWg== X-Google-Smtp-Source: AGHT+IGBZ0Zs3F0vGo2Kfk7kybk38534C/ous9PQr2m3WH4T1AdeIQd+XBtNQgnTVRterfh0isoAQw== X-Received: by 2002:a05:6214:46a1:b0:6cb:f79a:cb38 with SMTP id 6a1803df08f44-6d39e107cfcmr371927836d6.5.1731611447762; Thu, 14 Nov 2024 11:10:47 -0800 (PST) Received: from denia.c.googlers.com (189.216.85.34.bc.googleusercontent.com. [34.85.216.189]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-6d3ee7cc7e1sm8857766d6.53.2024.11.14.11.10.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Nov 2024 11:10:47 -0800 (PST) From: Ricardo Ribalda Date: Thu, 14 Nov 2024 19:10:32 +0000 Subject: [PATCH v15 03/19] media: v4l2-ctrls: add support for V4L2_CTRL_WHICH_MIN/MAX_VAL Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241114-uvc-roi-v15-3-64cfeb56b6f8@chromium.org> References: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> In-Reply-To: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> To: Laurent Pinchart , Mauro Carvalho Chehab , Hans de Goede , Ricardo Ribalda , Sakari Ailus , Hans Verkuil Cc: Yunke Cao , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Ricardo Ribalda , Yunke Cao , Hans Verkuil X-Mailer: b4 0.13.0 From: Hans Verkuil Add the capability of retrieving the min and max values of a compound control. [Ricardo: Added static to v4l2_ctrl_type_op_(maximum|minimum) proto] [Ricardo: Fix documentation] Signed-off-by: Hans Verkuil Signed-off-by: Yunke Cao Signed-off-by: Ricardo Ribalda --- .../userspace-api/media/v4l/vidioc-g-ext-ctrls.rst | 22 ++- .../userspace-api/media/v4l/vidioc-queryctrl.rst | 9 +- .../userspace-api/media/videodev2.h.rst.exceptions | 3 + drivers/media/i2c/imx214.c | 4 +- drivers/media/platform/qcom/venus/venc_ctrls.c | 9 +- drivers/media/v4l2-core/v4l2-ctrls-api.c | 54 ++++++-- drivers/media/v4l2-core/v4l2-ctrls-core.c | 151 +++++++++++++++++---- drivers/media/v4l2-core/v4l2-ioctl.c | 4 +- include/media/v4l2-ctrls.h | 36 ++++- include/uapi/linux/videodev2.h | 3 + 10 files changed, 247 insertions(+), 48 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst index b74a74ac06fc..b8698b85bd80 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst @@ -338,14 +338,26 @@ still cause this situation. - Which value of the control to get/set/try. * - :cspan:`2` ``V4L2_CTRL_WHICH_CUR_VAL`` will return the current value of the control, ``V4L2_CTRL_WHICH_DEF_VAL`` will return the default - value of the control and ``V4L2_CTRL_WHICH_REQUEST_VAL`` indicates that - these controls have to be retrieved from a request or tried/set for - a request. In the latter case the ``request_fd`` field contains the + value of the control, ``V4L2_CTRL_WHICH_MIN_VAL`` will return the minimum + value of the control, and ``V4L2_CTRL_WHICH_MAX_VAL`` will return the maximum + value of the control. ``V4L2_CTRL_WHICH_REQUEST_VAL`` indicates that + the control value has to be retrieved from a request or tried/set for + a request. In that case the ``request_fd`` field contains the file descriptor of the request that should be used. If the device does not support requests, then ``EACCES`` will be returned. - When using ``V4L2_CTRL_WHICH_DEF_VAL`` be aware that you can only - get the default value of the control, you cannot set or try it. + When using ``V4L2_CTRL_WHICH_DEF_VAL``, ``V4L2_CTRL_WHICH_MIN_VAL`` + or ``V4L2_CTRL_WHICH_MAX_VAL`` be aware that you can only get the + default/minimum/maximum value of the control, you cannot set or try it. + + Whether a control supports querying the minimum and maximum values using + ``V4L2_CTRL_WHICH_MIN_VAL`` and ``V4L2_CTRL_WHICH_MAX_VAL`` is indicated + by the ``V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX`` flag. Most non-compound + control types support this. For controls with compound types, the + definition of minimum/maximum values are provided by + the control documentation. If a compound control does not document the + meaning of minimum/maximum value, then querying the minimum or maximum + value will result in the error code -EINVAL. For backwards compatibility you can also use a control class here (see :ref:`ctrl-class`). In that case all controls have to diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst index 56d5c8b0b88b..3549417c7feb 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst @@ -447,7 +447,10 @@ See also the examples in :ref:`control`. - n/a - A struct :c:type:`v4l2_rect`, containing a rectangle described by the position of its top-left corner, the width and the height. Units - depend on the use case. + depend on the use case. Support for ``V4L2_CTRL_WHICH_MIN_VAL`` and + ``V4L2_CTRL_WHICH_MAX_VAL`` is optional and depends on the + ``V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX`` flag. See the documentation of + the specific control on how to interpret the minimum and maximum values. * - ``V4L2_CTRL_TYPE_H264_SPS`` - n/a - n/a @@ -664,6 +667,10 @@ See also the examples in :ref:`control`. ``dims[0]``. So setting the control with a differently sized array will change the ``elems`` field when the control is queried afterwards. + * - ``V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX`` + - 0x1000 + - This control supports getting minimum and maximum values using + vidioc_g_ext_ctrls with V4L2_CTRL_WHICH_MIN/MAX_VAL. Return Value ============ diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions index 3cf1380b52b0..35d3456cc812 100644 --- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions +++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions @@ -396,6 +396,7 @@ replace define V4L2_CTRL_FLAG_HAS_PAYLOAD control-flags replace define V4L2_CTRL_FLAG_EXECUTE_ON_WRITE control-flags replace define V4L2_CTRL_FLAG_MODIFY_LAYOUT control-flags replace define V4L2_CTRL_FLAG_DYNAMIC_ARRAY control-flags +replace define V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX control-flags replace define V4L2_CTRL_FLAG_NEXT_CTRL control replace define V4L2_CTRL_FLAG_NEXT_COMPOUND control @@ -570,6 +571,8 @@ ignore define V4L2_CTRL_DRIVER_PRIV ignore define V4L2_CTRL_MAX_DIMS ignore define V4L2_CTRL_WHICH_CUR_VAL ignore define V4L2_CTRL_WHICH_DEF_VAL +ignore define V4L2_CTRL_WHICH_MIN_VAL +ignore define V4L2_CTRL_WHICH_MAX_VAL ignore define V4L2_CTRL_WHICH_REQUEST_VAL ignore define V4L2_OUT_CAP_CUSTOM_TIMINGS ignore define V4L2_CID_MAX_CTRLS diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c index 4962cfe7c83d..b0439005ec71 100644 --- a/drivers/media/i2c/imx214.c +++ b/drivers/media/i2c/imx214.c @@ -774,7 +774,9 @@ static int imx214_ctrls_init(struct imx214 *imx214) imx214->unit_size = v4l2_ctrl_new_std_compound(ctrl_hdlr, NULL, V4L2_CID_UNIT_CELL_SIZE, - v4l2_ctrl_ptr_create((void *)&unit_size)); + v4l2_ctrl_ptr_create((void *)&unit_size), + v4l2_ctrl_ptr_create(NULL), + v4l2_ctrl_ptr_create(NULL)); v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx214_ctrl_ops, &props); diff --git a/drivers/media/platform/qcom/venus/venc_ctrls.c b/drivers/media/platform/qcom/venus/venc_ctrls.c index 51801a962ed2..4d36c44f9d44 100644 --- a/drivers/media/platform/qcom/venus/venc_ctrls.c +++ b/drivers/media/platform/qcom/venus/venc_ctrls.c @@ -662,11 +662,16 @@ int venc_ctrl_init(struct venus_inst *inst) v4l2_ctrl_new_std_compound(&inst->ctrl_handler, &venc_ctrl_ops, V4L2_CID_COLORIMETRY_HDR10_CLL_INFO, - v4l2_ctrl_ptr_create(&p_hdr10_cll)); + v4l2_ctrl_ptr_create(&p_hdr10_cll), + v4l2_ctrl_ptr_create(NULL), + v4l2_ctrl_ptr_create(NULL)); v4l2_ctrl_new_std_compound(&inst->ctrl_handler, &venc_ctrl_ops, V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY, - v4l2_ctrl_ptr_create((void *)&p_hdr10_mastering)); + v4l2_ctrl_ptr_create((void *)&p_hdr10_mastering), + v4l2_ctrl_ptr_create(NULL), + v4l2_ctrl_ptr_create(NULL)); + v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE, diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c b/drivers/media/v4l2-core/v4l2-ctrls-api.c index 95a2202879d8..c61f3ec09d24 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-api.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c @@ -94,6 +94,22 @@ static int def_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) return ptr_to_user(c, ctrl, ctrl->p_new); } +/* Helper function: copy the minimum control value back to the caller */ +static int min_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) +{ + ctrl->type_ops->minimum(ctrl, 0, ctrl->p_new); + + return ptr_to_user(c, ctrl, ctrl->p_new); +} + +/* Helper function: copy the maximum control value back to the caller */ +static int max_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) +{ + ctrl->type_ops->maximum(ctrl, 0, ctrl->p_new); + + return ptr_to_user(c, ctrl, ctrl->p_new); +} + /* Helper function: copy the caller-provider value as the new control value */ static int user_to_new(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) { @@ -229,8 +245,8 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl, cs->error_idx = i; if (cs->which && - cs->which != V4L2_CTRL_WHICH_DEF_VAL && - cs->which != V4L2_CTRL_WHICH_REQUEST_VAL && + (cs->which < V4L2_CTRL_WHICH_DEF_VAL || + cs->which > V4L2_CTRL_WHICH_MAX_VAL) && V4L2_CTRL_ID2WHICH(id) != cs->which) { dprintk(vdev, "invalid which 0x%x or control id 0x%x\n", @@ -259,6 +275,15 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl, return -EINVAL; } + if (!(ctrl->flags & V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX) && + (cs->which == V4L2_CTRL_WHICH_MIN_VAL || + cs->which == V4L2_CTRL_WHICH_MAX_VAL)) { + dprintk(vdev, + "invalid which 0x%x or control id 0x%x\n", + cs->which, id); + return -EINVAL; + } + if (ctrl->cluster[0]->ncontrols > 1) have_clusters = true; if (ctrl->cluster[0] != ctrl) @@ -368,8 +393,8 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl, */ static int class_check(struct v4l2_ctrl_handler *hdl, u32 which) { - if (which == 0 || which == V4L2_CTRL_WHICH_DEF_VAL || - which == V4L2_CTRL_WHICH_REQUEST_VAL) + if (which == 0 || (which >= V4L2_CTRL_WHICH_DEF_VAL && + which <= V4L2_CTRL_WHICH_MAX_VAL)) return 0; return find_ref_lock(hdl, which | 1) ? 0 : -EINVAL; } @@ -389,10 +414,12 @@ int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl, struct v4l2_ctrl_helper *helpers = helper; int ret; int i, j; - bool is_default, is_request; + bool is_default, is_request, is_min, is_max; is_default = (cs->which == V4L2_CTRL_WHICH_DEF_VAL); is_request = (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL); + is_min = (cs->which == V4L2_CTRL_WHICH_MIN_VAL); + is_max = (cs->which == V4L2_CTRL_WHICH_MAX_VAL); cs->error_idx = cs->count; cs->which = V4L2_CTRL_ID2WHICH(cs->which); @@ -432,13 +459,14 @@ int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl, /* * g_volatile_ctrl will update the new control values. - * This makes no sense for V4L2_CTRL_WHICH_DEF_VAL and + * This makes no sense for V4L2_CTRL_WHICH_DEF_VAL, + * V4L2_CTRL_WHICH_MIN_VAL, V4L2_CTRL_WHICH_MAX_VAL and * V4L2_CTRL_WHICH_REQUEST_VAL. In the case of requests * it is v4l2_ctrl_request_complete() that copies the * volatile controls at the time of request completion * to the request, so you don't want to do that again. */ - if (!is_default && !is_request && + if (!is_default && !is_request && !is_min && !is_max && ((master->flags & V4L2_CTRL_FLAG_VOLATILE) || (master->has_volatiles && !is_cur_manual(master)))) { for (j = 0; j < master->ncontrols; j++) @@ -467,6 +495,10 @@ int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl, ret = -ENOMEM; else if (is_request && ref->p_req_valid) ret = req_to_user(cs->controls + idx, ref); + else if (is_min) + ret = min_to_user(cs->controls + idx, ref->ctrl); + else if (is_max) + ret = max_to_user(cs->controls + idx, ref->ctrl); else if (is_volatile) ret = new_to_user(cs->controls + idx, ref->ctrl); else @@ -564,9 +596,11 @@ int try_set_ext_ctrls_common(struct v4l2_fh *fh, cs->error_idx = cs->count; - /* Default value cannot be changed */ - if (cs->which == V4L2_CTRL_WHICH_DEF_VAL) { - dprintk(vdev, "%s: cannot change default value\n", + /* Default/minimum/maximum values cannot be changed */ + if (cs->which == V4L2_CTRL_WHICH_DEF_VAL || + cs->which == V4L2_CTRL_WHICH_MIN_VAL || + cs->which == V4L2_CTRL_WHICH_MAX_VAL) { + dprintk(vdev, "%s: cannot change default/min/max value\n", video_device_node_name(vdev)); return -EINVAL; } diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c index 4c8744c8cd96..d510ca67e815 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c @@ -182,29 +182,66 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx, } } -void v4l2_ctrl_type_op_init(const struct v4l2_ctrl *ctrl, u32 from_idx, +static void std_min_compound(const struct v4l2_ctrl *ctrl, u32 idx, + union v4l2_ctrl_ptr ptr) +{ + void *p = ptr.p + idx * ctrl->elem_size; + + if (ctrl->p_min.p_const) + memcpy(p, ctrl->p_min.p_const, ctrl->elem_size); + else + memset(p, 0, ctrl->elem_size); +} + +static void std_max_compound(const struct v4l2_ctrl *ctrl, u32 idx, union v4l2_ctrl_ptr ptr) +{ + void *p = ptr.p + idx * ctrl->elem_size; + + if (ctrl->p_max.p_const) + memcpy(p, ctrl->p_max.p_const, ctrl->elem_size); + else + memset(p, 0, ctrl->elem_size); +} + +static void __v4l2_ctrl_type_op_init(const struct v4l2_ctrl *ctrl, u32 from_idx, + u32 which, union v4l2_ctrl_ptr ptr) { unsigned int i; u32 tot_elems = ctrl->elems; u32 elems = tot_elems - from_idx; + s64 value; - if (from_idx >= tot_elems) + switch (which) { + case V4L2_CTRL_WHICH_DEF_VAL: + value = ctrl->default_value; + break; + case V4L2_CTRL_WHICH_MAX_VAL: + value = ctrl->maximum; + break; + case V4L2_CTRL_WHICH_MIN_VAL: + value = ctrl->minimum; + break; + default: return; + } switch (ctrl->type) { case V4L2_CTRL_TYPE_STRING: + if (which == V4L2_CTRL_WHICH_DEF_VAL) + value = ctrl->minimum; + for (i = from_idx; i < tot_elems; i++) { unsigned int offset = i * ctrl->elem_size; - memset(ptr.p_char + offset, ' ', ctrl->minimum); - ptr.p_char[offset + ctrl->minimum] = '\0'; + memset(ptr.p_char + offset, ' ', value); + ptr.p_char[offset + value] = '\0'; } break; case V4L2_CTRL_TYPE_INTEGER64: - if (ctrl->default_value) { + if (value) { for (i = from_idx; i < tot_elems; i++) - ptr.p_s64[i] = ctrl->default_value; + ptr.p_s64[i] = value; } else { memset(ptr.p_s64 + from_idx, 0, elems * sizeof(s64)); } @@ -214,9 +251,9 @@ void v4l2_ctrl_type_op_init(const struct v4l2_ctrl *ctrl, u32 from_idx, case V4L2_CTRL_TYPE_MENU: case V4L2_CTRL_TYPE_BITMASK: case V4L2_CTRL_TYPE_BOOLEAN: - if (ctrl->default_value) { + if (value) { for (i = from_idx; i < tot_elems; i++) - ptr.p_s32[i] = ctrl->default_value; + ptr.p_s32[i] = value; } else { memset(ptr.p_s32 + from_idx, 0, elems * sizeof(s32)); } @@ -226,32 +263,61 @@ void v4l2_ctrl_type_op_init(const struct v4l2_ctrl *ctrl, u32 from_idx, memset(ptr.p_s32 + from_idx, 0, elems * sizeof(s32)); break; case V4L2_CTRL_TYPE_U8: - memset(ptr.p_u8 + from_idx, ctrl->default_value, elems); + memset(ptr.p_u8 + from_idx, value, elems); break; case V4L2_CTRL_TYPE_U16: - if (ctrl->default_value) { + if (value) { for (i = from_idx; i < tot_elems; i++) - ptr.p_u16[i] = ctrl->default_value; + ptr.p_u16[i] = value; } else { memset(ptr.p_u16 + from_idx, 0, elems * sizeof(u16)); } break; case V4L2_CTRL_TYPE_U32: - if (ctrl->default_value) { + if (value) { for (i = from_idx; i < tot_elems; i++) - ptr.p_u32[i] = ctrl->default_value; + ptr.p_u32[i] = value; } else { memset(ptr.p_u32 + from_idx, 0, elems * sizeof(u32)); } break; default: - for (i = from_idx; i < tot_elems; i++) - std_init_compound(ctrl, i, ptr); + for (i = from_idx; i < tot_elems; i++) { + switch (which) { + case V4L2_CTRL_WHICH_DEF_VAL: + std_init_compound(ctrl, i, ptr); + break; + case V4L2_CTRL_WHICH_MAX_VAL: + std_max_compound(ctrl, i, ptr); + break; + case V4L2_CTRL_WHICH_MIN_VAL: + std_min_compound(ctrl, i, ptr); + break; + } + } break; } } + +void v4l2_ctrl_type_op_init(const struct v4l2_ctrl *ctrl, u32 from_idx, + union v4l2_ctrl_ptr ptr) +{ + __v4l2_ctrl_type_op_init(ctrl, from_idx, V4L2_CTRL_WHICH_DEF_VAL, ptr); +} EXPORT_SYMBOL(v4l2_ctrl_type_op_init); +static void v4l2_ctrl_type_op_minimum(const struct v4l2_ctrl *ctrl, + u32 from_idx, union v4l2_ctrl_ptr ptr) +{ + __v4l2_ctrl_type_op_init(ctrl, from_idx, V4L2_CTRL_WHICH_MIN_VAL, ptr); +} + +static void v4l2_ctrl_type_op_maximum(const struct v4l2_ctrl *ctrl, + u32 from_idx, union v4l2_ctrl_ptr ptr) +{ + __v4l2_ctrl_type_op_init(ctrl, from_idx, V4L2_CTRL_WHICH_MAX_VAL, ptr); +} + void v4l2_ctrl_type_op_log(const struct v4l2_ctrl *ctrl) { union v4l2_ctrl_ptr ptr = ctrl->p_cur; @@ -1296,6 +1362,8 @@ EXPORT_SYMBOL(v4l2_ctrl_type_op_validate); static const struct v4l2_ctrl_type_ops std_type_ops = { .equal = v4l2_ctrl_type_op_equal, .init = v4l2_ctrl_type_op_init, + .minimum = v4l2_ctrl_type_op_minimum, + .maximum = v4l2_ctrl_type_op_maximum, .log = v4l2_ctrl_type_op_log, .validate = v4l2_ctrl_type_op_validate, }; @@ -1768,7 +1836,10 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, s64 min, s64 max, u64 step, s64 def, const u32 dims[V4L2_CTRL_MAX_DIMS], u32 elem_size, u32 flags, const char * const *qmenu, - const s64 *qmenu_int, const union v4l2_ctrl_ptr p_def, + const s64 *qmenu_int, + const union v4l2_ctrl_ptr p_def, + const union v4l2_ctrl_ptr p_min, + const union v4l2_ctrl_ptr p_max, void *priv) { struct v4l2_ctrl *ctrl; @@ -1892,6 +1963,12 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, break; } + if (type < V4L2_CTRL_COMPOUND_TYPES && + type != V4L2_CTRL_TYPE_BUTTON && + type != V4L2_CTRL_TYPE_CTRL_CLASS && + type != V4L2_CTRL_TYPE_STRING) + flags |= V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX; + /* Sanity checks */ if (id == 0 || name == NULL || !elem_size || id >= V4L2_CID_PRIVATE_BASE || @@ -1900,6 +1977,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, handler_set_err(hdl, -ERANGE); return NULL; } + err = check_range(type, min, max, step, def); if (err) { handler_set_err(hdl, err); @@ -1941,6 +2019,10 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const) sz_extra += elem_size; + if (type >= V4L2_CTRL_COMPOUND_TYPES && p_min.p_const) + sz_extra += elem_size; + if (type >= V4L2_CTRL_COMPOUND_TYPES && p_max.p_const) + sz_extra += elem_size; ctrl = kvzalloc(sizeof(*ctrl) + sz_extra, GFP_KERNEL); if (ctrl == NULL) { @@ -2006,6 +2088,22 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, memcpy(ctrl->p_def.p, p_def.p_const, elem_size); } + if (flags & V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX) { + void *ptr = ctrl->p_def.p; + + if (p_min.p_const) { + ptr += elem_size; + ctrl->p_min.p = ptr; + memcpy(ctrl->p_min.p, p_min.p_const, elem_size); + } + + if (p_max.p_const) { + ptr += elem_size; + ctrl->p_max.p = ptr; + memcpy(ctrl->p_max.p, p_max.p_const, elem_size); + } + } + ctrl->type_ops->init(ctrl, 0, ctrl->p_cur); cur_to_new(ctrl); @@ -2056,7 +2154,8 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl, type, min, max, is_menu ? cfg->menu_skip_mask : step, def, cfg->dims, cfg->elem_size, - flags, qmenu, qmenu_int, cfg->p_def, priv); + flags, qmenu, qmenu_int, cfg->p_def, cfg->p_min, + cfg->p_max, priv); if (ctrl) ctrl->is_private = cfg->is_private; return ctrl; @@ -2081,7 +2180,8 @@ struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl, } return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, min, max, step, def, NULL, 0, - flags, NULL, NULL, ptr_null, NULL); + flags, NULL, NULL, ptr_null, ptr_null, + ptr_null, NULL); } EXPORT_SYMBOL(v4l2_ctrl_new_std); @@ -2114,7 +2214,8 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl, } return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, 0, max, mask, def, NULL, 0, - flags, qmenu, qmenu_int, ptr_null, NULL); + flags, qmenu, qmenu_int, ptr_null, ptr_null, + ptr_null, NULL); } EXPORT_SYMBOL(v4l2_ctrl_new_std_menu); @@ -2146,7 +2247,8 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl, } return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, 0, max, mask, def, NULL, 0, - flags, qmenu, NULL, ptr_null, NULL); + flags, qmenu, NULL, ptr_null, ptr_null, + ptr_null, NULL); } EXPORT_SYMBOL(v4l2_ctrl_new_std_menu_items); @@ -2154,7 +2256,9 @@ EXPORT_SYMBOL(v4l2_ctrl_new_std_menu_items); /* Helper function for standard compound controls */ struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl, const struct v4l2_ctrl_ops *ops, u32 id, - const union v4l2_ctrl_ptr p_def) + const union v4l2_ctrl_ptr p_def, + const union v4l2_ctrl_ptr p_min, + const union v4l2_ctrl_ptr p_max) { const char *name; enum v4l2_ctrl_type type; @@ -2168,7 +2272,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl, } return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, min, max, step, def, NULL, 0, - flags, NULL, NULL, p_def, NULL); + flags, NULL, NULL, p_def, p_min, p_max, NULL); } EXPORT_SYMBOL(v4l2_ctrl_new_std_compound); @@ -2192,7 +2296,8 @@ struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl, } return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, 0, max, 0, def, NULL, 0, - flags, NULL, qmenu_int, ptr_null, NULL); + flags, NULL, qmenu_int, ptr_null, ptr_null, + ptr_null, NULL); } EXPORT_SYMBOL(v4l2_ctrl_new_int_menu); diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 0304daa8471d..bfdba96e938c 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -893,7 +893,9 @@ static bool check_ext_ctrls(struct v4l2_ext_controls *c, unsigned long ioctl) return false; break; case V4L2_CTRL_WHICH_DEF_VAL: - /* Default value cannot be changed */ + case V4L2_CTRL_WHICH_MIN_VAL: + case V4L2_CTRL_WHICH_MAX_VAL: + /* Default, minimum or maximum value cannot be changed */ if (ioctl == VIDIOC_S_EXT_CTRLS || ioctl == VIDIOC_TRY_EXT_CTRLS) { c->error_idx = c->count; diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index b0db167a3ac4..9ed7be1e696f 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -133,6 +133,8 @@ struct v4l2_ctrl_ops { * * @equal: return true if all ctrl->elems array elements are equal. * @init: initialize the value for array elements from from_idx to ctrl->elems. + * @minimum: set the value to the minimum value of the control. + * @maximum: set the value to the maximum value of the control. * @log: log the value. * @validate: validate the value for ctrl->new_elems array elements. * Return 0 on success and a negative value otherwise. @@ -142,6 +144,10 @@ struct v4l2_ctrl_type_ops { union v4l2_ctrl_ptr ptr1, union v4l2_ctrl_ptr ptr2); void (*init)(const struct v4l2_ctrl *ctrl, u32 from_idx, union v4l2_ctrl_ptr ptr); + void (*minimum)(const struct v4l2_ctrl *ctrl, u32 idx, + union v4l2_ctrl_ptr ptr); + void (*maximum)(const struct v4l2_ctrl *ctrl, u32 idx, + union v4l2_ctrl_ptr ptr); void (*log)(const struct v4l2_ctrl *ctrl); int (*validate)(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr ptr); }; @@ -247,6 +253,12 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv); * @p_def: The control's default value represented via a union which * provides a standard way of accessing control types * through a pointer (for compound controls only). + * @p_min: The control's minimum value represented via a union which + * provides a standard way of accessing control types + * through a pointer (for compound controls only). + * @p_max: The control's maximum value represented via a union which + * provides a standard way of accessing control types + * through a pointer (for compound controls only). * @p_cur: The control's current value represented via a union which * provides a standard way of accessing control types * through a pointer. @@ -306,6 +318,8 @@ struct v4l2_ctrl { } cur; union v4l2_ctrl_ptr p_def; + union v4l2_ctrl_ptr p_min; + union v4l2_ctrl_ptr p_max; union v4l2_ctrl_ptr p_new; union v4l2_ctrl_ptr p_cur; }; @@ -425,6 +439,8 @@ struct v4l2_ctrl_handler { * @step: The control's step value for non-menu controls. * @def: The control's default value. * @p_def: The control's default value for compound controls. + * @p_min: The control's minimum value for compound controls. + * @p_max: The control's maximum value for compound controls. * @dims: The size of each dimension. * @elem_size: The size in bytes of the control. * @flags: The control's flags. @@ -454,6 +470,8 @@ struct v4l2_ctrl_config { u64 step; s64 def; union v4l2_ctrl_ptr p_def; + union v4l2_ctrl_ptr p_min; + union v4l2_ctrl_ptr p_max; u32 dims[V4L2_CTRL_MAX_DIMS]; u32 elem_size; u32 flags; @@ -723,17 +741,25 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl, * @ops: The control ops. * @id: The control ID. * @p_def: The control's default value. + * @p_min: The control's minimum value. + * @p_max: The control's maximum value. * - * Sames as v4l2_ctrl_new_std(), but with support to compound controls, thanks - * to the @p_def field. Use v4l2_ctrl_ptr_create() to create @p_def from a - * pointer. Use v4l2_ctrl_ptr_create(NULL) if the default value of the - * compound control should be all zeroes. + * Same as v4l2_ctrl_new_std(), but with support for compound controls. + * To fill in the @p_def, @p_min and @p_max fields, use v4l2_ctrl_ptr_create() + * to convert a pointer to a const union v4l2_ctrl_ptr. + * Use v4l2_ctrl_ptr_create(NULL) if you want the default, minimum or maximum + * value of the compound control to be all zeroes. + * If the compound control does not set the ``V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX`` + * flag, then it does not has minimum and maximum values. In that case just use + * v4l2_ctrl_ptr_create(NULL) for the @p_min and @p_max arguments. * */ struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl, const struct v4l2_ctrl_ops *ops, u32 id, - const union v4l2_ctrl_ptr p_def); + const union v4l2_ctrl_ptr p_def, + const union v4l2_ctrl_ptr p_min, + const union v4l2_ctrl_ptr p_max); /** * v4l2_ctrl_new_int_menu() - Create a new standard V4L2 integer menu control. diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index c1c2ae150d30..c8cb2796130f 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1912,6 +1912,8 @@ struct v4l2_ext_controls { #define V4L2_CTRL_WHICH_CUR_VAL 0 #define V4L2_CTRL_WHICH_DEF_VAL 0x0f000000 #define V4L2_CTRL_WHICH_REQUEST_VAL 0x0f010000 +#define V4L2_CTRL_WHICH_MIN_VAL 0x0f020000 +#define V4L2_CTRL_WHICH_MAX_VAL 0x0f030000 enum v4l2_ctrl_type { V4L2_CTRL_TYPE_INTEGER = 1, @@ -2019,6 +2021,7 @@ struct v4l2_querymenu { #define V4L2_CTRL_FLAG_EXECUTE_ON_WRITE 0x0200 #define V4L2_CTRL_FLAG_MODIFY_LAYOUT 0x0400 #define V4L2_CTRL_FLAG_DYNAMIC_ARRAY 0x0800 +#define V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX 0x1000 /* Query flags, to be ORed with the control ID */ #define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000 From patchwork Thu Nov 14 19:10:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Ribalda X-Patchwork-Id: 843395 Received: from mail-qk1-f174.google.com (mail-qk1-f174.google.com [209.85.222.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A3D171AA7AF for ; Thu, 14 Nov 2024 19:10:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611453; cv=none; b=m4AdEAEFG+kZ8PmtE/6p/nOyFhq+1GR2NPZKu1K1sFyQLbzsrtNwQ6k91ZxskAU+hueMEo2Es8gVzPxJZfJYmNweDCqwAc9KN8G9N25rZEcGZijo5RXPavjcamyi7Dks/anx8nN+rFEEtHzF6vluAISsf0sDNzZB+031xdbY4qI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611453; c=relaxed/simple; bh=rPQhRflph/OInqLTKMInrEsUWj88dYYh+206vtmsiRg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rsRYOLIGkx9Dl4CwWhneLdB073Kqu9CE1C92/uNE2bvCFEmRhlT1QjhWNBaWCwXBPczjNCE3ojI0vR4yaD6pCTos6r8lcchjsiDuhZrukhCIRfJP1C6wU+tD5J6nWO3EsnKn9pRXTV9c2ybvIZ+eSJbMZ4FMUCQpcJtfjpv9610= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=ab3VSkGU; arc=none smtp.client-ip=209.85.222.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="ab3VSkGU" Received: by mail-qk1-f174.google.com with SMTP id af79cd13be357-7b15d7b7a32so61824085a.1 for ; Thu, 14 Nov 2024 11:10:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1731611450; x=1732216250; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=pH1OuQ5/XwP0NAJGYmmTzFwWtNbM3f5Um97UBRgql50=; b=ab3VSkGUm3iJRXFp1KRbrezr7zk52+k68rw9vHTgPmR2Gni5OPfY1vcE0T+hsOTYna fJTDnSY++el4Pvs6+5XSPbGSUOOmJ+G/rmfyn11LjOz+r7a6dqEy0iBNYSRuGzhqzcmq qejw3zByGrFr23waC5XaABSh3r7lbzoJKGP8Y= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731611450; x=1732216250; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=pH1OuQ5/XwP0NAJGYmmTzFwWtNbM3f5Um97UBRgql50=; b=TtxAX+tdMW8BcDTIbuxowNT8ZTXmvzKU/DfSu0rmj5Ff8ClnvZWEfRIhbJbxi8j28Q HM6SkXWfAGmpNX1a786g/r2TLUruAN4UuawaaK1C352xlzmA+vv5tlZ3nXztQPgclMOu aWiS3DylF9D3BhTJDZDMG/WYisVNl9gAdaES4tieWErjY6Bqwey8K2vlA19/GNwRLtvP fO1gg47n/CCJrLIJImxVbXM3M1tOUBm0x2tijseir3RufeQVstdmO4S5GFCVAYxZqFWI C3pHlSGLxDG5Ge88qrZ0OJIFngI8xwVU+pXamyGMrZ40Rt0ZP3PWeqXpo1wiNduXr/Q/ B6Pg== X-Forwarded-Encrypted: i=1; AJvYcCUJvZ30uIXmdeJxLqONtVN8S0uQ4u5lwPgDEHlbdRYeYaQrywtmJ4Z2pTBgFTw13Koa7hLschziKxS6rQ==@vger.kernel.org X-Gm-Message-State: AOJu0YzAeKN8McgVRq8XdOktHHK6FJ/yRWaPGZ/V9E8jXjCq+XswB8Hp v3k7rscFZuVAvheHSRerJ31Fy/QvJwS6q3OTWNBzIxhZSNH/RuClRcSPymu0zg== X-Google-Smtp-Source: AGHT+IFTGsrShBjgM848OqL1CfPKk91R3Op/+31v6HbDQXfgIAqpr7uyzdwQGXGarOa1YbiIhfrByw== X-Received: by 2002:a05:6214:4347:b0:6ce:266a:85d5 with SMTP id 6a1803df08f44-6d39e14f151mr369822306d6.20.1731611450688; Thu, 14 Nov 2024 11:10:50 -0800 (PST) Received: from denia.c.googlers.com (189.216.85.34.bc.googleusercontent.com. [34.85.216.189]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-6d3ee7cc7e1sm8857766d6.53.2024.11.14.11.10.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Nov 2024 11:10:50 -0800 (PST) From: Ricardo Ribalda Date: Thu, 14 Nov 2024 19:10:35 +0000 Subject: [PATCH v15 06/19] media: uvcvideo: Handle uvc menu translation inside uvc_set_le_value Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241114-uvc-roi-v15-6-64cfeb56b6f8@chromium.org> References: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> In-Reply-To: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> To: Laurent Pinchart , Mauro Carvalho Chehab , Hans de Goede , Ricardo Ribalda , Sakari Ailus , Hans Verkuil Cc: Yunke Cao , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Ricardo Ribalda X-Mailer: b4 0.13.0 Be consistent with uvc_get_le_value() and do the menu translation there. Note that in this case, the refactor does not provide much... but consistency is a nice feature. Signed-off-by: Ricardo Ribalda --- drivers/media/usb/uvc/uvc_ctrl.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 77f7058ec966..c975e0ab479b 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -939,6 +939,8 @@ static void uvc_set_le_value(struct uvc_control_mapping *mapping, int offset = mapping->offset; u8 mask; + if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) + value = uvc_mapping_get_menu_value(mapping, value); /* * According to the v4l2 spec, writing any value to a button control * should result in the action belonging to the button control being @@ -1988,23 +1990,23 @@ int uvc_ctrl_set(struct uvc_fh *handle, if (!test_bit(xctrl->value, &mapping->menu_mask)) return -EINVAL; - value = uvc_mapping_get_menu_value(mapping, xctrl->value); - /* * Valid menu indices are reported by the GET_RES request for * UVC controls that support it. */ if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK) { + int val = uvc_mapping_get_menu_value(mapping, + xctrl->value); if (!ctrl->cached) { ret = uvc_ctrl_populate_cache(chain, ctrl); if (ret < 0) return ret; } - if (!(uvc_get_ctrl_bitmap(ctrl, mapping) & value)) + if (!(uvc_get_ctrl_bitmap(ctrl, mapping) & val)) return -EINVAL; } - + value = xctrl->value; break; default: From patchwork Thu Nov 14 19:10:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Ribalda X-Patchwork-Id: 843394 Received: from mail-qv1-f46.google.com (mail-qv1-f46.google.com [209.85.219.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AC4651AC428 for ; Thu, 14 Nov 2024 19:10:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611455; cv=none; b=IdnqknzgFl8HoN41i7HZm3Oyb01M6Wwg06cRdouupB8mRGVifbb9Le0kHAvnniu8TXT80WNV1MRSB3L1uncFBkjC1YnT+Iv15MYwhK0TyCP+Hmt6Oeu5axJDEk0x7yB03J3enhkC4wXhH/SSIuHiwjyee6LxN/BEnZjxV5j03AA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611455; c=relaxed/simple; bh=WuLUGkHs5rzPTrMYeFD9MhMpg+rW/hjaacAF210Zlvc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HIDa6SXEUxZ1NuVmW8tCpzN5m1noUV3ZKis4b/wVrLJyaA4DqtuplkWVdmcfcPUVTHBCRfO0Cu6Z5G4T6gqyGLWNUP9LsUalWjKfmj7A7ZGLE9WQbzCmbkORNLfZ1eAoKtAQJxwr2N16BnACqJ7muJ6cK+bg4gVZD7yIlDu+zp4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=Wi9nDRUG; arc=none smtp.client-ip=209.85.219.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="Wi9nDRUG" Received: by mail-qv1-f46.google.com with SMTP id 6a1803df08f44-6d3f6a548b2so3815416d6.2 for ; Thu, 14 Nov 2024 11:10:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1731611452; x=1732216252; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=Agd78fl9Wg05tfWj8TXE/qjuiAxKCZ/bzWF7jfaD9AQ=; b=Wi9nDRUGygxIy2h9iFUZPS+/9jSzndUdZMiRzz6bYdKMnxYrBb6yIH5vJa1GlWYoBs yhxx5EvC2TLKr+zVmJMmC2RVL0fggmukurTKf1TxAJMUtGshTxECtjRooJztzGmeW8gR c8FxR+GjREE6aCViOLxKaUirTgg5gIPpMcXzo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731611452; x=1732216252; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Agd78fl9Wg05tfWj8TXE/qjuiAxKCZ/bzWF7jfaD9AQ=; b=o6m4+PDIB0xGO39CHBNQBTj9oOF0c1RmNA85vAWrf/LCEI9UENFHnvzbB2Ph9OHmeh rtb0W9nULncpntsy5vDNcuy+F4o2TzswYljT/NYzaKzTJe8600eKLNXAWEYJgIt/V6Dh 56b47E2WXRoQNahR65FuU6LRLbERGLsh757hM/j6wLp3STeMFnJIqpAVGt4Ogy555ZYY XmaVR6vmExyCHX8Wsn9H543sYC980Lb4UVhzpNea/NPmfIVEbiWwyYa8WVVK8RqT9txN 1kkbgzQmpmzctAwc9ATWpKnquxYUqgM1XWtIVhVR7YuChU9qTa0OVgd3Q0U/qqcuNG07 GlNg== X-Forwarded-Encrypted: i=1; AJvYcCUj7SWuYIbhxrsgbI5uObO0q5giqU2mbDwcNGVJRoZeIlz+4lGAXcaCf3UHMFXqE9/2IHnR3yVz/jrXEA==@vger.kernel.org X-Gm-Message-State: AOJu0Yz1h8HGfvfBL3Bbva45+oapWgrpKbCqJFMwtPZE5s/HBJpZkiIv cLtNPPri8U3hYshQUnON9Cbref38asiLxH/XV11SVwTjHqQaPSsDIy4weq5tbA== X-Google-Smtp-Source: AGHT+IGfGZ77XmRsvM5pDShNqOVcnKjpwCHBu8ODcL423ifRxyF1TlWSXvxwnSO8pYYbWRznBIZQ6g== X-Received: by 2002:a05:6214:418e:b0:6cb:e632:a059 with SMTP id 6a1803df08f44-6d39e1f66b9mr323111656d6.49.1731611452695; Thu, 14 Nov 2024 11:10:52 -0800 (PST) Received: from denia.c.googlers.com (189.216.85.34.bc.googleusercontent.com. [34.85.216.189]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-6d3ee7cc7e1sm8857766d6.53.2024.11.14.11.10.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Nov 2024 11:10:52 -0800 (PST) From: Ricardo Ribalda Date: Thu, 14 Nov 2024 19:10:37 +0000 Subject: [PATCH v15 08/19] media: uvcvideo: uvc_ioctl_(g|s)_ext_ctrls: handle NoP case Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241114-uvc-roi-v15-8-64cfeb56b6f8@chromium.org> References: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> In-Reply-To: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> To: Laurent Pinchart , Mauro Carvalho Chehab , Hans de Goede , Ricardo Ribalda , Sakari Ailus , Hans Verkuil Cc: Yunke Cao , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Ricardo Ribalda X-Mailer: b4 0.13.0 If nothing needs to be done. Exit early. Signed-off-by: Ricardo Ribalda --- drivers/media/usb/uvc/uvc_v4l2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 02fd5cbc3474..65dbb53b1e75 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -1081,6 +1081,9 @@ static int uvc_ioctl_g_ext_ctrls(struct file *file, void *fh, u32 which; int ret; + if (!ctrls->count) + return 0; + switch (ctrls->which) { case V4L2_CTRL_WHICH_DEF_VAL: case V4L2_CTRL_WHICH_CUR_VAL: @@ -1121,6 +1124,9 @@ static int uvc_ioctl_s_try_ext_ctrls(struct uvc_fh *handle, unsigned int i; int ret; + if (!ctrls->count) + return 0; + ret = uvc_ctrl_check_access(chain, ctrls, ioctl); if (ret < 0) return ret; From patchwork Thu Nov 14 19:10:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Ribalda X-Patchwork-Id: 843393 Received: from mail-qk1-f172.google.com (mail-qk1-f172.google.com [209.85.222.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 04B5D1AF0AA for ; Thu, 14 Nov 2024 19:10:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611458; cv=none; b=HXvDIqkwRS8KunrSjJPeMARsRS4bqqgA/gbdQzOgl+ShSfoFgkYrkmMfhPTgfi/2J2nPMMdy9RFi/8j92527mAyIhZFTByXLm4HCB4JOo/K9WLXn0Sqx2VwJZSXXH6WO4G3BDtoEWsMbvgAbCjWqcHD4T+UgHH/W+1Ob3SeaOMo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611458; c=relaxed/simple; bh=eEpxjAmbwD3Lt+gRDs1Am6dF+cKdoldhzE/k4zEeBtQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WpZtSaCcBNiUaj6yn8QwruByZKuyKRmN8gLUfiOQemzzzSosdf6r/RmS3Bnk3LgWeJw0AR9V6lCD89EjFgANGNth0FA/U0lADXW7lrZX3u2Yvyh39SlZLXyy90Ob96vCO4aslx1H/Rnt6Pj5gLJiuGQ0xMICo4XekzBa7nCNxTo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=njsaxu8/; arc=none smtp.client-ip=209.85.222.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="njsaxu8/" Received: by mail-qk1-f172.google.com with SMTP id af79cd13be357-7b150dc7bc0so56998885a.1 for ; Thu, 14 Nov 2024 11:10:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1731611455; x=1732216255; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=zJbE2HWSb90CvyoZHkq71MDXLaiW+wPC8fPWnyVZD4E=; b=njsaxu8/gMz6dHHEwUP5vhf4ogLr9un9Am0HdzZG7ldwhAcb5jLWLGLD3XyQh+RqhJ Ltj0oLG4rnLlhFPYZzog3me/SgItAqOpR7uFCjbev2ZYgUrafyhTsiMZgXAENFnWzegW upFYjZ4jrkGwIRxpPa9sKfl7iZ/40XCkXgmWM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731611455; x=1732216255; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zJbE2HWSb90CvyoZHkq71MDXLaiW+wPC8fPWnyVZD4E=; b=GCTjGbYP1b7TwmLifMWSG03x1gVP1e9g2ArAv6+71dWQXrCzxTUaW00z5CpnOTlOnl PxYMfGjCPs4NYLuvi7YlCEPYR2gaSCraHrOju656gmm93TFV80QtK/N3S+D5OL8ZkUZw THlV6AzbBH9v7P0/8aNg/Knp2qqV1/MTM8ms7Lj/hLnQu2a4nMTnG/PhWRDxFBfjeZ/B 6+jtnY59KCQRAm/FgCwSmWsJaVfis6nZ7JFm0S2/Ms/I9k+4ufiN4oUHIfPPZjlaoVMi lWwiD/ktR0C9tsk00ze3XNA+QZ57ObHUZWzBCfdGFeV/ogjSqUF5Ck9pX/jgxN+w353v JE6A== X-Forwarded-Encrypted: i=1; AJvYcCUQLG4J/sPN91+6C9XvzDbFWsiqaJZv5EM3Kb4Y5LRQUq74GDXUR3c6wk/4gY2etnESNPQ8uB4FSVEOSg==@vger.kernel.org X-Gm-Message-State: AOJu0YxA0Fsh69ww1O9VNbp0zGekjui7Ql6loMIx9FVGArq+hQlDN70P hf+tCKzNC7PU0hnppsMujGiVM7tDcuSauA8OiKYXXTy9RzQNnlUwQqwnP277xA== X-Google-Smtp-Source: AGHT+IEvcPAJuJO2mAlNO/pEgGAbnA4uxX9GYiqUlzz3FMhGvdAEvXWG55u9OyHeUYdgEK9DLzdemw== X-Received: by 2002:a0c:9e81:0:b0:6d3:fa75:e9ed with SMTP id 6a1803df08f44-6d3fa75ec86mr4480876d6.41.1731611455074; Thu, 14 Nov 2024 11:10:55 -0800 (PST) Received: from denia.c.googlers.com (189.216.85.34.bc.googleusercontent.com. [34.85.216.189]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-6d3ee7cc7e1sm8857766d6.53.2024.11.14.11.10.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Nov 2024 11:10:54 -0800 (PST) From: Ricardo Ribalda Date: Thu, 14 Nov 2024 19:10:39 +0000 Subject: [PATCH v15 10/19] media: uvcvideo: Factor out clamping from uvc_ctrl_set Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241114-uvc-roi-v15-10-64cfeb56b6f8@chromium.org> References: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> In-Reply-To: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> To: Laurent Pinchart , Mauro Carvalho Chehab , Hans de Goede , Ricardo Ribalda , Sakari Ailus , Hans Verkuil Cc: Yunke Cao , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Ricardo Ribalda X-Mailer: b4 0.13.0 Move the logic to a separated function. Do not expect any change. This is a preparation for supporting compound controls. Signed-off-by: Ricardo Ribalda --- drivers/media/usb/uvc/uvc_ctrl.c | 82 +++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 6d5167eb368d..893d12cd3f90 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -2002,28 +2002,17 @@ int uvc_ctrl_get(struct uvc_video_chain *chain, u32 which, return -EINVAL; } -int uvc_ctrl_set(struct uvc_fh *handle, - struct v4l2_ext_control *xctrl) +static int uvc_ctrl_clamp(struct uvc_video_chain *chain, + struct uvc_control *ctrl, + struct uvc_control_mapping *mapping, + s32 *value_in_out) { - struct uvc_video_chain *chain = handle->chain; - struct uvc_control *ctrl; - struct uvc_control_mapping *mapping; - s32 value; + s32 value = *value_in_out; u32 step; s32 min; s32 max; int ret; - if (__uvc_query_v4l2_class(chain, xctrl->id, 0) >= 0) - return -EACCES; - - ctrl = uvc_find_control(chain, xctrl->id, &mapping); - if (ctrl == NULL) - return -EINVAL; - if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR)) - return -EACCES; - - /* Clamp out of range values. */ switch (mapping->v4l2_type) { case V4L2_CTRL_TYPE_INTEGER: if (!ctrl->cached) { @@ -2041,14 +2030,13 @@ int uvc_ctrl_set(struct uvc_fh *handle, if (step == 0) step = 1; - xctrl->value = min + DIV_ROUND_CLOSEST((u32)(xctrl->value - min), - step) * step; + value = min + DIV_ROUND_CLOSEST((u32)(value - min), step) * step; if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED) - xctrl->value = clamp(xctrl->value, min, max); + value = clamp(value, min, max); else - xctrl->value = clamp_t(u32, xctrl->value, min, max); - value = xctrl->value; - break; + value = clamp_t(u32, value, min, max); + *value_in_out = value; + return 0; case V4L2_CTRL_TYPE_BITMASK: if (!ctrl->cached) { @@ -2057,21 +2045,20 @@ int uvc_ctrl_set(struct uvc_fh *handle, return ret; } - xctrl->value &= uvc_get_ctrl_bitmap(ctrl, mapping); - value = xctrl->value; - break; + value &= uvc_get_ctrl_bitmap(ctrl, mapping); + *value_in_out = value; + return 0; case V4L2_CTRL_TYPE_BOOLEAN: - xctrl->value = clamp(xctrl->value, 0, 1); - value = xctrl->value; - break; + *value_in_out = clamp(value, 0, 1); + return 0; case V4L2_CTRL_TYPE_MENU: - if (xctrl->value < (ffs(mapping->menu_mask) - 1) || - xctrl->value > (fls(mapping->menu_mask) - 1)) + if (value < (ffs(mapping->menu_mask) - 1) || + value > (fls(mapping->menu_mask) - 1)) return -ERANGE; - if (!test_bit(xctrl->value, &mapping->menu_mask)) + if (!test_bit(value, &mapping->menu_mask)) return -EINVAL; /* @@ -2079,8 +2066,7 @@ int uvc_ctrl_set(struct uvc_fh *handle, * UVC controls that support it. */ if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK) { - int val = uvc_mapping_get_menu_value(mapping, - xctrl->value); + int val = uvc_mapping_get_menu_value(mapping, value); if (!ctrl->cached) { ret = uvc_ctrl_populate_cache(chain, ctrl); if (ret < 0) @@ -2090,14 +2076,34 @@ int uvc_ctrl_set(struct uvc_fh *handle, if (!(uvc_get_ctrl_bitmap(ctrl, mapping) & val)) return -EINVAL; } - value = xctrl->value; - break; + return 0; default: - value = xctrl->value; - break; + return 0; } + return 0; +} + +int uvc_ctrl_set(struct uvc_fh *handle, struct v4l2_ext_control *xctrl) +{ + struct uvc_video_chain *chain = handle->chain; + struct uvc_control_mapping *mapping; + struct uvc_control *ctrl; + int ret; + + if (__uvc_query_v4l2_class(chain, xctrl->id, 0) >= 0) + return -EACCES; + + ctrl = uvc_find_control(chain, xctrl->id, &mapping); + if (!ctrl) + return -EINVAL; + if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR)) + return -EACCES; + + ret = uvc_ctrl_clamp(chain, ctrl, mapping, &xctrl->value); + if (ret) + return ret; /* * If the mapping doesn't span the whole UVC control, the current value * needs to be loaded from the device to perform the read-modify-write @@ -2116,7 +2122,7 @@ int uvc_ctrl_set(struct uvc_fh *handle, ctrl->info.size); } - uvc_mapping_set_s32(mapping, value, + uvc_mapping_set_s32(mapping, xctrl->value, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) From patchwork Thu Nov 14 19:10:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Ribalda X-Patchwork-Id: 843392 Received: from mail-qv1-f47.google.com (mail-qv1-f47.google.com [209.85.219.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BE8A41B0F0B for ; Thu, 14 Nov 2024 19:10:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611459; cv=none; b=ltRKPCYmNr7vfeV0mk3lk1kfph8HbljjwOEERd+luMRQN2c9I6/hAGE3EExxwL/CjOvHeqw0jaFlhmg5C8EZytYgsozTqiJDS+w8uH5acmc6d6lG7OEwvnIm4MtCpxSZClyCanct3CV3yd3YrHWDNgznfG7dIcZxVbMN6J9iK8E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611459; c=relaxed/simple; bh=GTSzb2cA6iQFUD2LVLPdIY84kmKQY+ou4DnZ+2EhUOw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lxKXY9txNVPq043W9EfjrC94sQ5V1ay5xzIZIDyhf63YWCh8RC8vTob41tL/8Lw21XCkPwnlnooV7CEo20SWKLYbybY2Tnr2yHb7ZaB6NwVRNOrL0WBpFnFOl2uELgk5rrsglhfuB9RglakJO/gZNEBX1UpuYJOhy48Qc49OVbI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=Gqi+yGAh; arc=none smtp.client-ip=209.85.219.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="Gqi+yGAh" Received: by mail-qv1-f47.google.com with SMTP id 6a1803df08f44-6d382664fadso5471216d6.2 for ; Thu, 14 Nov 2024 11:10:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1731611457; x=1732216257; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=5zASJkExVzt3mz1dGZGb6YpVtR37par5ZxSQfpFLGtY=; b=Gqi+yGAhM2LqdtHWH811XnV+hAqDqK5dwBNWbFA8SUVMz55DsV2uRyAX4qJ4VQ/Zk/ OssuyR/KQhjnquiGC39u+FJF3jPNLWfaogRk6HyvB4cMzx60GuVwBx2YSjsACRbWuaSv mEUpapUskK6RkyHM4Xm1v0Mmlj6CSP8UletCs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731611457; x=1732216257; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=5zASJkExVzt3mz1dGZGb6YpVtR37par5ZxSQfpFLGtY=; b=qaZyG/q1/dA6JZdiDuPmDUS3nH0cuyPJhM5CkaeFQ8hQJsPciUQyeHkuFf6CTxwrq7 5sNuZLcV6PfGYzZcArH+Ca6pnWbXiQ6sV7N43ODIssgbZ2COL3bQbAqYniP17nqwN2nU Ioe00+82eCiG90HALa3z6mQtcOVDGhXEqpZuSFYWFjcSXAic8V9msUxC0GV8i+wS2NQD c/Es6qdKek3Ke6tNqdS0E8GEouILh/WLVyyYJ2i3Cy4qq+J8BT1YBzITac/r4H6Wol66 KL4z/MFL81qLfOk6+fu3Zd5n0cFtJKD1ONl1MSlhyNpQ/mszmd4qBZA+k24E48j31+0m 8GIw== X-Forwarded-Encrypted: i=1; AJvYcCUp0MtMmB6bxJBX5U/0qo839aYCFm+7N+TWI3yNY34lbnUpWnf1209r+s8FJawzs+IWdLXQU5iwQKeiUw==@vger.kernel.org X-Gm-Message-State: AOJu0Yz4Z8htgbzCPUO1GXx00cSUFkOEo2ypP4KU3QFFnbAdBnisQgkA 4EtQrQk7cLne+Exk3gvvWcnACdrQReMouKLb/J3HXLETwUpFSPrJcw5PYjhUYQ== X-Google-Smtp-Source: AGHT+IFwQipG5MnSIrGPPQp4Ve+16Xv+jGuSrD7kyFyzdHnlGC/qJY1Unw7LCbkK+PWogHsT4KSLpQ== X-Received: by 2002:a05:6214:118b:b0:6d3:dcce:a2d3 with SMTP id 6a1803df08f44-6d3dccea322mr96855556d6.47.1731611456783; Thu, 14 Nov 2024 11:10:56 -0800 (PST) Received: from denia.c.googlers.com (189.216.85.34.bc.googleusercontent.com. [34.85.216.189]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-6d3ee7cc7e1sm8857766d6.53.2024.11.14.11.10.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Nov 2024 11:10:56 -0800 (PST) From: Ricardo Ribalda Date: Thu, 14 Nov 2024 19:10:41 +0000 Subject: [PATCH v15 12/19] media: uvcvideo: Factor out query_boundaries from query_ctrl Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241114-uvc-roi-v15-12-64cfeb56b6f8@chromium.org> References: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> In-Reply-To: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> To: Laurent Pinchart , Mauro Carvalho Chehab , Hans de Goede , Ricardo Ribalda , Sakari Ailus , Hans Verkuil Cc: Yunke Cao , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Ricardo Ribalda X-Mailer: b4 0.13.0 Split the function in two parts. queryctrl_boundaries will be used in future patches. No functional change expected from this patch. Signed-off-by: Ricardo Ribalda --- drivers/media/usb/uvc/uvc_ctrl.c | 106 ++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 46 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index e51cd0a2228a..b591d7fddc37 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -1367,53 +1367,11 @@ static u32 uvc_get_ctrl_bitmap(struct uvc_control *ctrl, return ~0; } -static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, - struct uvc_control *ctrl, - struct uvc_control_mapping *mapping, - struct v4l2_queryctrl *v4l2_ctrl) +static int __uvc_queryctrl_boundaries(struct uvc_video_chain *chain, + struct uvc_control *ctrl, + struct uvc_control_mapping *mapping, + struct v4l2_queryctrl *v4l2_ctrl) { - struct uvc_control_mapping *master_map = NULL; - struct uvc_control *master_ctrl = NULL; - - memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl)); - v4l2_ctrl->id = mapping->id; - v4l2_ctrl->type = mapping->v4l2_type; - strscpy(v4l2_ctrl->name, uvc_map_get_name(mapping), - sizeof(v4l2_ctrl->name)); - v4l2_ctrl->flags = 0; - - if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) - v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY; - if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR)) - v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; - - if (mapping->master_id) - __uvc_find_control(ctrl->entity, mapping->master_id, - &master_map, &master_ctrl, 0, 0); - if (master_ctrl && (master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) { - s32 val; - int ret; - - if (WARN_ON(uvc_ctrl_mapping_is_compound(master_map))) - return -EIO; - - ret = __uvc_ctrl_get(chain, master_ctrl, master_map, &val); - if (ret < 0) - return ret; - - if (val != mapping->master_manual) - v4l2_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; - } - - if (v4l2_ctrl->type >= V4L2_CTRL_COMPOUND_TYPES) { - v4l2_ctrl->flags |= V4L2_CTRL_FLAG_HAS_PAYLOAD; - v4l2_ctrl->default_value = 0; - v4l2_ctrl->minimum = 0; - v4l2_ctrl->maximum = 0; - v4l2_ctrl->step = 0; - return 0; - } - if (!ctrl->cached) { int ret = uvc_ctrl_populate_cache(chain, ctrl); if (ret < 0) @@ -1456,18 +1414,74 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN) v4l2_ctrl->minimum = uvc_mapping_get_s32(mapping, UVC_GET_MIN, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN)); + else + v4l2_ctrl->minimum = 0; if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX) v4l2_ctrl->maximum = uvc_mapping_get_s32(mapping, UVC_GET_MAX, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX)); + else + v4l2_ctrl->maximum = 0; if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) v4l2_ctrl->step = uvc_mapping_get_s32(mapping, UVC_GET_RES, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); + else + v4l2_ctrl->step = 0; return 0; } +static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, + struct uvc_control *ctrl, + struct uvc_control_mapping *mapping, + struct v4l2_queryctrl *v4l2_ctrl) +{ + struct uvc_control_mapping *master_map = NULL; + struct uvc_control *master_ctrl = NULL; + + memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl)); + v4l2_ctrl->id = mapping->id; + v4l2_ctrl->type = mapping->v4l2_type; + strscpy(v4l2_ctrl->name, uvc_map_get_name(mapping), + sizeof(v4l2_ctrl->name)); + v4l2_ctrl->flags = 0; + + if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) + v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY; + if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR)) + v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; + + if (mapping->master_id) + __uvc_find_control(ctrl->entity, mapping->master_id, + &master_map, &master_ctrl, 0, 0); + if (master_ctrl && (master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) { + s32 val; + int ret; + + if (WARN_ON(uvc_ctrl_mapping_is_compound(master_map))) + return -EIO; + + ret = __uvc_ctrl_get(chain, master_ctrl, master_map, &val); + if (ret < 0) + return ret; + + if (val != mapping->master_manual) + v4l2_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; + } + + if (v4l2_ctrl->type >= V4L2_CTRL_COMPOUND_TYPES) { + v4l2_ctrl->flags |= V4L2_CTRL_FLAG_HAS_PAYLOAD; + v4l2_ctrl->default_value = 0; + v4l2_ctrl->minimum = 0; + v4l2_ctrl->maximum = 0; + v4l2_ctrl->step = 0; + return 0; + } + + return __uvc_queryctrl_boundaries(chain, ctrl, mapping, v4l2_ctrl); +} + int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, struct v4l2_queryctrl *v4l2_ctrl) { From patchwork Thu Nov 14 19:10:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Ribalda X-Patchwork-Id: 843391 Received: from mail-oo1-f43.google.com (mail-oo1-f43.google.com [209.85.161.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 634C41B0F3C for ; Thu, 14 Nov 2024 19:10:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611461; cv=none; b=LC5l9ZQuOwccuUCch1cH+Dx3mBwRSSMDJ15Jxb5vljZQ/WmdoHQFGEUgDuOsPbUgD1IMot3dh4VGsuBE4rXQfprpq+c2ZE3uqd22wrm8e122KUv/FryjxnAuWGFCZm3Ro8+8ovuqlvB4qyB5/mOISj55eTid8vtXbJnkrwqLyKU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611461; c=relaxed/simple; bh=EY5Eo52MkamV+RiJa+5OacEJMnFkljSo2OxdtrPOeRg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RWs6JuFNKRF5A+YsuCDFUjmV0KkPXv+5KWFXEDWPev+KUqMPfaEB9GQT1ynidndVM5YraeONVXmX4JGhKmC2OucxiYmlP1dU2dcwNFKyCIGEG/XqLR9L/qouzbTr7cPW+N+Y7FZLQKv/Q6bFkrSTFtVhdGZL8qaR6Hw4DVJFiuw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=OqYSFX5P; arc=none smtp.client-ip=209.85.161.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="OqYSFX5P" Received: by mail-oo1-f43.google.com with SMTP id 006d021491bc7-5ebc27fdc30so480649eaf.2 for ; Thu, 14 Nov 2024 11:10:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1731611458; x=1732216258; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=uFp+1e8oNM+DJbAtPSv+MyzrHN+BGnrJgCSNAWaI55I=; b=OqYSFX5P2wbtV/NYx1TnDFjnHWAAfLhTbsi2V6xwUnSHtvGPLOS6mdd1lTA0pd616G VqbP98GAxYOHGCtmHW3CoegmtVdFFS5oETPSd7gGGeriK9lmA6LlrIElX+fVe1DHFdQf MseJWhdlOxsZpyplHjHJ6HAkM84Z1yE7OG2BA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731611458; x=1732216258; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uFp+1e8oNM+DJbAtPSv+MyzrHN+BGnrJgCSNAWaI55I=; b=u4YmRY5kalxPFmIyfaeuAaJPPcFDUt4yvbrxMdoJijLTcQqkk6+OzKyR1VGHoU4+g9 WIoUCVf86vEz7vSC5tE9IUXtJXBRBE9ECibGZ+NCXopipH/ZPM4kEC9x4Y9CumHJMI4D cg+dCPs2TJzcHsyY9g/vYOC3ncFb+mZiSAg4g/y01tkElWsV/tYCnQ3f8LirN7OPD+O0 HxR5/8MZHSCiHjZtEl7sUAJF9k/zSx8DXnEM5RND+xzhS0k2ASvdUlOJW++V8HAw/Gpc wdPv03EprfJoTrHZ5ENAEvj8LQfiDYWdK0MbgOQu3eJVZcczwXwB9cZO8G+NrL52dfcI gTOA== X-Forwarded-Encrypted: i=1; AJvYcCXKLySuQAAzv/WUOpuzl5RyOEplOIO6HbvjPdUBq/DJyNzU8MHXG+2/5uZvb6qNIbbg85i0nwa1Hv08pA==@vger.kernel.org X-Gm-Message-State: AOJu0YzHcwfuo4Wi0n1pyqUOo1fIPrkzd5cOUgRfiirOgyuJxAXBN5VQ 2ZOzCZCO+fYaBmxXq5sIhOcwXge8ft+tdy1mY/kzYmkY83avIB1Amis7qUn6mg== X-Google-Smtp-Source: AGHT+IFNvD+gf1x55TT4Tlp5DIkK4UJiITK817j7zFhtUPdS3c13ovbIzET8/U/C8Kmf0gEGTY4ncg== X-Received: by 2002:a05:6359:5197:b0:1c3:e003:bddb with SMTP id e5c5f4694b2df-1c6cd2a3094mr13550655d.22.1731611458448; Thu, 14 Nov 2024 11:10:58 -0800 (PST) Received: from denia.c.googlers.com (189.216.85.34.bc.googleusercontent.com. [34.85.216.189]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-6d3ee7cc7e1sm8857766d6.53.2024.11.14.11.10.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Nov 2024 11:10:58 -0800 (PST) From: Ricardo Ribalda Date: Thu, 14 Nov 2024 19:10:43 +0000 Subject: [PATCH v15 14/19] media: uvcvideo: Use the camera to clamp compound controls Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241114-uvc-roi-v15-14-64cfeb56b6f8@chromium.org> References: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> In-Reply-To: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> To: Laurent Pinchart , Mauro Carvalho Chehab , Hans de Goede , Ricardo Ribalda , Sakari Ailus , Hans Verkuil Cc: Yunke Cao , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Ricardo Ribalda X-Mailer: b4 0.13.0 Compound controls cannot e reliable clamped. There is plenty of space for interpretation for the device manufacturer. When we write a compound control, let the camera do the clamping and return back to the user the value used by the device. Signed-off-by: Ricardo Ribalda --- drivers/media/usb/uvc/uvc_ctrl.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 0dae5e8c3ca0..72ed7dc9cfc1 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -2339,6 +2339,18 @@ int uvc_ctrl_set(struct uvc_fh *handle, struct v4l2_ext_control *xctrl) ctrl->dirty = 1; ctrl->modified = 1; + + /* + * Compound controls cannot reliable clamp the value when they are + * written to the device. Let the device do the clamping and read back + * the value that the device is using. We do not need to return an + * error if this fails. + */ + if (uvc_ctrl_mapping_is_compound(mapping) && + uvc_ctrl_is_readable(V4L2_CTRL_WHICH_CUR_VAL, ctrl, mapping)) + uvc_mapping_get_xctrl_compound(chain, ctrl, mapping, + V4L2_CTRL_WHICH_CUR_VAL, xctrl); + return 0; } From patchwork Thu Nov 14 19:10:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Ribalda X-Patchwork-Id: 843390 Received: from mail-ot1-f42.google.com (mail-ot1-f42.google.com [209.85.210.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D29A71B392B for ; Thu, 14 Nov 2024 19:11:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611463; cv=none; b=us8aPAfwIMM2alUkklGrM++nRfRMTj4p2BzaUCGJnoXKyV1A1NzgkdkG2ckDZtN3Zq8hJdNHk11VBBJy6XAmbPUEEy33tFgJPL8CSbXUWHBW4PMx7oCI4SQaJlbTGVwSgmZp5cbMn+zujaH5W0Mugr+19oHGB6SV+NebcjsmbSA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611463; c=relaxed/simple; bh=Z9uDVvItoljuKYfunavqY95I9UqlcIp6s4l6b4f5U+s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=u69HjTPfKTyKzF8JPV2zEaN2sTQy2aERmUY8oW6suCSI7fDZTQoAR067WX+Fhl6/VXM7SlW+wjsDR2CqI3Q3IKXMnDv+ALIkVx/dwbZGEZUyANONzLxS1jNagrmWx6P/qYKKIQoiu4sqS1XBuGYMLNWjAEVfOKkK/2qzU6/cTBc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=lMEET6M6; arc=none smtp.client-ip=209.85.210.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="lMEET6M6" Received: by mail-ot1-f42.google.com with SMTP id 46e09a7af769-7180cc146d8so511562a34.0 for ; Thu, 14 Nov 2024 11:11:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1731611461; x=1732216261; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=gBJrp7mg23fLq0H3uAUw+Zj5QMkIuMcISNIeTGg09NQ=; b=lMEET6M6y6+UZil4eqnYPfySGNnG4eIaQM0VKqVp+ea34cbS2IdDtYJp97f1KanE1g H2aRW94TK26jf/Soz/uM5L/RE4OqxZGoy1b3L08Qit3WDTFAh6GY22gCZz+0EfFEwg3f kJlAFX1EiubEjJfe2cu5xXfyda/nAhB13v3TI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731611461; x=1732216261; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gBJrp7mg23fLq0H3uAUw+Zj5QMkIuMcISNIeTGg09NQ=; b=puxO3+IGaYXopqa4jxsl4P4EBqG9UKNutR/ybug15gvjqgPpdljhZw2D1MwG38N0SN HXoiIKVKLt1SjXsNEcv+pI3P9ce88zrFNapjkoDMG8jiOGzjpblqBXEkalZJ2TjpkeWW 3t47eJ2G5cZ3nrkE6lYhShRI0V2yc5I6myMlkmz/U6kcPoad5UZHZS6R5f/wRF1Xo/Za Fx/CtV++B90h4eSZf2+SQ1LFl6wvR1aJUBnNRtJEjsZLXj+ZEeiTATknrfoD0qttAc0j zkE/nvaGv/yTh8mZt0kr43kbIaIA+DbzgnQ9pkUVrohgTjFRYvsLzcK5KZYmwFmCtalY +iVQ== X-Forwarded-Encrypted: i=1; AJvYcCXRA67sC99pi8GKdThpwbf25m26Q3REA13uXEmBiSApOPCdoPc5OtV81sySpG+di7R8nGEEuwZEdjHZ8g==@vger.kernel.org X-Gm-Message-State: AOJu0Yw4Vc0tQBSf+9ZdGCg+HMQ/JOgrublRi4H38ngZLw9rnHBn1iuM +8SYhwc7OngTZ7wJ29wvKsZDrnV+aoC/e3kJvy7qztFimwZoxRtjjsHzmcWHKw== X-Google-Smtp-Source: AGHT+IFNVlvDBjAW1cRege8knW5DelZl6pBdMLjl5E5lB/Wc9jyTp/KkdgXqMEneu89a9XWemF/hGg== X-Received: by 2002:a05:6358:c83:b0:1c3:7157:2868 with SMTP id e5c5f4694b2df-1c6cd108afdmr31228355d.20.1731611460947; Thu, 14 Nov 2024 11:11:00 -0800 (PST) Received: from denia.c.googlers.com (189.216.85.34.bc.googleusercontent.com. [34.85.216.189]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-6d3ee7cc7e1sm8857766d6.53.2024.11.14.11.11.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Nov 2024 11:11:00 -0800 (PST) From: Ricardo Ribalda Date: Thu, 14 Nov 2024 19:10:45 +0000 Subject: [PATCH v15 16/19] media: uvcvideo: Introduce uvc_mapping_v4l2_size Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241114-uvc-roi-v15-16-64cfeb56b6f8@chromium.org> References: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> In-Reply-To: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> To: Laurent Pinchart , Mauro Carvalho Chehab , Hans de Goede , Ricardo Ribalda , Sakari Ailus , Hans Verkuil Cc: Yunke Cao , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Ricardo Ribalda X-Mailer: b4 0.13.0 Centralize the calculation for the v4l2_size of a mapping. Signed-off-by: Ricardo Ribalda --- drivers/media/usb/uvc/uvc_ctrl.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 1bc019138995..f262e05ad3a8 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -1463,6 +1463,14 @@ static int __uvc_queryctrl_boundaries(struct uvc_video_chain *chain, return 0; } +static size_t uvc_mapping_v4l2_size(struct uvc_control_mapping *mapping) +{ + if (uvc_ctrl_mapping_is_compound(mapping)) + return DIV_ROUND_UP(mapping->size, 8); + + return sizeof(s32); +} + static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, struct uvc_control *ctrl, struct uvc_control_mapping *mapping, @@ -1504,7 +1512,7 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, v4l2_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; } - v4l2_ctrl->elem_size = sizeof(s32); + v4l2_ctrl->elem_size = uvc_mapping_v4l2_size(mapping); v4l2_ctrl->elems = 1; if (v4l2_ctrl->type >= V4L2_CTRL_COMPOUND_TYPES) { @@ -2093,7 +2101,7 @@ static int uvc_mapping_get_xctrl_compound(struct uvc_video_chain *chain, return -EINVAL; } - size = DIV_ROUND_UP(mapping->size, 8); + size = uvc_mapping_v4l2_size(mapping); if (xctrl->size < size) { xctrl->size = size; return -ENOSPC; @@ -2271,9 +2279,8 @@ static int uvc_mapping_set_xctrl_compound(struct uvc_control *ctrl, struct v4l2_ext_control *xctrl) { u8 *data __free(kfree) = NULL; - size_t size; + size_t size = uvc_mapping_v4l2_size(mapping); - size = DIV_ROUND_UP(mapping->size, 8); if (xctrl->size != size) return -EINVAL; From patchwork Thu Nov 14 19:10:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ricardo Ribalda X-Patchwork-Id: 843389 Received: from mail-qk1-f170.google.com (mail-qk1-f170.google.com [209.85.222.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 797E71B4C35 for ; Thu, 14 Nov 2024 19:11:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611465; cv=none; b=U8PuUt4BFgYCZwP8ZR506BP+1WKYY8BmpYqGvTcFMOPPPWFsMCLyfp9FPbqCozh9zc9NY08z/U2YWztMN0CiTAs7+3ywNiqh0lqveQwPomtaIyJ+XiqjUoigf2GjhyUusq2caruhFWH6jXRRpl5Db07ckBF4rimzWEtVh0yCUMQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731611465; c=relaxed/simple; bh=G5/w2LpBfII/nbK2O7RqW+iuApIAiWZ+5waBhl2Gw9s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=b2HOV4DrtibRVtID3hmkO2QMMEp/pvuel85rWcCuw4VJnGBOvpPP+WvtaDN9djnUqisx0niNe60wJYRk3E+7YXeSRxV1wBHYnjVuA0vS7wXfT8pDSEviqunHheI5xSlk0r8o9s9eCzKNteyD9dZgAF7awyUq/NnjR+SZ3TocxCw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=S/gNryTz; arc=none smtp.client-ip=209.85.222.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="S/gNryTz" Received: by mail-qk1-f170.google.com with SMTP id af79cd13be357-7b35b1ca0c2so116257585a.0 for ; Thu, 14 Nov 2024 11:11:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1731611462; x=1732216262; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=UcG3FhcuZvbG2+NnY7etdL0t4ZcduW99Sq/T3Mxk4/I=; b=S/gNryTzOns6I0sSuG8FgXJGCWOl6Q6wIc9olx9B+Hcw87xRgQjKHebbApc179VntG vQjqfBaPS4XJgzqnto4BucktBakgR3OGZVJYt5QwiDa0rEzOWKehkB8AXvW9fRoN4HHt Oyg/9ngVUH5EEZSEmA3ywN+VlWtFQZaT5cm2s= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731611462; x=1732216262; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=UcG3FhcuZvbG2+NnY7etdL0t4ZcduW99Sq/T3Mxk4/I=; b=Y9Ntuuvx5JMLyLAeA9llNGnEEjivrvqmkATKbdzAAtjPLkQ8o8dAz2LjDP2AUP0YuR QYUf0RxoIuY4ahaPppbPimNMe6mgQ4ve8xDU8LVGWDFHWjFLNhSDowVk8ZC49HvQFCiF Q2NDQPAFW4Eai/ktkVecsz2VcF4KSOy3LebddZgHEW95WSAteHfhi4YbSmKnciRYseSh lp1hMtMyu1zsjDPl/k+5U/8Gyd8e2AIicqwM7Nuuq1erVjclMS9hRnU/G+W2HJn8o0X+ vECjYTVsSPkGFK/uAT3rgzVTZHpaaVXRwTzDGsoVMKeBGo61KriFAVN5g81t+1FvUtv3 NPNw== X-Forwarded-Encrypted: i=1; AJvYcCU6b+2LhdtTA1OVldzOPz5UPH+prygEwRXSvDDNWI3yaYq4ePUCfPvEeQgu0DBbSCyDWJD5L3a8NjQJ5g==@vger.kernel.org X-Gm-Message-State: AOJu0YyrDlYwztzIdin5lTeByv4MKF/lFr8Js8a1Ag6CFLAH815nN7wD +X+W90j71YgB0kUhB/ilnewgcSEECwmyBxyGjw4H8mSkdkXWS/gudTxSD3dJfQ== X-Google-Smtp-Source: AGHT+IHuR1WrTlDipWbGX/ArVVt+6TY3Oto5+lhHEishv/BK6dw2+cEm5UP4ltJavxeCNCbGdQOA4A== X-Received: by 2002:ad4:5742:0:b0:6d3:5bcc:485c with SMTP id 6a1803df08f44-6d3e8dbbffcmr70212226d6.0.1731611462443; Thu, 14 Nov 2024 11:11:02 -0800 (PST) Received: from denia.c.googlers.com (189.216.85.34.bc.googleusercontent.com. [34.85.216.189]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-6d3ee7cc7e1sm8857766d6.53.2024.11.14.11.11.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Nov 2024 11:11:02 -0800 (PST) From: Ricardo Ribalda Date: Thu, 14 Nov 2024 19:10:47 +0000 Subject: [PATCH v15 18/19] media: uvcvideo: implement UVC v1.5 ROI Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241114-uvc-roi-v15-18-64cfeb56b6f8@chromium.org> References: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> In-Reply-To: <20241114-uvc-roi-v15-0-64cfeb56b6f8@chromium.org> To: Laurent Pinchart , Mauro Carvalho Chehab , Hans de Goede , Ricardo Ribalda , Sakari Ailus , Hans Verkuil Cc: Yunke Cao , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Ricardo Ribalda , Yunke Cao X-Mailer: b4 0.13.0 From: Yunke Cao Implement support for ROI as described in UVC 1.5: 4.2.2.1.20 Digital Region of Interest (ROI) Control ROI control is implemented using V4L2 control API as two UVC-specific controls: V4L2_CID_UVC_REGION_OF_INTEREST_RECT and V4L2_CID_UVC_REGION_OF_INTEREST_AUTO. Reviewed-by: Ricardo Ribalda Signed-off-by: Yunke Cao --- drivers/media/usb/uvc/uvc_ctrl.c | 81 ++++++++++++++++++++++++++++++++++++++ drivers/media/usb/uvc/uvcvideo.h | 7 ++++ include/uapi/linux/usb/video.h | 1 + include/uapi/linux/uvcvideo.h | 13 ++++++ include/uapi/linux/v4l2-controls.h | 9 +++++ 5 files changed, 111 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index f262e05ad3a8..5b619ef40dd3 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -358,6 +358,24 @@ static const struct uvc_control_info uvc_ctrls[] = { .flags = UVC_CTRL_FLAG_GET_CUR | UVC_CTRL_FLAG_AUTO_UPDATE, }, + /* + * UVC_CTRL_FLAG_AUTO_UPDATE is needed because the RoI may get updated + * by sensors. + * "This RoI should be the same as specified in most recent SET_CUR + * except in the case where the ‘Auto Detect and Track’ and/or + * ‘Image Stabilization’ bit have been set." + * 4.2.2.1.20 Digital Region of Interest (ROI) Control + */ + { + .entity = UVC_GUID_UVC_CAMERA, + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL, + .index = 21, + .size = 10, + .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR + | UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX + | UVC_CTRL_FLAG_GET_DEF + | UVC_CTRL_FLAG_AUTO_UPDATE, + }, }; static const u32 uvc_control_classes[] = { @@ -603,6 +621,44 @@ static const struct uvc_control_mapping *uvc_ctrl_filter_plf_mapping( return out_mapping; } +static int uvc_get_rect(struct uvc_control_mapping *mapping, u8 query, + const void *uvc_in, size_t v4l2_size, void *v4l2_out) +{ + const struct uvc_rect *uvc_rect = uvc_in; + struct v4l2_rect *v4l2_rect = v4l2_out; + + if (WARN_ON(v4l2_size != sizeof(struct v4l2_rect))) + return -EINVAL; + + if (uvc_rect->left > uvc_rect->right || + uvc_rect->top > uvc_rect->bottom) + return -EIO; + + v4l2_rect->top = uvc_rect->top; + v4l2_rect->left = uvc_rect->left; + v4l2_rect->height = uvc_rect->bottom - uvc_rect->top + 1; + v4l2_rect->width = uvc_rect->right - uvc_rect->left + 1; + + return 0; +} + +static int uvc_set_rect(struct uvc_control_mapping *mapping, size_t v4l2_size, + const void *v4l2_in, void *uvc_out) +{ + struct uvc_rect *uvc_rect = uvc_out; + const struct v4l2_rect *v4l2_rect = v4l2_in; + + if (WARN_ON(v4l2_size != sizeof(struct v4l2_rect))) + return -EINVAL; + + uvc_rect->top = max(0xffff, v4l2_rect->top); + uvc_rect->left = max(0xffff, v4l2_rect->left); + uvc_rect->bottom = max(0xffff, v4l2_rect->height + v4l2_rect->top - 1); + uvc_rect->right = max(0xffff, v4l2_rect->width + v4l2_rect->left - 1); + + return 0; +} + static const struct uvc_control_mapping uvc_ctrl_mappings[] = { { .id = V4L2_CID_BRIGHTNESS, @@ -897,6 +953,28 @@ static const struct uvc_control_mapping uvc_ctrl_mappings[] = { .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL, .filter_mapping = uvc_ctrl_filter_plf_mapping, }, + { + .id = V4L2_CID_UVC_REGION_OF_INTEREST_RECT, + .entity = UVC_GUID_UVC_CAMERA, + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL, + .size = sizeof(struct uvc_rect) * 8, + .offset = 0, + .v4l2_type = V4L2_CTRL_TYPE_RECT, + .data_type = UVC_CTRL_DATA_TYPE_RECT, + .get = uvc_get_rect, + .set = uvc_set_rect, + .name = "Region Of Interest Rectangle", + }, + { + .id = V4L2_CID_UVC_REGION_OF_INTEREST_AUTO, + .entity = UVC_GUID_UVC_CAMERA, + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL, + .size = 16, + .offset = 64, + .v4l2_type = V4L2_CTRL_TYPE_BITMASK, + .data_type = UVC_CTRL_DATA_TYPE_BITMASK, + .name = "Region Of Interest Auto Controls", + }, }; /* ------------------------------------------------------------------------ @@ -1465,6 +1543,9 @@ static int __uvc_queryctrl_boundaries(struct uvc_video_chain *chain, static size_t uvc_mapping_v4l2_size(struct uvc_control_mapping *mapping) { + if (mapping->v4l2_type == V4L2_CTRL_TYPE_RECT) + return sizeof(struct v4l2_rect); + if (uvc_ctrl_mapping_is_compound(mapping)) return DIV_ROUND_UP(mapping->size, 8); diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 8aca1a2fe587..d910a5e5b514 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -294,6 +294,13 @@ struct uvc_streaming_header { u8 bTriggerUsage; }; +struct uvc_rect { + u16 top; + u16 left; + u16 bottom; + u16 right; +} __packed; + enum uvc_buffer_state { UVC_BUF_STATE_IDLE = 0, UVC_BUF_STATE_QUEUED = 1, diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h index 2ff0e8a3a683..2afb4420e6c4 100644 --- a/include/uapi/linux/usb/video.h +++ b/include/uapi/linux/usb/video.h @@ -104,6 +104,7 @@ #define UVC_CT_ROLL_ABSOLUTE_CONTROL 0x0f #define UVC_CT_ROLL_RELATIVE_CONTROL 0x10 #define UVC_CT_PRIVACY_CONTROL 0x11 +#define UVC_CT_REGION_OF_INTEREST_CONTROL 0x14 /* A.9.5. Processing Unit Control Selectors */ #define UVC_PU_CONTROL_UNDEFINED 0x00 diff --git a/include/uapi/linux/uvcvideo.h b/include/uapi/linux/uvcvideo.h index f86185456dc5..cbe15bca9569 100644 --- a/include/uapi/linux/uvcvideo.h +++ b/include/uapi/linux/uvcvideo.h @@ -16,6 +16,7 @@ #define UVC_CTRL_DATA_TYPE_BOOLEAN 3 #define UVC_CTRL_DATA_TYPE_ENUM 4 #define UVC_CTRL_DATA_TYPE_BITMASK 5 +#define UVC_CTRL_DATA_TYPE_RECT 6 /* Control flags */ #define UVC_CTRL_FLAG_SET_CUR (1 << 0) @@ -38,6 +39,18 @@ #define UVC_MENU_NAME_LEN 32 +/* V4L2 driver-specific controls */ +#define V4L2_CID_UVC_REGION_OF_INTEREST_RECT (V4L2_CID_USER_UVC_BASE + 1) +#define V4L2_CID_UVC_REGION_OF_INTEREST_AUTO (V4L2_CID_USER_UVC_BASE + 2) +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_EXPOSURE (1 << 0) +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_IRIS (1 << 1) +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_WHITE_BALANCE (1 << 2) +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_FOCUS (1 << 3) +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_FACE_DETECT (1 << 4) +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_DETECT_AND_TRACK (1 << 5) +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_IMAGE_STABILIZATION (1 << 6) +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_HIGHER_QUALITY (1 << 7) + struct uvc_menu_info { __u32 value; __u8 name[UVC_MENU_NAME_LEN]; diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index 974fd254e573..6c91d6fa4708 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -215,6 +215,13 @@ enum v4l2_colorfx { */ #define V4L2_CID_USER_THP7312_BASE (V4L2_CID_USER_BASE + 0x11c0) +/* + * The base for the uvc driver controls. + * See linux/uvcvideo.h for the list of controls. + * We reserve 64 controls for this driver. + */ +#define V4L2_CID_USER_UVC_BASE (V4L2_CID_USER_BASE + 0x11e0) + /* MPEG-class control IDs */ /* The MPEG controls are applicable to all codec controls * and the 'MPEG' part of the define is historical */ @@ -1089,6 +1096,8 @@ enum v4l2_auto_focus_range { #define V4L2_CID_HDR_SENSOR_MODE (V4L2_CID_CAMERA_CLASS_BASE+36) +/* CAMERA-class private control IDs */ + /* FM Modulator class control IDs */ #define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)