lens驱动和HAL分析

一.6737的lens 搜索HAL层分析

Mcu_drv.cpp (vendor\mediatek\proprietary\hardware\mtkcam\legacy\platform\mt6735\core\featureio\drv\lens)
根据摄像头搜索lens
MCUDrv::lensSearch( unsigned int a_u4CurrSensorDev, unsigned int a_u4CurrSensorId)
    //Camera_custom_msdk.cpp (vendor\mediatek\proprietary\custom\mt6735\hal\d1\camera_3a)
    LensCustomInit(a_u4CurrSensorDev); //得到lens列表,  //单独分析1   
    LensCustomGetInitFunc(&MCUDrv::m_LensInitFunc_main[0]);  //把LensCustomInit得到的数组赋值到a_pLensInitFunc
        memcpy(a_pLensInitFunc, &LensInitFunc[0], sizeof(MSDK_LENS_INIT_FUNCTION_STRUCT) * MAX_NUM_OF_SUPPORT_LENS);
    MCUDrv::m_u4CurrLensIdx_main = 0;
    for (i=0; i<MAX_NUM_OF_SUPPORT_LENS; i++) //搜索每个lens
       if (MCUDrv::m_LensInitFunc_main[i].LensId == DUMMY_LENS_ID)  //如果某个lens的ID为DUMMY_LENS_ID,记录,这里是选择最后一个DUMMY_LENS_ID
           MCUDrv::m_u4CurrLensIdx_main = i;
    for (i=0; i<MAX_NUM_OF_SUPPORT_LENS; i++)
       //把当前的sensor id和数组里面的比较,如果有,就记录,并且跳槽,所以是选择匹配的第一个
       if ((MCUDrv::m_LensInitFunc_main[i].SensorId == a_u4CurrSensorId) && (a_u4CurrSensorId!=0xFFFF) && (a_u4CurrSensorId!=0x0))
           MCUDrv::m_u4CurrLensIdx_main = i;
               MCU_DRV_DBG("[idx]%d\n", i);
               break;
    LensCustomSetIndex(MCUDrv::m_u4CurrLensIdx_main); //记录下主摄像头的lens的ID
        gMainLensIdx = a_u4CurrIdx;
    

//单独分析1
 //Lenslist.cpp (vendor\mediatek\proprietary\custom\mt6735\hal\d1\lens\src)
        GetLensInitFuncList(&LensInitFunc[0], a_u4CurrSensorDev);
            if(a_u4CurrSensorDev==2) //sub
memcpy(pLensList, &LensList_sub[0], sizeof(MSDK_LENS_INIT_FUNCTION_STRUCT)* MAX_NUM_OF_SUPPORT_LENS);
            else if(a_u4CurrSensorDev==4) //main 2
memcpy(pLensList, &LensList_main2[0], sizeof(MSDK_LENS_INIT_FUNCTION_STRUCT)* MAX_NUM_OF_SUPPORT_LENS);
   else  // main or others
memcpy(pLensList, &LensList_main[0], sizeof(MSDK_LENS_INIT_FUNCTION_STRUCT)* MAX_NUM_OF_SUPPORT_LENS);  //拷贝到pLensList


MSDK_LENS_INIT_FUNCTION_STRUCT LensList_main[MAX_NUM_OF_SUPPORT_LENS] =
{
{DUMMY_SENSOR_ID, DUMMY_LENS_ID, "Dummy", pDummy_getDefaultData},
#if defined(SENSORDRIVE)
{OV3640_SENSOR_ID, SENSOR_DRIVE_LENS_ID, "kd_camera_hw", pSensorDrive_getDefaultData},
#endif
#if defined(FM50AF)
{DUMMY_SENSOR_ID, FM50AF_LENS_ID, "FM50AF", pFM50AF_getDefaultData},
#endif
#if defined(DW9714AF)
{MN34152_SENSOR_ID, DW9714AF_LENS_ID, "DW9714AF", pDW9714AF_getDefaultData},
{IMX219_SENSOR_ID, DW9714AF_LENS_ID, "DW9714AF", pDW9714AF_getDefaultData},
#endif
}



二.lens HAL层调用分析
Lens_drv.cpp (vendor\mediatek\proprietary\hardware\mtkcam\legacy\platform\mt6735\core\featureio\drv\lens)

1.初始化
LensDrv::init(unsigned int a_u4CurrSensorDev )
   sprintf(cBuf, "/dev/%s", MCUDrv::m_LensInitFunc_main[a_u4CurrLensIdx].LensDrvName);
    m_fdMCU_main = open("/dev/MAINAF", O_RDWR); //打开这个节点
    memcpy(motorName.uMotorName, MCUDrv::m_LensInitFunc_main[a_u4CurrLensIdx].LensDrvName, 32); //得到AF的名字
   int err = ioctl(m_fdMCU_main,mcuIOC_S_SETDRVNAME,&motorName);   //设置AF的名字,驱动的AFIOC_S_SETDRVNAME,后面有分析


2.移动马达
LensDrv::moveMCU(int a_i4FocusPos,unsigned int a_u4CurrSensorDev )
    a_fdMCU=m_fdMCU_main;
    //设置马达位置,操作/dev/MAINAF,a_i4FocusPos为知(0--1023),去的default,后面有分析
    err = ioctl(a_fdMCU,mcuIOC_T_MOVETO,(unsigned long)a_i4FocusPos);  

3.获取马达信息
LensDrv::getMCUInfo(mcuMotorInfo *a_pMotorInfo, unsigned int a_u4CurrSensorDev )
    err = ioctl(a_fdMCU,mcuIOC_G_MOTORINFO, &motorInfo);

。。。。。。。。其他操作。。。。。。。。。
    

三.Main_lens公共驱动分析
Main_lens.c (kernel-3.18\drivers\misc\mediatek\lens)

#define PLATFORM_DRIVER_NAME "lens_actuator_main_af"

/* platform structure */
static struct platform_driver g_stAF_Driver = {
.probe = AF_probe,
.remove = AF_remove,
.suspend = AF_suspend,
.resume = AF_resume,
.driver = {
  .name = PLATFORM_DRIVER_NAME,
  .owner = THIS_MODULE,
  }
};

static struct platform_device g_stAF_device = {
.name = PLATFORM_DRIVER_NAME,
.id = 0,
.dev = {}
};

1.初始化,注册平台设备驱动
MAINAF_i2C_init
    platform_device_register(&g_stAF_device) //平台驱动匹配,进入probe函数
    platform_driver_register(&g_stAF_Driver)


2.注册I2C设备
#if I2C_CONFIG_SETTING == 2
static const struct of_device_id MAINAF_of_match[] = {
{.compatible = "mediatek,CAMERA_MAIN_AF"},
{},
};
#endif
static struct i2c_driver AF_i2c_driver = {
.probe = AF_i2c_probe,
.remove = AF_i2c_remove,
.driver.name = AF_DRVNAME,
#if I2C_CONFIG_SETTING == 2
.driver.of_match_table = MAINAF_of_match,
#endif
.id_table = AF_i2c_id,
};

AF_probe
    i2c_add_driver(&AF_i2c_driver); //匹配进入AF_i2c_probe函数,生成节点/sys/bus/i2c/drivers/MAINAF


3.I2C初始化

static const struct file_operations g_stAF_fops = {
.owner = THIS_MODULE,
.open = AF_Open,
.release = AF_Release,
.unlocked_ioctl = AF_Ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = AF_Ioctl,
#endif
};

 AF_i2c_probe
     g_pstAF_I2Cclient = client; //保存client,应该和camera一样,先注册个假的地址
         i4RetValue = Register_AF_CharDrv();
              alloc_chrdev_region(&g_AF_devno, 0, 1, AF_DRVNAME) //分配设备号
              g_pAF_CharDrv = cdev_alloc(); //分配字符设备
               #define AF_DRVNAME "MAINAF"
               cdev_init(g_pAF_CharDrv, &g_stAF_fops); 初始化操作函数
               cdev_add(g_pAF_CharDrv, g_AF_devno, 1) //注册进系统,生成节点/dev/MAINAF
               actuator_class = class_create(THIS_MODULE, AF_DRIVER_CLASS_NAME);   //创建class
               vcm_device = device_create(actuator_class, NULL, g_AF_devno, NULL, AF_DRVNAME); //创建设备节点sys/bus/platform/drivers/lens_actuator_main_af


4.AF_Ioctl,提供接口给上层使用
//lens的list
static stAF_DrvList g_stAF_DrvList[MAX_NUM_OF_LENS] = {
#ifdef CONFIG_MTK_LENS_BU6424AF_SUPPORT
{1, AFDRV_BU6424AF, BU6424AF_SetI2Cclient, BU6424AF_Ioctl, BU6424AF_Release},
#endif
}

switch (a_u4Command)
    case AFIOC_S_SETDRVNAME: //设置名字和把变量传入具体驱动
        i4RetValue = AF_SetMotorName((__user stAF_MotorName *)(a_u4Param));
            copy_from_user(&stMotorName , pstMotorName, sizeof(stAF_MotorName) //用户空间拷贝数据
            for (i = 0; i < MAX_NUM_OF_LENS; i++)
                if (strcmp(stMotorName.uMotorName, g_stAF_DrvList[i].uDrvName) == 0) //如果名字相同
                    g_pstAF_CurDrv = &g_stAF_DrvList[i]; //设置当前设备
                    g_pstAF_CurDrv->pAF_SetI2Cclient(g_pstAF_I2Cclient, &g_AF_SpinLock, &g_s4AF_Opened); //调用具体lens的pAF_SetI2Cclient
                        DW9714AF_SetI2Cclient //比如DW9714AF马达
                            g_pstAF_I2Cclient = pstAF_I2Cclient;  //保存传进来的client指针,以后就可以在具体驱动中修改main_af的东西了
                    g_pAF_SpinLock = pAF_SpinLock;
                    g_pAF_Opened = pAF_Opened;  //open标志位

    default:
        i4RetValue = g_pstAF_CurDrv->pAF_Ioctl(a_pstFile, a_u4Command, a_u4Param); //调用具体驱动的ioctl



四.具体AF驱动分析:DW9714AF为例
    DW9714AF.c (kernel-3.18\drivers\misc\mediatek\lens\common\dw9714af)
主要是ioctl分析
DW9714AF_Ioctl
    switch (a_u4Command)
    case AFIOC_G_MOTORINFO: //获取一些信息,比如位置
        getAFInfo((__user stAF_MotorInfo *) (a_u4Param));
    case AFIOC_T_MOVETO:  //驱动到马达到具体位置
        i4RetValue = moveAF(a_u4Param); 
            ret = s4AF_ReadReg(&InitPos); //单独分析1
                g_pstAF_I2Cclient->addr = AF_I2C_SLAVE_ADDR; 
    case AFIOC_T_SETINFPOS: //设置AF的位置
i4RetValue = setAFInf(a_u4Param);
            g_u4AF_INF = a_u4Position; /
    case AFIOC_T_SETMACROPOS: //设置AF最大的移动位置
i4RetValue = setAFMacro(a_u4Param);
            g_u4AF_MACRO = a_u4Position; 

//单独分析1
ret = s4AF_ReadReg(&InitPos);
   g_pstAF_I2Cclient->addr = AF_I2C_SLAVE_ADDR;  //当前驱动的I2C地址
   g_pstAF_I2Cclient->addr = g_pstAF_I2Cclient->addr >> 1; 
   i4RetValue = i2c_master_recv(g_pstAF_I2Cclient, pBuff, 2); /读写I2C


    
posted @ 2020-11-25 14:32  luoyuna  阅读(674)  评论(0编辑  收藏  举报