uvc攝像頭程式碼解析5
阿新 • • 發佈:2019-01-26
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控制資料
};
9初始化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;
}