个人学习总结记录,有错误望指正
在配置这个驱动的过程中,设备名称和ID配置无误的前提下,我们能成功加载进GC02M1的驱动文件,但是获取sensor_id异常,从后往前进行一个添加log排查,自己梳理一遍
1、进入初始化后调用sensor_func结构体,进行一个初始化配置
UINT32 GC02M1MIPI_RAW_SensorInit(struct SENSOR_FUNCTION_STRUCT **pfFunc)
{
/* To Do : Check Sensor status here */
if (pfFunc != NULL)
{
printk("GC02M1MIPI_RAW_SensorInit\n");
*pfFunc = &sensor_func;
}
return ERROR_NONE;
}
static struct SENSOR_FUNCTION_STRUCT sensor_func = {
open,
get_info,
get_resolution,
feature_control, //在这里获取sensor id
control,
close
};
2、查看这个 feature_control() 函数
static kal_uint32 feature_control(MSDK_SENSOR_FEATURE_ENUM feature_id,
UINT8 *feature_para, UINT32 *feature_para_len)
{
...
UINT32 *feature_return_para_32 = (UINT32 *)feature_para;
//通过这个switch选择,匹配成功后,调用get_imgsensor_id()函数,去获取id
switch (feature_id) {
...
case SENSOR_FEATURE_CHECK_SENSOR_ID:
get_imgsensor_id(feature_return_para_32);
break;
...
}
}
3、继续跟这个 get_imgsensor_id() 函数的参数来源
static kal_uint32 get_imgsensor_id(UINT32 *sensor_id)
{
kal_uint8 i = 0;
kal_uint8 retry = 2;
//打印结果:gc02m1 get_imgsensor_id,0x0
printk("gc02m1 %s,0x%x\n ",__func__,*sensor_id);
/*
循环遍历这个iic列表
static struct imgsensor_info_struct imgsensor_info = {
.i2c_addr_table = {0x6e, 0x20, 0xff},
.i2c_speed = 400,
};
*/
while (imgsensor_info.i2c_addr_table[i] != 0xff) {
spin_lock(&imgsensor_drv_lock);
imgsensor.i2c_write_id = imgsensor_info.i2c_addr_table[i];
printk("gc02m1 imgsensor i2c_write_id : 0x%x", imgsensor.i2c_write_id);
spin_unlock(&imgsensor_drv_lock);
do {
/*
通过这个函数,返回sensor id
打印结果:gc02m1 return_sensor_id : 0x0
在这里没有获取到正确的id
*/
*sensor_id = return_sensor_id();
printk("gc02m1 return_sensor_id : 0x%x" , *sensor_id);
if (*sensor_id == imgsensor_info.sensor_id) {
printk("GC02M1(YH&YJ&YK&YC) i2c write id: 0x%x, sensor id: 0x%x\n", imgsensor.i2c_write_id, *sensor_id);
return ERROR_NONE;
}
printk("Read sensor id fail, write id: 0x%x, id: 0x%x\n", imgsensor.i2c_write_id, *sensor_id);
retry--;
} while (retry > 0);
i++;
retry = 2;
}
/*
这里ID不一致
打印log为:gc02m1 sensor_id : 0x0 imgsensor_info.sensor_id : 0x2e0
*/
if (*sensor_id != imgsensor_info.sensor_id) {
/* if Sensor ID is not correct, Must set *sensor_id to 0xFFFFFFFF */
printk("gc02m1 sensor_id : 0x%x imgsensor_info.sensor_id : 0x%x\n",*sensor_id,imgsensor_info.sensor_id);
*sensor_id = 0xFFFFFFFF;
return ERROR_SENSOR_CONNECT_FAIL;
}
return ERROR_NONE;
}
4、继续跟进 return_sensor_id() 函数
static kal_uint32 return_sensor_id(void)
{
return ((read_cmos_sensor(0xf0) << 8) | read_cmos_sensor(0xf1));
}
static kal_uint16 read_cmos_sensor(kal_uint32 addr)
{
kal_uint16 get_byte = 0;
char pu_send_cmd[1] = {(char)(addr & 0xff)};
//这里通过这个函数,读取iic里面信息,来往get_byte里面写值
iReadRegI2C(pu_send_cmd, 1, (u8 *)&get_byte, 1, imgsensor.i2c_write_id);
printk("gc02m1 get_byte : %d\n",get_byte);
return get_byte;
}
关于iReadRegI2C函数,在文件eeprom_i2c_custom_driver.c中
文件位置:
/mtk8766/alps/s0_vnd/kernel-4.19/drivers/misc/mediatek/cam_cal/src/mt6761/eeprom_i2c_custom_driver.c
5、在kernel层的 imgsensor.c 中,判断是否存在该sensor id
static inline int imgsensor_check_is_alive(struct IMGSENSOR_SENSOR *psensor)
{
...
IMGSENSOR_PROFILE_INIT(&psensor_inst->profile_time);
//摄像头上电
err = imgsensor_hw_power(&pgimgsensor->hw,
psensor,
psensor_inst->psensor_name,
IMGSENSOR_HW_POWER_STATUS_ON);
if (err == IMGSENSOR_RETURN_SUCCESS)
imgsensor_sensor_feature_control(
psensor,
SENSOR_FEATURE_CHECK_SENSOR_ID,
(MUINT8 *)&sensorID,
&retLen);
/*
这里判断sensorid是否存在,如果存在,那么久将其打印出来
这里打印log信息为:gc02m1 Fail to get sensor ID ffffffff
*/
if (sensorID == 0 || sensorID == 0xFFFFFFFF) {
printk("gc02m1 Fail to get sensor ID %x\n", sensorID);
err = ERROR_SENSOR_CONNECT_FAIL;
} else {
printk("gc02m1 and s5k5e8yx Sensor found ID = 0x%x\n", sensorID);
err = ERROR_NONE;
}
if (err != ERROR_NONE)
printk("gc02m1 ERROR: No imgsensor alive\n");
//下电
imgsensor_hw_power(&pgimgsensor->hw,
psensor,
psensor_inst->psensor_name,
IMGSENSOR_HW_POWER_STATUS_OFF);
...
}
原因排查:iic不通
检查上电时序
内容无误,但是ID配置错误!修改后获取sensor_id正常,前置正常开启
#if defined(GC02M1_MIPI_RAW)
{
- SENSOR_DRVNAME_GC02M1MIPI_RAW,
+ SENSOR_DRVNAME_GC02M1_MIPI_RAW,
{
{PDN, Vol_Low, 0},
{RST, Vol_Low, 0},
{AVDD, Vol_2800, 2},
{DOVDD, Vol_1800, 2},
{DVDD, Vol_1800, 2},
{SensorMCLK, Vol_High, 1},
{PDN, Vol_High, 2},
{RST, Vol_High, 10}
},
},
#endif
也希望大家在排查的时候,先确保这些基础信息正常!