MT6737的lens HAL层分析

2024-01-25 02:08
文章标签 分析 hal lens mt6737

本文主要是介绍MT6737的lens HAL层分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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_pLensInitFuncmemcpy(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++) //搜索每个lensif (MCUDrv::m_LensInitFunc_main[i].LensId == DUMMY_LENS_ID)  //如果某个lens的ID为DUMMY_LENS_ID,记录,这里是选择最后一个DUMMY_LENS_IDMCUDrv::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的IDgMainLensIdx = a_u4CurrIdx;//单独分析1//Lenslist.cpp (vendor\mediatek\proprietary\custom\mt6735\hal\d1\lens\src)GetLensInitFuncList(&LensInitFunc[0], a_u4CurrSensorDev);if(a_u4CurrSensorDev==2) //submemcpy(pLensList, &LensList_sub[0], sizeof(MSDK_LENS_INIT_FUNCTION_STRUCT)* MAX_NUM_OF_SUPPORT_LENS);else if(a_u4CurrSensorDev==4) //main 2memcpy(pLensList, &LensList_main2[0], sizeof(MSDK_LENS_INIT_FUNCTION_STRUCT)* MAX_NUM_OF_SUPPORT_LENS);else  // main or othersmemcpy(pLensList, &LensList_main[0], sizeof(MSDK_LENS_INIT_FUNCTION_STRUCT)* MAX_NUM_OF_SUPPORT_LENS);  //拷贝到pLensListMSDK_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_initplatform_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_probei2c_add_driver(&AF_i2c_driver); //匹配进入AF_i2c_probe函数,生成节点/sys/bus/i2c/drivers/MAINAF3.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_probeg_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/MAINAFactuator_class = class_create(THIS_MODULE, AF_DRIVER_CLASS_NAME);   //创建classvcm_device = device_create(actuator_class, NULL, g_AF_devno, NULL, AF_DRVNAME); //创建设备节点sys/bus/platform/drivers/lens_actuator_main_af4.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_SetI2CclientDW9714AF_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_Ioctlswitch (a_u4Command)case AFIOC_G_MOTORINFO: //获取一些信息,比如位置getAFInfo((__user stAF_MotorInfo *) (a_u4Param));case AFIOC_T_MOVETO:  //驱动到马达到具体位置i4RetValue = moveAF(a_u4Param); ret = s4AF_ReadReg(&InitPos); //单独分析1g_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

 

这篇关于MT6737的lens HAL层分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/641769

相关文章

Nginx分布式部署流程分析

《Nginx分布式部署流程分析》文章介绍Nginx在分布式部署中的反向代理和负载均衡作用,用于分发请求、减轻服务器压力及解决session共享问题,涵盖配置方法、策略及Java项目应用,并提及分布式事... 目录分布式部署NginxJava中的代理代理分为正向代理和反向代理正向代理反向代理Nginx应用场景

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

Redis中的AOF原理及分析

《Redis中的AOF原理及分析》Redis的AOF通过记录所有写操作命令实现持久化,支持always/everysec/no三种同步策略,重写机制优化文件体积,与RDB结合可平衡数据安全与恢复效率... 目录开篇:从日记本到AOF一、AOF的基本执行流程1. 命令执行与记录2. AOF重写机制二、AOF的

MyBatis Plus大数据量查询慢原因分析及解决

《MyBatisPlus大数据量查询慢原因分析及解决》大数据量查询慢常因全表扫描、分页不当、索引缺失、内存占用高及ORM开销,优化措施包括分页查询、流式读取、SQL优化、批处理、多数据源、结果集二次... 目录大数据量查询慢的常见原因优化方案高级方案配置调优监控与诊断总结大数据量查询慢的常见原因MyBAT

分析 Java Stream 的 peek使用实践与副作用处理方案

《分析JavaStream的peek使用实践与副作用处理方案》StreamAPI的peek操作是中间操作,用于观察元素但不终止流,其副作用风险包括线程安全、顺序混乱及性能问题,合理使用场景有限... 目录一、peek 操作的本质:有状态的中间操作二、副作用的定义与风险场景1. 并行流下的线程安全问题2. 顺

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe

Java中最全最基础的IO流概述和简介案例分析

《Java中最全最基础的IO流概述和简介案例分析》JavaIO流用于程序与外部设备的数据交互,分为字节流(InputStream/OutputStream)和字符流(Reader/Writer),处理... 目录IO流简介IO是什么应用场景IO流的分类流的超类类型字节文件流应用简介核心API文件输出流应用文

Android 缓存日志Logcat导出与分析最佳实践

《Android缓存日志Logcat导出与分析最佳实践》本文全面介绍AndroidLogcat缓存日志的导出与分析方法,涵盖按进程、缓冲区类型及日志级别过滤,自动化工具使用,常见问题解决方案和最佳实... 目录android 缓存日志(Logcat)导出与分析全攻略为什么要导出缓存日志?按需过滤导出1. 按

Linux中的HTTPS协议原理分析

《Linux中的HTTPS协议原理分析》文章解释了HTTPS的必要性:HTTP明文传输易被篡改和劫持,HTTPS通过非对称加密协商对称密钥、CA证书认证和混合加密机制,有效防范中间人攻击,保障通信安全... 目录一、什么是加密和解密?二、为什么需要加密?三、常见的加密方式3.1 对称加密3.2非对称加密四、

MySQL中读写分离方案对比分析与选型建议

《MySQL中读写分离方案对比分析与选型建议》MySQL读写分离是提升数据库可用性和性能的常见手段,本文将围绕现实生产环境中常见的几种读写分离模式进行系统对比,希望对大家有所帮助... 目录一、问题背景介绍二、多种解决方案对比2.1 原生mysql主从复制2.2 Proxy层中间件:ProxySQL2.3