RK3588新增SENSOR(一)

以下步骤为个人验证过的,本人非科班出身,未系统性学习过相应的技术知识,目前所掌握的内容均来自于网络,故以下内容中所描述的用词可能有误。

  1. 新增驱动文件,可根据相近型号copy一份,根据sensor datasheet来修改;

  1. 驱动文件目录:

SDK_TOP_DIR/kernel/drovers/media/i2c/
  1. 添加sensor驱动源文件

在驱动文件目录下,可根据自己要添加的Sensor与已有的sensor相似性,选择性的复制一份来自己修改;

sensor驱动的详细内容后续再写。

  1. 在Makefile中SENSOR的编译项

例如我需要添加的SENSOR为SC2210,参照其它SENSOR,添加的是以下内容

obj-$(CONFIG_VIDEO_SC2210) += sc2210.o
  1. 在Kconfig中添加menu config可选配置项

config VIDEO_SC2210
    tristate "SmartSens SC2210 sensor support"
    depends on I2C && VIDEO_V4L2
    select MEDIA_CONTROLLER
    select VIDEO_V4L2_SUBDEV_API
    select V4L2_FWNODE
    help
      This is a Video4Linux2 sensor driver for the SmartSens
      SC2210 camera.
  1. 在dts中添加sensor支持;

  1. dts文件目录

SDK_TOP_DIR/kernel/arch/arm64/boot/dts/rockchip
  1. 查看开发板使用的dts文件名称 ,不同开发板使用的dts不同。

我用的是LKD3588,厂商识别码是neardi;

先从开发包配置文件入手,目录如下:

SDK_TOP_DIR/device/rockchip/rk3388

查看有BoardConfig-rk3588-neardi-linux-lc160.mk文件,打开有以下行:

# Kernel dts
export RK_KERNEL_DTS=rk3588-neardi-linux-lc160

没有后缀?这就需要去研究SDK_TOP_DIR/build.sh文件了。

  1. 添加sensor的dtsi文件,注意不是dts。因我用的是dphy1来连接的sensor,添加是rk3588-dphy1-sc2210.dtsi,文件内容如下

/{
     vcc_mipidphy1: vcc-mipidphy1-regulator {
        compatible                =    "regulator-fixed";
        gpio                    =    <&gpio1 RK_PB1 GPIO_ACTIVE_HIGH>;
        pinctrl-names            =    "default";
        pinctrl-0                =    <&mipidphy1_pwr>;
        regulator-name            =    "vcc_mipidphy1";
        enable-active-high;
        //regulator-always-on;
        //regulator-boot-on;
    };
 };


&i2c2 {
    status = "okay";
        sc2210_dphy1: sc2210@30 {
            compatible                            =    "smartsens,sc2210";
            reg                                    =    <0x30>;
            clocks                                =    <&cru    CLK_MIPI_CAMARAOUT_M2>;
            clock-names                            =    "xvclk";
            power-domains                        =    <&power    RK3588_PD_VI>;
            pinctrl-names                        =    "default";    //,"sleep";
            pinctrl-0                            =    <&mipim0_camera2_clk>;    //,<&sc2210_pwdn_gpio>;
            // pinctrl-1                            =    <&mipim0_camera2_clk>;    //,<&sc2210_pwdn_gpio>;
            rockchip,grf                        =    <&sys_grf>;
            reset-gpios                            =    <&gpio2    RK_PB6 GPIO_ACTIVE_LOW>;
            pwdn-gpios                            =    <&gpio1    RK_PA7 GPIO_ACTIVE_HIGH>;
            avdd-supply                            =    <&vcc_mipidphy1>;
            rockchip,camera-module-index        =    <1>;
            rockchip,camera-module-facing        =    "back";
            //rockchip,camera-module-name = "CMK-OT1607-FV1";
            //rockchip,camera-module-lens-name = "M12-40IRC-4MP-F16";
            rockchip,camera-module-name            =    "bzs2-v10";
            rockchip,camera-module-lens-name    =    "default";
            port {
                sc2210_dphy1_4lene: endpoint {
                    remote-endpoint    =    <&csi2_dphy1_in>;
                    data-lanes        =    <1 2 3 4>;        
                };
            };
       };
};

//  CSI2_DPHY1    ->    MIPI4_CSI2    ->    RKCIF_MIPI_LVDS4    ->    RKCIF_MIPI_LVDS4_SDITF
&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>;
            csi2_dphy1_in: endpoint@1 {
                reg                =    <1>;
                remote-endpoint    =    <&sc2210_dphy1_4lene>;
                data-lanes        =    <1 2 3 4>;
            };
        };
        port@1 {
            reg                =    <1>;
            #address-cells    =    <1>;
            #size-cells        =    <0>;
            csi2_dphy1_out: endpoint@0 {
                reg                =    <0>;
                remote-endpoint    =    <&mipi4_csi2_input>;
            };
        };
    };
};

&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 = <&csi2_dphy1_out>;
            };
        };
        port@1 {
            reg = <1>;
            #address-cells = <1>;
            #size-cells = <0>;
            mipi4_csi2_output: endpoint@0 {
                reg = <0>;
                remote-endpoint = <&rkcif_mipi_lvds4_in>;
            };
        };
    };
};

&rkcif {
    status = "okay";
};

&rkcif_mipi_lvds4{
    status = "okay";
    port {
        rkcif_mipi_lvds4_in: endpoint {
            remote-endpoint = <&mipi4_csi2_output>;
        };
    };
};

&rkcif_mipi_lvds4_sditf {
    status = "okay";
    port {
        mipi_lvds4_sditf: endpoint {
            remote-endpoint = <&isp1_vir1>;            //isp编号
        };
    };
};

&rkcif_mmu {
    status = "okay";
};

&rkisp1 {
    status = "okay";
};

&isp1_mmu {
    status = "okay";
};

&rkisp1_vir1 {
    status = "okay";
    port {
        #address-cells = <1>;
        #size-cells = <0>;
        isp1_vir1: endpoint@0 {
            reg = <0>;
            remote-endpoint = <&mipi_lvds4_sditf>;
        };
    };
};

&pinctrl {
    cam {
        mipidphy1_pwr: mipidphy1-pwr {
            /* camera power en */
            rockchip,pins    =    <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
        };
        
        sc2210_pwdn_gpio: pwdn-gpio {
            /* camera power en */
            rockchip,pins    =    <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_down_drv_level_15>;
        };
    };
};

PS:不能保证dtsi在其它平台可用。

  1. 将rk3588-dphy1-sc2210.dtsi添加至rk3588-neardi-linux-lc160.dts文件中;

#include "rh3588-dphy1-sc2210.dtsi"
  1. 在内核配置文件中添加sensor构建

因SDK的根目录下的build.sh自动化程度较高,建议直接修改SDK_TOP_DIR/kernel/arch/arm64/configs/下的内核配置文件,内核配置文件名称在BoardConfig-rk3588-neardi-linux-lc160.mk文件中查看;我添加的是:

CONFIG_VIDEO_SC2210=y

CONFIG_VIEDO_SC2210与sensor驱动目录下的Kconfig中添加的名称需要一致(在Kconfig中的名称前需要加CONFIG_);其它项请自行解决。

  1. 至此需要添加的文件已经完成,下面编译内核

  1. 编译内核

  1. 进入SDK根目录

cd SDK_TOP_DIR/
  1. 执行以下命令:

./build.sh kernel 

注意,因SDK根目录下有kernel/目录。在使用tab补全时需要删除/。

编译完内核,先检查下sensor驱动是否已经编进内核。进kernel目录进行make menuconfig,按/后进入搜索模式,输入sensor名称,可查看到相关信息。

  1. 编译完成后在SDK_TOP_DIR/kernel/下会生成boot.img,这就是内核镜像。

  1. 使用RKDevTool.exe工具烧录内核镜像;

RKDevTool.exe烧录工具的目录请查看SDK,用法后续再讲。

  1. 烧录完成后开发板会自动重启;

  1. 测试驱动

  1. 查看media链接信息

media-ctl -p -d /dev/media*

若有sensor相关的entity,说明驱动注册成功。

  1. 查看节点,查到mainpath对应的video节点号

grep '' /sys/class/video4linux/video*/name
  1. 抓图,比如我查到的节点是11

v4l2-ctl --verbose -d /dev/video11 \
       --set-fmt-video=width=1920,height=1080,pixelformat='NV12' \
        --stream-mmap=4 \
         --set-selection=target=crop,flags=0,top=0,left=0,width=1920,height=1080 \
         --stream-to=/mnt/out11.yuv \
         --stream-count=3
  1. 在/mnt/目录下的out11.yuv就是抓到的文件。用YUView-Win软件打开,不出意外的应该没有意外的就能看到SENSOR拍到的图了。

目前存在问题,

1,将sensor设为m,insmod sensor驱动后,media-ctl -p -d /dev/media* 链接信息中找不到sensor的entity;

2,isp tuner工具暂不可用。

你可能感兴趣的:(RK3588,嵌入式硬件)