一、V4L2应用层调用流程
二、V4L2设备注册
三、video设备初始化
四、V4L2 control结构框架图
五、v4l2 ctrl 函数初始化—增加标准接口v4l2_ctrl_new_std
六、v4l2 ctrl 函数初始化—增加自定义接口v4l2_ctrl_new_custom
七、V4L2 ioctl 标准接口 调用流程
八、V4L2 ioctl 控制接口 调用流程
v4l2_device 结构体
struct v4l2_device { struct device *dev; struct media_device *mdev; struct list_head subdevs; spinlock_t lock; char name[V4L2_DEVICE_NAME_SIZE]; void (*notify)(struct v4l2_subdev *sd, unsigned int notification, void *arg); struct v4l2_ctrl_handler *ctrl_handler; struct v4l2_prio_state prio; struct kref ref; void (*release)(struct v4l2_device *v4l2_dev); };
v4l2_device_register初始化
此函数的功能就是将当前设备和v4l2设备捆绑,把v4l2设备放到当前设备的driverdata中
int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev) { if (v4l2_dev == NULL) return -EINVAL;
INIT_LIST_HEAD(&v4l2_dev->subdevs);
spin_lock_init(&v4l2_dev->lock);
v4l2_prio_init(&v4l2_dev->prio);
kref_init(&v4l2_dev->ref);
get_device(dev);
v4l2_dev->dev = dev;
...
if (!v4l2_dev->name[0])
snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), “%s %s”,dev->driver->name, dev_name(dev));
//下面是非常重要的一步,即将v4l2设备对象保存到dev设备中,这个dev可以是platform,char,block,可以使用dev_get_drvdata获取v4l2对象
if (!dev_get_drvdata(dev))
dev_set_drvdata(dev, v4l2_dev);
return 0;
}