imx6平台video简介(二)

本文深入探讨Linux内核中V4L2(Video for Linux Two)驱动的主从设备注册过程,涉及V4L2_int_device的注册、I2C通信、主从设备的匹配以及video_device的注册。文章通过代码分析介绍了如何通过v4l2_int_device_register()和video_register_device()函数完成设备注册,并解析了设备间如何通过ioctl调用进行交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在上节中我们介绍V4L2的概念、v4l2的设备以及上层点击APP时的调用过程;这节我们详细分底层驱动的注册以及API的调用过程。

参考链接:https://blog.youkuaiyun.com/jack_a8/article/details/43113103向这位老师傅致敬,写的非常好!

言归正传,在这节中slave设备是ti940_mipi.c,master设备就不说了。先来看看流程图:


这张图基本上能说明了各个调用过程,接下里我们分析代码:

Dvr设备是通过I2C进行通信的,既然是I2C设备,那么肯定也有主从分别,现在看下slave设备注册,以ti940为例:

staticstruct v4l2_int_ioctl_desc ti_ub940_ioctl_desc[] = {

       { vidioc_int_dev_init_num,     (v4l2_int_ioctl_func*)ioctl_dev_init                         },

       {vidioc_int_dev_exit_num,      ioctl_dev_exit                                         },

       { vidioc_int_s_power_num,     (v4l2_int_ioctl_func*)ioctl_s_power                        },

       { vidioc_int_g_ifparm_num,    (v4l2_int_ioctl_func*)ioctl_g_ifparm                       },

       { vidioc_int_init_num,            (v4l2_int_ioctl_func*)ioctl_init                         },

       { vidioc_int_enum_fmt_cap_num,  (v4l2_int_ioctl_func*)ioctl_enum_fmt_cap               },

       {vidioc_int_enum_frameintervals_num,(v4l2_int_ioctl_func*) ioctl_enum_frameintervals},

       { vidioc_int_g_fmt_cap_num,  (v4l2_int_ioctl_func*)ioctl_g_fmt_cap                            },

       { vidioc_int_g_parm_num,      (v4l2_int_ioctl_func*)ioctl_g_parm                         },

       { vidioc_int_s_parm_num,      (v4l2_int_ioctl_func*)ioctl_s_parm                          },

       { vidioc_int_enum_framesizes_num,(v4l2_int_ioctl_func*)ioctl_enum_framesizes                    },

       { vidioc_int_g_chip_ident_num,      (v4l2_int_ioctl_func*)ioctl_g_chip_ident                  },

       { vidioc_int_reset_num,   (v4l2_int_ioctl_func*)ioctl_reset               },

};

staticstruct v4l2_int_slave ti_ub940_slave = {

       .ioctls             =ti_ub940_ioctl_desc,

       .num_ioctls     = ARRAY_SIZE(ti_ub940_ioctl_desc),

};

staticstruct v4l2_int_device ti_ub940_int_device = {

       .module          =THIS_MODULE,

       .name             ="ti_ub940",

       .type        =v4l2_int_type_slave,

       .u            =

       {

              .slave       = &ti_ub940_slave,

       },

};

在probe函数中用 v4l2_int_device_register(&ti_ub940_int_device);注册v4l2_int_device

intv4l2_int_device_register(struct v4l2_int_device *d)

{

       if (d->type == v4l2_int_type_slave)       

              sort(d->u.slave->ioctls,d->u.slave->num_ioctls,  //依次排序存储

                   sizeof(struct v4l2_int_ioctl_desc),

                   &ioctl_sort_cmp, NULL);

       mutex_lock(&mutex);

       list_add(&d->head, &int_list);     //主从设备都会加到int_list链表中

       v4l2_int_device_try_attach_all();    //调用此函数进行适配

       mutex_unlock(&mutex);

       return 0;

}

voidv4l2_int_device_try_attach_all(void)

{

       struct v4l2_int_device *m, *s;

       list_for_each_entry(m, &int_list,head) {         //对链表中的每一个master进行适配

              if (m->type !=v4l2_int_type_master)      

                     continue;

              list_for_each_entry(s,&int_list, head) {         //对链表中每一个slave进行适配

                     if (s->type !=v4l2_int_type_slave)

                            continue;

                     /* Slave is connected? */

                     if(s->u.slave->master)               //slave有master了就继续

                            continue;

                     /* Slave wants to attach tomaster? */

                     if(s->u.slave->attach_to[0] != 0

                         && strncmp(m->name,s->u.slave->attach_to,

                                   V4L2NAMESIZE))

&nbs

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值