用TP做贴脸熄屏的方法

         手机上一般都用距离感应器来做通话时的贴脸熄屏,而现在的TP芯片一般也都具有了这个功能,所以如果TP能够实现贴脸熄屏的话,将可以省下距离感应器的成本。其原理就是通话时打开TP的电容感应,通过脸的靠近和移动来检测TP电容的变化,从而判断人脸跟听筒的距离,调整LCD背光的亮灭,在通话断开时关闭TP的此功能即可。

        MELFAS的芯片此项功能做法如下:

(1)首先定义两个全局变量:

[cpp]  view plain copy
  1. unsigned char ps_data_state_value;      //从TP的PS寄存器读出的当前是否贴脸的判断值,只可读  
  2. unsigned char ps_onoff_state_control;   //使能TP做PS功能的开关,可读可写  

(2)在TP的probe函数中用device_create_file分别创建两个设备属性,名字分别是:“/sys/class/mtk-tpd/device/proximity_sensor”和“/sys/class/mtk-tpd/device/proximity_sensor_state”,这两个变量只需上层open即可用来跟上层进行控制通讯,前者可读可写,上层用来对TP的PS功能的使能和禁止进行控制,通话时写1,通话断开时写0;后者仅可读,当通话时TP的PS功能打开时,该值为1表明贴脸了要关掉LCD背光,该值为0表明脸移开要打开LCD背光。

        上面两个属性对应的show/store函数如下,分别在read/write时被调用,需要用到的寄存器是0x01和0x17。

[cpp]  view plain copy
  1. static ssize_t show_proximity_sensor(struct device *dev, struct device_attribute *attr, char *buf)  //显示TP PS功能是否打开  
  2. {  
  3.     static unsigned char temp = 2;  
  4.         if(temp != ps_onoff_state_control){  
  5.                 printk("proximity_sensor_show: ps_onoff_state_control=%d\r\n", ps_onoff_state_control);  
  6.                 temp = ps_onoff_state_control;  
  7.         }  
  8.         return sprintf(buf, "%d\n", ps_onoff_state_control);  
  9. }  
  10.   
  11. static ssize_t store_proximity_sensor(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)  
  12. {  
  13.     printk("store_proximity_sensor ,*buf is %s \r\n",buf);      //上层对TP PS的使能控制  
  14.     U8 RegValue;  
  15.   
  16.      if(buf != NULL && size != 0)   
  17.      {  
  18.         printk("store_proximity_sensor no null  \r\n");  
  19.         if('0' == *buf) {               //通话断开禁止功能  
  20.             printk("DISABLE_CTP_PS buf=%d,size=%d\n", *buf, size);  
  21.             mfs_i2c_read_single_reg(0x01,&RegValue);  
  22.             msleep(200);  
  23.             RegValue &= 0xdf;  
  24.             mfs_i2c_write_single_reg(0x01,RegValue);    //该功能的寄存器位置0  
  25.             msleep(500);  
  26.             ps_onoff_state_control = 0;         //该功能开关状态置0  
  27.             ps_data_state_value = 0;            //该功能只是状态置0  
  28.         }  
  29.         else if('1' == *buf){               //通话使能该功能时  
  30.             printk("ENABLE_CTP_PS buf=%d,size=%d\n", *buf, size);  
  31.             mfs_i2c_read_single_reg(0x01,&RegValue);  
  32.             msleep(200);  
  33.             RegValue |= 0x20;  
  34.             mfs_i2c_write_single_reg(0x01,RegValue);    //该功能的寄存器位置1  
  35.             msleep(500);  
  36.             ps_onoff_state_control = 1;         //该功能开关状态置1  
  37.         }  
  38.      }  
  39.   
  40.         return size;  
  41. }  
  42.   
  43. static ssize_t show_proximity_sensor_state(struct device *dev, struct device_attribute *attr, char *buf) //显示TP PS的工作指示状态  
  44. {  
  45.     static unsigned char temp = 2;  
  46.         if(temp != ps_data_state_value){  
  47.                 printk("show_proximity_sensor_state: ps_data_state_value=%d\n\n", ps_data_state_value);  
  48.                 temp = ps_data_state_value;  
  49.         }  
  50.         return sprintf(buf, "%d\n", ps_data_state_value);  
  51. }  

(3)上面着重使能的控制,下面讲述TP PS状态的指示。当通话时TP的该功能激活后,TP也处于一种中断状态,屏表面电容的变化都会触发中断,让TP进行相应的处理,所以在TP的中断处理函数中,加上如下处理:

[cpp]  view plain copy
  1. uint8_t ProximityEn;        //读TP工作状态的PS位是否激活  
  2. uint8_t ProximityDecetVal;      //读TP的PS反馈值   
  3. mfs_i2c_read_single_reg(0x01,&ProximityEn);  
  4. if((ProximityEn&0x20)!=0)       //只有PS功能激活后,才去读反馈值  
  5. {  
  6.                mfs_i2c_read_single_reg(0x17,&ProximityDecetVal);  
  7.                if(ProximityDecetVal == 1) // close to  
  8.                {  
  9.                    printk("TP_PROXIMITY_SENSOR_DEFINE '1'  close to by zhangcheng\n");  
  10.                    ps_data_state_value = 1;     //人脸接近LCD,置1  
  11.                }  
  12.                else if(ProximityDecetVal == 0) // leave  
  13.                {  
  14.                    printk("TP_PROXIMITY_SENSOR_DEFINE '0'  leave by zhangcheng\n");  
  15.                    ps_data_state_value = 0;     //人脸离开LCD,置0  
  16.                }  
  17. }  

完毕。

         需要注意的是:偶尔会出现贴脸通话一段时间,移开手机后,LCD不会重亮,原因是手机睡眠后导致TP也会睡眠,这样就算拿开手机后TP也不会相应外部的电容变化。所以解决方法是:通话过程中贴脸熄屏激活后,睡眠时不要走正常的睡眠处理,PASS掉就行了。

         另外一个需要注意的是:操作手机的睡眠和唤醒时,偶尔会出现TP不能使用,要睡眠再唤醒后才可以使用。此时一个可能的原因是LCD跟TP的上电先后顺序可能会影响到。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值