高通CameraSenorBringup

7614ed36e81c5898573263fdaed8daa5.gif

和你一起终身学习,这里是程序员Android

经典好文推荐,通过阅读本文,您将收获以下知识点:

一、Kernel 代码移植
二、Vendor 代码移植
三、扩展

一、Kernel 代码移植

1. DTS 文件配置

dts 文件目录:
高通SDM660平台代码中,arm64 与 arm 走的是同一个目录文件,
kernel\msm-4.4\arch\arm64\boot\dts\qcom这个目录其实是 \kernel\msm-4.4\arch\arm\boot\dts\qcom的软链接。

Camera 相关的 dts 文件:

@ kernel\msm-4.4\arch\arm64\boot\dts\qcom\sdm660.dtsi
@ kernel\msm-4.4\arch\arm64\boot\dts\qcom\sdm660-camera.dtsi
@ kernel\msm-4.4\arch\arm64\boot\dts\qcom\sdm660-pinctrl.dtsi
@ kernel\msm-4.4\arch\arm64\boot\dts\qcom\sdm660-camera-sensor-mtp.dtsi
1.1 sdm660.dtsi

在该文件中,主要功能如下:

引入 sdm660-camera.dtsi 文件
配置 camera_focus 和 camera_snapshot 对应的 GPIO 及 上报的 keycode。

@ \kernel\msm-4.4\arch\arm\boot\dts\qcom\sdm660.dtsi
// 1. 引入 sdm660-camera.dtsi
#include "sdm660-camera.dtsi"   

// 2. 配置 camera_focus 和 camera_snapshot GPIO 及对应的 keycode。
&soc {
    gpio_keys {
        status = "okay";
        compatible = "gpio-keys";
        input-name = "gpio-keys";
        pinctrl-names = "tlmm_gpio_key_active","tlmm_gpio_key_suspend";
        pinctrl-0 = <&gpio_key_active>;
        pinctrl-1 = <&gpio_key_suspend>;

        camera_focus {
            label = "camera_focus";
            gpios = <&tlmm 64 0x1>;
            linux,input-type = <1>;
            linux,code = <0x210>;
            debounce-interval = <15>;
        };
        camera_snapshot {
            label = "camera_snapshot";
            gpios = <&tlmm 113 0x1>;
            linux,input-type = <1>;
            linux,code = <0x2fe>;
            debounce-interval = <15>;
        };
    };
};

1.2 sdm660-camera.dtsi

在 sdm660-camera.dtsi 中主要是配置了平台相关的Camera 底层硬件相关的配置,比如 CSI,CS。
如无特殊需求,一般不会修改此处的代码。

部分代码及对应的解释如下:

各参数解析详见: 
@ \kernel\msm-4.4\Documentation\devicetree\bindings\media\video\msm-csid.txt
@ \kernel\msm-4.4\Documentation\devicetree\bindings\media\video\msm-csi-phy.txt

&soc {
    qcom,csiphy@c824000 {                                   // CSI 总线映射的寄存器地址
        cell-index = <0>;                                   // CSI 硬件总线索引号 0
        compatible = "qcom,csiphy-v3.5", "qcom,csiphy";     // compatible = “a厂商,p产品”, “标准bbb类型设备”。
        // 那么linux kernel可能首先使用“a厂商,p产品”来匹配适合的driver,
        // 如果没有匹配到,那么使用字符串“标准bbb类型设备”来继续寻找适合的driver。
        
        reg = <0xc824000 0x1000>,<0xca00120 0x4>;           // 使用的寄存器地址 及 长度
        reg-names = "csiphy", "csiphy_clk_mux";             // cisphy 寄存器地址为 0xc824000, 长度为 0x1000
                                                            // csiphy_clk_mux 寄存器地址为 0xca00120,长度为 0x4
        interrupts = <0 78 0>;  // interrupt的格式是<type, interrupt number, trigger type>, 详见《(扩展1) interrupts 中断节点解析》
        interrupt-names = "csiphy";  // 中断name,可通过 cat /proc/interrupts 获取
        gdscr-supply = <&gdsc_camss_top>;   
        bimc_smmu-supply = <&gdsc_bimc_smmu>;
        qcom,cam-vreg-name = "gdscr", "bimc_smmu";      // voltage regulators 和 name
        clocks = <&clock_rpmcc MMSSNOC_AXI_CLK>,        // clocks 和 name
            <&clock_mmss MMSS_MNOC_AHB_CLK>,
            <&clock_mmss MMSS_BIMC_SMMU_AHB_CLK>,
            <&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>,
            <&clock_mmss MMSS_CAMSS_AHB_CLK>,
            <&clock_mmss MMSS_CAMSS_TOP_AHB_CLK>,
            <&clock_mmss CSI0_CLK_SRC>,
            <&clock_mmss MMSS_CAMSS_CSI0_CLK>,
            <&clock_mmss MMSS_CAMSS_CPHY_CSID0_CLK>,
            <&clock_mmss CSI0PHYTIMER_CLK_SRC>,
            <&clock_mmss MMSS_CAMSS_CSI0PHYTIMER_CLK>,
            <&clock_mmss MMSS_CAMSS_ISPIF_AHB_CLK>,
            <&clock_mmss CSIPHY_CLK_SRC>,
            <&clock_mmss MMSS_CAMSS_CSIPHY0_CLK>,
            <&clock_mmss MMSS_CSIPHY_AHB2CRIF_CLK>;
        clock-names = "mmssnoc_axi", "mnoc_ahb",
            "bmic_smmu_ahb", "bmic_smmu_axi",
            "camss_ahb_clk", "camss_top_ahb_clk",
            "csi_src_clk", "csi_clk", "cphy_csid_clk",
            "csiphy_timer_src_clk", "csiphy_timer_clk",
            "camss_ispif_ahb_clk", "csiphy_clk_src", "csiphy_clk",
            "csiphy_ahb2crif";
        qcom,clock-rates = <0 0 0 0 0 0 310000000 0 0 269333333 0 0 200000000 0 0>;  // 上面对应所有clock 的速率
        status = "ok";
    };

    qcom,csiphy@c825000 {
        cell-index = <1>;                               // CSI 硬件总线索引号 1
        compatible = "qcom,csiphy-v3.5", "qcom,csiphy";
        reg = <0xc825000 0x1000>, <0xca00124 0x4>;
        reg-names = "csiphy", "csiphy_clk_mux";     // cisphy 寄存器地址为 0xc825000, 长度为 0x1000
                                                    // csiphy_clk_mux 寄存器地址为 0xca00124 ,长度为 0x4
        interrupts = <0 79 0>;
        interrupt-names = "csiphy";
        ...... // 此处省略一大段代码,内容和前面 CSI 0 一样,配置clk 及其速率
    };
1.3 sdm660-camera-sensor-mtp.dtsi

文件 sdm660-pinctrl.dtsi和 sdm660-camera-sensor-mtp.dtsi是在 sdm660-mtp.dtsi中被包含的。

@ \kernel\msm-4.4\arch\arm\boot\dts\qcom\sdm660-mtp.dtsi

#include "sdm660-pinctrl.dtsi"
#include "sdm660-camera-sensor-mtp.dtsi"

sdm660-camera-sensor-mtp.dtsi是kernel camera 重点要配置的文件
其中包括了 camera 闪光灯的配置,avdd/dovdd/dvdd/vaf 等电压的配置,camera 马达的配置 ,eeprom的配置,camera sensor的配置。

1.3.1 Camera Sensor DTS配置
@ \kernel\msm-4.4\arch\arm\boot\dts\qcom\sdm660-camera-sensor-mtp.dtsi
@ \kernel\msm-4.4\Documentation\devicetree\bindings\media\video\msm-cci.txt

&cci {
    qcom,camera@0 {
        cell-index = <0>;           // Camera索引号 0,此处注意不要重复了
        compatible = "qcom,camera";
        reg = <0x0>;                // 和索引号一样
        qcom,csiphy-sd-index = <0>; // 使用 CSI 0,具体根据硬件决定,一般来说, 0:后摄, 1:前摄
        qcom,csid-sd-index = <0>;   // 使用 CSI 0 
        qcom,mount-angle = <90>;    // Sensor 成像方向与主板的角度,camear旋转角度
        qcom,led-flash-src = <&led_flash0>; // 闪光灯,使用 led_flash0
        qcom,actuator-src = <&actuator0>;   // 马达,使用 actuator0
        qcom,ois-src = <&ois0>;             // 是否支持 光学防抖
        qcom,eeprom-src = <&eeprom1>;       // eeprom 1
        cam_vio-supply = <&pm660_l11>;                      // IO voltage       IO口电压 VDDIO 数字 IO 电源主要给 I2C 部分供电;
        cam_vana-supply = <&cam_avdd_gpio_regulator>;       // analog voltage   模拟电压 AVDD 模拟供电,主要给感光区和 ADC 部分供电;
        cam_vdig-supply = <&cam_rear_dvdd_gpio_regulator>;  // digital voltage  数字电压DVDD 数字供电,主要给 ISP 供电
        cam_vaf-supply = <&cam_vaf_gpio_regulator>;         // AF voltage       Camera 自动对焦马达的供电
        cam_v_custom1-supply = <&cam_dovdd_gpio_regulator>;
        qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig", "cam_vaf","cam_v_custom1";   // 供电配置 及对应的 电压,详见下
        qcom,cam-vreg-min-voltage = <1780000 0 0 0 0>;
        qcom,cam-vreg-max-voltage = <1950000 0 0 0 0>;
        qcom,cam-vreg-op-mode = <105000 0 0 0 0>;
        qcom,gpio-no-mux = <0>;     // 1:表示 gpio mux 不可用   0:表示可用
        pinctrl-names = "cam_default", "cam_suspend";   // Camera gpio clk 和 reset gpio 配置 
        pinctrl-0 = <&cam_sensor_mclk0_active &cam_sensor_rear_active>;
        pinctrl-1 = <&cam_sensor_mclk0_suspend &cam_sensor_rear_suspend>;
        gpios = <&tlmm 32 0>, <&tlmm 46 0>;
        qcom,gpio-reset = <1>;
        qcom,gpio-req-tbl-num = <0 1>;
        qcom,gpio-req-tbl-flags = <1 0>;
        qcom,gpio-req-tbl-label = "CAMIF_MCLK0", "CAM_RESET0";
        qcom,sensor-position = <0>;     // 1:前置   0:后置
        qcom,sensor-mode = <0>;         
            ===>{  @ \kernel\msm-4.4\Documentation\devicetree\bindings\media\video\msm-cci.txt
            - qcom,sensor-mode : should contain sensor mode supported
                - 0 -> back camera 2D
                - 1 -> front camera 2D
                - 2 -> back camera 3D
                - 3 -> back camera int 3D
            }
        qcom,cci-master = <0>;      // I2C 0
        status = "ok";
        clocks = <&clock_mmss MCLK0_CLK_SRC>, <&clock_mmss MMSS_CAMSS_MCLK0_CLK>;
        clock-names = "cam_src_clk", "cam_clk";
        qcom,clock-rates = <24000000 0>;    // clock rate in Hz

//- qcom,sensor-type : should contain format of data that sensor streams
//    - 0 -> bayer format
//    - 1 -> yuv format

    };

    qcom,camera@1 {
        cell-index = <1>;       // Camera索引号 1,此处注意不要重复了
        compatible = "qcom,camera";
        reg = <0x1>;
        qcom,csiphy-sd-index = <1>;
        qcom,csid-sd-index = <1>;
        qcom,mount-angle = <90>;
        qcom,actuator-src = <&actuator1>;
        qcom,eeprom-src = <&eeprom1>;
        cam_vio-supply = <&cam_dovdd_gpio_regulator>;
        cam_vana-supply = <&cam_avdd_gpio_regulator>;
        cam_vdig-supply = <&cam_rear_dvdd_gpio_regulator>;
        cam_vaf-supply = <&cam_vaf_gpio_regulator>;
        qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig", "cam_vaf";
        qcom,cam-vreg-min-voltage = <0 0 0 0>;
        qcom,cam-vreg-max-voltage = <0 0 0 0>;
        qcom,cam-vreg-op-mode = <105000 0 0 0>;
        qcom,gpio-no-mux = <0>;
        pinctrl-names = "cam_default", "cam_suspend";
        pinctrl-0 = <&cam_sensor_mclk2_active &cam_sensor_rear2_active>;
        pinctrl-1 = <&cam_sensor_mclk2_suspend &cam_sensor_rear2_suspend>;
        gpios = <&tlmm 34 0>, <&tlmm 48 0>;
        qcom,gpio-reset = <1>;
        qcom,gpio-req-tbl-num = <0 1>;
        qcom,gpio-req-tbl-flags = <1 0>;
        qcom,gpio-req-tbl-label = "CAMIF_MCLK", "CAM_RESET";
        qcom,sensor-position = <0>;     // 1:前置   0:后置
        qcom,sensor-mode = <0>;         // 0 -> back camera 2D
        qcom,cci-master = <1>;          // I2C 1
        status = "ok";
        clocks = <&clock_mmss MCLK2_CLK_SRC>, <&clock_mmss MMSS_CAMSS_MCLK2_CLK>;
        clock-names = "cam_src_clk", "cam_clk";
        qcom,clock-rates = <24000000 0>;
    };

    qcom,camera@2 {
        cell-index = <2>;           // Camera索引号 2,此处注意不要重复了
        compatible = "qcom,camera";
        reg = <0x02>;
        qcom,csiphy-sd-index = <2>;
        qcom,csid-sd-index = <2>;
        qcom,mount-angle = <270>;
        //qcom,actuator-src = <&actuator2>;     // 前报不需要马达,所以此处不用配置马达 ,同样下面也不用配置 af voltage
        qcom,eeprom-src = <&eeprom2>;
        cam_vio-supply = <&pm660_l11>;
        cam_vana-supply = <&cam_avdd_gpio_regulator>;
        cam_vdig-supply = <&cam_dvdd_gpio_regulator>;
        qcom,cam-vreg-name = "cam_vio", "cam_vana", "ca
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员Android

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值