8.初始化uvc控制
8.1 重要结构体
- struct uvc_control { //uvc控制
- struct uvc_entity *entity; //uvc实体
- struct uvc_control_info info; //uvc控制信息
- __u8 index; //索引值
- __u8 dirty:1,
- loaded:1,
- modified:1,
- cached:1,
- initialized:1; //初始化标志
- __u8 *uvc_data; //uvc控制数据
- };
- int uvc_ctrl_init_device(struct uvc_device *dev)
- {
- struct uvc_entity *entity;
- unsigned int i;
- /* Walk the entities list and instantiate controls */
- list_for_each_entry(entity, &dev->entities, list) { //遍历uvc设备实体entities链表
- struct uvc_control *ctrl; //uvc控制
- unsigned int bControlSize = 0, ncontrols = 0;
- __u8 *bmControls = NULL;
- if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) { //扩展Unit
- bmControls = entity->extension.bmControls; //控制位图
- bControlSize = entity->extension.bControlSize; //控制位域大小
- }
- else if (UVC_ENTITY_TYPE(entity) == UVC_VC_PROCESSING_UNIT) { //处理Unit
- bmControls = entity->processing.bmControls; //控制位图
- bControlSize = entity->processing.bControlSize; //控制位域大小
- }
- else if (UVC_ENTITY_TYPE(entity) == UVC_ITT_CAMERA) { //输入Terminal Camera
- bmControls = entity->camera.bmControls; //控制位图
- bControlSize = entity->camera.bControlSize; //控制位域大小
- }
- /* Remove bogus/blacklisted controls 移除假的/黑名单控制组件*/
- uvc_ctrl_prune_entity(dev, entity);
- /* Count supported controls and allocate the controls array */
- for (i = 0; i < bControlSize; ++i)
- ncontrols += hweight8(bmControls[i]); //统计控制组件个数
- if (ncontrols == 0)
- continue;
- entity->controls = kzalloc(ncontrols * sizeof(*ctrl),GFP_KERNEL); //分配ncontrols个uvc控制内存
- if (entity->controls == NULL)
- return -ENOMEM;
- entity->ncontrols = ncontrols; //设置uvc控制个数
- /* Initialize all supported controls */
- ctrl = entity->controls; //指向uvc控制数组
- for (i = 0; i < bControlSize * 8; ++i) {
- if (uvc_test_bit(bmControls, i) == 0) //跳过控制位域没设置1的
- continue;
- ctrl->entity = entity; //捆绑uvc实体和uvc控制
- ctrl->index = i; //设置控制位域索引
- uvc_ctrl_init_ctrl(dev, ctrl); //9初始化uvc控件
- ctrl++; //uvc控制 指向下一个uvc控制数组项
- }
- }
- return 0;
- }
9.1 相关结构体
9.1.1 uvc控制信息
- struct uvc_control_info { //uvc控制信息
- struct list_head mappings; //uvc控制位图链表头
- __u8 entity[16];
- __u8 index; /* Bit index in bmControls */
- __u8 selector;
- __u16 size;
- __u32 flags;
- };
- struct uvc_control_mapping { //uvc控制位图
- struct list_head list; //链表
- struct uvc_control_info *ctrl; //uvc控制信息
- __u32 id;
- __u8 name[32];
- __u8 entity[16];
- __u8 selector;
- __u8 size;
- __u8 offset;
- enum v4l2_ctrl_type v4l2_type; //v4l2控制类型
- __u32 data_type;
- struct uvc_menu_info *menu_info; //uvc菜单信息
- __u32 menu_count; //uvc菜单个数
- __s32 (*get) (struct uvc_control_mapping *mapping, __u8 query,const __u8 *data);
- void (*set) (struct uvc_control_mapping *mapping, __s32 value,__u8 *data);
- };
9.2 初始化uvc控制
- static void uvc_ctrl_init_ctrl(struct uvc_device *dev, struct uvc_control *ctrl)
- {
- const struct uvc_control_info *info = uvc_ctrls; //指向全局静态uvc控制信息数组
- const struct uvc_control_info *iend = info + ARRAY_SIZE(uvc_ctrls); //指向数组末端
- const struct uvc_control_mapping *mapping = uvc_ctrl_mappings; //指向全局静态uvc控制位图数组
- const struct uvc_control_mapping *mend = mapping + ARRAY_SIZE(uvc_ctrl_mappings); //指向数组末端
- if (UVC_ENTITY_TYPE(ctrl->entity) == UVC_VC_EXTENSION_UNIT) //ctrl->entity->type为扩展Unit(延后扩展Unit的初始化到当它第一次使用)
- return;
- for (; info < iend; ++info) { //遍历整个uvc控制信息数据
- if (uvc_entity_match_guid(ctrl->entity, info->entity) && ctrl->index == info->index) { //匹配条件
- uvc_ctrl_add_info(dev, ctrl, info); //添加uvc控制信息
- break;
- }
- }
- if (!ctrl->initialized) //已经给初始化
- return;
- for (; mapping < mend; ++mapping) { //遍历整个uvc控制位图数组
- if (uvc_entity_match_guid(ctrl->entity, mapping->entity) && ctrl->info.selector == mapping->selector) //匹配条件
- __uvc_ctrl_add_mapping(dev, ctrl, mapping); //添加控制位图
- }
- }
9.2.1 全局静态uvc控制信息数组uvc-ctrls
- static struct uvc_control_info uvc_ctrls[] = {
- { //背光控制
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_BRIGHTNESS_CONTROL,
- .index = 0,
- .size = 2,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE,
- },
- { //对比度控制
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_CONTRAST_CONTROL,
- .index = 1,
- .size = 2,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE,
- },
- { //色度控制
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_HUE_CONTROL,
- .index = 2,
- .size = 2,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
- },
- { //饱和度控制
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_SATURATION_CONTROL,
- .index = 3,
- .size = 2,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE,
- },
- { //锐度控制
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_SHARPNESS_CONTROL,
- .index = 4,
- .size = 2,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE,
- },
- { //gamma设置
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_GAMMA_CONTROL,
- .index = 5,
- .size = 2,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE,
- },
- { //白平衡温度控制
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
- .index = 6,
- .size = 2,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
- },
- { //白平衡组件
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
- .index = 7,
- .size = 4,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
- },
- { //背光补偿
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,
- .index = 8,
- .size = 2,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE,
- },
- { //增益
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_GAIN_CONTROL,
- .index = 9,
- .size = 2,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE,
- },
- { //电源线频率
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
- .index = 10,
- .size = 1,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR| UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
- },
- { //自动色度调节
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_HUE_AUTO_CONTROL,
- .index = 11,
- .size = 1,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR| UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
- },
- { //白平衡色温自动调节
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
- .index = 12,
- .size = 1,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR| UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
- },
- { //白平衡自动调节
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
- .index = 13,
- .size = 1,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR| UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
- },
- { //数字多功能控制
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_DIGITAL_MULTIPLIER_CONTROL,
- .index = 14,
- .size = 2,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE,
- },
- { //数字多功能限制控制
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL,
- .index = 15,
- .size = 2,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE,
- },
- { //模拟视频标准控制
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL,
- .index = 16,
- .size = 1,
- .flags = UVC_CONTROL_GET_CUR,
- },
- { //模拟视频锁存状态
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_ANALOG_LOCK_STATUS_CONTROL,
- .index = 17,
- .size = 1,
- .flags = UVC_CONTROL_GET_CUR,
- },
- { //扫描模式
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_SCANNING_MODE_CONTROL,
- .index = 0,
- .size = 1,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR| UVC_CONTROL_RESTORE,
- },
- { //。。。
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_AE_MODE_CONTROL,
- .index = 1,
- .size = 1,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR| UVC_CONTROL_GET_DEF | UVC_CONTROL_GET_RES| UVC_CONTROL_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_AE_PRIORITY_CONTROL,
- .index = 2,
- .size = 1,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR| UVC_CONTROL_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
- .index = 3,
- .size = 4,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL,
- .index = 4,
- .size = 1,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_FOCUS_ABSOLUTE_CONTROL,
- .index = 5,
- .size = 2,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_FOCUS_RELATIVE_CONTROL,
- .index = 6,
- .size = 2,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN| UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES| UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_IRIS_ABSOLUTE_CONTROL,
- .index = 7,
- .size = 2,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_IRIS_RELATIVE_CONTROL,
- .index = 8,
- .size = 1,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_ZOOM_ABSOLUTE_CONTROL,
- .index = 9,
- .size = 2,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_ZOOM_RELATIVE_CONTROL,
- .index = 10,
- .size = 3,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN| UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES| UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,
- .index = 11,
- .size = 8,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_PANTILT_RELATIVE_CONTROL,
- .index = 12,
- .size = 4,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN| UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES| UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_ROLL_ABSOLUTE_CONTROL,
- .index = 13,
- .size = 2,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_ROLL_RELATIVE_CONTROL,
- .index = 14,
- .size = 2,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN
- | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES
- | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_FOCUS_AUTO_CONTROL,
- .index = 17,
- .size = 1,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR| UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_PRIVACY_CONTROL,
- .index = 18,
- .size = 1,
- .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
- },
- };
9.2.2 全局静态uvc控制位图数组(uvc_ctrl_mappings)
- static struct uvc_control_mapping uvc_ctrl_mappings[] = {
- {
- .id = V4L2_CID_BRIGHTNESS,
- .name = "Brightness",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_BRIGHTNESS_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
- },
- {
- .id = V4L2_CID_CONTRAST,
- .name = "Contrast",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_CONTRAST_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_HUE,
- .name = "Hue",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_HUE_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
- },
- {
- .id = V4L2_CID_SATURATION,
- .name = "Saturation",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_SATURATION_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_SHARPNESS,
- .name = "Sharpness",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_SHARPNESS_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_GAMMA,
- .name = "Gamma",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_GAMMA_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_BACKLIGHT_COMPENSATION,
- .name = "Backlight Compensation",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_GAIN,
- .name = "Gain",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_GAIN_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_POWER_LINE_FREQUENCY,
- .name = "Power Line Frequency",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
- .size = 2,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_MENU,
- .data_type = UVC_CTRL_DATA_TYPE_ENUM,
- .menu_info = power_line_frequency_controls,
- .menu_count = ARRAY_SIZE(power_line_frequency_controls),
- },
- {
- .id = V4L2_CID_HUE_AUTO,
- .name = "Hue, Auto",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_HUE_AUTO_CONTROL,
- .size = 1,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
- .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
- },
- {
- .id = V4L2_CID_EXPOSURE_AUTO,
- .name = "Exposure, Auto",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_AE_MODE_CONTROL,
- .size = 4,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_MENU,
- .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
- .menu_info = exposure_auto_controls,
- .menu_count = ARRAY_SIZE(exposure_auto_controls),
- },
- {
- .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY,
- .name = "Exposure, Auto Priority",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_AE_PRIORITY_CONTROL,
- .size = 1,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
- .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
- },
- {
- .id = V4L2_CID_EXPOSURE_ABSOLUTE,
- .name = "Exposure (Absolute)",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
- .size = 32,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_AUTO_WHITE_BALANCE,
- .name = "White Balance Temperature, Auto",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
- .size = 1,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
- .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
- },
- {
- .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
- .name = "White Balance Temperature",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_AUTO_WHITE_BALANCE,
- .name = "White Balance Component, Auto",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
- .size = 1,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
- .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .name = "White Balance Blue Component",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .name = "White Balance Red Component",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
- .size = 16,
- .offset = 16,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
- },
- {
- .id = V4L2_CID_FOCUS_ABSOLUTE,
- .name = "Focus (absolute)",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_FOCUS_ABSOLUTE_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_FOCUS_AUTO,
- .name = "Focus, Auto",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_FOCUS_AUTO_CONTROL,
- .size = 1,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
- .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
- },
- {
- .id = V4L2_CID_IRIS_ABSOLUTE,
- .name = "Iris, Absolute",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_IRIS_ABSOLUTE_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_IRIS_RELATIVE,
- .name = "Iris, Relative",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_IRIS_RELATIVE_CONTROL,
- .size = 8,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
- },
- {
- .id = V4L2_CID_ZOOM_ABSOLUTE,
- .name = "Zoom, Absolute",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_ZOOM_ABSOLUTE_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_ZOOM_CONTINUOUS,
- .name = "Zoom, Continuous",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_ZOOM_RELATIVE_CONTROL,
- .size = 0,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
- .get = uvc_ctrl_get_zoom,
- .set = uvc_ctrl_set_zoom,
- },
- {
- .id = V4L2_CID_PAN_ABSOLUTE,
- .name = "Pan (Absolute)",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,
- .size = 32,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_TILT_ABSOLUTE,
- .name = "Tilt (Absolute)",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,
- .size = 32,
- .offset = 32,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_PRIVACY,
- .name = "Privacy",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_PRIVACY_CONTROL,
- .size = 1,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
- .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
- },
- };
9.2.3 添加uvc控制信息
- static int uvc_ctrl_add_info(struct uvc_device *dev, struct uvc_control *ctrl,const struct uvc_control_info *info)
- {
- int ret = 0;
- memcpy(&ctrl->info, info, sizeof(*info)); //初始化uvc控制的uvc控制信息对象
- INIT_LIST_HEAD(&ctrl->info.mappings); //初始化uvc控制信息的uvc链表头
- /* Allocate an array to save control values (cur, def, max, etc.) */
- ctrl->uvc_data = kzalloc(ctrl->info.size * UVC_CTRL_DATA_LAST + 1,GFP_KERNEL); //分配uvc控制数据内存
- if (ctrl->uvc_data == NULL) {
- ret = -ENOMEM;
- goto done;
- }
- ctrl->initialized = 1; //设置uvc控制初始化标准
- uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s entity %u\n", ctrl->info.entity, ctrl->info.selector,dev->udev->devpath, ctrl->entity->id);
- done:
- if (ret < 0)
- kfree(ctrl->uvc_data);
- return ret;
- }
9.2.4 添加uvc位图
- static int __uvc_ctrl_add_mapping(struct uvc_device *dev,struct uvc_control *ctrl, const struct uvc_control_mapping *mapping)
- {
- struct uvc_control_mapping *map;
- unsigned int size;
- map = kmemdup(mapping, sizeof(*mapping), GFP_KERNEL); //分配uvc控制位图内存
- if (map == NULL)
- return -ENOMEM;
- size = sizeof(*mapping->menu_info) * mapping->menu_count; //计算uvc菜单数组占用空间
- map->menu_info = kmemdup(mapping->menu_info, size, GFP_KERNEL); //分配uvc菜单数组内存
- if (map->menu_info == NULL) {
- kfree(map);
- return -ENOMEM;
- }
- if (map->get == NULL)
- map->get = uvc_get_le_value; //设置默认获取方法
- if (map->set == NULL)
- map->set = uvc_set_le_value; //设置默认设置方法
- map->ctrl = &ctrl->info; //捆绑uvc控制信息和uvc控制信息位图
- list_add_tail(&map->list, &ctrl->info.mappings); //添加uvc控制位图到uvc控制信息的位图链表
- uvc_trace(UVC_TRACE_CONTROL,"Adding mapping '%s' to control %pUl/%u.\n",map->name, ctrl->info.entity, ctrl->info.selector);
- return 0;
- }