8.初始化uvc控制 8.1 重要結構體 [cpp] 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控制設備 [cpp] 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控制信息 [cpp] 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控制位圖 [cpp] 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控制 [cpp] 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); //添加控制位圖 }