零、点亮新len
1. 修改device\lentek\len6737m_35_m0\ProjectConfig.mk
CUSTOM_HAL_LENS=fm50af dw9714af
CUSTOM_HAL_MAIN_LENS=fm50af dw9714af
CUSTOM_KERNEL_LENS=fm50af dw9714af
CUSTOM_KERNEL_MAIN_LENS=fm50af dw9714af
2. 修改kernel-3.18\arch\arm\configs\len6737m_35_m0_debug_defconfig、len6737m_35_m0_defconfig
CONFIG_MTK_LENS_FM50AF_SUPPORT=y
CONFIG_MTK_LENS_DW9714AF_SUPPORT=y
3. 修改alps\kernel-3.18\drivers\misc\mediatek\lens\main\inc\lens_info.h
#define AFDRV_DW9714A "DW9714A"
4. 修改alps\kernel-3.18\drivers\misc\mediatek\lens\main\inc\lens_list.h
#ifdef CONFIG_MTK_LENS_DW9714AF_SUPPORT
#define DW9714AF_SetI2Cclient DW9714AF_SetI2Cclient_Main
#define DW9714AF_Ioctl DW9714AF_Ioctl_Main
#define DW9714AF_Release DW9714AF_Release_Main
extern void DW9714AF_SetI2Cclient(struct i2c_client *pstAF_I2Cclient, spinlock_t *pAF_SpinLock, int *pAF_Opened);
extern long DW9714AF_Ioctl(struct file *a_pstFile, unsigned int a_u4Command, unsigned long a_u4Param);
extern int DW9714AF_Release(struct inode *a_pstInode, struct file *a_pstFile);
#endif
5. 修改alps\kernel-3.18\drivers\misc\mediatek\lens\main\main_lens.c
static stAF_DrvList g_stAF_DrvList[MAX_NUM_OF_LENS] = {
...
#ifdef CONFIG_MTK_LENS_DW9714AF_SUPPORT
{1, AFDRV_DW9714AF, DW9714AF_SetI2Cclient, DW9714AF_Ioctl, DW9714AF_Release},
#endif
6. 添加驱动代码,放到kernel-3.18\drivers\misc\mediatek\lens\main\common\
创建文件夹dw9714af文件夹中包含DW9714AF.c、Makefile
7.修改上电时序: kernel-3.18\drivers\misc\mediatek\imgsensor\src\mt6735m\camera_hw\kd_camera_hw.c
//POWER ON
if (On) {
if ((currSensorName && (0 == strcmp(SENSOR_DRVNAME_GC8024MIPI_RAW, currSensorName))) ||
(currSensorName && (0 == strcmp(SENSOR_DRVNAME_GC5005MIPI_RAW, currSensorName)))){
...
// AF_VCC
if (TRUE != _hwPowerOn(VCAMAF, VOL_2800)) {
PK_DBG("[CAMERA SENSOR] Fail to enable AF power (VCAM_AF), power id = %d\n", VCAMAF);
//goto _kdCISModulePowerOn_exit_;
}
}
}
====================================以下是HAL层====================================
8. 添加HAL层代码: alps\vendor\mediatek\proprietary\custom\mt6735\hal\D2\lens\lens_para_DW9714AF.cpp
9. 修改alps\vendor\mediatek\proprietary\custom\mt6735\hal\D2\lens\Android.mk
+ LOCAL_SRC_FILES += lens_para_DW9714AF.cpp
10. 修改alps\vendor\mediatek\proprietary\custom\mt6735\hal\D2\lens\lenslist.cpp
#if defined(DW9714AF)
extern PFUNC_GETLENSDEFAULT pDW9714AF_getDefaultData;
// 这里的pDW9714AF_getDefaultData要与lens_para_DW9714AF.cpp中函数名一致
#endif
MSDK_LENS_INIT_FUNCTION_STRUCT LensList_main[MAX_NUM_OF_SUPPORT_LENS] =
{
#if defined(DW9714AF)
{IMX219_SENSOR_ID, DW9714AF_LENS_ID, "DW9714AF", pDW9714AF_getDefaultData},
// 后摄imx219的AF选定为: DW9714AF
#endif
二、前摄AF - 与后摄AF基本一致,需要注意的地方:
1.alps\vendor\mediatek\proprietary\custom\mt6735\hal\D2\lens\lenslist.cpp中注意核对: LensList_sub[]
MSDK_LENS_INIT_FUNCTION_STRUCT LensList_sub[MAX_NUM_OF_SUPPORT_LENS] ={
...
#if defined(DW9718AF)
{OV8865_SENSOR_ID, DW9718AF_LENS_ID, "DW9718AF", pDW9718AF_getDefaultData},
#endif
2.dws中的i2c栏目中,默认没有前摄AF,需要配上:
CAMERA_SUB_AF I2C_CHANNEL_2 0x0c
注: a)i2c总线,查看硬件原理图,与前摄读ID一个总线
b)i2c地址,驱动中写死,这里随意写
3.由于前摄AF比较少见,需要注意上电时序中把前摄AF上电
修改kernel-3.18\drivers\misc\mediatek\imgsensor\src\mt6735m\camera_hw\kd_camera_hw.c
//POWER ON
if (On) {
if ((currSensorName && (0 == strcmp(SENSOR_DRVNAME_GC8024MIPI_RAW, currSensorName))) ||
(currSensorName && (0 == strcmp(SENSOR_DRVNAME_GC5005MIPI_RAW, currSensorName)))){
...
// AF_VCC
if (TRUE != _hwPowerOn(VCAMAF, VOL_2800)) {
PK_DBG("[CAMERA SENSOR] Fail to enable AF power (VCAM_AF), power id = %d\n", VCAMAF);
}
}
}
4.由于前摄AF比较少见,需要注意硬件电路板中AF上电引脚是否有贴限流电阻(10k),可请硬件工程师帮忙检查
比如: v618_m5501项目就没有贴该电阻,导致AF的i2c不通 (原理图上有)
三、调试 - 驱动中没有实现什么调试节点,需要自己添加log打印
根据len的
注册流程: -> 前半部分需要通过串口查看log
-> 先运行AF_SetMotorName() - 设置AF是哪个
alps\kernel-3.18\drivers\misc\mediatek\lens\main\main_lens.c (架构)
MAINAF_i2C_init() // 模块入口
platform_driver_register(&g_stAF_Driver)
AF_probe() // 平台设备与平台驱动probe
i2c_add_driver(&AF_i2c_driver)
AF_i2c_probe() // i2c设备与i2c驱动probe - 【这里需要dws中的i2c栏目中有前摄af配置】
Register_AF_CharDrv();
alloc_chrdev_region(&g_AF_devno, 0, 1, AF_DRVNAME)
g_pAF_CharDrv = cdev_alloc();
cdev_init(g_pAF_CharDrv, &g_stAF_fops); // 关键 - 注册fops
cdev_add(g_pAF_CharDrv, g_AF_devno, 1)
class_create(THIS_MODULE, AF_DRIVER_CLASS_NAME);
device_create(actuator_class, NULL, g_AF_devno, NULL, AF_DRVNAME);
static const struct file_operations g_stAF_fops = {
.unlocked_ioctl = AF_Ioctl,
AF_Ioctl(struct file *a_pstFile, unsigned int a_u4Command, unsigned long a_u4Param)
switch (a_u4Command) {
case AFIOC_S_SETDRVNAME: AF_SetMotorName((__user stAF_MotorName *) (a_u4Param)); // 【设置af是哪个 - 首先运行】
case AFIOC_S_SETPOWERDOWN: AF_PowerDown(); // power down
default: g_pstAF_CurDrv->pAF_Ioctl(a_pstFile, a_u4Command, a_u4Param); // 驱动中实现
AF_SetMotorName()中默认会打印log:
LOG_INF("Set Motor Name : %s\n", stMotorName.uMotorName);
- mtklog中的kernel_log.boot查看 - 上层传下来操作哪个AF,看是否与模组对应
运行流程: 上层通过字符设备节点进行ioctl()
alps\kernel-3.18\drivers\misc\mediatek\lens\main\main_lens.c (架构)
g_pstAF_CurDrv->pAF_Ioctl(a_pstFile, a_u4Command, a_u4Param)
alps\kernel-3.18\drivers\misc\mediatek\lens\main\common\ad5820af\AD5820AF.c(驱动)
AD5820AF_Ioctl(struct file *a_pstFile, unsigned int a_u4Command, unsigned long a_u4Param)
switch (a_u4Command) {
case AFIOC_G_MOTORINFO: getAFInfo(a_u4Param); // 获取af开关,当前位置等信息
case AFIOC_T_MOVETO: moveAF(a_u4Param); // 【AF移动到传入的位置】
case AFIOC_T_SETINFPOS: setAFInf(a_u4Param);
case AFIOC_T_SETMACROPOS: setAFMacro(a_u4Param);
-> 最终驱动中会运行moveAF(a_u4Param);写AF的寄存器,可以在此添加打印log看是否有运行
四、无对焦,在moveAF()函数中添加log,并手动操作对焦马达,看马达功能是否正常
kernel-3.18\drivers\misc\mediatek\lens\main\common\fm50af\FM50AF.c
static inline int moveAF(unsigned long a_u4Position)
{
int ret = 0;
+ printk("liuzhigou test moveAF() ===========start 1\n");
if ((a_u4Position > g_u4AF_MACRO) || (a_u4Position < g_u4AF_INF)) {
LOG_INF("out of range\n");
return -EINVAL;
}
if (*g_pAF_Opened == 1) {
unsigned short InitPos;
+ printk("liuzhigou test moveAF() ===========start2\n");
ret = s4AF_ReadReg(&InitPos);
if (ret == 0) {
LOG_INF("Init Pos %6d\n", InitPos);
+ printk("liuzhigou test moveAF() ===========start3\n");
spin_lock(g_pAF_SpinLock);
g_u4CurrPosition = (unsigned long)InitPos;
spin_unlock(g_pAF_SpinLock);
} else {
+ printk("liuzhigou test moveAF() ===========start4\n");
spin_lock(g_pAF_SpinLock);
g_u4CurrPosition = 0;
spin_unlock(g_pAF_SpinLock);
}
+ printk("liuzhigou test moveAF() ===========start5\n");
spin_lock(g_pAF_SpinLock);
*g_pAF_Opened = 2;
spin_unlock(g_pAF_SpinLock);
}
if (g_u4CurrPosition == a_u4Position){ // 目标Position(上层下发)若与 当前Position是一样的,无需对焦,直接return
+ printk("liuzhigou test moveAF() ===========start6\n");
- return 0;
+ //return 0;
}
+ printk("liuzhigou test moveAF() ===========start7\n");
spin_lock(g_pAF_SpinLock);
g_u4TargetPosition = a_u4Position;
g_SR = 3;
spin_unlock(g_pAF_SpinLock);
/* LOG_INF("move [curr] %d [target] %d\n", g_u4CurrPosition, g_u4TargetPosition); */
+ while(1){
+ g_u4TargetPosition = 1000;
+ s4AF_WriteReg((unsigned short)g_u4TargetPosition);
+ mdelay(1000);
+
+ g_u4TargetPosition = 1;
+ s4AF_WriteReg((unsigned short)g_u4TargetPosition);
+ mdelay(1000);
+ }
if (s4AF_WriteReg((unsigned short)g_u4TargetPosition) == 0) {
+ printk("liuzhigou test moveAF() ===========start8\n");
spin_lock(g_pAF_SpinLock);
g_u4CurrPosition = (unsigned long)g_u4TargetPosition;
spin_unlock(g_pAF_SpinLock);
} else {
+ printk("liuzhigou test moveAF() ==========start9\n");
LOG_INF("set I2C failed when moving the motor\n");
}
return 0;
}
五、len调试案例
案例一 : len(fm50af)对焦框不能变绿(变绿代表对焦ok)
现象 : 对焦框不能变绿
平台 : androidN,MTK6737
排查过程: 1. FAE优化无果
2. 询问驱动同事郭工,修改alps/vendor/mediatek/proprietary/custom/mt6735/hal/D1/lens/fm50af/lens_para_FM50AF.cpp
- 2, // i4AFC_FAIL_CNT
+ 5, // i4AFC_FAIL_CNT 【增大循环次数】,改善概率性马达对焦时间长的问题。(四个地方都改)
3. 问题解决
处理方案: 修改增大循环次数
总结 : 驱动工作多重复性工作,需要做好总结与交流
案例二 : 后摄gc5025的af(未知,可能是fm50af)无功能 - hal层未配置
现象 : 无功能
平台 : androidN,MTK6737
排查过程: 1. 查看mtklog(kernel_log),发现:
[name:gc5025mipi_Sensor&]GC5025_camera_sensor[set_gain] GC5025MIPI analogic gain 1x, GC5025MIPI add pregain = 64
[name:main_lens&]MAINAF [AF_Open] Start
[name:main_lens&]MAINAF [AF_Open] End
[name:main_lens&]MAINAF [AF_SetMotorName] Set Motor Name : Dummy
[name:main_lens&]MAINAF [AF_SetMotorName] Search Motor Name : FM50AF
->由"Set Motor Name : Dummy"可知,hal层没有配
2. hal层配上就ok了: alps\vendor\mediatek\proprietary\custom\mt6735\hal\D2\lens\lenslist.cpp
MSDK_LENS_INIT_FUNCTION_STRUCT LensList_main[MAX_NUM_OF_SUPPORT_LENS] =
{
#if defined(FM50AF)
+ {GC5025MIPI_SENSOR_ID, FM50AF_LENS_ID, "FM50AF", pFM50AF_getDefaultData},
处理方案: 配hal层
总结 : 看log
案例五 : 后摄imx258的af(ad5820)无功能 - android.mk需要配置
现象 : af无功能
平台 : androidN,MTK6737
排查过程: 1. 查看out目录 - 发现有编译生产相应.o文件
2. 在alps\kernel-3.18\drivers\misc\mediatek\lens\main\main_lens.c (架构)和相应驱动中打印log,发现架构有跑,但驱动没跑:
mtklog:
5820 ARCH: AF_SetMotorName
5820 strcmp g_stAF_DrvList[0].uDrvName AD5820AF
5820 strcmp stMotorName.uMotorName = Dummy
-> 【hal层传下来的af是Dummy】(即无af)- 定位到问题出在hal层
3. 查看hal层,怀疑是【[#if defined(AD5820AF)]这个宏没开】,测试->果然没开
修改:alps\vendor\mediatek\proprietary\custom\mt6735\hal\D2\lens\lenslist.cpp
MSDK_LENS_INIT_FUNCTION_STRUCT LensList_main[MAX_NUM_OF_SUPPORT_LENS] =
{
{DUMMY_SENSOR_ID, DUMMY_LENS_ID, "Dummy", pDummy_getDefaultData},
+ //#if defined(AD5820AF)
+ // {OV5648MIPI_SENSOR_ID, AD5820AF_LENS_ID, "AD5820AF", pAD5820AF_getDefaultData},
{IMX258_SENSOR_ID, AD5820AF_LENS_ID, "AD5820AF", pAD5820AF_getDefaultData},
+ //#endif
4. 编译报错,修改alps\vendor\mediatek\proprietary\custom\mt6735\hal\D2\lens\Android.mk
+ LOCAL_SRC_FILES += lens_para_AD5820AF.cpp
-> 后摄af(ad5820)正常工作
处理方案: 修改lenslist.cpp
总结 : 这里的宏,本应由编译脚本开,不知为何没开,干脆先写死为开
案例六 : 前摄ov8865的af(dw9718)无功能 - 多处需要配置
现象 : af无功能
平台 : androidN,MTK6737
排查过程: 1. 查看hal层即kernel发现有相应文件,修改编译脚本(即修改ProjectConfig.mk和***_defconfig),
编译查看out目录有生成相应.o文件
修改alps\vendor\mediatek\proprietary\custom\mt6735\hal\D2\lens\Android.mk
+ LOCAL_SRC_FILES += lens_para_DW9718AF.cp
修改alps\vendor\mediatek\proprietary\custom\mt6735\hal\D2\lens\lenslist.cpp
MSDK_LENS_INIT_FUNCTION_STRUCT LensList_sub[MAX_NUM_OF_SUPPORT_LENS] =
{
+ //#if defined(DW9718AF)
{OV8865_SENSOR_ID, DW9718AF_LENS_ID, "DW9718AF", pDW9718AF_getDefaultData},
+ //#endif
2. 在前摄af的架构和驱动中添加log,查看mtklog,发现无任何相关log打印
3. 查看串口log发现,架构有跑,但是i2c匹配不到(没有跑i2c_probe),【查看dws,缺少前摄af】,修改dws
添加:
CAMERA_SUB_AF I2C_CHANNEL_2 0x0c(由于i2c地址写死在驱动,这边随意写一个)
4. 查看mtklog,发现i2c通讯失败:
mtklog:
9718: s4AF_WriteReg // 我在驱动中加的printk
id=2,addr: c, transfer error
I2C_ACKERR
检查硬件原理图->是i2c总线2没错,询问硬件王工,是【af上电端需要贴一个电阻】。贴上电阻
->前摄af(dw9718)正常工作
处理方案: 修改编译脚本,android.mk,lenslist.cpp,dws,硬件贴电阻
总结 : 公司首次调试前摄af,多处需要配置
案例七 : AF的优化参数合入未生效
现象 :
平台 : androidN,MTK6737
排查过程: 1. vendor/mediatek/proprietary/custom/mt6735/hal/D2/camera_3a/camera_custom_msdk.cpp
void GetLensDefaultPara(PNVRAM_LENS_PARA_STRUCT pLensParaDefault)
{
// 原本获取AF参数的方式是:
// 1. 通过传入的参数:gMainLensIdx(219在数组LensList_main[]中的位置),找到对应的AF ID(如FM50AF_LENS_ID)
// 2. 遍历数组LensList_main[],找到第一个AF ID(如FM50AF_LENS_ID), 使用它的Default参数
// 新的方式是:
// 1. 通过传入的参数:gMainLensIdx(219在数组LensList_main[]中的位置),找到对应的Default参数
//
+ #if 0
MUINT32 i;
MUINT32 LensId = LensInitFunc[gMainLensIdx].LensId;
if (LensInitFunc[0].getLensDefault == NULL)
{
CAM_MSDK_LOG("[GetLensDefaultPara]: uninit yet\n\n");
return;
}
for (i=0; i<MAX_NUM_OF_SUPPORT_LENS; i++)
{
if (LensId == LensInitFunc[i].LensId)
{
break;
}
}
if (pLensParaDefault != NULL)
{
LensInitFunc[i].getLensDefault((VOID*)pLensParaDefault, sizeof(NVRAM_LENS_PARA_STRUCT));
}
+ #else
+ if (pLensParaDefault != NULL)
+ {
+ LensInitFunc[gMainLensIdx].getLensDefault((VOID*)pLensParaDefault, sizeof(NVRAM_LENS_PARA_STRUCT));
+ }
+ #endif
}
2. vendor/mediatek/proprietary/custom/mt6735/hal/D2/lens/lenslist.cpp
extern PFUNC_GETLENSDEFAULT pFM50AF_getIMX219Data;
MSDK_LENS_INIT_FUNCTION_STRUCT LensList_main[MAX_NUM_OF_SUPPORT_LENS] =
{
{IMX219_SENSOR_ID, FM50AF_LENS_ID, "FM50AF", pFM50AF_getIMX219Data},
3. vendor/mediatek/proprietary/custom/mt6735/hal/D2/lens/lens_para_FM50AF.cpp
const NVRAM_LENS_PARA_STRUCT FM50AF_LENS_PARA_IMX219_VALUE =
{...}
UINT32 FM50AF_getIMX219Data(VOID *pDataBuf, UINT32 size){
memcpy(pDataBuf, &FM50AF_LENS_PARA_IMX219_VALUE, dataSize);}
PFUNC_GETLENSDEFAULT pFM50AF_getIMX219Data = FM50AF_getIMX219Data;
4. 用CCT验证更改是否生效
打开CCT --> Action --> Connect --> Connect --> 连接手机
Page --> AF --> AF Parameter --> sAF_Coef
查看表格中的参数是否与如何的参数一致
处理方案:
总结 : 最好添加宏控制
案例八 : 后摄af(gc8024)无功能 -- AFVDD未上电 -- 在tp中使能pmu2.8v电压(VLDO28_PMU)
现象 :
平台 : androidO,MTK6739
排查过程: 1. 查看mtklog,显示i2c不通
kernel-4.4/drivers/misc/mediatek/lens/main/common/fm50af/FM50AF.c
moveAF()函数中调加log:
01-01 00:19:06.163184 3208 3208 I [ 182.765965] (2)[3208:3ATHREAD][name:main_lens&]: MAINAF [AF_SetMotorName] Set Motor Name : FM50AF (10)
01-01 00:19:06.163652 3208 3208 W [ 182.766433] (2)[3208:3ATHREAD]: liuzhigou test moveAF() ===========start 1
01-01 00:19:06.163682 3208 3208 W [ 182.766463] (2)[3208:3ATHREAD]: liuzhigou test moveAF() ===========start 2 //s4AF_ReadReg()
01-01 00:19:06.165263 3208 3208 I [ 182.768044] (1)[3208:3ATHREAD]: i2c i2c-2: addr: c, transfer ACK error
01-01 00:19:06.165298 3208 3208 I [ 182.768079] (1)[3208:3ATHREAD][name:i2c_mtk&]: i2c_dump_info ++++++++++++++++++++++++++++++++++++++++++
01-01 00:19:06.165311 3208 3208 E [ 182.768092] (1)[3208:3ATHREAD][name:i2c_mtk&]: I2C structure:
01-01 00:19:06.165627 3208 3208 D [ 182.768408] (1)[3208:3ATHREAD][name:FM50AF&]: FM50AF_DRV [s4AF_ReadReg] I2C read failed!!
01-01 00:19:06.165643 3208 3208 W [ 182.768424] (1)[3208:3ATHREAD]: liuzhigou test moveAF() ===========start 4
01-01 00:19:06.167544 3208 3208 W [ 182.770325] (1)[3208:3ATHREAD]: liuzhigou test moveAF() ===========start 5
01-01 00:19:06.167573 3208 3208 W [ 182.770354] (1)[3208:3ATHREAD]: liuzhigou test moveAF() ===========start 6
01-01 00:19:06.167584 3208 3208 W [ 182.770365] (1)[3208:3ATHREAD]: liuzhigou test moveAF() ===========start 7 // s4AF_WriteReg()
01-01 00:19:06.167998 3208 3208 I [ 182.770779] (1)[3208:3ATHREAD]: i2c i2c-2: addr: c, transfer ACK error
01-01 00:19:06.168029 3208 3208 I [ 182.770810] (1)[3208:3ATHREAD][name:i2c_mtk&]: i2c_dump_info ++++++++++++++++++++++++++++++++++++++++++
01-01 00:19:06.168041 3208 3208 E [ 182.770822] (1)[3208:3ATHREAD][name:i2c_mtk&]: I2C structure:
01-01 00:19:06.168354 3208 3208 D [ 182.771135] (1)[3208:3ATHREAD][name:FM50AF&]: FM50AF_DRV [s4AF_WriteReg] I2C send failed!!
2. 怀疑afvdd没有上电,用万用表测量afvdd电压
打开camera之后afvdd电压还是0v
3. 怀疑afvdd电压被拉低,打开camera之后将后摄拔掉 -->afvdd还是0v
怀疑afvdd电压上电之后迅速拉低 --> 接示波器 -->afvdd始终为0v
4. 怀疑afvdd电压,在软件上就没有上电操作,查看代码
alps\kernel-4.4\drivers\misc\mediatek\imgsensor\src\mt6739\camera_hw\imgsensor_cfg_table.c
struct IMGSENSOR_HW_POWER_SEQ sensor_power_sequence[] = {
#if defined(GC8024MIPI_RAW)
{
SENSOR_DRVNAME_GC8024MIPI_RAW,
{
{SensorMCLK, Vol_High, 0},
{PDN, Vol_High, 1},
{RST, Vol_Low, 10},
{DOVDD, Vol_1800, 5},
{AVDD, Vol_2800, 5},
{DVDD, Vol_1200, 5},
{AFVDD, Vol_2800, 5},
{PDN, Vol_Low, 5},
{RST, Vol_High, 5}
},
},
#endif
alps\kernel-4.4\drivers\misc\mediatek\imgsensor\src\common\v1\imgsensor_hw.c
imgsensor_hw_power()
PK_DBG("sensor_idx %d, power %d curr_sensor_name %s\n", sensor_idx, pwr_status, curr_sensor_name);
imgsensor_hw_power_sequence(phw, sensor_idx, pwr_status, sensor_power_sequence, curr_sensor_name);
imgsensor_hw_power_sequence(
struct IMGSENSOR_HW *phw,
enum IMGSENSOR_SENSOR_IDX sensor_idx,
enum IMGSENSOR_HW_POWER_STATUS pwr_status,
struct IMGSENSOR_HW_POWER_SEQ *ppower_sequence,
char *pcurr_idx)
{
struct IMGSENSOR_HW_SENSOR_POWER *psensor_pwr = &phw->sensor_pwr[sensor_idx];
struct IMGSENSOR_HW_POWER_SEQ *ppwr_seq = ppower_sequence;
struct IMGSENSOR_HW_POWER_INFO *ppwr_info;
struct IMGSENSOR_HW_DEVICE *pdev;
int pin_cnt = 0;
ppwr_info = ppwr_seq->pwr_info;
while (ppwr_info->pin != IMGSENSOR_HW_PIN_NONE && ppwr_info < ppwr_seq->pwr_info + IMGSENSOR_HW_POWER_INFO_MAX) {
if (pwr_status == IMGSENSOR_HW_POWER_STATUS_ON && ppwr_info->pin != IMGSENSOR_HW_PIN_UNDEF) {
pdev = phw->pdev[psensor_pwr->id[ppwr_info->pin]];
// 可以查看这条log
PK_DBG("sensor_idx = %d, pin=%d, pin_state_on=%d, hw_id =%d(0:PMIC, 1:GPIO, 2:exGPIO 3:mclk)\n",
sensor_idx, ppwr_info->pin, ppwr_info->pin_state_on, psensor_pwr->id[ppwr_info->pin]);
if (pdev->set != NULL)
pdev->set(pdev->pinstance, sensor_idx, ppwr_info->pin, ppwr_info->pin_state_on);
mdelay(ppwr_info->pin_on_delay);
}
ppwr_info++;
pin_cnt++;
}
查看mtklog:
Line 2163: 01-01 00:18:59.982048 3203 3203 D [ 176.584829] (1)[3203:initCamdevice][name:imgsensor_hw&]: [imgsensor]sensor_idx = 0, pin=7, pin_state_on=11, hw_id =2(0:PMIC, 1:GPIO, 2:exGPIO 3:mclk) // {SensorMCLK, Vol_High, 0},
Line 2164: 01-01 00:18:59.982092 3203 3203 D [ 176.584873] (1)[3203:initCamdevice][name:imgsensor_hw&]: [imgsensor]sensor_idx = 0, pin=1, pin_state_on=11, hw_id =1(0:PMIC, 1:GPIO, 2:exGPIO 3:mclk) // {PDN, Vol_High, 1},
Line 2165: 01-01 00:18:59.983126 3203 3203 D [ 176.585907] (1)[3203:initCamdevice][name:imgsensor_hw&]: [imgsensor]sensor_idx = 0, pin=2, pin_state_on=0, hw_id =1(0:PMIC, 1:GPIO, 2:exGPIO 3:mclk) // {RST, Vol_Low, 10},
Line 2171: 01-01 00:19:00.133413 3203 3203 D [ 176.736194] (1)[3203:initCamdevice][name:imgsensor_hw&]: [imgsensor]sensor_idx = 0, pin=5, pin_state_on=7, hw_id =0(0:PMIC, 1:GPIO, 2:exGPIO 3:mclk) // {DOVDD, Vol_1800, 5},
Line 2174: 01-01 00:19:00.190700 3203 3203 D [ 176.793481] (1)[3203:initCamdevice][name:imgsensor_hw&]: [imgsensor]sensor_idx = 0, pin=3, pin_state_on=9, hw_id =0(0:PMIC, 1:GPIO, 2:exGPIO 3:mclk) // {AVDD, Vol_2800, 5},
Line 2186: 01-01 00:19:00.212471 3203 3203 D [ 176.815252] (0)[3203:initCamdevice][name:imgsensor_hw&]: [imgsensor]sensor_idx = 0, pin=4, pin_state_on=3, hw_id =0(0:PMIC, 1:GPIO, 2:exGPIO 3:mclk) // {DVDD, Vol_1200, 5},
Line 2191: 01-01 00:19:00.243363 3203 3203 D [ 176.846144] (1)[3203:initCamdevice][name:imgsensor_hw&]: [imgsensor]sensor_idx = 0, pin=6, pin_state_on=9, hw_id =0(0:PMIC, 1:GPIO, 2:exGPIO 3:mclk) // {AFVDD, Vol_2800, 5},
Line 2194: 01-01 00:19:00.262478 3203 3203 D [ 176.865259] (1)[3203:initCamdevice][name:imgsensor_hw&]: [imgsensor]sensor_idx = 0, pin=1, pin_state_on=0, hw_id =1(0:PMIC, 1:GPIO, 2:exGPIO 3:mclk) // {PDN, Vol_Low, 5},
Line 2195: 01-01 00:19:00.267541 3203 3203 D [ 176.870322] (1)[3203:initCamdevice][name:imgsensor_hw&]: [imgsensor]sensor_idx = 0, pin=2, pin_state_on=11, hw_id =1(0:PMIC, 1:GPIO, 2:exGPIO 3:mclk) // {RST, Vol_High, 5}
5. 查看原理图,发现afvdd与tp的供电脚接在一起,都是VLDO28_PMU
TP功能正常
但是这个TP(nt36xxx)笔记特殊,是incell屏(tp与lcm同一个ic),tp供电不走VLDO28_PMU,而是由incell屏的5.4v电压分出来的
故tp代码中没有VLDO28_PMU使能的操作,尝试加上: --> af ok!
kernel-4.4/drivers/input/touchscreen/mediatek/nt36xxx/nt36xxx.c
+ #define FTS_POWER_SOURCE_CUST_EN
+ #ifdef FTS_POWER_SOURCE_CUST_EN
+ int fts_power_init(void)
{
int ret;
/*set TP volt*/
tpd->reg = regulator_get(tpd->tpd_dev, "vtouch");
ret = regulator_set_voltage(tpd->reg, 2800000, 2800000);
if (ret != 0) {
NVT_ERR("[POWER]Failed to set voltage of regulator,ret=%d!", ret);
return ret;
}
ret = regulator_enable(tpd->reg);
if (ret != 0) {
NVT_ERR("[POWER]Fail to enable regulator when init,ret=%d!", ret);
return ret;
}
return 0;
}
void fts_power_suspend(void)
{
regulator_disable(tpd->reg);
}
int fts_power_resume(void)
{
int ret = 0;
ret = regulator_enable(tpd->reg);
return ret;
+ }
+ #endif
static int nvt_local_init(void)
{
int ret = 0;
NVT_LOG("start\n");
+ #ifdef FTS_POWER_SOURCE_CUST_EN
+ if (fts_power_init() != 0)
+ return -1;
+ #endif
...
}
static void nvt_ts_suspend(struct device *dev)
{
...
+ #ifdef FTS_POWER_SOURCE_CUST_EN
+ fts_power_suspend();
+ #endif
NVT_LOG("end\n");
return;
}
static void nvt_ts_resume(struct device *dev)
{
...
+ #ifdef FTS_POWER_SOURCE_CUST_EN
+ fts_power_resume();
+ #endif
NVT_LOG("end\n");
return;
}
6. 分析总结:
查看开机log中af的注册log
01-01 00:16:08.795211 1 1 I [ 5.397991].(2)[1:swapper/0][name:main_lens&]: MAINAF [AF_i2c_probe] Start
01-01 00:16:08.796102 1 1 I [ 5.398882].(2)[1:swapper/0][name:main_lens&]: MAINAF [Register_AF_CharDrv] Start
01-01 00:16:08.798672 1 1 I [ 5.401452].(2)[1:swapper/0][name:main_lens&]: MAINAF [Register_AF_CharDrv] End
01-01 00:16:08.799621 1 1 I [ 5.402401].(2)[1:swapper/0][name:main_lens&]: MAINAF [AFRegulatorCtrl] AFIOC_S_SETPOWERCTRL regulator_put (null)
01-01 00:16:08.801305 1 1 W [ 5.404085].(2)[1:swapper/0][name:core&]: MAINAF supply vcamaf not found, using dummy regulator
01-01 00:16:08.803231 1 1 I [ 5.406011].(2)[1:swapper/0][name:main_lens&]: MAINAF [AFRegulatorCtrl] [Init] regulator_get ce425b00
01-01 00:16:08.804408 1 1 I [ 5.407188].(2)[1:swapper/0][name:main_lens&]: MAINAF [AF_i2c_probe] Attached!!
kernel-4.4/drivers/misc/mediatek/lens/main/main_lens.c
module_init(MAINAF_i2C_init);
static int __init MAINAF_i2C_init(void)
{
platform_device_register(&g_stAF_device)
platform_driver_register(&g_stAF_Driver)
static struct platform_driver g_stAF_Driver = {
.probe = AF_probe,
static int AF_probe(struct platform_device *pdev)
{
return i2c_add_driver(&AF_i2c_driver);
static struct i2c_driver AF_i2c_driver = {
.probe = AF_i2c_probe,
static int AF_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
...
#if !defined(CONFIG_MTK_LEGACY)
AFRegulatorCtrl(0); // 跑这里,这里与37m有区别,37m这里是注释掉的不会跑
#endif
LOG_INF("Attached!!\n");
return 0;
}
static int AF_Open(struct inode *a_pstInode, struct file *a_pstFile)
{
...
#if !defined(CONFIG_MTK_LEGACY)
AFRegulatorCtrl(1);
#endif
...
}
static int AF_Release(struct inode *a_pstInode, struct file *a_pstFile)
{
...
#if !defined(CONFIG_MTK_LEGACY)
AFRegulatorCtrl(2);
#endif
...
}
/*
根据tp代码,使能pmu 2.8v电压有三步
tpd->reg = regulator_get(tpd->tpd_dev, "vtouch");
regulator_set_voltage(tpd->reg, 2800000, 2800000);
regulator_enable(tpd->reg);
*/
void AFRegulatorCtrl(int Stage)
{
LOG_INF("AFIOC_S_SETPOWERCTRL regulator_put %p\n", regVCAMAF);
if (Stage == 0) {
if (regVCAMAF == NULL) {
struct device_node *node, *kd_node;
node = of_find_compatible_node(NULL, NULL, "mediatek,CAMERA_MAIN_AF");
if (node) {
kd_node = lens_device->of_node;
lens_device->of_node = node;
// AF_i2c_probe()的时候跑到这里,但是打印了下面这条log:
// 01-01 00:16:08.801305 1 1 W [ 5.404085].(2)[1:swapper/0][name:core&]: MAINAF supply vcamaf not found, using dummy regulator
regVCAMAF = regulator_get(lens_device, "vcamaf");
LOG_INF("[Init] regulator_get %p\n", regVCAMAF);
lens_device->of_node = kd_node;
}
}
} else if (Stage == 1) {
01-01 00:19:05.810434 3208 3208 I [ 182.413215] (2)[3208:3ATHREAD][name:main_lens&]: MAINAF [AF_Open] Start
01-01 00:19:05.810463 3208 3208 I [ 182.413244] (2)[3208:3ATHREAD][name:main_lens&]: MAINAF [AFRegulatorCtrl] AFIOC_S_SETPOWERCTRL regulator_put ce425b00
01-01 00:19:05.810477 3208 3208 I [ 182.413258] (2)[3208:3ATHREAD][name:main_lens&]: MAINAF [AFRegulatorCtrl] regulator_is_enabled 1
01-01 00:19:05.810489 3208 3208 I [ 182.413270] (2)[3208:3ATHREAD][name:main_lens&]: MAINAF [AFRegulatorCtrl] AF Power on
01-01 00:19:05.810502 3208 3208 I [ 182.413283] (2)[3208:3ATHREAD][name:main_lens&]: MAINAF [AF_Open] End
01-01 00:19:05.810537 3208 3208 I [ 182.413318] (2)[3208:3ATHREAD][name:main_lens&]: MAINAF [AF_SetMotorName] Set Motor Name : FM50AF (10)
01-01 00:19:05.810562 3208 3208 I [ 182.413343] (2)[3208:3ATHREAD][name:main_lens&]: MAINAF [AF_Release] Start
01-01 00:19:05.810575 3208 3208 D [ 182.413356] (2)[3208:3ATHREAD][name:FM50AF&]: FM50AF_DRV [FM50AF_Release_Main
if (regVCAMAF != NULL && g_regVCAMAFEn == 0) {
int Status = regulator_is_enabled(regVCAMAF);
LOG_INF("regulator_is_enabled %d\n", Status);
if (!Status) {
regulator_set_voltage(regVCAMAF, 2800000, 2800000); // 没有跑这里
regulator_enable(regVCAMAF);
} else {
LOG_INF("AF Power on\n"); // AF_Open()的时候没有使能2.8v电压,跑到else这个分支
}
}
} else {
if (regVCAMAF != NULL && g_regVCAMAFEn == 1) {
int Status = regulator_is_enabled(regVCAMAF);
LOG_INF("regulator_is_enabled %d\n", Status);
if (Status) {
regulator_disable(regVCAMAF);
}
}
}
}
#endif
处理方案:
总结 :
案例九 :
现象 :
平台 : androidN,MTK6737
排查过程: 1.
2.
3.
4.
处理方案:
总结 :
MTK平台AF调试日志
最新推荐文章于 2023-08-04 15:25:13 发布