From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B2C282BD932; Mon, 5 May 2025 22:47:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746485226; cv=none; b=kM3B67GqsFKYqhBe4jlM/HhHisQGLGXnVqBQgZas9U3x9ijXyhSTyhJ71C3xyXb/tujgwjNIV+YUd7RlFgv0+7ExGXhYAPreSHDB9zTMYXpj3LiML/kbSbp7E9gFVTfmoSqTVVywry3KDVT9niGW3yak32Kyb65wy2fAaZ4IGUM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746485226; c=relaxed/simple; bh=5EullgelvG9T7O6H1QgaCM1QPpNnDFhnOaZ4J/gB9p8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=U9k/dauPgzwavy6bDbElU7MpHXTYqAjuzixSWqZV3bNNaFfQXix7HwwhvvApurjyBtA6WEZ+zkWodyPDwktecFkm1e7MSZMY9lpWHdKbYKiS5DM1AX0H0u/p0AUf6O0GHg1uCamlSMm184p+oB6loY5BQXQFKGYuwk595XbE3rU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kwtHLWOd; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kwtHLWOd" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 81119C4CEEF; Mon, 5 May 2025 22:47:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746485225; bh=5EullgelvG9T7O6H1QgaCM1QPpNnDFhnOaZ4J/gB9p8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kwtHLWOdP+7bRr0/Jo1HtTBrYBzLCw++09FkQiYhM1Y5ZRKCKrhg5rNYDRxH/juS3 zQcGRYzlvuiGQd8uq3KXvpx8eYj9H1B7TWruWziPrLcp4wdOMOz6A6YoReQcpb8cz4 LakP6uR/OCqXHz7LY+JdDLSN+EoL8jNDRFPkRjfMaIEwpN9na0gjwDMmRwJXm8We6I +MFmbm/X/aTQa27+3m3VRur5K6iEb1YHhei/5c//ykXNIb6eJEv9waY0oVMmLH+njD 6tta1biycZkKpsn5eCy2sPAWvcLm2VDz1+n7xX7MhAgu4K3i47RpZPn+0DbqUKOwcJ k7GQqBCaGtI3Q== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Ricardo Ribalda , Hans de Goede , Yunke Cao , Hans Verkuil , Sasha Levin , laurent.pinchart@ideasonboard.com, mchehab@kernel.org, linux-media@vger.kernel.org Subject: [PATCH AUTOSEL 6.12 221/486] media: uvcvideo: Handle uvc menu translation inside uvc_get_le_value Date: Mon, 5 May 2025 18:34:57 -0400 Message-Id: <20250505223922.2682012-221-sashal@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250505223922.2682012-1-sashal@kernel.org> References: <20250505223922.2682012-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 6.12.26 Content-Transfer-Encoding: 8bit From: Ricardo Ribalda [ Upstream commit 9109a0b4cb10fd681e9c6e9a4497a6fec5b91c39 ] map->get() gets a value from an uvc_control in "UVC format" and converts it to a value that can be consumed by v4l2. Instead of using a special get function for V4L2_CTRL_TYPE_MENU, we were converting from uvc_get_le_value in two different places. Move the conversion to uvc_get_le_value(). Reviewed-by: Hans de Goede Tested-by: Yunke Cao Signed-off-by: Ricardo Ribalda Link: https://lore.kernel.org/r/20250203-uvc-roi-v17-4-5900a9fed613@chromium.org Signed-off-by: Hans de Goede Signed-off-by: Hans Verkuil Signed-off-by: Sasha Levin --- drivers/media/usb/uvc/uvc_ctrl.c | 77 +++++++++++++------------------- 1 file changed, 32 insertions(+), 45 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 4837d8df9c038..58d1bc80253e8 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -862,6 +862,25 @@ static inline void uvc_clear_bit(u8 *data, int bit) data[bit >> 3] &= ~(1 << (bit & 7)); } +static s32 uvc_menu_to_v4l2_menu(struct uvc_control_mapping *mapping, s32 val) +{ + unsigned int i; + + for (i = 0; BIT(i) <= mapping->menu_mask; ++i) { + u32 menu_value; + + if (!test_bit(i, &mapping->menu_mask)) + continue; + + menu_value = uvc_mapping_get_menu_value(mapping, i); + + if (menu_value == val) + return i; + } + + return val; +} + /* * Extract the bit string specified by mapping->offset and mapping->size * from the little-endian data stored at 'data' and return the result as @@ -896,6 +915,16 @@ static s32 uvc_get_le_value(struct uvc_control_mapping *mapping, if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED) value |= -(value & (1 << (mapping->size - 1))); + /* If it is a menu, convert from uvc to v4l2. */ + if (mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) + return value; + + switch (query) { + case UVC_GET_CUR: + case UVC_GET_DEF: + return uvc_menu_to_v4l2_menu(mapping, value); + } + return value; } @@ -1060,32 +1089,6 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain, return 0; } -static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping, - const u8 *data) -{ - s32 value = mapping->get(mapping, UVC_GET_CUR, data); - - if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) { - unsigned int i; - - for (i = 0; BIT(i) <= mapping->menu_mask; ++i) { - u32 menu_value; - - if (!test_bit(i, &mapping->menu_mask)) - continue; - - menu_value = uvc_mapping_get_menu_value(mapping, i); - - if (menu_value == value) { - value = i; - break; - } - } - } - - return value; -} - static int __uvc_ctrl_load_cur(struct uvc_video_chain *chain, struct uvc_control *ctrl) { @@ -1136,8 +1139,8 @@ static int __uvc_ctrl_get(struct uvc_video_chain *chain, if (ret < 0) return ret; - *value = __uvc_ctrl_get_value(mapping, - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); + *value = mapping->get(mapping, UVC_GET_CUR, + uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); return 0; } @@ -1287,7 +1290,6 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, { struct uvc_control_mapping *master_map = NULL; struct uvc_control *master_ctrl = NULL; - unsigned int i; memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl)); v4l2_ctrl->id = mapping->id; @@ -1330,21 +1332,6 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, v4l2_ctrl->minimum = ffs(mapping->menu_mask) - 1; v4l2_ctrl->maximum = fls(mapping->menu_mask) - 1; v4l2_ctrl->step = 1; - - for (i = 0; BIT(i) <= mapping->menu_mask; ++i) { - u32 menu_value; - - if (!test_bit(i, &mapping->menu_mask)) - continue; - - menu_value = uvc_mapping_get_menu_value(mapping, i); - - if (menu_value == v4l2_ctrl->default_value) { - v4l2_ctrl->default_value = i; - break; - } - } - return 0; case V4L2_CTRL_TYPE_BOOLEAN: @@ -1627,7 +1614,7 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain, uvc_ctrl_set_handle(handle, ctrl, NULL); list_for_each_entry(mapping, &ctrl->info.mappings, list) { - s32 value = __uvc_ctrl_get_value(mapping, data); + s32 value = mapping->get(mapping, UVC_GET_CUR, data); /* * handle may be NULL here if the device sends auto-update -- 2.39.5