11. Linux USB 视频类 (UVC) 驱动程序

此文件记录了 UVC 驱动程序的某些特定于驱动程序的方面,例如特定于驱动程序的 ioctl 和实现说明。

问题和意见可以发送至 Linux UVC 开发邮件列表 linux-media@vger.kernel.org

11.1. 扩展单元 (XU) 支持

11.1.1. 简介

UVC 规范允许通过扩展单元 (XU) 进行特定于供应商的扩展。 Linux UVC 驱动程序通过两种独立的机制支持扩展单元控件 (XU 控件)

  • 通过将 XU 控件映射到 V4L2 控件

  • 通过特定于驱动程序的 ioctl 接口

第一种方法允许通用的 V4L2 应用程序通过将某些 XU 控件映射到 V4L2 控件来使用 XU 控件,然后在普通控件枚举期间显示这些控件。

第二种机制需要 uvcvideo 特定的知识才能使应用程序访问 XU 控件,但将整个 UVC XU 概念暴露给用户空间以获得最大的灵活性。

这两种机制相互补充,并在下面进行更详细的描述。

11.1.2. 控制映射

UVC 驱动程序为用户空间应用程序提供了一个 API,用于在运行时定义所谓的控制映射。这些允许将单个 XU 控件或其字节范围映射到新的 V4L2 控件。此类控件的显示和功能与普通的 V4L2 控件完全相同(即,诸如亮度、对比度等之类的库存控件)。但是,读取或写入此类 V4L2 控件会触发相关 XU 控件的读取或写入。

用于创建这些控制映射的 ioctl 称为 UVCIOC_CTRL_MAP。之前的驱动程序版本(0.2.0 之前)需要事先使用另一个 ioctl (UVCIOC_CTRL_ADD) 将 XU 控制信息传递给 UVC 驱动程序。这不再必要,因为较新的 uvcvideo 版本直接从设备查询信息。

有关 UVCIOC_CTRL_MAP ioctl 的详细信息,请参阅下面标题为“IOCTL 参考”的部分。

  1. 特定于驱动程序的 XU 控制接口

对于需要直接访问 XU 控件的应用程序,例如用于测试目的、固件上传或访问二进制控件,提供了第二种访问 XU 控件的机制,形式是特定于驱动程序的 ioctl,即 UVCIOC_CTRL_QUERY。

调用此 ioctl 允许应用程序向 UVC 驱动程序发送直接映射到低级 UVC 控制请求的查询。

为了发出此类请求,需要知道控件的扩展单元的 UVC 单元 ID 和控件选择器。此信息需要硬编码在应用程序中,或者通过解析 UVC 描述符或其他方式查询,或者如果可用,则使用媒体控制器 API 来枚举设备的实体。

除非已知控件大小,否则有必要首先发出 UVC_GET_LEN 请求,以便能够分配足够大的缓冲区并将缓冲区大小设置为正确的值。 同样,要找出 UVC_GET_CUR 或 UVC_SET_CUR 对于给定控件是否是有效的请求,应发出 UVC_GET_INFO 请求。结果字节的第 0 位(支持 GET)和第 1 位(支持 SET)指示哪些请求有效。

随着 UVCIOC_CTRL_QUERY ioctl 的添加,UVCIOC_CTRL_GET 和 UVCIOC_CTRL_SET ioctl 已过时,因为它们的功能是前一个 ioctl 的子集。 目前仍然支持它们,但鼓励应用程序开发人员使用 UVCIOC_CTRL_QUERY 代替。

有关 UVCIOC_CTRL_QUERY ioctl 的详细信息,请参阅下面标题为“IOCTL 参考”的部分。

11.1.3. 安全性

该 API 目前不提供细粒度的访问控制工具。 UVCIOC_CTRL_ADD 和 UVCIOC_CTRL_MAP ioctl 需要超级用户权限。

欢迎提出如何改进此方面的建议。

11.1.4. 调试

为了调试与 XU 控件或一般控件相关的问题,建议在模块参数 'trace' 中启用 UVC_TRACE_CONTROL 位。这会导致额外的输出写入系统日志。

11.1.5. IOCTL 参考

11.1.5.1. UVCIOC_CTRL_MAP - 将 UVC 控件映射到 V4L2 控件

参数:struct uvc_xu_control_mapping

描述:

此 ioctl 在 UVC 控件或 UVC 控件的一部分与 V4L2 控件之间创建映射。 定义映射后,用户空间应用程序可以通过 V4L2 控件 API 访问供应商定义的 UVC 控件。

要创建映射,应用程序需要用使用 UVCIOC_CTRL_ADD 定义的现有 UVC 控件和新的 V4L2 控件的相关信息填充 uvc_xu_control_mapping 结构。

一个 UVC 控件可以映射到多个 V4L2 控件。 例如,UVC 平移/倾斜控件可以映射到单独的平移和倾斜 V4L2 控件。 UVC 控件使用 “size” 和 “offset” 字段分为非重叠字段,然后独立映射到 V4L2 控件。

对于带符号整数 V4L2 控件,data_type 字段应设置为 UVC_CTRL_DATA_TYPE_SIGNED。 目前忽略其他值。

返回值:

成功返回 0。 发生错误时返回 -1,并设置 errno。

ENOMEM

没有足够的内存来执行操作。

EPERM

权限不足(需要超级用户权限)。

EINVAL

没有此 UVC 控件。

EOVERFLOW

请求的偏移量和大小将溢出 UVC 控件。

EEXIST

映射已存在。

数据类型:

* struct uvc_xu_control_mapping

__u32   id              V4L2 control identifier
__u8    name[32]        V4L2 control name
__u8    entity[16]      UVC extension unit GUID
__u8    selector        UVC control selector
__u8    size            V4L2 control size (in bits)
__u8    offset          V4L2 control offset (in bits)
enum v4l2_ctrl_type
        v4l2_type       V4L2 control type
enum uvc_control_data_type
        data_type       UVC control data type
struct uvc_menu_info
        *menu_info      Array of menu entries (for menu controls only)
__u32   menu_count      Number of menu entries (for menu controls only)

* struct uvc_menu_info

__u32   value           Menu entry value used by the device
__u8    name[32]        Menu entry name


* enum uvc_control_data_type

UVC_CTRL_DATA_TYPE_RAW          Raw control (byte array)
UVC_CTRL_DATA_TYPE_SIGNED       Signed integer
UVC_CTRL_DATA_TYPE_UNSIGNED     Unsigned integer
UVC_CTRL_DATA_TYPE_BOOLEAN      Boolean
UVC_CTRL_DATA_TYPE_ENUM         Enumeration
UVC_CTRL_DATA_TYPE_BITMASK      Bitmask

11.1.5.2. UVCIOC_CTRL_QUERY - 查询 UVC XU 控件

参数:struct uvc_xu_control_query

描述:

此 ioctl 查询由其扩展单元 ID 和控件选择器标识的 UVC XU 控件。

有许多不同的查询可用,它们与 UVC 规范中描述的低级控制请求密切对应。 这些请求是

UVC_GET_CUR

获取控件的当前值。

UVC_GET_MIN

获取控件的最小值。

UVC_GET_MAX

获取控件的最大值。

UVC_GET_DEF

获取控件的默认值。

UVC_GET_RES

查询控件的分辨率,即允许的控件值的步长。

UVC_GET_LEN

以字节为单位查询控件的大小。

UVC_GET_INFO

查询控件信息位图,该位图指示是否支持 get/set 请求。

UVC_SET_CUR

更新控件的值。

应用程序必须将 “size” 字段设置为控件的正确长度。例外情况是 UVC_GET_LEN 和 UVC_GET_INFO 查询,其大小必须分别设置为 2 和 1。“data” 字段必须指向足够大的有效可写缓冲区,以容纳指示的多个数据字节。

数据直接从设备复制,无需任何驱动程序端处理。 应用程序负责数据缓冲区格式化,包括小端/大端转换。 这对于 UVC_GET_LEN 请求的结果尤为重要,该请求始终由设备以小端 16 位整数形式返回。

返回值:

成功返回 0。 发生错误时返回 -1,并设置 errno。

ENOENT

设备不支持给定的控件,或者找不到指定的扩展单元。

ENOBUFS

指定的缓冲区大小不正确(太大或太小)。

EINVAL

传递了无效的请求代码。

EBADRQC

给定的请求不受给定控件的支持。

EFAULT

数据指针引用了无法访问的内存区域。

数据类型:

* struct uvc_xu_control_query

__u8    unit            Extension unit ID
__u8    selector        Control selector
__u8    query           Request code to send to the device
__u16   size            Control data size (in bytes)
__u8    *data           Control value