1、先找到Camera的上电时序图,从图中可以看到我们接下来需要配置的GPIO引脚。
2、再找到板子原理图中的Camera部分引脚定义如下图,从中可以找到Camera的上电时序图的对应GPIO引脚。以CMMCLK为例,CMCLK --> CMMCLK --> Y27 --> GPIO45。
3、硬件连接分析完后,接下来就分析软件是否正确配置。在jsh\K9635_6735_5.1\kernel-3.10\tools\dct目录下运行DrvGen软件并打开\jsh\K9635_6735_5.1\kernel-3.10\drivers\misc\mediatek\mach\mt6735\f202_3566t\dct\dct目录下codegen.dws如下图。从图中可看到GPIO45引脚是否正确配置。
4、kd_camera_hw.c 是需要客制化的文件,主要控制imagesensor的上电和下电时序,一定要正确填写,否则可能会出现读不到id,黑屏,花屏,进入退出Camera速度慢等一系列问题。接下来着重理清上电时序代码
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 3u32 pinSet[3][8] = {
//for main sensor { CAMERA_CMRST_PIN, // The reset pin of main sensor uses GPIO10 of mt6306, please call mt6306 API to set 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_ONE, GPIO_OUT_ZERO, }, //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_ONE, GPIO_OUT_ZERO, }, //for main_2 sensor { GPIO_CAMERA_INVALID, GPIO_CAMERA_INVALID, /* mode */ GPIO_OUT_ONE, /* ON state */ GPIO_OUT_ZERO, /* OFF state */ GPIO_CAMERA_INVALID, GPIO_CAMERA_INVALID, GPIO_OUT_ONE, GPIO_OUT_ZERO, } }; //前面我们从硬件原理图入手如何在dws里面将这些RST,PDN pin等引脚配置好if (DUAL_CAMERA_MAIN_SENSOR == SensorIdx){
pinSetIdx = 0; } else if (DUAL_CAMERA_SUB_SENSOR == SensorIdx) { pinSetIdx = 1; } else if (DUAL_CAMERA_MAIN_2_SENSOR == SensorIdx) { pinSetIdx = 2; } //根据传入的SensorIdx 确定pinSentIdx 区分前后摄//power ON
if (On) { #if 0 ISP_MCLK1_EN(1); ISP_MCLK2_EN(1); ISP_MCLK3_EN(1); #else if(pinSetIdx == 0 ) { ISP_MCLK1_EN(1); } else if (pinSetIdx == 1) { ISP_MCLK1_EN(1); } //从上面的Camera引脚图可知前后摄共用同一个CMMCLK #endifPK_DBG("[PowerON]pinSetIdx:%d, currSensorName: %s\n", pinSetIdx, currSensorName);
//可以抓此处log信息查看currSensorName是否有配置的Camera name,没有则检查camera list数组及其他配置
if (currSensorName && (0 == strcmp(SENSOR_DRVNAME_GC2365B_MIPI_RAW, currSensorName))) { //根据sensor 的name来上下电,与kd_imagesensor里面的定义相对应 if(pinSetIdx == 1)
return; // currSensorName 匹配正确了如果是前摄就返回不进行上电,后摄就继续进入上电,这里要注意我们配置的是前摄还是后摄
//First Power Pin low and Reset Pin Low if (GPIO_CAMERA_INVALID != pinSet[pinSetIdx][IDX_PS_CMPDN]) { mt_set_gpio_mode(pinSet[pinSetIdx][IDX_PS_CMPDN],pinSet[pinSetIdx][IDX_PS_CMPDN+IDX_PS_MODE]) mt_set_gpio_dir(pinSet[pinSetIdx][IDX_PS_CMPDN],GPIO_DIR_OUT) mt_set_gpio_out(pinSet[pinSetIdx][IDX_PS_CMPDN], pinSet[pinSetIdx][IDX_PS_CMPDN+IDX_PS_OFF]) } if (GPIO_CAMERA_INVALID != pinSet[pinSetIdx][IDX_PS_CMRST]) { mt_set_gpio_mode(pinSet[pinSetIdx][IDX_PS_CMRST],pinSet[pinSetIdx][IDX_PS_CMRST+IDX_PS_MODE]) mt_set_gpio_dir(pinSet[pinSetIdx][IDX_PS_CMRST],GPIO_DIR_OUT) mt_set_gpio_out(pinSet[pinSetIdx][IDX_PS_CMRST], pinSet[pinSetIdx][IDX_PS_CMRST+IDX_PS_OFF])} //根据宏定义及数组的各成员配置好各引脚功能及状态,先将其配置为低电平
// VCAM_IO 根据上电时序图配置好 A D IO 的上电电压值 if(TRUE != hwPowerOn(CAMERA_POWER_VCAM_IO, VOL_1800, mode_name)) { PK_DBG("[CAMERA SENSOR] Fail to enable digital power (VCAM_IO), power id = %d \n", CAMERA_POWER_VCAM_IO); goto _kdCISModulePowerOn_exit_; } // VCAM_A if(TRUE != hwPowerOn(CAMERA_POWER_VCAM_A, VOL_2800,mode_name)) { PK_DBG("[CAMERA SENSOR] Fail to enable analog power (VCAM_A), power id = %d\n", CAMERA_POWER_VCAM_A); goto _kdCISModulePowerOn_exit_; } // VCAM_D // Main VCAMD max 1.5V if( pinSetIdx==0) // 区分CAMERA_POWER_VCAM_D,SUB_CAMERA_POWER_VCAM_D { if(TRUE != hwPowerOn(CAMERA_POWER_VCAM_D, VOL_1500,mode_name)) { PK_DBG("[CAMERA SENSOR] Fail to enable digital power\n"); goto _kdCISModulePowerOn_exit_; } } else { if(TRUE != hwPowerOn(SUB_CAMERA_POWER_VCAM_D, VOL_1500,mode_name)) { PK_DBG("[CAMERA SENSOR] Fail to enable digital power (VCAM_D), power id = %d \n", CAMERA_POWER_VCAM_D); goto _kdCISModulePowerOn_exit_; } } // AF_VCC if(TRUE != hwPowerOn(CAMERA_POWER_VCAM_AF, VOL_2800,mode_name)) { PK_DBG("[CAMERA SENSOR] Fail to enable analog power (VCAM_AF), power id = %d \n", CAMERA_POWER_VCAM_AF); goto _kdCISModulePowerOn_exit_; } mdelay(5); //enable active sensor if (GPIO_CAMERA_INVALID != pinSet[pinSetIdx][IDX_PS_CMPDN]) { mt_set_gpio_mode(pinSet[pinSetIdx][IDX_PS_CMPDN],pinSet[pinSetIdx][IDX_PS_CMPDN+IDX_PS_MODE]) mt_set_gpio_dir(pinSet[pinSetIdx][IDX_PS_CMPDN],GPIO_DIR_OUT) if(mt_set_gpio_out(pinSet[pinSetIdx][IDX_PS_CMPDN],pinSet[pinSetIdx][IDX_PS_CMPDN+ IDX_PS_OFF]) } //依据上电时序图将PDN配置为低电平mdelay(5);
if (GPIO_CAMERA_INVALID != pinSet[pinSetIdx][IDX_PS_CMRST]) {
mt_set_gpio_mode(pinSet[pinSetIdx][IDX_PS_CMRST],pinSet[pinSetIdx][IDX_PS_CMRST+IDX_PS_MODE]) mt_set_gpio_dir(pinSet[pinSetIdx][IDX_PS_CMRST],GPIO_DIR_OUT) mt_set_gpio_out(pinSet[pinSetIdx][IDX_PS_CMRST],pinSet[pinSetIdx][IDX_PS_CMRST+ IDX_PS_OFF]) mdelay(10); mt_set_gpio_out(pinSet[pinSetIdx][IDX_PS_CMRST],pinSet[pinSetIdx][IDX_PS_CMRST+ IDX_PS_ON]) }} //依据上电时序图将RST配置为高电平
else if (currSensorName && (0 == strcmp(XXX, currSensorName))) {
... //继续匹配sensor
}
else {
... //没有匹配的sensor就默认从这上电
}
else
{ //power off
...
}
至此如何根据上电时序图配置GPIO就基本OK了