九鼎创展论坛

标题: v4L2 soc-camera 分析 - soc_camera.c [打印本页]

作者: armeasy    时间: 2014-7-10 09:24
标题: v4L2 soc-camera 分析 - soc_camera.c
soc_camera.c

[cpp] view plaincopy


1472 platform_driver_probe和platform_driver_register的区别:前者功能上和platform_driver_register是一样的,但是在内核启动完成后,这个函数就不能再执行了,这样可以释放函数soc_camera_pdrv_probe所占的空间。soc_camera_pdrv_probe会probe系统内名称为"soc-camera-pdrv"的平台设备,系统内有几个这样的平台设备,那么就会创建几个soc_camera_device。这些平台设备可如下定义:
[cpp] view plaincopy


注意,这里假定系统的camera处理模块,接了两个camera sensor, adv7180_link和tw9912_link
[cpp] view plaincopy


soc_camera_link主要用来定义i2c地址,如果sensor不是通过i2c连接到host上,那么要定义add_device和del_device函数

1465 注册一条新的总线soc-camera,这样在scan_add_host中调用device_register时,就会把这个设备挂到这个总线上。

[cpp] view plaincopy


当一个soc-camera-device设备通过device_register注册设备时,就会调用soc_camera_probe函数
[cpp] view plaincopy


查找匹配名为soc-camera-pdrv的platform device时,调用该函数。
1419 调用soc_camera_device_register,把这个soc_camera_device加到全局camera device链表@devices上,并且为它分配设备号,做一些必要的初始化
1423 设置soc_came_device对应device的bus为soc_camera_bus_type,这样当我们注册设备时,就会调用soc_camera_probe

[cpp] view plaincopy


在当前的上下文,soc_camera_video_start的调用路径如下
soc_camera_host_register ==> scan_add_host ==> device_register ==> bus_probe_device ==> soc_camera_bus_type.probe ==> soc_camera_video_start

1390 我们可以看出,系统为每一个soc-camera-device创建了一个video device设备节点

[cpp] view plaincopy


当前的上下文,video_dev_create的调用路径如下
soc_camera_host_register ==> scan_add_host ==> device_register ==> bus_probe_device ==> soc_camera_bus_type.probe ==> soc_camera_video_start
这里面设置了video_device的两个非常重要的参数:soc_camera_ioctl_ops和soc_camera_fops,当user space打开video device后,所有可执行的操作,都是通过这两个入口进行的,下面是他们的定义。
[cpp] view plaincopy



[cpp] view plaincopy


soc_camera_ops 不支持read操作,因此如果使用了soc camera子系统,那么应用层就无法再使用read操作获取camera 数据,而只能选择使用mmap方式。不支持read操作没什么关系,大部分camera操作都是使用mmap方式进行的。samsung的s5pv210不支持read操作,而freescale mxc系列则支持read操作获取camera数据。
soc_camera_ioctl_ops也仅仅支持了v4l2_ioctl_ops的一个子集,这就意味着应用程序的作者需要考虑ioctl可能没有被支持。

[cpp] view plaincopy


把给定的@icd加到全局soc camera device列表中

1290~1294 @devices是一个全局soc camera device列表,这段代码相当拗口,注意1293行是break 1290这个循环
[cpp] view plaincopy


1231 每个camera host对应一个v4l2 device(注意不是video device),host上device对应的才是video device

1235 @host是一个全局camera host 链表
1238 scan_add_host 关联系统内属于这个host的video device

[cpp] view plaincopy


soc camera总线代码,当调用device_register注册一个新设备时,会调用probe函数


[cpp] view plaincopy


在host-driver probe函数中调用,soc_camera_host_register ==> scan_add_host ==> device_register ==> bus_probe_device ==> soc_camera_probe
972 调用camera host驱动的add函数,比如pxa平台的pxa_camera_add_device
977 在调用video_device_register之前,要先创建video_device
982~1008 如果是i2c camera,那么调用soc_camera_init_i2c来初始华i2c,否则就调用add_device增加设备。soc_camera_init_i2c会调用到芯片驱动i2c_driver.probe,对于我们的项目,则是adv7180_probe
1010~1013  初始化client format,调用soc_camera_init_user_format之前,已经执行了芯片的probe函数,已经可以对芯片进一步的操作。
1026 调用soc_camera_video_start注册一个video device
1031 每一个soc camera device都一一对应一个v4l2 subdev
1044 ~ 1046 已经获取了soc camera device必要的信息后,调用remove_device关闭soc camera device,然后调用soc_camera_power_set关闭soc camera device的电源。

[cpp] view plaincopy


这个函数只被soc_camera_host_register调用。扫描系统所有的camera device,把属于这个camera host(参数@ici指定)的所有camera device注册到系统中。
876 系统所有的camera device,在没有被camera host注册前,这些camera device仅保存在@devices链表中
877 比较camera device的host number是否等于这个camera host
882 device_register 注册一个设备到系统中,这个函数会调用bus_probe_device,而bus_probe_device则会调用soc_camera_bus_type.probe,也就是soc_camera_probe。这样soc_camera_host_register就会注册所有属于这个host的camera device到系统中,并且创建了相应的设备节点/dev/videoX,整个设备的注册过程全部结束了,从现在开始,可以在设备节点/dev/videoX上调用open read write ioctl以及poll。
[cpp] view plaincopy


185 soc_camera驱动并没有实现这句话,而是直接  return 0,这就导致当前的soc camera子系统不支持S_INPUT接口。

[cpp] view plaincopy


当应用通过open系统调用,打开设备节点/dev/videoX时,会调用soc_camera_open
430 ici->ops->add 不仅要执行host内部的初始化,还会调用camera sensor(参数icd指定)的init
447 配置camera sensor缺省的格式参数,从我个人理解,一切合理的fmt都应该在调用S_INPUT之后进行设置。当然,这需要应用程序编程时先调用S_INPUT再进行S_FMT。
405~408 仅在第一次打开时,才对camera host和camera sensor做初始化操作,否则,仅仅增加引用计数。





欢迎光临 九鼎创展论坛 (http://bbs.9tripod.com/) Powered by Discuz! X3.2