分享

android mtk6732 camera otp 加载流程

 linux_android 2016-08-17

  

在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 烧录的是infmacro两个位置,在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采用水平远近焦烧录,故手机端在调用InfinityCode值时,需要减去向下方向的位置差CodeMax,故手机端在调用MacroCode值,需要加上向上方向的位置差Code(Max)

 

从我手边的模组来看,向下方向的位置差CodeMax=100,向上方向的位置差Code(Max)=100,应该可以用.例如你手头的模组读取的OTP_Infinity=220, OTP_Macro=334,那么你可以设置Mobile_Infinity=120 Mobile_Macro=434. 特别注意需要保证驱动,Mobile_Infinity>=0, Mobile_Macro<=1023,不能越界。

 

以后,力求把思路,代码以准确兼形象的方式来进行总结.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多