整個uvc驅動,在內核中的路徑是drivers/media/video/uvc
在kernel中配置uvc驅動,須要本身手動在make menuconfig中勾選以下路徑:bash
Device Drivers ---> Multimedia support ---> Video For Linux Device Drivers ---> Multimedia support ---> [*] Video capture adapters ---> [*] V4L USB devices ---> USB Video Class (UVC)
咱們先用tree看戲uvc目錄下的文件組成:架構
guanguojin@WX-ASIC-S02-Android:uvc$ tree . ├── Kconfig ├── Makefile ├── uvc_ctrl.c ├── uvc_driver.c //uvc驅動的入口處 ├── uvc_isight.c ├── uvc_queue.c ├── uvc_status.c ├── uvc_v4l2.c ├── uvc_video.c └── uvcvideo.h
那咱們就先從uvc_driver.c開始剖析整個uvc驅動的架構
首先咱們找到驅動的加載入口module_init宏定義的函數:app
static int __init uvc_init(void) { int result; INIT_LIST_HEAD(&uvc_driver.devices); INIT_LIST_HEAD(&uvc_driver.controls); mutex_init(&uvc_driver.ctrl_mutex); uvc_ctrl_init(); result = usb_register(&uvc_driver.driver); if (result == 0) printk(KERN_INFO DRIVER_DESC " (" DRIVER_VERSION ")\n"); return result; } module_init(uvc_init);
加載函數很簡單,除了必要的初始化外,最重要的兩步操做就是:uvc_ctrl_init和usb_registeride
void uvc_ctrl_init(void) { struct uvc_control_info *ctrl = uvc_ctrls; struct uvc_control_info *cend = ctrl + ARRAY_SIZE(uvc_ctrls); struct uvc_control_mapping *mapping = uvc_ctrl_mappings; struct uvc_control_mapping *mend = mapping + ARRAY_SIZE(uvc_ctrl_mappings); for (; ctrl < cend; ++ctrl) uvc_ctrl_add_info(ctrl); for (; mapping < mend; ++mapping) uvc_ctrl_add_mapping(mapping); }
這裏面將uvc支持的GUID(即uvc支持的操做選項,包括亮度調節、灰度調節....)
struct uvc_control_info添加到uvc_driver的controls這個隊列中去,其中主要關注這個結構體便可:函數
struct uvc_control_info { struct list_head list; struct list_head mappings;----->添加結構體成員類型struct uvc_control_mapping __u8 entity[16]; __u8 index; __u8 selector; __u16 size; __u32 flags; };
這是註冊uvc驅動的接口,就是將spa
struct uvc_driver uvc_driver = { .driver = { .name = "uvcvideo", .probe = uvc_probe, .disconnect = uvc_disconnect, .suspend = uvc_suspend, .resume = uvc_resume, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) .reset_resume = uvc_reset_resume, #endif .id_table = uvc_ids, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) .supports_autosuspend = 1, #endif }, };
這個結構體註冊到usb驅動中,其中uvc_ids就是usb的過濾器,只有將支持uvc camera的VID和PID填入這個結構體,usb驅動纔會在識別到camera後將其分發給uvc驅動,固然在uvc_ids中最後有這麼個賦值:
/* Generic USB Video Class */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
也即只要usb描述符中說明是USB_CLASS_VIDEO的,都會交由uvc處理,沒必要單獨將其VID和PID填入了。code