soc-camera的作者之所以引入這個子系統,我想一個主要目的就是把camera驅動劃分為camera host端,camera sensor端,這樣同一個camera sensor驅動就可以方便的移植到多個camera host下,而無須做較多的改動。
本譯文取自kernel文檔:Documentation/video4linux/soc-camera.txt
術語
在閱讀本文檔前先明確幾個術語:
soc-camera subsystem的目的
soc-camera 子系統在camera host驅動和camera sensor驅動間提供了統一的接口。子系統向上提供了V4L2接口,當前僅支持mmap method。
這個子系統連接SoC video capture接口和CMOS camera sensor chips,使得sensor驅動可以在其他的hosts驅動上復用。子系統在設計時也考慮到了多個camera host接口的存在,以及每個接口存在多個camera sensor,盡管在大部分情況下僅有一個camera sensor。
現存的驅動
在2.6.27-rc4中,主線內核有兩個host 驅動:PXA27x的pxa_camera.c和SuperH SoCs的sh_mobile_ceu_camera.c,有四個sensor驅動:mt9m001.c,mt9v002.c以及一個通用的soc_camera_platform.c驅動。這個列表可能不是最新的,所以在你的源碼樹中查看,可能有更多的例子存在。
實際開發中,新的sensor驅動可以參照mt9m001.c和mt9v002.c這兩個sensor驅動框架,根據項目所用的sensor稍加修改即可。
Camera host API
一個host camera driver使用soc_camera_host_register(struct soc_camera_host *)函數來注冊。host object可以如下初始化
static struct soc_camera_host pxa_soc_camera_host = {
.drv_name = PXA_CAM_DRV_NAME,
.ops = &pxa_soc_camera_host_ops,
};
所有的方法都是通過struct soc_camera_host_ops
static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
.owner = THIS_MODULE,
.add = pxa_camera_add_device,
.remove = pxa_camera_remove_device,
.suspend = pxa_camera_suspend,
.resume = pxa_camera_resume,
.set_fmt_cap = pxa_camera_set_fmt_cap,
.try_fmt_cap = pxa_camera_try_fmt_cap,
.init_videobuf = pxa_camera_init_videobuf,
.reqbufs = pxa_camera_reqbufs,
.poll = pxa_camera_poll,
.querycap = pxa_camera_querycap,
.try_bus_param = pxa_camera_try_bus_param,
.set_bus_param = pxa_camera_set_bus_param,
};
.add和 .remove方法是sensro接入host和從host卸載時調用,除了執行host內部的初始化工作,還會調用sensor的.init和.release方法。
.suspend和.resume方法實現host的電源管理功能, 他們要負責調用相應的sensor 方法。
.try_bus_param和.set_bus_param用來協商host和sensor間的物理連接參數。
.init_videobuf是當一個video-device被打開時調用,video-buffer管理的實現是完全依賴於特定的host
其余部分被V4L2的相應部分調用。