好久之前做过camera驱动,最近几年没有从事这方向的工作。想来重新温习下v4l2驱动框架,与大家一起学习研究,在现有的MTK8518平台上看了下cx23885这个 pcie驱动程序比较全面。基本的v4l2核心api都有涉及,就以这个驱动来重新学习下这个框架。大体调用流程图如下:

1、v4l2_device初始化
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 (dev == NULL) {
/* If dev == NULL, then name must be filled in by the caller */
if (WARN_ON(!v4l2_dev->name[0]))
return -EINVAL;
return 0;
}
/* Set name to driver name + device name if it is empty. */
if (!v4l2_dev->name[0])
snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",
dev->driver->name, dev_name(dev));
if (!dev_get_drvdata(dev))
dev_set_drvdata(dev, v4l2_dev);
return 0;
}
通用API,内容简单明了主要包括:
一、初始化subdev链表,为后续增加subdev设备提支持
二、初始化自旋锁,常规操作
三、初始化优先级,这是个整形数组大小为4,代表4种类型与如下枚举定义一一对应
enum v4l2_priority {
V4L2_PRIORITY_UNSET = 0, /* not initialized */
V4L2_PRIORITY_BACKGROUND = 1,
V4L2_PRIORITY_INTERACTIVE = 2,
V4L2_PRIORITY_RECORD = 3,
V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE,
};
四、根据条件是否为此结构体 成员name进行赋值
五、将此v4l2_device设置为dev的私有数据,后续有必要可以通过私有数据进行访问v4l2_device
cx23885_video_register

一般的v4l2驱动程序都会有上面类型的初始化的动作,核心的是fops和ioctl_ops两个回调函数
vb2_queue_init
队列初始化:
q = &dev->vb2_vidq;
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
q->gfp_flags = GFP_DMA32;
q->min_buffers_needed = 2;
q->drv_priv = dev;
q->buf_str

最低0.47元/天 解锁文章

400

被折叠的 条评论
为什么被折叠?



