uvc摄像头代码解析5

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控制数据
};


8.2 初始化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初始化uvc控件

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;
};


9.1.2 uvc控制位图

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
", 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.
",map->name, ctrl->info.entity, ctrl->info.selector);
	return 0;
}





 






原文地址:https://www.cnblogs.com/keanuyaoo/p/3315533.html