Camera Porting Guide  

分享到:

alpha-star
Level 2Admin
注册时间:8年 前
帖子数: 22
2016年9月22日 下午8:16  

1.M camera driver code path

1.1 Config file

kernel-3.18/arch/arm64/configs/<$PROJECT>_debug_defconfig (for Eng load)

kernel-3.18/arch/arm64/configs/<$PROJECT>_defconfig ( for user load)

device/mediatek/<$PROJECT>/ProjectConfig.mk

1.2 Kernel driver & build Makefile

[BY PROJECT]

kernel-3.18/drivers/misc/mediatek/mach/mt6797/<project>/imgsensor/

[BY PLATFORM]

kernel-3.18/drivers/misc/mediatek/imgsensor/src/mt6797/

PRIORITY: PROJECT > PLATFORM

1.3 Kd_sensorlist.c/kd_sensorlist.h

/kernel-3.18/drivers/misc/mediatek/imgsensor/src/<platform>/

1.4 Kd_camera_hw.c/kd_camera_hw.h

kernel-3.18/drivers/misc/mediatek/imgsensor/src/mt6755/camera_project/<project>/camera_hw

1.5 Header files

kd_imgsensor.h
kd_imgsensor_errcode.h
kd_imgsensor_define.h
kd_camera_feature_id.h
kd_camera_feature.h
kd_camera_feature_enum.h

FILE PATH:

1) Kernel space
kernel-3.18/drivers/misc/mediatek/imgsensor/inc/kd_imgsensor.h
2) User space
device/mediatek/common/kernel-headers/kd_imgsensor.h

NOTICE:

These files must be the same inuser and kernel space, otherwise you will encounter the io-ctrl error.Why? One rule: Android should not Access Kernel space Source and Header Files directly.

2.DTS

2.1 Power on template

ADD YOUR SENSOR TO POWERONLIST @ KD_CAMERA_HW.C

NO DEFAULT POWER ON SEQUENCE

KDCISMODULEPOWERON()

kdCISModulePowerOn()

hwpoweron()

- _hwPowerOn() for regulator( aka LDO)

 

- mtkcam_gpio_set() for gpio

 

- mt_set_gpio_mode(), mt_set_gpio_dir() and mt_set_gpio_out()

 

- hwPowerOn() regulator( aka LDO)

2.2 GPIO

2.2.1 USAGE

To control the PWD/RST pin for camera power on

To control the external LDO for camera

2.2.2KERNEL 3.18

Kernel standard

PINCTRL
For details, please find kernel-3.18/ Documentation/pinctrl.txt

Need customized for each project manually

Ex.kernel-3.18/arch/arm64/boot/dts/amt6797_64_open.dts

2.3 PINCTRL

PINCTRL_STATE

FUNCTIONS

pinctrl_lookup_state()

/* GPIO Pin control*/
struct platform_device *cam_plt_dev = NULL;
struct pinctrl *camctrl = NULL;
struct pinctrl_state *cam0_pnd_h = NULL;/* main cam */
struct pinctrl_state *cam0_pnd_l = NULL;
struct pinctrl_state *cam0_rst_h = NULL;
struct pinctrl_state *cam0_rst_l = NULL;
struct pinctrl_state *cam1_pnd_h = NULL;/* sub cam */
struct pinctrl_state *cam1_pnd_l = NULL;
struct pinctrl_state *cam1_rst_h = NULL;
struct pinctrl_state *cam1_rst_l = NULL;
struct pinctrl_state *cam2_pnd_h = NULL;/* main2 cam */
struct pinctrl_state *cam2_pnd_l = NULL;
struct pinctrl_state *cam2_rst_h = NULL;
struct pinctrl_state *cam2_rst_l = NULL;
struct pinctrl_state *cam_ldo_vcama_h = NULL;/* for AVDD */
struct pinctrl_state *cam_ldo_vcama_l = NULL;
struct pinctrl_state *cam_ldo_vcamd_h = NULL;/* for DVDD */
struct pinctrl_state *cam_ldo_vcamd_l = NULL;
struct pinctrl_state *cam_ldo_vcamio_h = NULL;/* for DOVDD */
struct pinctrl_state *cam_ldo_vcamio_l = NULL;
struct pinctrl_state *cam_ldo_vcamaf_h = NULL;/* for AFVDD */
struct pinctrl_state *cam_ldo_vcamaf_l = NULL;
struct pinctrl_state *cam_ldo_sub_vcamd_h = NULL;/* for SUB_DVDD */
struct pinctrl_state *cam_ldo_sub_vcamd_l = NULL;
struct pinctrl_state *cam_ldo_main2_vcamd_h = NULL;/* for MAIN2_DVDD */
struct pinctrl_state *cam_ldo_main2_vcamd_l = NULL;

get specified pinctrl_state descripted in xxx.dts

am0_pnd_hGPIO state for PDN of main cam @ high,

cam0_pnd_lGPIO state for PDN of main cam @ low

pinctrl_select_state()

pinctrl_select_state(camctrl, cam0_pnd_l); set PDN of main cam to low

3.How to customized xxx.dts for each project

3.1 kernel-3.18/arch/arm64/boot/dts/amt6797_64_open.dts

3.2 For camera

&piodefine states of GPIOs

camera_pins_cam0_pnd0

camera_pins_cam0_pnd1

all the gpio of camera are listed

kd_camera_hw1pinctrl mapping

PATH KERNEL-3.18/ARCH/ARM64/BOOT/DTS/AMT6797_64_OPEN.DTS

&kd_camera_hw1 {
pinctrl-names = "default",
"cam0_rst0", "cam0_rst1", "cam0_pnd0", "cam0_pnd1",
"cam1_rst0", "cam1_rst1", "cam1_pnd0", "cam1_pnd1",
"cam2_rst0", "cam2_rst1", "cam2_pnd0", "cam2_pnd1",
"cam_ldo_vcama_0", "cam_ldo_vcama_1", "cam_ldo_vcamd_0", "cam_ldo_vcamd_1",
"cam_ldo_vcamd2_0", "cam_ldo_vcamd2_1";
pinctrl-0 = <&camera_pins_default>;
pinctrl-1 = <&camera_pins_cam0_rst0>;
pinctrl-2 = <&camera_pins_cam0_rst1>;
pinctrl-3 = <&camera_pins_cam0_pnd0>;
pinctrl-4 = <&camera_pins_cam0_pnd1>;
pinctrl-5 = <&camera_pins_cam1_rst0>;
pinctrl-6 = <&camera_pins_cam1_rst1>;
pinctrl-7 = <&camera_pins_cam1_pnd0>;
pinctrl-8 = <&camera_pins_cam1_pnd1>;
/* for main2 */
pinctrl-9 = <&camera_pins_cam2_rst0>;
pinctrl-10 = <&camera_pins_cam2_rst1>;
pinctrl-11 = <&camera_pins_cam2_pnd0>;
pinctrl-12 = <&camera_pins_cam2_pnd1>;
/* for ldo control by gpio */
pinctrl-13 = <&camera_pins_cam_ldo_vcama_0>;
pinctrl-14 = <&camera_pins_cam_ldo_vcama_1>;
pinctrl-15 = <&camera_pins_cam_ldo_vcamd_0>;
pinctrl-16 = <&camera_pins_cam_ldo_vcamd_1>;
pinctrl-17 = <&camera_pins_cam_ldo_e2_vcamd_0>;
pinctrl-18 = <&camera_pins_cam_ldo_e2_vcamd_1>;
status = "okay";
};

&pio {
camera_pins_cam0_rst0: cam0@0 {
pins_cmd_dat {
pins = <PINMUX_GPIO32__FUNC_GPIO32>;
slew-rate = <1>; /*direction 0:in, 1:out*/
output-low;/*direction out used only. output_low or high*/
};
};
camera_pins_cam0_rst1: cam0@1 {
pins_cmd_dat {
pins = <PINMUX_GPIO32__FUNC_GPIO32>;
slew-rate = <1>;
output-high;
};
};
camera_pins_cam0_pnd0: cam0@2 {
pins_cmd_dat {
pins = <PINMUX_GPIO28__FUNC_GPIO28>;
slew-rate = <1>;
output-low;
};
};
camera_pins_cam0_pnd1: cam0@3 {
pins_cmd_dat {
pins = <PINMUX_GPIO28__FUNC_GPIO28>;
slew-rate = <1>;
output-high;
};
};

PATH \KERNEL-3.18\DRIVERS\MISC\MEDIATEK\IMGSENSOR\SRC\MT6797\CAMERA_HW

/*Cam0 Power/Rst Ping initialization */
cam0_pnd_h = pinctrl_lookup_state(camctrl, "cam0_pnd1");
if (IS_ERR(cam0_pnd_h)) {
ret = PTR_ERR(cam0_pnd_h);
PK_ERR("%s : pinctrl err, cam0_pnd_h\n", __func__);
}

`cam0_pnd_l = pinctrl_lookup_state(camctrl, "cam0_pnd0");

if (IS_ERR(cam0_pnd_l)) {

        ret = PTR_ERR(cam0_pnd_l);

        PK_ERR("%s : pinctrl err, cam0_pnd_l\n", __func__);

}`

 

 

`cam0_rst_h = pinctrl_lookup_state(camctrl, "cam0_rst1");

if (IS_ERR(cam0_rst_h)) {

        ret = PTR_ERR(cam0_rst_h);

        PK_ERR("%s : pinctrl err, cam0_rst_h\n", __func__);

}`

 

`cam0_rst_l = pinctrl_lookup_state(camctrl, "cam0_rst0");

if (IS_ERR(cam0_rst_l)) {

        ret = PTR_ERR(cam0_rst_l);

        PK_ERR("%s : pinctrl err, cam0_rst_l\n", __func__);

}`

4.For external LDO control mt6797

PATH KERNEL-3.18/ARCH/ARM64/BOOT/DTS/AMT6797_64_OPEN.DTS

camera_pins_cam_ldo_vcamd_0: cam0@vcamd0 {
pins_cmd_dat {
pins = <PINMUX_GPIO63__FUNC_GPIO63>;
slew-rate = <1>;
output-low;
};
};

camera_pins_cam_ldo_vcamd_1: cam1@vcamd1 {
pins_cmd_dat {
pins = <PINMUX_GPIO63__FUNC_GPIO63>;
slew-rate = <1>;
output-high;
};
};

&kd_camera_hw1 {
pinctrl-names = "default",
"cam0_rst0", "cam0_rst1", "cam0_pnd0", "cam0_pnd1",
"cam1_rst0", "cam1_rst1", "cam1_pnd0", "cam1_pnd1",
"cam2_rst0", "cam2_rst1", "cam2_pnd0", "cam2_pnd1",
"cam_ldo_vcama_0", "cam_ldo_vcama_1", "cam_ldo_vcamd_0", "cam_ldo_vcamd_1",
"cam_ldo_vcamd2_0", "cam_ldo_vcamd2_1";
pinctrl-0 = <&camera_pins_default>;
pinctrl-1 = <&camera_pins_cam0_rst0>;
pinctrl-2 = <&camera_pins_cam0_rst1>;
pinctrl-3 = <&camera_pins_cam0_pnd0>;
pinctrl-4 = <&camera_pins_cam0_pnd1>;
pinctrl-5 = <&camera_pins_cam1_rst0>;
pinctrl-6 = <&camera_pins_cam1_rst1>;
pinctrl-7 = <&camera_pins_cam1_pnd0>;
pinctrl-8 = <&camera_pins_cam1_pnd1>;
/* for main2 */
pinctrl-9 = <&camera_pins_cam2_rst0>;
pinctrl-10 = <&camera_pins_cam2_rst1>;
pinctrl-11 = <&camera_pins_cam2_pnd0>;
pinctrl-12 = <&camera_pins_cam2_pnd1>;
/* for ldo control by gpio */
pinctrl-13 = <&camera_pins_cam_ldo_vcama_0>;
pinctrl-14 = <&camera_pins_cam_ldo_vcama_1>;
pinctrl-15 = <&camera_pins_cam_ldo_vcamd_0>;
pinctrl-16 = <&camera_pins_cam_ldo_vcamd_1>;
pinctrl-17 = <&camera_pins_cam_ldo_e2_vcamd_0>;
pinctrl-18 = <&camera_pins_cam_ldo_e2_vcamd_1>;
status = "okay";
};

PATH \KERNEL-3.18\DRIVERS\MISC\MEDIATEK\IMGSENSOR\SRC\MT6797\CAMERA_HW

cam_ldo_vcamd_l = pinctrl_lookup_state(camctrl, "cam_ldo_vcamd_0");

if (pinSetIdx == 2) {
if (PowerCustList.PowerCustInfo[CUST_MAIN2_AVDD].Gpio_Pin == GPIO_UNSUPPORTED) {
if (TRUE != _hwPowerOn(pwInfo.PowerType, pwInfo.Voltage)) {
PK_ERR("[CAMERA SENSOR] Fail to enable digital power\n");
return FALSE;
}
} else {
if (mtkcam_gpio_set(pinSetIdx, MAIN2_AVDD, PowerCustList.PowerCustInfo[CUST_MAIN2_AVDD].Voltage)) {
PK_INFO("[CAMERA CUST_AVDD] set gpio failed!!\n");
}
}
}

case AVDD:
case MAIN2_AVDD:
/*Main & Main2 use same cotrol GPIO */
PK_DBG("mAVDD_usercounter(%d)\n",mAVDD_usercounter);
if (Val == 0 && !IS_ERR(cam_ldo_vcama_l)){
mAVDD_usercounter --;
if(mAVDD_usercounter <= 0)
{
if(mAVDD_usercounter < 0)
PK_ERR("Please check AVDD pin control\n");

                       mAVDD_usercounter = 0;

                       pinctrl_select_state(camctrl, cam_ldo_vcama_l);

               }

              

        }

        else if (Val == 1 && !IS_ERR(cam_ldo_vcama_h)){

               mAVDD_usercounter ++;

               pinctrl_select_state(camctrl, cam_ldo_vcama_h);

        }

        break;

PowerUp PowerOnList = {
{
{SENSOR_DRVNAME_OV23850_MIPI_RAW,
{
{SensorMCLK, Vol_High, 0},
{DOVDD, Vol_1800, 0},
{AVDD, Vol_2800, 0},
{DVDD, Vol_1200, 0},
{AFVDD, Vol_2800, 2},
{PDN, Vol_Low, 0},
{PDN, Vol_High, 0},
{RST, Vol_Low, 0},
{RST, Vol_High, 5},
},
},

4.1 PMIC

4.1.1 USE DCT TOOLS FOR CUSTOMIZED

4.1.2 CUST.DTSI WAS GENERATED DURING

Compiling out/target/product/amt6797_64_open/obj/KERNEL_OBJ/arch/arm64/boot/dts/cust.dtsi

4.1.3 KERNEL STANDARD

Regulator

regulator_get()

Get instance of regulator

Called @ probe in kd_sensorlist.c

regulator_set_voltage() & regulator_enable()

Set voltage and enable among different regulator

Called @_hwPowerOn() in kd_sensorlist.c

regulator_disable()

Turn off regulator

Called @_hwPowerDown() in kd_sensorlist.c

PATHOUT/TARGET/PRODUCT/AMT6797_64_OPEN/OBJ/KERNEL_OBJ/ARCH/ARM64/BOOT/DTS/CUST.DTSI

&kd_camera_hw1 {
vcama-supply = <&mt_pmic_vcama_ldo_reg>;
vcama_main2-supply = <&mt_pmic_vcama_ldo_reg>;
vcama_sub-supply = <&mt_pmic_vcama_ldo_reg>;

`vcamaf-supply = <&mt_pmic_vldo28_ldo_reg>;

vcamaf_main2-supply = <&mt_pmic_vldo28_ldo_reg>;

vcamaf_sub-supply = <&mt_pmic_vldo28_ldo_reg>;`

 

`vcamd-supply = <&mt_pmic_vcamd_ldo_reg>;

vcamd_main2-supply = <&mt_pmic_vcamd_ldo_reg>;

vcamd_sub-supply = <&mt_pmic_vcamd_ldo_reg>;`

 

`vcamio-supply = <&mt_pmic_vcamio_ldo_reg>;

vcamio_main2-supply = <&mt_pmic_vcamio_ldo_reg>;

vcamio_sub-supply = <&mt_pmic_vcamio_ldo_reg>;`

 

status = "okay";

};

5.I2C BUS

5.1 Also use dct tools for customized and located at cust.dtsi

5.2 &i2cX

&I2C1 FOR BUS1, &I2C2 FOR BUS AND SO ON

Pathout/target/product/amt6797_64_open/obj/KERNEL_OBJ/arch/arm64/boot/dts/cust.dtsi

&i2c2 {
#address-cells = <1>;
#size-cells = <0>;
clock-frequency = <400000>;
mediatek,use-open-drain;
camera_main@36 {
compatible = "mediatek,camera_main";
reg = <0x36>;
status = "okay";
};
camera_main_af@72 {
compatible = "mediatek,camera_main_af";
reg = <0x72>;
status = "okay";
};
};

6.ADD A NEW CAMERA FLOW

6.1 Configure camera sensor hal driver in ProjectConfig.mk

file path device\mediatek\$project\ProjectConfig.mk

EXAMPLE:

CUSTOM_HAL_IMGSENSOR = ov23850_mipi_raw

CUSTOM_HAL_MAIN_IMGSENSOR = ov23850_mipi_raw

6.2 Add camera sensor kernel driver project config (<project>_defconfig)

file path : alps<kernel>\arch\arm64\configs<project>_debug_defconfig

EXAMPLE:

CONFIG_CUSTOM_KERNEL_IMGSENSOR= ov23850_mipi_raw s5k3m2_mipi_raw s5k5e2ya_mipi_raw imx258_mipi_raw imx377_mipi_raw s5k2x8_mipi_raw CUSTOM_HAL_MAIN_IMGSENSOR = ov23850_mipi

use menuconfig with console to modify xxx_defconfig

6.3. Add camera sensor kernel driver code to the corresponding path

[BY PROJECT]

kernel-3.18/drivers/misc/mediatek/mach/mt6755/<project>/ imgsensor/

[BY PLATFORM]

kernel-3.18/drivers/misc/mediatek/imgsensor/src/<platform>/

Must modify the corresponding makefile

6.3.1 Add image sensor kernel driver folder

[BY PROJECT]

kernel-3.18/drivers/misc/mediatek/mach/mt6797/<project>/ imgsensor/Makefile (if it exsit)

EXAMPLE:

Add the following items

obj-y += imgsensor/ov23850_mipi_raw/

[BY PLATFORM]

If the image sensor driver doesnt exist in the ,Project- directory , build system will proceed to search the driver in {platform} directory. Do not need to modify the makefile.

kernel-3.18\drivers\misc\mediatek\imgsensor\src<platform>\Makefile .

6.3.2 Add camera sensor kernel driver code to the corresponding path

[BY PROJECT]

kernel-3.18/drivers/misc/mediatek/mach/mt6797/<project>/ imgsensor/

[By Platform]

If the image sensor driver doesnt exist in the ,Project- directory , build system will proceed to search the driver in {platform} directory. Do not need to modify the makefile.

kernel-3.18\drivers\misc\mediatek\imgsensor\src<platform>\Makefile .

6.3.2 Add camera sensor kernel driver code to the corresponding path

[BY PROJECT]

kernel-3.18/drivers/misc/mediatek/mach/mt6797/<project>/ imgsensor/

[BY PLATFORM]

kernel-3.18/drivers/misc/mediatek/imgsensor/src/<platform>/

Must modify the corresponding makefile

link you image sensor compiled object

Example: obj-y += ov23850_mipi_raw.o

[BY PROJECT]

alps/kernel-3.18/drivers/misc/mediatek/mach/mt6755/<project>/ imgsensor/xxxx/Makefile (if it exsit)

[BY PLATFORM]

alps<kernel>\drivers\misc\mediatek\imgsensor\src<platform>\Makefile

6.3.3 Modify other related files

1 .Makefile

ProjectConfig.mk xxx_defconfig

Kernel xxx_defconfig

2 .imgsensor

CUSTOM_HAL_IMGSENSOR = xxxxxx_xxx

CUSTOM_KERNEL_IMGSENSOR = xxxxxx_xxx

CUSTOM_HAL_SUB_IMGSENSOR = xxxxxx_xxx

CUSTOM_HAL_MAIN_IMGSENSOR = xxxxxx_xxx

CUSTOM_KERNEL_MAIN_IMGSENSOR = xxxxxx_xxx=

CUSTOM_KERNEL_SUB_IMGSENSOR = xxxxxx_xxx

CUSTOM_HAL_IMGSENSOR& CUSTOM_KERNEL_IMGSENSOR mainsub sensor

CUSTOM_HAL_MAIN_IMGSENSOR& CUSTOM_KERNEL_MAIN_IMGSENSOR main sensor

CUSTOM_HAL_SUB_IMGSENSOR& CUSTOM_KERNEL_SUB_IMGSENSOR sub sensor

3 .camera

# lens port sensor dummy AF sensormain or sub module AF IC

CUSTOM_HAL_LENS = dummy_lens

CUSTOM_KERNEL_LENS = dummy_lens

CUSTOM_HAL_MAIN_LENS = dummy_lens

CUSTOM_HAL_SUB_LENS =

CUSTOM_KERNEL_MAIN_LENS = dummy_lens

CUSTOM_KERNEL_SUB_LENS =

#Flashlight port sensor dummy constant_flashlight

CUSTOM_KERNEL_FLASHLIGHT=dummy_flashlight

CUSTOM_HAL_FLASHLIGHT=dummy_flashlight

#OTPRAW sensorport sensor dummy, OTP driver

CUSTOM_KERNEL_CAM_CAL=dummy_eeprom

CUSTOM_HAL_CAM_CAL=dummy_eeprom

CUSTOM_KERNEL_EEPROM=dummy_eeprom

CUSTOM_HAL_EEPROM=dummy_eeprom

4.Image Sensor

kd_imgsensor.h

sensor ID
#define XXXXXX_SENSOR_ID 0xFFFF
#define SENSOR_DRVNAME_XXXXXX_RAW
xxxxxxxxx //RAW sensor

kd_sensorlist.h

  • RAW sensor
  • UINT32 XXXXXX_RAW_SensorInit(PSENSOR_FUNCTION_STRUCT *pfFunc);
  • kdSensorList[]
    -#if defined(XXXXXX_RAW)
    -{XXXXXX_SENSOR_ID, SENSOR_DRVNAME_XXXXXX_RAW, XXXXXX_RAW_SensorInit},
    -#endif
  • YUV sensor
  • UINT32 XXXXXX_YUV_SensorInit(PSENSOR_FUNCTION_STRUCT *pfFunc);
  • kdSensorList[]
    #if defined(XXXXXX_YUV)
    {XXXXXX_SENSOR_ID, SENSOR_DRVNAME_XXXXXX_YUV, XXXXXX_YUV_SensorInit},
    #endif
    sensorlist.cpp
  • SensorList[]
    #if defined(XXXXXX_RAW)
    RAW_INFO(XXXXXX_SENSOR_ID, SENSOR_DRVNAME_XXXXXX_RAW, NULL),
    #endif
    #if defined(XXXXXX_YUV)
    YUV_INFO(XXXXXX_SENSOR_ID, SENSOR_DRVNAME_XXXXXX_YUV, NULL),
    #endif
    sensorkdSensorList[]SensorList[]resolution

 

 

编辑:8年 前

回复引用
  
Working

登陆 或者 注册