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 B296D2857E1; Mon, 5 May 2025 22:25:40 +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=1746483940; cv=none; b=NFLIyX5owZ7mtVjYqDfbUl0DEe1iGbyQNvA/S3VxQZPOh18INzKinAP3Y/2WQ7imE0EGvRTz0r/d4p7q+yGZMmpsiKsxpS00IjVp/FdrAmT4DzkcLTSZFrYyO6lb0oHqf+QXmi33LI6VMSKBP/+nPcWBKeTA0oUz/khKuSfcM9A= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746483940; c=relaxed/simple; bh=IKu4h9ZWOLtvpnqLJRj2ND9OQ+s0EXys6cwEegcLOq0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=HdORn5ebEYM8w/ylktYEK9eoMn3XGEEa4D51tBlolJXlFL/nFukkZgA76rL3ZpXTT0Zl1kfptwuC9oY+VB9my4VmAE9UOGXIMK+e87h10dx0fmP9OKoV90SQjADVPqNMSTMcFn8/v9acVdf+5WnzeARYAx5uSwBmkCNmqiJ137Y= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZvSgxfx4; 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="ZvSgxfx4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0787FC4CEF1; Mon, 5 May 2025 22:25:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746483940; bh=IKu4h9ZWOLtvpnqLJRj2ND9OQ+s0EXys6cwEegcLOq0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZvSgxfx4hOoCbSuHQrQa/jpRt/xcig16twsZWw3xQixrrrduxPD9Sta0h7qtfF9kB SIVdmudbl6pOIRXycz++TOes0Z5Z2yHpLe4eiEqDHeeEcjllr5qCGzAqqI+Cf5AnI8 eovw193OINPkrmJD4x0umhyXpeWaMpmEe9Zae8a3lIbxrQ2tVphoZwN4M/BzLKIlVp zIAsLxoifD50lu9QXcvMXWlGVPg0DmYyllx6+BhXpCnbpjiWDLOgwqWkk27JEiyguo JYVNFAVpOhyP1i0XIv7G6ReTHaV1Dljvnm2jyXgoRCO+Evmn0sebelVBrv9jOWBvGN usiuvVLAoz+Ng== 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.14 280/642] media: uvcvideo: Handle uvc menu translation inside uvc_get_le_value Date: Mon, 5 May 2025 18:08:16 -0400 Message-Id: <20250505221419.2672473-280-sashal@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250505221419.2672473-1-sashal@kernel.org> References: <20250505221419.2672473-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@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.14.5 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 4e58476d305ef..4a55cf78ec526 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: @@ -1630,7 +1617,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