1、先找到Camera的上电时序图,从图中可以看到我们接下来需要配置的GPIO引脚。
2、再找到板子原理图中的Camera部分引脚定义如下图,从中可以找到Camera的上电时序图的对应GPIO引脚。以CMMCLK为例,CMCLK --> CMMCLK --> Y27 --> GPIO45。
3、硬件连接分析完后,接下来就分析软件是否正确配置。在jshK9635_6735_5.1kernel-3.10 oolsdct目录下运行DrvGen软件并打开jshK9635_6735_5.1kernel-3.10driversmiscmediatekmachmt6735f202_3566tdctdct目录下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 3
u32 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 #endif
PK_DBG("[PowerON]pinSetIdx:%d, currSensorName: %s
", 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
", 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
", 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
");
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
", 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
", 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了