MTK调试-PLsensor
1、流程步骤
1.1 准备工作
1.1.1 项目配置确认
1)了解基本配置的信息,包括用的哪颗物料,是否需要做兼容。
2)查看原理图和datesheet,如ap3216原理图如下:
原理图上可以得知该sensor是常供电,代码上无线做上电操作。
Datesheet上可知所用IC的I2C slave 地址。如ap3216c地址是: 0x1e (0x3c>>1) ;
(有时,有些IC的地址是可以在出厂时根据客户需求修改的,用于防止同一个I2C总线上有地址冲突; 所以若有供应商咨询项目上的I2C地址是多少,若项目上没有冲突,就直接让他们使用默认地址即可,若有冲突,就给他们选一个不冲突的。)
1.1.2 LCM驱动文件配置
1)Alps/mediatek/custom/common/kernel/alsps/drivername //driver ic的代码
2)Alps/mediatek/config/$(project)/Projectconfig.mk //确保alsps参与编译
MTK_SENSOR_SUPPORT =yes
CUSTOM_KERNEL_ALSPS= drivername
MTK_AUTO_DETECT_ALSPS=yes/no(兼容宏控)
3)Alps/mediate/factory/src/test/ ftm_alsps.c & ftm_ps_cali.c //工厂模式测试和校准功能
4)Alps/mediatek/config/$(project)/inc/Custom_NvRam_LID.h
Alps/mediatek/config/$(project)/inc/Custom_NvRam_data_item.h
Alps/mediatek/config/$(project)/inc/custom_cfg_module_file.h
Alps/mediatek/config/$(project)/inc/custom_cfg_module_default.h
Alps/mediatek/config/$(project)/inc/CFG_file_info_custom.h
Alps/mediatek/custom/common/cgen/CFG_file_info.c
Alps/mediatek/custom/common/cgen/ cfgdefault/CFG_PS_Default.h
Alps/mediatek/custom/common/cgen/cfgfileinc/CFG_PS_File.h
//校准功能的nvram分区的添加
5)alps/mediate/external/proximity_sensor/nvram_proximity.c
Alps/mediate/config/mt6572/init.rc
//nvram分区的校准值的读出,写入到硬件寄存器
1.2 PLsensor驱动
Alps/mediatek/custom/common/kernel/alsps/drivername文件夹中包含了所用的驱动文件,此处以ap3216为例。
1.2.1 驱动加载
1)非兼容方式(单个sensor):CUSTOM_KERNEL_ALSPS= XXXXX
static int __init AP3216C_init(void)
{
APS_FUN();
i2c_register_board_info(hw->i2c_num, &i2c_ap3216c, 1);
if(platform_driver_register(&AP3216C_alsps_driver))
{
APS_ERR("failed to register driver");
return -ENODEV;
}
return 0;
}
2)兼容方式:CUSTOM_KERNEL_ALSPS= XXXXX_auto YYYYYY_auto;MTK_AUTO_DETECT_ALSPS=yes
驱动IC的模块入口函数只需调用hwmsen_alsps_sensor_add
static int __init AP3216C_init(void)
{
APS_FUN();
i2c_register_board_info(hw->i2c_num, &i2c_ap3216c, 1);
hwmsen_alsps_sensor_add(&AP3216C_init_info);
return 0;
}
static struct sensor_init_info AP3216C_init_info = {
.name = "AP3216C",
.init = AP3216C_local_init,
.uninit = AP3216C_remove,
};
而平台驱动的加载在hwmsen_dev.c中实现
#if defined(MTK_AUTO_DETECT_ALSPS)
if(platform_driver_register(&alsps_sensor_driver))
{
HWM_ERR("failed to register alsps_sensor driver");
return -ENODEV;
}
#endif
其中i2c_register_board_info注册了设备的信息到内核的设备链表,static struct i2c_board_info __initdata i2c_ap3216c={ I2C_BOARD_INFO(AP3216C_DEV_NAME, 0x3C>>1)}; 信息包括了名字和设备的地址。
1.2.2 alsps参数配置
static struct alsps_hw cust_alsps_hw = {
.i2c_num = 1, //表示i2c适配器号,有些driver ic 写死了,没有用到。
.polling_mode_ps =0, //0
.polling_mode_als =1,
.power_id = MT65XX_POWER_NONE, //没有使用到。
.power_vol = VOL_DEFAULT, //没有使用到。
.i2c_addr = {0x3C, 0x38, 0x3A, 0x00}, //没有使用到。
.als_level = { 5, 10, 20, 30, 50, 60, 80, 120, 160, 240, 320, 400, 800, 1600, 4000},
.als_value = {10, 20, 40, 40, 160, 160, 225, 320, 640, 640, 1280, 1280, 2600, 2600, 10240, 10240},
.ps_threshold_high = 60,
.ps_threshold_low = 50,
};
polling_mode_ps polling_mode_als 表示光感和距离感应响应方式。(0表示中断,1表示轮询)若为中断需要在dct中进行配置,如下:
als_level:表示从光感寄存器获取的原始raw数据
als_value:对应于als_level的值,上报给HAL层的LUX值。
比如:5<als_level<10 将对应als_value 的20,其他以此类推。当需要调整光感的再某一范围的灵敏度和改变等级时,可以修改这些配置参数。
ps_threshold_high,ps_threshold_low:表示远离和靠近的门限值,在强制开启校准宏控后,该值已经没有作用。
\alps\wingcust\$(project)\base\custom\kernel\alsps\ap3216c \ap3216c_mtk.c
#define PS_DETECTED_THRES 180 // close
#define PS_UNDETECTED_THRES 80 // far
上面两个宏控,就是采样的经验值(接近/离开);psensor是一个非常难调试的sensor,受影响的因素太多。但是主要能归结为两方面:
1)结构:结构上的硅胶套所需要的开孔的直径也会影响psensor。
2)一致性:psensor的一致性是影响最大的因素,因为芯片受结构,TP等影响,所产生的底噪值(底噪值是psensor没有遮挡情况下所读取到的值)都不一致,所以对于psensor的判断有很大的影响。
所以需要通过项目30台机器采样后;分别将3cm diff 数据/ 5cm diff 数据 做平均后得到。(3cm diff = 灰卡3cm遮挡采样RAW数据 - 底噪)
Framework层(针对背光亮度调节的数组):\alps\frameworks\base\core\res\res\values\config.xml
<integer-array name="config_autoBrightnessLevels">
<item>16</item>
<item>32</item>
......
<item>300</item>
<......
<item>8000</item>
<item>10000</item>
</integer-array>
<integer-array name="config_autoBrightnessLcdBacklightValues">
<item>30</item>
......
<item>70</item>
<item>80</item>
<item>102</item>
......
<item>255</item>
</integer-array>
数组config_autoBrightnessLevels 的成员单位是LUX ,用于比较从KERNEL 上报的LUX处于哪个一个LEVEL 等级,而这个LEVEL等级会经过运算后映射成config_autoBrightnessLcdBacklightValues
1.2.3 清除校准数据:将数据从nvram中删除, ps显示的值是做了30的平均,表示为距离感应的底噪值。低噪一般要求维持在50左右,不能超过100。
Als是光感的值,测试时可以看到快速的变化,在强光下值越大,弱光下值越小。
PS是距离感应的值,far表示远离 close表示接近。遮挡住手ps表现为靠近,测试通过则显示pass
SRN表示读取10次距离感应值的平均。
2、工厂模式
在factory.c中调用了各个模块的初始化函数,函数中主要是构造了相应模块的结构体。
并用ftm_register函数将模块放入数组ftm_mods中,以便外部能通过该数组找到对应的模块。entry是模块主要实现函数。
Ps_cali_init
mod = ftm_alloc(ITEM_PS_CALI, sizeof(struct ps_cali_data)); //分配一个结构体空间
dat = mod_to_ps_cali_data(mod); //把结构体空间扩大转换
memset(dat, 0x00, sizeof(*dat));
ps_cali_init_priv(&dat->ps_cali);
ret = ftm_register(mod, ps_cali_entry, (void*)dat); // ps_cali_entry为入口函数
ftm_register(struct ftm_module *mod, ftm_entry_fn entry, void *priv)
{
......
mod->test_result = FTM_TEST_UNKNOWN;
mod->visible = true;
mod->entry = entry;
mod->priv = priv;
ftm_mods[mod->id] = mod;
return 0;
}
ps_cali_entry
àpthread_create(&dat->update_thd, NULL, ps_cali_update_iv_thread, priv);
àps_cali_update_iv_thread
àps_cali_open(lps)
à ioctl(ps_cali->fd, ALSPS_SET_PS_MODE, &flags)
àps_calibration(lps))
AP3216C_enable_ps(obj->client, 1);
ap3216c_read_data_for_cali(obj->client,&ps_cali_temp);
à ps_write_nvram(lps)
NVM_GetFileDesc(file_lid, &rec_size, &rec_num, ISWRITE)
write(fd.iFileDesc, &hwmonPs , rec_size*rec_num)
à ps_cali_update_info(lps)
......
3、经验总结
Psensor的直观表现就是打电话靠近离开产生的亮灭屏效果。一般出现的问题就下面几类
1)打电话不灭屏:看sensor有没有工作,有没有外部中断过来,读取的值是否小于我们设定的门限值
2)打电话灭屏,不再亮屏:更新后的代码,打电话直接灭屏不在亮,看是否安装了硅胶套。
3)打电话概率性的不亮屏:
Lsensor补充:采样方法
1)经验值如何采样:
公司要求:主要是参考了华为的要求:3厘米灭屏;5厘米亮屏;其他项目可以遵循这个要求。
经验值采样步骤:
>准备30台好的项目机器,(至少也要10台,否则没有意义);
>进工厂模式代码,将当前PS的显示值做一个30次的求平均,让数据不会变化太快;
>版本灌进测试机器。进入工厂模式下-->单项测试-->光传感器距离传感器 菜单
>分别测试:底噪 //在没有任何遮挡情况
3厘米灰卡 //使用灰卡在机器3CM处遮挡
5厘米灰卡 //使用灰卡在机器5CM处遮挡
并记录在附件的XLS表格中,用于后续分析。
>将3cm/5cm 灰卡遮挡的数据分别减去底噪(无遮挡),获取到的DIFF数据,并将致谢数据进行平均以及求公差。
>一般认为,求出的3cm Diff 平均就是接近的经验值(PS_DETECTED_THRES)。求出的5cm Diff 平均就是离开的经验值(PS_UNDETECTED_THRES)。
2)采样数据简单分析:这里的分析,主要是做一个数据的平均计算,公差,以及异常数据分析
>经验值的平均计算: 就是简单DIFF 数据平均。
我们使用这个平均值作为经验值的前提是:我们认为,在采样到一定机器数据样品下,这些采样到的机器能代表绝大多数的机器状态。它的平均值,可以代表大部分的机器。
>公差 : 对同一列的DIFF数据做公差,从公差上,我们可以看出这批机器的一致性是否比较好。公差越小,一致性越好。
>若有比较异常的数据,需要确认是否组装问题,还是PCB板问题,还是IC本身的误差。
做法:可以把机器拆开,去掉结构件的所有影响,然后再确认一次数据,若数据有改善,说明结构件影响比较大,否则,PCB 或IC 的问题。