From nobody Tue Dec 2 02:29:10 2025 Received: from mail-lf1-f50.google.com (mail-lf1-f50.google.com [209.85.167.50]) (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 877CE35BDA6 for ; Wed, 19 Nov 2025 19:37:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763581040; cv=none; b=MqOMSP7DcmlF0Ntaiu9dFY+KSy4AWHBFX/1saEjI03UlbFQ0pr7OlhFP7a2jNoseNkA6YUJEM7qrZkyTjMtQY4vuTfxuvXM6mStuFqsz7CTNt7ATkNQAgl3aEVyr0bJyOQHwcXAwkeOjWFWG6CI2B1KUgcc3AuGBjy8a6D1drZs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763581040; c=relaxed/simple; bh=yDVjeEIL8VTe0A73YXx6ikv0Q8i+JImq30aDISEsNeQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iU6kReT+f/hnOIokOFVvMsd+YJnJv3Ifp0nQ2qaq4TQI1Gm9zVTRFM71+CFbOVYF1DsC4XEOmN4+lbeN7E4L5tJynSBQU8YTpVxjTvmreKOZzkEzOAFntgSb147Mp+zcuihJsa7uZGvdi+DmTHthFM9j8gTsd6woQOE1Ms+z6g4= 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=Ps+QQ3wH; arc=none smtp.client-ip=209.85.167.50 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="Ps+QQ3wH" Received: by mail-lf1-f50.google.com with SMTP id 2adb3069b0e04-5958931c9c7so22110e87.2 for ; Wed, 19 Nov 2025 11:37:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1763581034; x=1764185834; 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=Urb4TUB7FuFPTt5EqRfevkiU7cF4I6ahZ/fgTz9sy5U=; b=Ps+QQ3wHSmUKJFOMgJqG/vvGOz84qJEUHxncR1b4PvFof4cQFAyOzjCjVhlDFf4gw8 PJx5+cTrfVnjdm63aQL/3bMiD9eQDj1C7t1xwO7V/02KYrcIi6lVIS2ii/9BZS34NflD iPfJVxvFwuBGMAqbc9pSdubDje0JS/6Jtuolc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763581034; x=1764185834; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=Urb4TUB7FuFPTt5EqRfevkiU7cF4I6ahZ/fgTz9sy5U=; b=mMBL6snOVTsKoCXHqQAGyQ14HH+RTyWHL8q+D8egi/KfVtQ3MoRrV/h+BE/Qqw+OyF 0MRdfdkUUoD+9FXObyMtHHbvNRTF2qGJWW3VAoXy+85GTTWpRTiSxWBT4wSjvyy0nTIJ qS3R+XRc0ec1NL0shHISgSos+GPdeFVF3a0qTtqwZw72AP2qZaI+2t2hrp4DTiMAd6mh nBDbV+gr+pKMk3+s0xlyljHar56ya1Dvh2ziBkcP2QiDGG8+fr8csCt40NuwBn4G+32X XjAgaQgED2Kxg1VLkX6KADKTYD5wcJDVpeTVYq3F/eSeYkksJK3BSxgTt8BoP9Op6mdv tH0g== X-Forwarded-Encrypted: i=1; AJvYcCUy2+Q+XWbGI0JF5lOhXLDz5J0guyvm21G0QGsOiWji9c6E7cQnPTbe22JOUs2+Bzi6I3dsZeAInDXA8MI=@vger.kernel.org X-Gm-Message-State: AOJu0YymvPQ7voNFjEUzwnL54UCClOrDa22YONp/GEuFsotblzMblJ1l upeHEcrsHJeM4hXkKCOW82tfX33kjxOmiDzMVWTztNIewCq3k6awjTZFu7yMU1t+bA== X-Gm-Gg: ASbGncv3stogCGiqc7UaIo001BYe09S65DRNxCA1d+PL0XmaIQWzGNb1IVm5+E1sIWr m/zZgo5v+fpJFWnm4o1vPgyUVTgZqCJJSnty2+1jsuweHR+O3YDyYdzgS8H0unxsXYpm6m7MZAu kw0zPJfcWrUs8Gu2JYILxyxNHaorvQHaRDguna9wDnXOyA/X6kXhKAPtehq2KF8hqO/WLwja1N3 QkGxq44SPm0O4PE0I8QBxd65ambW5nUVKt3ImiwyQtg08uyR1J5qLTNcJKoLk6+DquEPR4ntZ1x qMM1ETz6v71aa74XMXiaUmsn3bx2X6TiAS9IRTZVwUy1KKi+8wbdcgzpOHiHxZkDHs5dC9AkJ2I DsnL3Zsk4z0CM2K2XtwKTTeSwykg+ktgoKpjsrLHxy2x/RcXh+kuAlCGx9GGRrbg2GW1y3/tBiS MGL8jgta6GXFzPCsHW5cBe0E0i06tQ37k0xpfAuRtWT74A9knXKX9Uj2FQ1/Kfa8NPBejT5wrp X-Google-Smtp-Source: AGHT+IEh+tdUOzMD8Okc/mI6rgrMVyMk7m+HLiNzXG3iO0XlxNHcpo70Zd5NDuYMvXvwI/oaVGcPqw== X-Received: by 2002:a05:6512:6d3:b0:595:91dc:72a1 with SMTP id 2adb3069b0e04-5969e2ae995mr43544e87.3.1763581034086; Wed, 19 Nov 2025 11:37:14 -0800 (PST) Received: from ribalda.c.googlers.com (80.38.88.34.bc.googleusercontent.com. [34.88.38.80]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5969dbd15a1sm65790e87.98.2025.11.19.11.37.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Nov 2025 11:37:13 -0800 (PST) From: Ricardo Ribalda Date: Wed, 19 Nov 2025 19:37:11 +0000 Subject: [PATCH v2 2/6] media: uvcvideo: Import standard controls from uvcdynctrl Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251119-uvcdynctrl-v2-2-0359ffb98c9e@chromium.org> References: <20251119-uvcdynctrl-v2-0-0359ffb98c9e@chromium.org> In-Reply-To: <20251119-uvcdynctrl-v2-0-0359ffb98c9e@chromium.org> To: Laurent Pinchart , Hans de Goede , Mauro Carvalho Chehab , Greg Kroah-Hartman Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, Ricardo Ribalda , Manav Gautama , Martin Rubli X-Mailer: b4 0.14.2 The uvcdynctrl tool from libwebcam: https://sourceforge.net/projects/libwebcam/ maps proprietary controls into v4l2 controls using the UVCIOC_CTRL_MAP ioctl. The tool has not been updated for 10+ years now, and there is no reason for the UVC driver to not do the mapping by itself. This patch adds the mappings from the uvcdynctrl into the driver. Hopefully this effort can help in deprecating the UVCIOC_CTRL_MAP ioctl. Some background about UVCIOC_CTRL_MAP (thanks Laurent for the context): ``` this was envisioned as the base of a vibrant ecosystem where a large number of vendors would submit XML files that describe their XU control mappings, at a pace faster than could be supported by adding XU mappings to the driver. This vision failed to materialize and the tool has not been updated for 10+ years now. There is no reason to believe the situation will change. ``` During the porting, the following mappings where NOT imported because they were not using standard v4l2 IDs. It is recommended that userspace moves to UVCIOC_CTRL_QUERY for non standard controls. { .id =3D V4L2_CID_FLASH_MODE, .entity =3D UVC_GUID_SIS_LED_HW_CONTROL, .selector =3D 4, .size =3D 4, .offset =3D 0, .v4l2_type =3D V4L2_CTRL_TYPE_MENU, .data_type =3D UVC_CTRL_DATA_TYPE_UNSIGNED, .menu_mask =3D 0x3, .menu_mapping =3D { 0x20, 0x22 }, .menu_names =3D { "Off", "On" }, }, { .id =3D V4L2_CID_FLASH_FREQUENCY, .entity =3D UVC_GUID_SIS_LED_HW_CONTROL, .selector =3D 4, .size =3D 8, .offset =3D 16, .v4l2_type =3D V4L2_CTRL_TYPE_INTEGER, .data_type =3D UVC_CTRL_DATA_TYPE_UNSIGNED, }, { .id =3D V4L2_CID_LED1_MODE, .entity =3D UVC_GUID_LOGITECH_USER_HW_CONTROL_V1, .selector =3D 1, .size =3D 8, .offset =3D 0, .v4l2_type =3D V4L2_CTRL_TYPE_MENU, .data_type =3D UVC_CTRL_DATA_TYPE_UNSIGNED, .menu_mask =3D 0xF, .menu_mapping =3D { 0, 1, 2, 3 }, .menu_names =3D { "Off", "On", "Blinking", "Auto" }, }, { .id =3D V4L2_CID_LED1_FREQUENCY, .entity =3D UVC_GUID_LOGITECH_USER_HW_CONTROL_V1, .selector =3D 1, .size =3D 8, .offset =3D 16, .v4l2_type =3D V4L2_CTRL_TYPE_INTEGER, .data_type =3D UVC_CTRL_DATA_TYPE_UNSIGNED, }, { .id =3D V4L2_CID_DISABLE_PROCESSING, .entity =3D UVC_GUID_LOGITECH_VIDEO_PIPE_V1, .selector =3D 5, .size =3D 8, .offset =3D 0, .v4l2_type =3D V4L2_CTRL_TYPE_BOOLEAN, .data_type =3D UVC_CTRL_DATA_TYPE_BOOLEAN, }, { .id =3D V4L2_CID_RAW_BITS_PER_PIXEL, .entity =3D UVC_GUID_LOGITECH_VIDEO_PIPE_V1, .selector =3D 8, .size =3D 8, .offset =3D 0, .v4l2_type =3D V4L2_CTRL_TYPE_INTEGER, .data_type =3D UVC_CTRL_DATA_TYPE_UNSIGNED, }, { .id =3D V4L2_CID_LED1_MODE, .entity =3D UVC_GUID_LOGITECH_PERIPHERAL, .selector =3D 0x09, .size =3D 2, .offset =3D 8, .v4l2_type =3D V4L2_CTRL_TYPE_MENU, .data_type =3D UVC_CTRL_DATA_TYPE_UNSIGNED, .menu_mask =3D 0xF, .menu_mapping =3D { 0, 1, 2, 3 }, .menu_names =3D { "Off", "On", "Blink", "Auto" }, }, { .id =3D V4L2_CID_LED1_FREQUENCY, .entity =3D UVC_GUID_LOGITECH_PERIPHERAL, .selector =3D 0x09, .size =3D 8, .offset =3D 24, .v4l2_type =3D V4L2_CTRL_TYPE_INTEGER, .data_type =3D UVC_CTRL_DATA_TYPE_UNSIGNED, }, This script has been used to generate the mappings. They were then reformatted manually to follow the driver style. import sys import uuid import re import xml.etree.ElementTree as ET def get_namespace(root): return re.match(r"\{.*\}", root.tag).group(0) def get_single_guid(ns, constant): id =3D constant.find(ns + "id").text value =3D constant.find(ns + "value").text return (id, value) def get_constants(ns, root): out =3D dict() for constant in root.iter(ns + "constant"): attr =3D constant.attrib if attr["type"] =3D=3D "integer": id, value =3D get_single_guid(ns, constant) if id in out: print(f"dupe constant {id}") out[id] =3D value return out def get_guids(ns, root): out =3D dict() for constant in root.iter(ns + "constant"): attr =3D constant.attrib if attr["type"] =3D=3D "guid": id, value =3D get_single_guid(ns, constant) if id in out: print(f"dupe guid {id}") out[id] =3D value return out def get_single_control(ns, control): out =3D {} for id in "entity", "selector", "index", "size", "description": v =3D control.find(ns + id) if v is None and id =3D=3D "description": continue out[id] =3D v.text reqs =3D set() for r in control.find(ns + "requests"): reqs.add(r.text) out["requests"] =3D reqs return (control.attrib["id"], out) def get_controls(ns, root): out =3D dict() for control in root.iter(ns + "control"): id, value =3D get_single_control(ns, control) if id in out: print(f"Dupe control id {id}") out[id] =3D value return out def get_single_mapping(ns, mapping): out =3D {} out["name"] =3D mapping.find(ns + "name").text uvc =3D mapping.find(ns + "uvc") for id in "size", "offset", "uvc_type": out[id] =3D uvc.find(ns + id).text out["control_ref"] =3D uvc.find(ns + "control_ref").attrib["idref"] v4l2 =3D mapping.find(ns + "v4l2") for id in "id", "v4l2_type": out[id] =3D v4l2.find(ns + id).text menu =3D {} for entry in v4l2.iter(ns + "menu_entry"): menu[entry.attrib["name"]] =3D entry.attrib["value"] if menu: out["menu"] =3D menu return out def get_mapping(ns, root): out =3D [] for control in root.iter(ns + "mapping"): mapping =3D get_single_mapping(ns, control) out +=3D [mapping] return out def print_guids(guids): for g in guids: print(f"#define {g} \\") u_bytes =3D uuid.UUID(guids[g]).bytes_le u_bytes =3D [f"0x{b:02x}" for b in u_bytes] print("\t{ " + ", ".join(u_bytes) + " }") def print_flags(flags): get_range =3D {"GET_MIN", "GET_DEF", "GET_MAX", "GET_CUR", "GET_RES"} if get_range.issubset(flags): flags -=3D get_range flags.add("GET_RANGE") flags =3D list(flags) flags.sort() out =3D "" for f in flags[:-1]: out +=3D f"UVC_CTRL_FLAG_{f}\n\t\t\t\t| " out +=3D f"UVC_CTRL_FLAG_{flags[-1]}" return out def print_description(desc): print("/*") for line in desc.strip().splitlines(): print(f" * {line.strip()}") print("*/") def print_controls(controls, cons): for id in controls: c =3D controls[id] if "description" in c: print_description(c["description"]) print( f"""\t{{ \t\t.entity\t\t=3D {c["entity"]}, \t\t.selector\t=3D {cons[c["selector"]]}, \t\t.index\t\t=3D {c["index"]}, \t\t.size\t\t=3D {c["size"]}, \t\t.flags\t\t=3D {print_flags(c["requests"])}, \t}},""" ) def menu_mapping_txt(menu): out =3D f"\n\t\t.menu_mask\t=3D 0x{((1< Cc: Martin Rubli Reviewed-by: Laurent Pinchart Signed-off-by: Ricardo Ribalda --- drivers/media/usb/uvc/uvc_ctrl.c | 174 +++++++++++++++++++++++++++++++++++= ++++ include/linux/usb/uvc.h | 6 ++ 2 files changed, 180 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_c= trl.c index 2905505c240c060e5034ea12d33b59d5702f2e1f..57ce486f22bbc404a1f127539eb= 2d12373431631 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -385,6 +385,99 @@ static const struct uvc_control_info uvc_ctrls[] =3D { | UVC_CTRL_FLAG_GET_RANGE | UVC_CTRL_FLAG_RESTORE, }, + /* + * Allows the control of pan/tilt motor movements for camera models + * that support mechanical pan/tilt. + * + * Bits 0 to 15 control pan, bits 16 to 31 control tilt. + * The unit of the pan/tilt values is 1/64th of a degree and the + * resolution is 1 degree. + */ + { + .entity =3D UVC_GUID_LOGITECH_MOTOR_CONTROL_V1, + .selector =3D 1, + .index =3D 0, + .size =3D 4, + .flags =3D UVC_CTRL_FLAG_GET_DEF + | UVC_CTRL_FLAG_GET_MAX + | UVC_CTRL_FLAG_GET_MIN + | UVC_CTRL_FLAG_SET_CUR, + }, + /* + * Reset the pan/tilt motors to their original position for camera + * models that support mechanical pan/tilt. + * + * Setting bit 0 resets the pan position. + * Setting bit 1 resets the tilt position. + * + * Both bits can be set at the same time to reset both, pan and tilt, + * at the same time. + */ + { + .entity =3D UVC_GUID_LOGITECH_MOTOR_CONTROL_V1, + .selector =3D 2, + .index =3D 1, + .size =3D 1, + .flags =3D UVC_CTRL_FLAG_GET_DEF + | UVC_CTRL_FLAG_GET_MAX + | UVC_CTRL_FLAG_GET_MIN + | UVC_CTRL_FLAG_SET_CUR, + }, + /* + * Allows the control of focus motor movements for camera models that + * support mechanical focus. + * + * Bits 0 to 7 allow selection of the desired lens position. + * There are no physical units, instead, the focus range is spread over + * 256 logical units with 0 representing infinity focus and 255 being + * macro focus. + */ + { + .entity =3D UVC_GUID_LOGITECH_MOTOR_CONTROL_V1, + .selector =3D 3, + .index =3D 2, + .size =3D 6, + .flags =3D UVC_CTRL_FLAG_GET_CUR + | UVC_CTRL_FLAG_GET_DEF + | UVC_CTRL_FLAG_GET_MAX + | UVC_CTRL_FLAG_GET_MIN + | UVC_CTRL_FLAG_SET_CUR, + }, + /* + * Allows the control of pan/tilt motor movements for camera models + * that support mechanical pan/tilt. + * + * Bits 0 to 15 control pan, bits 16 to 31 control tilt. + */ + { + .entity =3D UVC_GUID_LOGITECH_PERIPHERAL, + .selector =3D 1, + .index =3D 0, + .size =3D 4, + .flags =3D UVC_CTRL_FLAG_GET_DEF + | UVC_CTRL_FLAG_GET_MAX + | UVC_CTRL_FLAG_GET_MIN + | UVC_CTRL_FLAG_GET_RES + | UVC_CTRL_FLAG_SET_CUR, + }, + /* + * Reset the pan/tilt motors to their original position for camera + * models that support mechanical pan/tilt. + * + * Setting bit 0 resets the pan position. + * Setting bit 1 resets the tilt position. + */ + { + .entity =3D UVC_GUID_LOGITECH_PERIPHERAL, + .selector =3D 2, + .index =3D 1, + .size =3D 1, + .flags =3D UVC_CTRL_FLAG_GET_DEF + | UVC_CTRL_FLAG_GET_MAX + | UVC_CTRL_FLAG_GET_MIN + | UVC_CTRL_FLAG_GET_RES + | UVC_CTRL_FLAG_SET_CUR, + }, }; =20 static const u32 uvc_control_classes[] =3D { @@ -1009,6 +1102,87 @@ static const struct uvc_control_mapping uvc_ctrl_map= pings[] =3D { .menu_mask =3D BIT(V4L2_COLORFX_VIVID) | BIT(V4L2_COLORFX_NONE), }, + { + .id =3D V4L2_CID_PAN_RELATIVE, + .entity =3D UVC_GUID_LOGITECH_MOTOR_CONTROL_V1, + .selector =3D 1, + .size =3D 16, + .offset =3D 0, + .v4l2_type =3D V4L2_CTRL_TYPE_INTEGER, + .data_type =3D UVC_CTRL_DATA_TYPE_SIGNED, + }, + { + .id =3D V4L2_CID_TILT_RELATIVE, + .entity =3D UVC_GUID_LOGITECH_MOTOR_CONTROL_V1, + .selector =3D 1, + .size =3D 16, + .offset =3D 16, + .v4l2_type =3D V4L2_CTRL_TYPE_INTEGER, + .data_type =3D UVC_CTRL_DATA_TYPE_SIGNED, + }, + { + .id =3D V4L2_CID_PAN_RESET, + .entity =3D UVC_GUID_LOGITECH_MOTOR_CONTROL_V1, + .selector =3D 2, + .size =3D 1, + .offset =3D 0, + .v4l2_type =3D V4L2_CTRL_TYPE_BUTTON, + .data_type =3D UVC_CTRL_DATA_TYPE_UNSIGNED, + }, + { + .id =3D V4L2_CID_TILT_RESET, + .entity =3D UVC_GUID_LOGITECH_MOTOR_CONTROL_V1, + .selector =3D 2, + .size =3D 1, + .offset =3D 1, + .v4l2_type =3D V4L2_CTRL_TYPE_BUTTON, + .data_type =3D UVC_CTRL_DATA_TYPE_UNSIGNED, + }, + { + .id =3D V4L2_CID_PAN_RELATIVE, + .entity =3D UVC_GUID_LOGITECH_PERIPHERAL, + .selector =3D 1, + .size =3D 16, + .offset =3D 0, + .v4l2_type =3D V4L2_CTRL_TYPE_INTEGER, + .data_type =3D UVC_CTRL_DATA_TYPE_SIGNED, + }, + { + .id =3D V4L2_CID_TILT_RELATIVE, + .entity =3D UVC_GUID_LOGITECH_PERIPHERAL, + .selector =3D 1, + .size =3D 16, + .offset =3D 16, + .v4l2_type =3D V4L2_CTRL_TYPE_INTEGER, + .data_type =3D UVC_CTRL_DATA_TYPE_SIGNED, + }, + { + .id =3D V4L2_CID_PAN_RESET, + .entity =3D UVC_GUID_LOGITECH_PERIPHERAL, + .selector =3D 2, + .size =3D 1, + .offset =3D 0, + .v4l2_type =3D V4L2_CTRL_TYPE_BUTTON, + .data_type =3D UVC_CTRL_DATA_TYPE_UNSIGNED, + }, + { + .id =3D V4L2_CID_TILT_RESET, + .entity =3D UVC_GUID_LOGITECH_PERIPHERAL, + .selector =3D 2, + .size =3D 1, + .offset =3D 1, + .v4l2_type =3D V4L2_CTRL_TYPE_BUTTON, + .data_type =3D UVC_CTRL_DATA_TYPE_UNSIGNED, + }, + { + .id =3D V4L2_CID_FOCUS_ABSOLUTE, + .entity =3D UVC_GUID_LOGITECH_MOTOR_CONTROL_V1, + .selector =3D 3, + .size =3D 8, + .offset =3D 0, + .v4l2_type =3D V4L2_CTRL_TYPE_INTEGER, + .data_type =3D UVC_CTRL_DATA_TYPE_UNSIGNED, + }, }; =20 /* ------------------------------------------------------------------------ diff --git a/include/linux/usb/uvc.h b/include/linux/usb/uvc.h index 22e0dab0809e296e089940620ae0e8838e109701..b939a01da11466747249c64c72a= 3ea40cd364a59 100644 --- a/include/linux/usb/uvc.h +++ b/include/linux/usb/uvc.h @@ -35,6 +35,12 @@ #define UVC_GUID_MSXU_1_5 \ {0xdc, 0x95, 0x3f, 0x0f, 0x32, 0x26, 0x4e, 0x4c, \ 0x92, 0xc9, 0xa0, 0x47, 0x82, 0xf4, 0x3b, 0xc8} +#define UVC_GUID_LOGITECH_MOTOR_CONTROL_V1 \ + {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ + 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x56 } +#define UVC_GUID_LOGITECH_PERIPHERAL \ + {0x21, 0x2d, 0xe5, 0xff, 0x30, 0x80, 0x2c, 0x4e, \ + 0x82, 0xd9, 0xf5, 0x87, 0xd0, 0x05, 0x40, 0xbd } =20 /* https://learn.microsoft.com/en-us/windows-hardware/drivers/stream/uvc-e= xtensions-1-5#222-extension-unit-controls */ #define UVC_MSXU_CONTROL_FOCUS 0x01 --=20 2.52.0.rc1.455.g30608eb744-goog