在android的hal层获取属性节点信息值:
//====== Get Property ======
char value[PROPERTY_VALUE_MAX] = {'\0'};
property_get("camcaldrv.log", value, "0");
MINT32 dumpEnable = atoi(value);
//====== Get Property ======
af_mgr.cpp init() --> readOTP() : //lens_para_FM50AF.cpp里面有关于这个功能的开关:0,disable,1,enable
CamCalDrvBase *pCamCalDrvObj = CamCalDrvBase::createInstance();
result= pCamCalDrvObj->GetCamCalCalData(i4SensorDevID, enCamCalEnum, (void *)&GetCamCalData);
MINT32 i4InfPos, i4MacroPos;
if (GetCamCalData.Single2A.S2aBitEn & 0x1)//判断是否使能此OTP
{
i4InfPos = GetCamCalData.Single2A.S2aAf[0];
if (GetCamCalData.Single2A.S2aBitEn & 0x2)//判断是否使能此OTP
{
i4MacroPos = GetCamCalData.Single2A.S2aAf[1];
if (i4MacroPos < i4InfPos)
{
MY_LOG("OTP abnormal return [Inf]%d [Macro]%d", i4InfPos, i4MacroPos);
return S_AF_OK;
}
}
else i4MacroPos = 0;
MY_LOG("OTP [Inf]%d [Macro]%d", i4InfPos, i4MacroPos);
if (m_pIAfAlgo)
m_pIAfAlgo->updateAFtableBoundary(i4InfPos, i4MacroPos);//传给算法那边会针对每颗模组产生新的table
}
mtk备注:
Af otp 烧录的是inf和macro两个位置,在af_mgr.cpp文件的init()函数调用readOtp(),将两个位置读取出来,传给算法那边会针对每颗模组产生新的table。
m_pIAfAlgo->updataAFTableBoundary(i4InfPos,i4MacroPos);
上述代码中 result= pCamCalDrvObj->GetCamCalCalData(i4SensorDevID, enCamCalEnum, (void *)&GetCamCalData); --->
cam_cal_drv.cpp ---> class CamCalDrvBase ---> GetCamCalCalData(unsigned long i4SensorDevId,CAMERA_CAM_CAL_TYPE_ENUM a_eCamCalDataType,void *a_pCamCalData) :
PCAM_CAL_DATA_STRUCT la_pCamCalData = (PCAM_CAL_DATA_STRUCT)a_pCamCalData;
PCAM_CAL_DATA_STRUCT pCamcalData = &StCamCalCaldata;
m32CamCalDataValidation= GetCameraCalData(i4CurrSensorId, (MUINT32*)pCamcalData);
memcpy((UINT8*)la_pCamCalData, (UINT8*)pCamcalData, sizeof(CAM_CAL_DATA_STRUCT));//最终获取到OTP数据
其中GetCameraCalData() :
if (pstSensorInitFunc[i].getCameraCalData != NULL)//针对当前camera id ,如果sensorlist.cpp的SensorList[]某一项camera配置了GetSensorCalData()就会获取OTP数据.
{
result = pstSensorInitFunc[i].getCameraCalData(pGetSensorCalData);
}
比如:
#if defined(IMX135_MIPI_RAW)
RAW_INFO(IMX135_SENSOR_ID, SENSOR_DRVNAME_IMX135_MIPI_RAW,IMX135_CAM_CALGetCalData),
#endif
camera_calibration_cam_cal.cpp ---> UINT32 IMX135_CAM_CALGetCalData(UINT32* pGetSensorCalData)
PCAM_CAL_DATA_STRUCT pCamCalData = (PCAM_CAL_DATA_STRUCT)pGetSensorCalData;
然后会OPEN如下图片中的设备来I2C通信,读取模组的OTP数据.
需要读取的块及实现函数:
const CALIBRATION_LAYOUT_STRUCT CalLayoutTbl[MAX_CALIBRATION_LAYOUT_NUM]=...
MTK 的 OTP格式:
其中,重点是如下两项,第一项是模组的lsc,第二项是模组的AWB,AF等校准信息:
{0x00000001, 0x00000017, 0x00000001, DoCamCalSingleLsc}, //CAMERA_CAM_CAL_DATA_SHADING_TABLE
{0x00000001, 0x00000007, 0x0000000E, DoCamCal2AGain}, //CAMERA_CAM_CAL_DATA_3A_GAIN
eg:
if(0x2&AWBAFConfig){
////AF////
cam_calCfg.u4Offset = (start_addr+10);
cam_calCfg.u4Length = 2;
cam_calCfg.pu1Params = (u8 *)&AFInf;
ioctlerr= ioctl(CamcamFID, CAM_CALIOC_G_READ, &cam_calCfg);
...
cam_calCfg.u4Offset = (start_addr+12);
cam_calCfg.u4Length = 2;
cam_calCfg.pu1Params = (u8 *)&AFMacro;
ioctlerr= ioctl(CamcamFID, CAM_CALIOC_G_READ, &cam_calCfg);
...
pCamCalData->Single2A.S2aAf[0] = AFInf;
pCamCalData->Single2A.S2aAf[1] = AFMacro;
}
MTK底层otp读写I2C设备驱动位置:
mediatek/custom/common/kernel/cam_cal/dummy_eeprom/dummy_cam_cal.c
在cam_cal里面的设备名字要和上面打开的设备名字相一致:CAM_CAL_DRV
再就是,在i2c设备cam_cal里,要注意读写地址是一个字节还是两个字节,如果不符会导致I2C不通:
#ifdef _SUNNY_AF_OTP_MODIFY_//for otp
i4RetValue = i2c_master_send(g_pstI2Cclient, puReadCmd+1, 1);
if (i4RetValue != 1)
{
CAM_CALDB("[CAM_CAL] I2C send read address failed!! \n");
return -1;
}
#else
i4RetValue = i2c_master_send(g_pstI2Cclient, puReadCmd, 2);
if (i4RetValue != 2)
{
CAM_CALDB("[CAM_CAL] I2C send read address failed!! \n");
return -1;
}
#endif
注意: 摄像头模组水平,向上,向下拍摄时code值范围是不同的,相差100code左右:
1#模组 |
向上 |
水平 |
向下 |
起始Code |
216 |
148 |
102 |
终止Code |
559 |
494 |
432 |
2#模组 |
向上 |
水平 |
向下 |
起始Code |
175 |
124 |
68 |
终止Code |
495 |
434 |
375 |
由于P13N07F的马达是开环马达,手机驱动端在调用舜宇的OTP数据时,需要考虑向上,水平,向下三个方向的兼容。
制程工艺上,P13N07F采用水平远近焦烧录,故手机端在调用Infinity的Code值时,需要减去向下方向的位置差Code(Max),故手机端在调用Macro的Code值,需要加上向上方向的位置差Code(Max)。
从我手边的模组来看,向下方向的位置差Code(Max)=100,向上方向的位置差Code(Max)=100,应该可以用.例如你手头的模组读取的OTP_Infinity=220, OTP_Macro=334,那么你可以设置Mobile_Infinity=120, Mobile_Macro=434. 特别注意需要保证驱动,Mobile_Infinity>=0, Mobile_Macro<=1023,不能越界。
以后,力求把思路,代码以准确兼形象的方式来进行总结.