上一篇文章介绍了如何在RK3588上面点亮一个sensor,以MIPI camera IMX577为例进行介绍的,从前面的文章也知道,RK3588最多支持6路MIPI camera,一路DVP,因此这篇文章作为补充,分别介绍一下MIPI camera和DVP camera的配置重点。
目录
(1)常用camera接口介绍
①USB camera
②MIPI camera
③DVP camera
(2)RK3588 调试
①概述
②RK3588 MIPI配置
1)驱动接口配置
2)dts配置
③RK3588 DVP camera
1)BT601接口
2)BT656/BT1120
(3)总结
(1)常用camera接口介绍
按照不同的接口进行分类,常见的camera有:USBcamera、MIPI camera、DVP camera。
USB Camera常见的数据格式有:YUYV/MJPEG/H.264
YUYV:传输的是YUV数据,数据量很大,分辨率和帧率较低,一般由后端对数据进行再处理,用于一些特殊用途(虹膜、红外人脸识别等)。
MJPEG:一般用于分辨率相对较低的USB Camera(720P,VGA),传输数据较大。
H.264:一般用于分辨率较高的USB Camera(1080p,720p),传输数据较小。
MIPI为低压差分信号,传输速度快,抗干扰能力强,一般支持800万及以上像素的camera。目前主流手机camera模组都使用MIPI传输,传输时使用4对差分数据信号和1对差分时钟信号。
DVP Camera或称为并口Camera,接口如下图所示,一般支持BT601/BT656/BT1120数据的传输。DVP是并口传输,速度相对较慢,传输的带宽较低,一般用于500万像素以下的camera。需要使用PCLK时钟、VSYNC场同步、HSYNC行同步、D[0:11]并口数据,可以是8/10/12bit/16bit数据位大小。
连接框图如下所示,这边简单介绍一下RK3588 camera配置的关键要点。
根据上述的结构图可以大概看出MIPI和DVP分别是如何连接的,关键点如下:
RK3588最多情况下可以使用4个2lane,2个4lane的MIPI接口camera,关键配置注意如下:
驱动主要注意g_mbus_config接口的配置,该接口需要配置使用的是DVP接口还是MIPI接口,是MIPI DPHY还是MIPI CPHY,例如IMX577配置为V4L2_MBUS_CSI2_DPHY;其次,若是MIPI接口,该接口还需要配置lane数,IMX577配置为4lane;最后还需要配置虚拟通道数,如IMX577,线性模式配置一个通道,HDR模式则需要配置两个通道,若是多路vc的转接芯片,例如N4,则需要配置4通道。
static int imx577_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
struct v4l2_mbus_config *config)
{
struct imx577 *imx577 = to_imx577(sd);
const struct imx577_mode *mode = imx577->cur_mode;
u32 lane_num = imx577->bus_cfg.bus.mipi_csi2.num_data_lanes;
u32 val = 0;
val = 1 << (lane_num - 1) |
V4L2_MBUS_CSI2_CHANNEL_0 |
V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
if (mode->hdr_mode != NO_HDR)
val |= V4L2_MBUS_CSI2_CHANNEL_1;
config->type = V4L2_MBUS_CSI2_DPHY;
config->flags = val;
return 0;
}
dts配置可以参考上一篇文章的IMX577的配置,这边主要强调几个重点:
data-lanes:配置lane数,如果是4lane则为<1 2 3 4>,2lane则为<1 2>;
camera-module-name和camera-module-lens-name:RAW sensor跑aiq时会用到;
RAW sensor配置:sensor->csi2_dphy->mipi_csi->rkcif_mipi_lvds ... rkcif_mipi_lvds_stdif->rkisp_vir
YUV/RGB888 sensor的配置:sensor->csi2_dphy->mipi_csi->rkcif_mipi_lvds
YUV或者RGB888的sensor,一般自带isp,直接输出YUV422的图像,不需要经过RK3588的isp,因此直接在vicap级存储到ddr即可。
RK3588有一个DVP接口,支持BT601/BT656/BT1120等,同样的,如果是RAW的sensor,需要配置到ISP,如果是YUV的,则不需经过ISP,关键配置如下:
BT601接口配置关键点:
驱动接口配置如下:
static int gc2145_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
struct v4l2_mbus_config *config)
{
struct gc2145 *gc2145 = to_gc2145(sd);
config->type = V4L2_MBUS_PARALLEL;
config->flags = V4L2_MBUS_HSYNC_ACTIVE_HIGH |
V4L2_MBUS_VSYNC_ACTIVE_LOW |
V4L2_MBUS_PCLK_SAMPLE_RISING;
return 0;
}
dts配置与BT656和BT1120基本相同,这里不再重复,参考下面BT656/BT1120即可;
配置关键点如下:
g_mbus_config接口示例代码如下:
static int lt8619c_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
struct v4l2_mbus_config *cfg)
{
struct lt8619c *lt8619c = to_lt8619c(sd);
cfg->type = V4L2_MBUS_BT656;
if (lt8619c->clk_ddrmode_en) {
cfg->flags = RKMODULE_CAMERA_BT656_CHANNELS |
V4L2_MBUS_PCLK_SAMPLE_RISING |
V4L2_MBUS_PCLK_SAMPLE_FALLING;
} else {
cfg->flags = RKMODULE_CAMERA_BT656_CHANNELS |
V4L2_MBUS_PCLK_SAMPLE_RISING;
}
return 0;
}
querystd接口示例如下:
static int lt8619c_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
{
struct lt8619c *lt8619c = to_lt8619c(sd);
if (lt8619c->yuv_output_mode == BT656_OUTPUT)
*std = V4L2_STD_PAL;
else
*std = V4L2_STD_ATSC;
return 0;
}
dts配置参考如下:
&i2c2 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c2m4_xfer>;
nvp6158: nvp6158@30 {
compatible = "nvp6158-v4l2";
status = "okay";
reg = <0x30>;
clocks = <&cru CLK_CIFOUT_OUT>;
clock-names = "xvclk";
power-domains = <&power RK3588_PD_VI>;
pinctrl-names = "default";
pinctrl-0 = <&cif_clk &cif_dvp_clk &cif_dvp_bus8 &cif_dvp_bus16>;
// pwr-gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_HIGH>;
pwr2-gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_HIGH>;
rst-gpios = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>;
// rst2-gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_HIGH>;
// pwdn-gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>;
// pwdn2-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "default";
rockchip,camera-module-lens-name = "default";
rockchip,dvp_mode = "BT1120"; //BT656 or BT1120 or BT656_TEST
rockchip,channel_nums = <4>; //channel nums, 1/2/4
rockchip,dual_edge = <1>; // pclk dual edge, 0/1
rockchip,default_rect= <1920 1080>; // default resolution
port {
nvp6158_out: endpoint {
remote-endpoint = <&dvp_in_bcam1>;
};
};
};
};
&rkcif {
status = "okay";
};
&rkcif_dvp {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
#address-cells = <1>;
#size-cells = <0>;
/* Parallel bus endpoint */
dvp_in_bcam1: endpoint@1 {
reg = <1>;
remote-endpoint = <&nvp6158_out>;
bus-width = <16>;
};
};
};
};
&rkcif_mmu {
status = "okay";
};
同样的,dts配置中,如果是YUV的sensor,则只需要上述配置,连接到rkcif_dvp节点即可,如果是RAW的sensor,则需要添加rkcif_dvp_sditf节点,并连接到rkisp_vir的节点。
如有问题可在评论进行讨论。