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 2BF9E27FB37; Tue, 27 May 2025 16:57:45 +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=1748365065; cv=none; b=u11/EuOSkjEckkNw/BUpefAD9813uRa2bkXs6bxRwW4an5v21Bl73FfjtnOriTwX7JPrzz4TGRo+VkEtI6BfgqTG2RbtBC5/G7u+u99omNJH614U2utww4g7aOffxMrvT1El18FWVqBJ/ExMdHeo4xyVvvDrxPYwwxuofVgDRJ0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748365065; c=relaxed/simple; bh=PKC9nTfKODdxlkMvuQHuJ6QrLz0BZT61sUIdZf/RNDA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WhRznTjPbEaV4ckK1PqPcH6C/hSLWL34fuKMIMQpvmhbgv/dj/IkZcJ7s5r4jZkti+ofS75AxzbfiVtEMxzO+OkD+8eA1oEUMukzceRZy6Qs+SbbQuqwotJ8PiEEmf6OyP3fBR9x3ABrQoakGTA84J/0IBsP7fvnK1LL1A9r9xg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=CiSZqTGP; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="CiSZqTGP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8D207C4CEED; Tue, 27 May 2025 16:57:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1748365065; bh=PKC9nTfKODdxlkMvuQHuJ6QrLz0BZT61sUIdZf/RNDA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CiSZqTGPOsWTlYKYPVZUFKXHDjhdbjgYqbscAl86dg0/vm51WmrYWh566MIvASapP EbSceX93PPeY1OuJSxhJf8NqNTRcT0kqOvDqBT8SZG/rX/vwaEIohlsPwFXihAhsS8 1T1Tx8Gs/7/ziW4LZ0rGkH6YDXLHVjH4/aqfRrrw= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Hans de Goede , Yunke Cao , Ricardo Ribalda , Hans Verkuil , Sasha Levin Subject: [PATCH 6.12 257/626] media: uvcvideo: Handle uvc menu translation inside uvc_get_le_value Date: Tue, 27 May 2025 18:22:30 +0200 Message-ID: <20250527162455.454264260@linuxfoundation.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250527162445.028718347@linuxfoundation.org> References: <20250527162445.028718347@linuxfoundation.org> User-Agent: quilt/0.68 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ 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