一 通用理论:
1、硬件链接:
一般情况下,Camera和SOC有两个接口进行连接,分为为MIPI接口和I2C接口,其中MIPI接口用来传输图像的数据,数据传输路径为从Sensor传输到SOC。另一个接口为I2C接口,主要是用来SOC对Sensor初始化配置寄存器和摄像头参数的配置,比如要进行图像数据捕获的时候就需要通过i2c对Sensor的寄存器进行配置。
2、图像数据流:
光线经过Sensor之后,Sensor芯片经过ADC转换生成原始图像数据(raw),然后Sensor生成的原始图像数据(raw)经过MIPI总线进入SOC,进入SOC之后经过图像处理芯片(如ISP)进行图像处理。所以由此可以可以看出,Camera驱动V4L2一定有这3部分组成:
- 第一部分与Sensor相关的,比如控制Sensor的寄存器进行配置,这一部分是有Sensor厂家提供。
- 第二部分和MIPI相关的,需要MIPI进行图像传输,所以驱动应该就有这一部分的驱动,这部分一般是由SOC厂家提供。
- 第三部分就是ISP部分,有些SOC有ISP图像处理模块,经过MIPI传输的图像进入SOC之后需要在传入SOC的ISP模块对图像进一步进行加工,所以一定是有一部分驱动是描述ISP模块的。
(光) -------> [sensor] ----->(raw图像数据) ----->[mipi总线] ----->[图像处理芯片(如ISP)] -----> (NV16/NV12等格式图像数据)
raw格式sensor的输出格式,是sensor将光信号转换为电信号时的电平高低的原始记录,没有经过处理的原始数据:
二 从DTS 中找到这三部分:
我们已经知道Camera有3部分的驱动,分别是描述Sensor、MIPI相关、图像处理芯片相关的,所以在dts中也有描述这3部分的。
第一部分:sensor 相关dts
代码语言:javascript复制&i2c1 {
tp2855_1: tp2855_1@44 {
compatible = "techpoint,tp2855";
reg = <0x44>; //i2c地址
...
port {
ucam_out0: endpoint {
remote-endpoint = <&csi_dphy0_input>; //Sensor连接到mipi
data-lanes = <1 2 3 4>;
};
};
};
tp2855_2: tp2855_2@45 {
compatible = "techpoint,tp2855";
reg = <0x45>; //i2c地址
...
port {
ucam_out1: endpoint {
remote-endpoint = <&csi_dphy1_input>; //Sensor连接到mipi csi_dphy1_input
data-lanes = <1 2 3 4>;
};
};
};
};
第二部分:mipi物理总线相关:
对于RV1126和RV1106平台而言,支持两个DPHY硬件,存在两个独立而完备的标准物理mipi csi2 dphy,对应于dts上的csi_dphy0和csi_dphy1(参见rv1126.dtsi),特性如下:
代码语言:javascript复制data lane最大4 lanes;
最大速率2.5Gbps/lane;
sensor----mipi dphy:
代码语言:javascript复制//连接 0x44 前四通道 摄像头
&csi_dphy0 {
status = "okay";
//mipi有两端一段连接Sensor,另一端连接 mipi_csi2_input
ports {
#address-cells = <1>;
#size-cells = <0>;
//连接到Sensor
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
csi_dphy0_input: endpoint@1 {
reg = <1>;
remote-endpoint = <&ucam_out0>; // 连接到Sensor : ucam_out0
data-lanes = <1 2 3 4>;
};
};
//连接到 mipi_csi2_input
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
csi_dphy0_output: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi_csi2_input>; // 连接到 mipi_csi2_input
data-lanes = <1 2 3 4>;
};
};
};
};
//连接 0x45 后四通道摄像头
&csi_dphy1 {
status = "okay";
//连接到Sensor
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
csi_dphy1_input: endpoint@1 {
reg = <1>;
remote-endpoint = <&ucam_out1>;// 连接到Sensor : ucam_out1
data-lanes = <1 2 3 4>;
};
};
//连接到ISP
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
csi_dphy1_output: endpoint@0 {
reg = <0>;
remote-endpoint = <&isp_in>; // 连接到ISP : isp_in
data-lanes = <1 2 3 4>;
};
};
};
};
第三部分:mipi 协议解析相关 (MIPI Host)
每个mipi phy都需要一个csi2模块来解析mipi协议 sensor----mipi dphy ---- mipi_csi2
代码语言:javascript复制&mipi_csi2 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi_csi2_input: endpoint@1 {
reg = <1>;
remote-endpoint = <&csi_dphy0_output>;
data-lanes = <1 2 3 4>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
mipi_csi2_output: endpoint@0 {
reg = <0>;
remote-endpoint = <&cif_mipi_in>;
data-lanes = <1 2 3 4>;
};
};
};
};
第四部分:图像处理芯片(vicap)相关
sensor----mipi dphy ---- mipi_csi2-----vicap
代码语言:javascript复制rkcif_mipi_lvds: rkcif_mipi_lvds {
compatible = "rockchip,rkcif-mipi-lvds";
rockchip,hw = <&rkcif>;
// iommus = <&rkcif_mmu>;
memory-region = <&isp_reserved>;
status = "disabled";
};
&rkcif_mipi_lvds {
status = "okay";
rockchip,cif-monitor = <3 2 25 1000 5>;
port {
/* MIPI CSI-2 endpoint */
cif_mipi_in: endpoint {
remote-endpoint = <&mipi_csi2_output>;
data-lanes = <1 2 3 4>;
};
};
};
图像处理芯片(isp)相关:
代码语言:javascript复制&rkisp_vir0 {
status = "okay";
ports {
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
isp_in: endpoint@0 {
reg = <0>;
remote-endpoint = <&csi_dphy1_output>;//连接到 mipi : csi_dphy1_output
};
};
};
};
0x44 前四通道 连接关系 图像处理走vicap:
代码语言:javascript复制ucam_out0 - csi_dphy0_input - csi_dphy0_output - mipi_csi2_input <-> mipi_csi2_output
tp2855_1@44 csi_dphy0 mipi_csi2 rkcif_mipi_lvds
ucam_out0 ---> csi_dphy0_input -- csi_dphy0_output --> mipi_csi2_input -- mipi_csi2_output <---> cif_mipi_in
前四通道 驱动拆分:
代码语言:javascript复制1 关于 sensor模块分析:sensor.c
kerneldriversmediai2ctechpointtechpoint_v4l2.c
2 关于 mipi 物理层 (csi dphy)模块 (csi_dphy0 / csi_dphy1)分析 : mipi_csi_dphy.c
kerneldriversphyrockchipphy-rockchip-mipi-rx.c
3 关于 mipi解析模块( mipi csi)(MIPI Host)模块分析:mipi_csi.c
kerneldriversmediaplatformrockchipcifmipi-csi2.c
4 关于 图像处理vicap 模块分析:rkcif_mipi.c
kerneldriversmediaplatformrockchipcifdev.c
0x45 后四通道 连接关系 图像处理走isp:
代码语言:javascript复制ucam_out1 - csi_dphy1_input - csi_dphy1_output <-> isp_in
tp2855_2@45 csi_dphy1 rkisp_vir0
ucam_out1 --> csi_dphy1_input -- csi_dphy1_output <---> isp_in
由上面分析我们可以知道在Camera的框架中在不同板子或者说不同平台,有3部分是需要实现的。
- 第一部分Sensor相关即不同板子摄像头选型肯定是不一样的,这部分的驱动就是要实现Sensor的初始化,寄存器的配置等,比如启动图像捕获的时候,需要配置寄存器,从应用层会使用一个ioctl一步一步的调用下来到驱动中,所以这部分是Sensor相关的,需要Sensor提供相应的驱动。
- 第二部分MIPI相关,比如我们常用的SOC和Sensor连接就是使用MIPI接口,所以就需要实现MIPI相关部分的驱动,这部分一般来说是由SOC厂商进行提供。
- 第三部分图像处理芯片(如ISP)部分,如果我们的SOC平台如果有ISP模块那么就有ISP模块部分的驱动代码,这部分也是SOC厂商提供的。
从dts的配置中我们可以看到,驱动的绑定路径为,从Sensor连接到MIPI然后MIPI连接到ISP,所以说Sensor捕获到的数据通过MIPI传入ISP,然后通过ISP处理后传动应用层进行处理,整个Camera的驱动框架大概就是这个流程。
文章参考:http://t.csdnimg.cn/3xcLG