MT6580 Android N camera调试
1.硬件原理
如下图所示,以后单摄为例:
备注:camera的上电部分很重要,要分清楚几路上电的电压,理解上电时序控制。比如对于格科微的camera芯片来说,有些是1.8V,有些是1.2V。这个调试上电时序的时候要和FAE咨询清楚,不然会导致一些不可预测的后果,比如画面绿屏等。
2.平台配置
alps/device/zechin/zechin6580_we_m$ vim ProjectConfig.mk
添加 HAL and KERNEL 摄像头驱动模组
CUSTOM_HAL_IMGSENSOR = gc8024mipi_raw gc5005_mipi_raw gc2365_mipi_raw gc030amipi_raw
CUSTOM_HAL_MAIN_IMGSENSOR = gc8024mipi_raw gc5005_mipi_raw
CUSTOM_HAL_SUB_IMGSENSOR = gc2365_mipi_raw gc030amipi_raw
CUSTOM_KERNEL_IMGSENSOR= gc8024mipi_raw gc5005_mipi_raw gc2365_mipi_raw gc030amipi_raw
CUSTOM_KERNEL_MAIN_IMGSENSOR = gc8024mipi_raw gc5005_mipi_raw
CUSTOM_KERNEL_SUB_IMGSENSOR = gc2365_mipi_raw gc030amipi_raw
CUSTOM_HAL_FLASHLIGHT = constant_flashlight
3.kernel配置
3.1config配置
alps/kernel-3.18/arch/arm/configs$ vim zechin6580_we_m_debug_defconfig alps/kernel-3.18/arch/arm/configs$ vim zechin6580_we_m_defconfig
CONFIG_CUSTOM_KERNEL_IMGSENSOR="gc8024mipi_raw gc5005_mipi_raw gc2365_mipi_raw gc030amipi_raw"
CONFIG_CUSTOM_KERNEL_FLASHLIGHT="constant_flashlight"
3.2 dts
alps/kernel-3.18/arch/arm/boot/dts/cust_i2c.dtsi
&i2c0 {
camera_main@10 {
compatible = "mediatek,camera_main";
reg = <0x10>;
};
camera_main_af@0c {
compatible = "mediatek,camera_main_af";
reg = <0x0c>;
};
camera_sub@3c {
compatible = "mediatek,camera_sub";
reg = <0x3c>;
};
};
A、根据原理图配置引脚,注意,引脚有两个,后摄、手电筒的控制引脚。
GPIO7 &GPIO8 方向为输出,引脚悬空状态
B、DTS 的配置,包括平台 dtsi 和项目 dts 的配置。
alps/kernel-3.18/arch/arm/boot/dts/mt6580.dtsi
strobe: strobe@0 {
compatible = "mediatek,strobe_gpio";
};
vim kernel-3.18/arch/arm/boot/dts/zechin6580_we_n.dts
/* strobe start */
&pio {
strobe_intpin_strobe_stb_h: stb@0 {
pins_cmd_dat {
pins = <PINMUX_GPIO7__FUNC_GPIO7>; slew-rate = <1>;
bias-pull-up = <00>; output-high;
};
};
strobe_intpin_strobe_stb_l: stb@1 {
pins_cmd_dat {
pins = <PINMUX_GPIO7__FUNC_GPIO7>; slew-rate = <1>;
bias-pull-up = <00>; output-low;
};
};
strobe_intpin_strobe_en_h: en@0 {
pins_cmd_dat {
pins = <PINMUX_GPIO8__FUNC_GPIO8>; slew-rate = <1>;
bias-pull-up = <00>; output-high;
};
};
strobe_intpin_strobe_en_l: en@1 {
pins_cmd_dat {
pins = <PINMUX_GPIO8__FUNC_GPIO8>; slew-rate = <1>;
bias-pull-up = <00>; output-low;
};
};
sub_strobe_intpin_strobe_en_h: sub_en@0 {
pins_cmd_dat {
pins = <PINMUX_GPIO21__FUNC_GPIO21>; slew-rate = <1>;
bias-pull-up = <00>; output-high;
};
};
sub_strobe_intpin_strobe_en_l: sub_en@1 {
pins_cmd_dat {
pins = <PINMUX_GPIO21__FUNC_GPIO21>; slew-rate = <1>;
bias-pull-up = <00>; output-low;
};
};
strobe_intpin_default: strobedefaultcfg {
};
};
&strobe {
pinctrl-names = "pin_default", "strobe_stb_h", "strobe_stb_l", "strobe_en_h", "strobe_en_l", "sub_strobe_en_h", "sub_strobe_en_l";
pinctrl-0 = <&strobe_intpin_default>;
pinctrl-1 = <&strobe_intpin_strobe_stb_h>;
pinctrl-2 = <&strobe_intpin_strobe_stb_l>;
pinctrl-3 = <&strobe_intpin_strobe_en_h>;
pinctrl-4 = <&strobe_intpin_strobe_en_l>;
pinctrl-5 = <&sub_strobe_intpin_strobe_en_h>;
pinctrl-6 = <&sub_strobe_intpin_strobe_en_l>;
status = "okay";
};
/* strobe end */
3.3driver code
alps/kernel-3.18/drivers/misc/mediatek/imgsensor/src/mt6580$
增加对应驱动,把驱动源码 kernel 目录中所有文件 copy进来
gc8024mipi_raw
gc2365_mipi_raw
gc030amipi_raw/
gc5005_mipi_raw/
sdk/alps/kernel-3.18/drivers/misc/mediatek/imgsensor/src/mt6580$
vim kd_sensorlist.h
增加对应驱动 Iinit 函数声明
在 kdSensorList 数组中增加对应驱动的配置
UINT32 GC2365_MIPI_RAW_SensorInit(PSENSOR_FUNCTION_STRUCT *pfFunc);
UINT32 GC030AMIPI_RAW_SensorInit(PSENSOR_FUNCTION_STRUCT *pfFunc);
UINT32 GC5005MIPI_RAW_SensorInit(PSENSOR_FUNCTION_STRUCT *pfFunc);
UINT32 GC8024MIPI_RAW_SensorInit(PSENSOR_FUNCTION_STRUCT *pfFunc);
....
#if defined(GC2365_MIPI_RAW)
{GC2365_SENSOR_ID,SENSOR_DRVNAME_GC2365_MIPI_RAW,GC2365_MIPI_RAW_SensorInt},
#endif
#if defined(GC030AMIPI_RAW)
{GC030AMIPI_SENSOR_ID, SENSOR_DRVNAME_GC030AMIPI_RAW,GC030AMIPI_RAW_SensorInit},
#endif
#if defined(GC8024MIPI_RAW)
{GC8024MIPI_SENSOR_ID, SENSOR_DRVNAME_GC8024MIPI_RAW,GC8024MIPI_RAW_SensorInit},
#endif
#if defined(GC5005_MIPI_RAW)
{GC5005MIPI_SENSOR_ID, SENSOR_DRVNAME_GC5005MIPI_RAW,GC5005MIPI_RAW_SensorInit},
#endif
alps/kernel-3.18/drivers/misc/mediatek/imgsensor/inc$ vim kd_imgsensor.h
增加对应驱动的 SENSOR_ID 和 SENSOR_DRVNAME 定义
#define GC2365_SENSOR_ID 0x2365
#define GC030AMIPI_SENSOR_ID 0x30A
#define GC5005MIPI_SENSOR_ID 0x5005
#define GC8024MIPI_SENSOR_ID 0x8024
#define SENSOR_DRVNAME_GC2365_MIPI_RAW "gc2365mipiraw" #define SENSOR_DRVNAME_GC030AMIPI_RAW "gc030amipiraw" #define SENSOR_DRVNAME_GC5005MIPI_RAW "gc5005mipiraw" #define SENSOR_DRVNAME_GC8024MIPI_RAW "gc8024mipiraw"
alps/kernel-3.18/drivers/misc/mediatek/imgsensor/src/mt6580/camera_hw$ vim kd_camera_hw.c
增加对应驱动的上电时序
电源部分:
VCAMD:就是 DVDD 供电,主要给 ISP 供电,
VCAMD_IO:就是 VDDIO 数字 IO 电源,主要给 IIC 部分供电,
VCAMA:就是 AVDD 模拟供电,主要给光感区和 ADC 部分供电
VCAM_AF:是对 camera 自动对焦马达的供电
管脚部分:
reset 管脚
powerdown 管脚
上电时序:
int kdCISModulePowerOn(CAMERA_DUAL_CAMERA_SENSOR_ENUM SensorIdx, char *currSensorName, BOOL On, char *mode_name)
{
u32 pinSetIdx = 0; /* default main sensor */
#define IDX_PS_CMRST 0
#define IDX_PS_CMPDN 4
#define IDX_PS_MODE 1
#define IDX_PS_ON 2
#define IDX_PS_OFF 3
#define VOL_2800 2800000
#define VOL_1800 1800000
#define VOL_1500 1500000
#define VOL_1200 1200000
#define VOL_1000 1000000
u32 pinSet[2][8] =
{
/* for main sensor */
{
/* The reset pin of main sensor uses GPIO10 of mt6306, please call mt6306 API to set */
CAMERA_CMRST_PIN,
CAMERA_CMRST_PIN_M_GPIO, /* mode */
GPIO_OUT_ONE, /* ON state */
GPIO_OUT_ZERO, /* OFF state */
CAMERA_CMPDN_PIN,
CAMERA_CMPDN_PIN_M_GPIO,
GPIO_OUT_ZERO,
GPIO_OUT_ONE,
},
/* for sub sensor */
{
CAMERA_CMRST1_PIN,
CAMERA_CMRST1_PIN_M_GPIO,
GPIO_OUT_ONE,
GPIO_OUT_ZERO,
CAMERA_CMPDN1_PIN,
CAMERA_CMPDN1_PIN_M_GPIO,
GPIO_OUT_ZERO,
GPIO_OUT_ONE,
},
};
if (DUAL_CAMERA_MAIN_SENSOR == SensorIdx)
{
pinSetIdx = 0;
}
else if (DUAL_CAMERA_SUB_SENSOR == SensorIdx)
{
pinSetIdx = 1;
}
else
{
return 0;
}
/* power ON */
if (On)
{
PK_DBG("[PowerON]pinSetIdx:%d, currSensorName: %s\n", pinSetIdx, currSensorName);
if(0 == strcmp(SENSOR_DRVNAME_GC8024MIPI_RAW, currSensorName))
{
/*According to GC8024 sequence chart modify position*/
/* First Power Pin low and Reset Pin Low */
mtkcam_gpio_set(pinSetIdx, CAMPDN,pinSet[pinSetIdx][IDX_PS_CMPDN + IDX_PS_OFF]);
mdelay(2);
mtkcam_gpio_set(pinSetIdx, CAMRST,pinSet[pinSetIdx][IDX_PS_CMRST + IDX_PS_OFF]);
mdelay(2);
_hwPowerOn(VCAMIO, VOL_1800);
mdelay(5);
_hwPowerOn(VCAMD, VOL_1200);
mdelay(5);
_hwPowerOn(VCAMA, VOL_2800);
mdelay(5);
_hwPowerOn(VCAMAF, VOL_2800);
mdelay(5);
pinSetIdx ? ISP_MCLK2_EN(1) : ISP_MCLK1_EN(1); mdelay(5);
/* enable active sensor */
mtkcam_gpio_set(pinSetIdx, CAMPDN,pinSet[pinSetIdx][IDX_PS_CMPDN + IDX_PS_ON]);
mdelay(10);
mtkcam_gpio_set(pinSetIdx, CAMRST,pinSet[pinSetIdx][IDX_PS_CMRST + IDX_PS_ON]);mdelay(10);
}else
{
pinSetIdx ? ISP_MCLK2_EN(1) : ISP_MCLK1_EN(1);
/* First Power Pin low and Reset Pin Low */
mtkcam_gpio_set(pinSetIdx, CAMPDN,pinSet[pinSetIdx][IDX_PS_CMPDN + IDX_PS_OFF]);
mtkcam_gpio_set(pinSetIdx, CAMRST,pinSet[pinSetIdx][IDX_PS_CMRST + IDX_PS_OFF]);
_hwPowerOn(VCAMA, VOL_2800);
mdelay(5);
_hwPowerOn(VCAMIO, VOL_1800);
mdelay(5);
if (0 == strcmp(SENSOR_DRVNAME_GC5005MIPI_RAW, currSensorName))
{
_hwPowerOn(VCAMD, VOL_1200);
}else
{
_hwPowerOn(VCAMD, VOL_1800);
}
mdelay(5);
_hwPowerOn(VCAMAF, VOL_2800);
mdelay(5);
/* enable active sensor */
mtkcam_gpio_set(pinSetIdx, CAMPDN,pinSet[pinSetIdx][IDX_PS_CMPDN + IDX_PS_ON]);
mdelay(10);
mtkcam_gpio_set(pinSetIdx, CAMRST,pinSet[pinSetIdx][IDX_PS_CMRST + IDX_PS_ON]);
mdelay(10);
}
pinSetIdx = pinSetIdx ? 0 : 1;
mtkcam_gpio_set(pinSetIdx, CAMPDN,pinSet[pinSetIdx][IDX_PS_CMPDN + IDX_PS_OFF]);
mdelay(5);
mtkcam_gpio_set(pinSetIdx, CAMRST,pinSet[pinSetIdx][IDX_PS_CMRST + IDX_PS_OFF]);
mdelay(5);
} else { /* power OFF */
PK_DBG("[PowerOFF]pinSetIdx:%d\n", pinSetIdx);
if(0 == strcmp(SENSOR_DRVNAME_GC8024MIPI_RAW, currSensorName))
{
/* Set Power Pin low and Reset Pin Low */
mtkcam_gpio_set(pinSetIdx, CAMPDN,pinSet[pinSetIdx][IDX_PS_CMPDN + IDX_PS_OFF]);
mdelay(5);
mtkcam_gpio_set(pinSetIdx, CAMRST,pinSet[pinSetIdx][IDX_PS_CMRST + IDX_PS_OFF]);
mdelay(5);
pinSetIdx ? ISP_MCLK2_EN(0) : ISP_MCLK1_EN(0);
mdelay(5);
_hwPowerDown(VCAMAF);
mdelay(3);
_hwPowerDown(VCAMA);
mdelay(3);
_hwPowerDown(VCAMD);
mdelay(3);
_hwPowerDown(VCAMIO);
mdelay(3);
}else
{
pinSetIdx ? ISP_MCLK2_EN(0) : ISP_MCLK1_EN(0);
/* Set Power Pin low and Reset Pin Low */
mtkcam_gpio_set(pinSetIdx, CAMPDN,pinSet[pinSetIdx][IDX_PS_CMPDN + IDX_PS_OFF]);
mtkcam_gpio_set(pinSetIdx, CAMRST,pinSet[pinSetIdx][IDX_PS_CMRST + IDX_PS_OFF]);
_hwPowerDown(VCAMD);
mdelay(3);
_hwPowerDown(VCAMA);
mdelay(3);
_hwPowerDown(VCAMIO);
mdelay(3);
_hwPowerDown(VCAMAF);
mdelay(3);
}
}
return 0;
//_kdCISModulePowerOn_exit_: // return -EIO;
}
这边的 pinSetIdx 可以反过来,这样就默认打开前摄了,现在是
rear camera 优先。
其次,上电时序,参考各 sensor 的 datasheet 来
3.4 闪光的控制
alps/kernel-3.18/drivers/misc/mediatek/flashlight/src/mt6580/constant_flashlight/leds_strobe.c
alps/kernel-3.18/drivers/misc/mediatek/flashlight/src/mt6580/sub_strobe.c
alps/kernel-3.18/drivers/misc/mediatek/flashlight/src/mt6580/kd_flashlightlist.c
@@ -713,6 +713,8 @@ static int flashlight_probe(struct platform_device *dev)
/* init_MUTEX(&flashlight_private.sem); */ sema_init(&flashlight_private.sem, 1);
+ strobe_gpio_init(dev); + sub_strobe_gpio_init(dev);
logI("[flashlight_probe] Done ~");
return 0;
@@ -755,6 +757,13 @@ static void flashlight_shutdown(struct platform_device *dev)
logI("[flashlight_shutdown] Done ~");
}
+#ifdef CONFIG_OF
+ static const struct of_device_id strobe_of_ids[] = {
+ {.compatible = "mediatek,strobe_gpio",},
+ {}
+ };
+#endif +
static struct platform_driver flashlight_platform_driver = {
.probe = flashlight_probe,
.remove = flashlight_remove,
@@ -762,6 +771,9 @@ static struct platform_driver flashlight_platform_driver = {
.driver = {
.name = FLASHLIGHT_DEVNAME,
.owner = THIS_MODULE,
alps/kernel-3.18/drivers/misc/mediatek/flashlight/inc/kd_flashlight.h
void strobe_gpio_init(struct platform_device *pdev);
void sub_strobe_gpio_init(struct platform_device *pdev);
4.hal配置
4.1camera配置
sdk/alps/vendor/mediatek/proprietary/custom/mt6580/hal/imgsensor$
增加对应camera的效果调试文件夹
gc030amipi_raw/
gc5005_mipi_raw/
sdk/alps/vendor/mediatek/proprietary/custom/mt6580/hal/imgsensor_src$ vim sensorlist.cpp
增加对应驱动的 SensorList 描述项,添加 Sensor 列表的定义:
添加对应驱动 SensorList[]数组中增加对应驱动的配置;
alps/vendor/mediatek/proprietary/custom/mt6580/hal/sendepfeature$
对应驱动定义的我们的相机支持哪些情景模式,有了这个
后,android framework 会根据这些做相应的处理, 然后传入到上层, 上层 java
就可以判断我们是否能支持该模式,
vim gc5005_mipi_raw/config.ftbl.gc5005_mipi_raw.
im gc030amipi_raw/config.ftbl.gc030amipi_raw.h
4.2闪光的效果调试
alps/vendor/mediatek/proprietary/custom/mt6580/hal/flashlight/flash_tuning_custom_cct.cpp
5.Android层配置
增加对应驱动的 SENSOR_ID 和 SENSOR_DRVNAME 定义
alps\device\mediatek\common\kernel-headers\kd_imgsensor.h
#define GC5005MIPI_SENSOR_ID 0x5005
#define GC030AMIPI_SENSOR_ID 0x30A
....
#define SENSOR_DRVNAME_GC5005MIPI_RAW "gc5005mipiraw"
#define SENSOR_DRVNAME_GC030AMIPI_RAW "gc030amipiraw"
6.DEBUG
6.1成像方向的修改
尽量不要修改平台的方向,以免影响其他模组的调试,通常在driver里面都会有对应成像方向的宏定义,修改driver的宏定义就好
kernel-3.18/drivers/misc/mediatek/imgsensor/src/mt6580/gc5005_mipi_raw/gc5005mipi_Sensor.h
* CMOS sensor header file *
****************************************************************************/
//#define IMAGE_NORMAL_MIRROR
#define IMAGE_H_MIRROR
//#define IMAGE_V_MIRROR
//#define IMAGE_HV_MIRROR
#ifdef IMAGE_NORMAL_MIRROR
6.2 成像效果调试
这一部风交个FAE来调试,fae会有对应的工具调试。
6.3压力测试概率黑屏卡死等问题
在对应驱动里修改
由 于 timing 的 问 题 , 先 下 shutter 再 去 调 用
set_max_framerate_by_scenario 函数后
set_max_framerate_by_scenario 里注释:
//set_dummy();
6.4前置 camera 没有搭配闪光灯,如何关闭闪光灯图标
alps/vendor/mediatek/proprietary/custom/mt6580/halinc/aaa/flash_tuning_custom2.h
#define SUB_FLASH_SUPPORT 0
6.5打开 EIS 录像变暗
+++ b/alps/vendor/mediatek/proprietary/hardware/mtkcam/legacy/platform/mt6580/v1/hal/adapter/MtkDefault/MtkDefaultCamParameter.cpp
@@ -247,7 +247,7 @@ setParameters() cam3aParam.u4ShotMode = mpParamsMgr->getShotMode();
cam3aParam.u4CamMode = mpParamsMgr->getHalAppMode();
cam3aParam.i4RotateDegree = mpParamsMgr->getInt(MtkCameraParameters::KEY_ROTATION);
- cam3aParam.bVideoStabilization = mpParamsMgr->getVideoStabilization();
+ cam3aParam.bVideoStabilization = 0;//mpParamsMgr->getVideoStabilization();
//
if ( ! p3AHal->setParams(cam3aParam) )
{
6.6关闭闪光灯白平衡以改良拍照效果
+++ b/alps/vendor/mediatek/proprietary/custom/mt6580/hal/camera_3a/flashawb_tuning_custom.cpp
@@ -41,5 +41,5 @@
MBOOL
isFlashAWBv2Enabled()
{
- return MTRUE; + return 0;//MTRUE
}
6.7修改闪光灯阀值
Z:\ztg\80m0\s5073\alps\vendor\mediatek\proprietary\custom\mt6580\hal\imgsensor\gc5025mipi_raw\ca mera_AE_PLineTable_gc5025mipi_raw.h
AETABLE_RPEVIEW_AUTO, //eAETableID
123, //u4TotalIndex
- 20, //u4StrobeTrigerBV
+ -20, //u4StrobeTrigerBV
106, //i4MaxBV
-16, //i4MinBV
90, //i4EffectiveMaxBV
备注:阀值:20、0、-20 .替换代码中所有//u4StrobeTrigerBV 项的值。大部分后摄 -20,前摄 0