一、rk3588硬件资源介绍
- 1、支持两个dcphy,节点名称分别为csi2_dcphy0与csi2_dcphy1。每个dcphy硬件支持RX/TX
同时使用,对于camera输入使用的是RX。支持DPHY/CPHY协议复用;需要注意的是同一个dcphy的TX/RX只能同时使用DPHY或同时使用CPHY。 - 2、支持2个dphy硬件,物理节点名称分别为csi2_dphy0_hw与csi2_dphy1_hw,两个dphy硬件都可以工作在full mode 和split mode两种模式下。full mode最多支持4 lane,split mode每个phy最多支持2 lane.
dcphy软件通路框图
dphy0软件通路框图
full mode
split mode: csi2_dphy1为0/1line,csi2_dphy2为2/3line,
dphy1软件通路框图
full mode
split mode: csi2_dphy4为0/1line,csi2_dphy5为2/3line,
使用上述mipi phy节点,需要把对应的物理节点配置上。(csi2_dcphy0_hw、csi2_dcphy1_hw、csi2_dphy0_hw、csi2_dphy1_hw)
双isp合成
当分辨率大于16M(4672x3504)时需要同时使用两个isp来处理一张图像,只支持单摄。从rk3588s.dtsi文件中,可以找到rkisp0、rkisp1、rkisp_unite三个节点。当需要处理的分辨
率大于16M,需要关闭rkisp0、rkisp1节点,并使能rkisp_unite,同时修改对应的iommu节
点。
&rkisp0 {
status = "disabled";
};
&isp0_mmu {
status = "disabled";
};
&rkisp1 {
status = "disabled";
};
&isp1_mmu {
status = "disabled";
};
&rkisp_unite {
status = "okay";
};
&rkisp_unite_mmu {
status = "okay";
};
&rkisp1_vir1 {
status = "okay";
rockchip,hw = <&rkisp_unite>; //链接rkisp_unite
port {
·······
};
};
};
二、单摄:OV50C40(48M分辨率)接dphy1 full mode 4LINE
&csi2_dphy1_hw {
status = "okay";
};
&csi2_dphy3 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi4_in_ov50c40: endpoint@1 {
reg = <1>;
remote-endpoint = <&ov50c40_out>;
data-lanes = <1 2 3 4>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
csidcphy1_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi4_csi2_input>;
};
};
};
};
&i2c3 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c3m0_xfer>;
clock-frequency = <200000>;
dw9800w: dw9800w@c {
compatible = "dongwoon,dw9800w";
status = "okay";
reg = <0x0c>;
rockchip,vcm-start-current = <256>;//-50
rockchip,vcm-rated-current = <998>;//95
rockchip,vcm-step-mode = <4>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
};
aw36518: aw36518@63 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "awinic,aw36518";
status = "okay";
reg = <0x63>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
aw36518_led0: led@0 {
reg = <0x0>;
led-max-microamp = <386000>;
flash-max-microamp = <1500000>;
flash-max-timeout-us = <1600000>;
};
};
ov50c40: ov50c40@10 {
compatible = "ovti,ov50c40";
status = "okay";
reg = <0x10>;
clocks = <&cru CLK_MIPI_CAMARAOUT_M1>;
clock-names = "xvclk";
power-domains = <&power RK3588_PD_VI>;
pinctrl-names = "rockchip,camera_default", "rockchip,camera_sleep";
pinctrl-0 = <&mipim1_camera1_clk>;
pinctrl-1 = <&camera1_pwdn>;
rockchip,grf = <&sys_grf>;
reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
pwdn-gpios = <&gpio3 RK_PA7 GPIO_ACTIVE_LOW>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "HZGA06";
rockchip,camera-module-lens-name = "ZE0082C1";
eeprom-ctrl = <&otp_eeprom>;
lens-focus = <&dw9800w>;
flash-leds = <&aw36518_led0>; //闪光灯
port {
ov50c40_out: endpoint {
remote-endpoint = <&mipi4_in_ov50c40>;
data-lanes = <1 2 3 4>;
};
};
};
otp_eeprom: otp_eeprom@50 {
compatible = "rk,otp_eeprom";
status = "disabled";
reg = <0x50>;
};
};
&mipi4_csi2 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi4_csi2_input: endpoint@1 {
reg = <1>;
remote-endpoint = <&csidcphy1_out>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
mipi4_csi2_output: endpoint@0 {
reg = <0>;
remote-endpoint = <&cif_mipi4_in1>;
};
};
};
};
&rkcif {
status = "okay";
};
&rkcif_mipi_lvds4 {
status = "okay";
port {
cif_mipi4_in1: endpoint {
remote-endpoint = <&mipi4_csi2_output>;
};
};
};
&rkcif_mipi_lvds4_sditf {
status = "okay";
port {
mipi4_lvds_sditf: endpoint {
remote-endpoint = <&isp1_vir1>;
};
};
};
&rkcif_mmu {
status = "okay";
};
&rkisp_unite {
status = "okay";
};
&rkisp_unite_mmu {
status = "okay";
};
&rkisp1_vir1 {
status = "okay";
rockchip,hw = <&rkisp_unite>;
port {
#address-cells = <1>;
#size-cells = <0>;
isp1_vir1: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi4_lvds_sditf>;
};
};
};
&pinctrl {
cam {
camera1_pwdn:camera1-pwdn{
rockchip,pins =
<3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
};
三、双摄 OV50C40 + OV13855
1、低分辨率后摄
关闭OV50C40的48M拍照模式,模拟普通摄像头。如下:
XXXX.dts
/*不使用48M拍照*/
// &rkisp_unite {
// status = "okay";
// };
//
// &rkisp_unite_mmu {
// status = "okay";
// };
&rkisp1 {
status = "okay";
};
&isp1_mmu {
status = "okay";
};
&rkisp1_vir1 {
status = "okay";
// rockchip,hw = <&rkisp_unite>;
port {
·······
};
};
};
--- a/kernel-5.10/drivers/media/i2c/ov50c40.c
+++ b/kernel-5.10/drivers/media/i2c/ov50c40.c
@@ -5755,24 +5755,24 @@ static const struct ov50c40_mode supported_modes_dphy[] = {
static const struct ov50c40_mode supported_modes_dphy[] = {
{
.bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10,
.width = 4096,
.height = 3072,
··················································
},/*屏蔽掉48M信息*/
// {
// .bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10,
// .width = 8192,
// .height = 6144,
// .max_fps = {
// .numerator = 10000,
// .denominator = 120000,
// },
// .exp_def = 0x0240,
// .hts_def = 0x9f6 * 4,
// .vts_def = 0x0cc3 * 2,
// .mipi_freq_idx = 3,
// .bpp = 10,
// .reg_list = ov50c40_10bit_8192x6144_dphy_12fps_regs,
// .hdr_mode = NO_HDR,
// .spd = &ov50c40_spd,
// .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
// },
#ifdef DEBUG
{
.bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10,
.width = 4096,
.height = 3072,
··········································
},/*屏蔽掉48M信息*/
// {
// .bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10,
// .width = 8192,
// .height = 6144,
// .max_fps = {
// .numerator = 10000,
// .denominator = 30000,
// },
// .exp_def = 0x0240,
// .hts_def = 0x09f6 * 4,
// .vts_def = 0x0cc3 * 2,
// .mipi_freq_idx = 1,
// .bpp = 10,
// .reg_list = ov50c40_10bit_8192x6144_dphy_regs,
// .hdr_mode = NO_HDR,
// .spd = &ov50c40_spd,
// .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
// },
{
.bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10,
.width = 4096,
.height = 3072,
.max_fps = {
·······································
},
#endif
};
--- a/hardware/rockchip/camera/etc/camera/camera3_profiles_rk3588.xml
+++ b/hardware/rockchip/camera/etc/camera/camera3_profiles_rk3588.xml
@@ -1152,7 +1152,6 @@
<scaler.availableMaxDigitalZoom value="4.0"/>
<scaler.availableInputOutputFormatsMap value="IMPLEMENTATION_DEFINED,2,YCbCr_420_888,BLOB,YCbCr_420_888,2,YCbCr_420_888,BLOB"/>
<scaler.availableStreamConfigurations value="
- BLOB,8064x6144,OUTPUT,
BLOB,4096x3072,OUTPUT,
BLOB,3840x2160,OUTPUT,
BLOB,3264x2448,OUTPUT,
@@ -1187,7 +1186,6 @@
IMPLEMENTATION_DEFINED,320x240,OUTPUT,
IMPLEMENTATION_DEFINED,176x144,OUTPUT"/>
<scaler.availableMinFrameDurations value="
- BLOB,8064x6144,83333333,
BLOB,4096x3072,33333333,
BLOB,3840x2160,33333333,
BLOB,3264x2448,33333333,
@@ -1222,7 +1220,6 @@
IMPLEMENTATION_DEFINED,320x240,33333333,
IMPLEMENTATION_DEFINED,176x144,33333333" />
<scaler.availableStallDurations value="
- BLOB,8064x6144,83333333,
BLOB,4096x3072,33333333,
BLOB,3840x2160,33333333,
BLOB,3264x2448,33333333,
@@ -1284,7 +1281,7 @@
<Hal_tuning_RKISP1> <!-- Parameters to tune the HAL and hacks for the HAL that are camera dependent -->
<flipping value="" value_v=""/> <!-- value: SENSOR_FLIP_H or "", value_v: SENSOR_FLIP_V or "" -->
<supportIsoMap value="false"/>
- <supportTuningSize value="8192x6144, 4096x3072"/>
+ <supportTuningSize value="4096x3072"/>
</Hal_tuning_RKISP1>
重新编译后烧录,即可(或直接推到终端,注意将摄像头APK清除缓存数据)。
2、48M分辨率后摄 13M分辨率前摄
由于RK平台摄像头的分辨率大于16M(4672x3504)时需要同时使用两个isp来处理一张图像,只支持单摄,这里采用分时复用的方式配置摄像头,如下:
&rkisp1 {
status = "disabled";
};
&isp1_mmu {
status = "disabled";
};
&rkisp0 {
status = "disabled";
};
&isp0_mmu {
status = "disabled";
};
&rkisp_unite {
status = "okay";
};
&rkisp_unite_mmu {
status = "okay";
};
&rkisp1_vir1 {
status = "okay";
rockchip,hw = <&rkisp_unite>;
port {
#address-cells = <1>;
#size-cells = <0>;
isp1_in1: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi4_lvds_sditf>;
};
isp1_in2: endpoint@1 {
reg = <1>;
remote-endpoint = <&mipi2_lvds_sditf>;
};
};
};
&rkcif_mipi_lvds4_sditf {
status = "okay";
port {
mipi4_lvds_sditf: endpoint {
remote-endpoint = <&isp1_in1>;
};
};
};
&rkcif_mipi_lvds2_sditf {
status = "okay";
port {
mipi2_lvds_sditf: endpoint {
remote-endpoint = <&isp1_in2>;
};
};
};
其余配置不变即可。
3、设置cameraID、facing与dts节点一致:
dw9763: dw9763@e {
compatible = "dongwoon,dw9763";
······················
rockchip,camera-module-index = <1>; //与ov13855一致
rockchip,camera-module-facing = "front"; //与ov13855一致
};
dw9800w: dw9800w@c {
compatible = "dongwoon,dw9800w";
···················
rockchip,camera-module-index = <0>; //与ov50c40一致
rockchip,camera-module-facing = "back"; //与ov50c40一致
};
aw36518: aw36518@63 {
·························
rockchip,camera-module-index = <0>; //与ov50c40一致
rockchip,camera-module-facing = "back"; //与ov50c40一致
aw36518_led0: led@0 {
reg = <0x0>;
led-max-microamp = <386000>;
flash-max-microamp = <1500000>;
flash-max-timeout-us = <1600000>;
};
};
ov13855: ov13855@36 {
compatible = "ovti,ov13855";
status = "okay";
·····················
rockchip,camera-module-index = <1>;
rockchip,camera-module-facing = "front";
·····················
lens-focus = <&dw9763>; //对焦马达
};
ov50c40: ov50c40@10 {
compatible = "ovti,ov50c40";
status = "okay";
·························
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
·························
};
};
--- a/hardware/rockchip/camera/etc/camera/camera3_profiles_rk3588.xml
+++ b/hardware/rockchip/camera/etc/camera/camera3_profiles_rk3588.xml
@ -****,1 +****,1 @@
- <Profiles cameraId="0" name="ov13855" moduleId="m00">
+ <Profiles cameraId="1" name="ov13855" moduleId="m01">
@ -2971,7 +2683,7 @@
<lens.info.minimumFocusDistance value="0.1"/> <!-- HAL may override this value from CMC for RAW sensors -->
<!-- Lens -->
- <lens.facing value="BACK"/>
+ <lens.facing value="FRONT"/>
<!-- Request -->
4、关闭前置闪光灯设置
--- a/hardware/rockchip/camera/etc/camera/camera3_profiles_rk3588.xml
+++ b/hardware/rockchip/camera/etc/camera/camera3_profiles_rk3588.xml
@@ -2899,7 +2899,7 @@
<!-- Flash info -->
- <flash.info.available value="TRUE"/>
+ <flash.info.available value="FALSE"/>
<flash.info.chargeDuration value="1000000"/>
四、修改拍照时闪光灯时长
拍照时闪光灯工作流程为:
使用aw36518闪光灯芯片,RK3588中默认支持此型号芯片,该芯片只有一个LED控制脚,驱动函数需做修改。
--- a/kernel-5.10/drivers/media/i2c/aw36518.c
+++ b/kernel-5.10/drivers/media/i2c/aw36518.c
@@ -98,2 +98,2 @@enum aw36518_led_id {
LED0 = 0,
- LED1,
+ LED0 = 1,
LED_MAX
};
RK3588中默认驱动函数未开启TORCH开关,这里添加打开并设置呼吸1ms亮起。
@@ -282,6 +282,7 @@ static int aw36518_set_mode(struct aw36518_flash *flash,
enum aw36518_led_id id, unsigned int mode)
{
int ret = 0;
+ u8 val = 0;
v4l2_dbg(1, debug, &flash->leds[id].sd,
"%s: %d cur:%d\n", __func__,
@@ -300,7 +301,9 @@ static int aw36518_set_mode(struct aw36518_flash *flash,
} else if (mode == V4L2_FLASH_LED_MODE_TORCH) {
//ret = aw36518_i2c_write(flash, 0x01, 0x08);
/* hw torch/strobe io trigger torch */
- ret = aw36518_i2c_write(flash, 0x01, AW36518_HW_TORCH);
+ ret = aw36518_i2c_write(flash, 0x01, AW36518_HW_TORCH | 0x08);
+ val = aw36518_i2c_read(flash, 0x08);
+ ret |= aw36518_i2c_write(flash, 0x08, val & 0x1f);
ret |= aw36518_torch_brt(flash, LED0);
按照芯片数据手册配置寄存器,打开手电筒模式即可。