一.alsps的初始化函数和重要结构体

epl2182_init //

Epl2182.c (kernel-3.10\drivers\misc\mediatek\alsps\epl2182-new)
    struct alsps_hw *hw = get_cust_alsps_hw(); //得到配置和硬件信息
        i2c_register_board_info(hw->i2c_num, &i2c_EPL2182, 1); //注册I2C信息
            list_add_tail(&devinfo->list, &__i2c_board_list); //加入到__i2c_board_list链表中
        alsps_driver_add(&epl2182_init_info); // alsps_local_init函数加入
            alsps_init_list[i] = obj; //加入到alsps_init_list[i] 数组中,以备后面用
 
alsps_local_init //这个函数在alsps核心调用,下面有分析
    get_cust_alsps_hw();  //得到配置和硬件信息
        epl2182_power(hw, 1); //上电
           //mtk专门的上电函数(pmic.c),很多模块都在用,if(hw->power_id != POWER_NONE_MACRO) 会进行上电操作,这里只是一个赋值操作power_on = on;
            hwPowerOn(hw->power_id, hw->power_vol, "EPL2182")
        i2c_add_driver(&epl2182_i2c_driver)  //I2C注册driver
 
i2c_driver 结构体:
static struct i2c_driver epl2182_i2c_driver =
{
    .probe      = epl2182_i2c_probe,
    .remove     = epl2182_i2c_remove,
    .detect     = epl2182_i2c_detect,
    .suspend    = epl2182_i2c_suspend,
    .resume     = epl2182_i2c_resume,
    .id_table   = epl2182_i2c_id,
    .driver = {
        .name           = EPL2182_DEV_NAME,
    },
};
 
 
 
二.I2C的alsps的probe函数
通过i2c_driver 与adapter的匹配调用epl2182_i2c_probe
epl2182_i2c_probe
    epl2182_get_addr(obj->hw, &obj->addr); //得到I2C的地址
    INIT_WORK(&obj->eint_work, epl2182_eint_work); //初始化中断工作任务
        epld = g_epl2182_ptr;   //得到epl2182私有数据
        elan_epl2182_I2C_Read(epld->client,REG_16,R_TWO_BYTE,0x02,read_data);  //i2c的读函数,读channel1,ps的数据
        elan_epl2182_I2C_Read(epld->client,REG_13,R_SINGLE_BYTE,0x01,read_data); //读取到PS的中断状态,0或者1
        ps_report_interrupt_data 
            ps_data_report(cxt->idev,value,3);
                input_report_rel(dev, EVENT_TYPE_PS_VALUE, (value+1));  //输入子系统上报数据
        input_report_rel(dev, EVENT_TYPE_PS_STATUS, status);
        input_sync(dev); 
    INIT_WORK(&obj->data_work, epl2182_check_ps_data);  //也是上报数据
    elan_epl2182_I2C_Write(client,REG_0,W_SINGLE_BYTE,0x02, EPL_S_SENSING_MODE); //把光照转换到电压的时间
    elan_epl2182_I2C_Write(client,REG_9,W_SINGLE_BYTE,0x02,EPL_INT_DISABLE); //把中断清零
    epl2182_init_client
        if(obj->hw->polling_mode_ps == 0) //这里是中断模式
        epl2182_setup_eint(client) //
            g_epl2182_ptr = obj;  //后面有用到epl2182的属性
        hw8k_init_device
            epl2182_i2c_client=client; //后面有用到
    misc_register(&epl2182_device) //注册混杂设备
    als_ctl.open_report_data= als_open_report_data;  //als_control的赋值
    als_ctl.enable_nodata = als_enable_nodata;
    als_ctl.set_delay  = als_set_delay;
 
 
混杂设备结构体:
static struct miscdevice epl2182_device =
{
    .minor = MISC_DYNAMIC_MINOR,
    .name = "als_ps",
    .fops = &epl2182_fops,
};
static struct file_operations epl2182_fops =
{
    .owner = THIS_MODULE,
    .open = epl2182_open,
    .release = epl2182_release,
    .unlocked_ioctl = epl2182_unlocked_ioctl,
};
 
 
 
三.alsps核心
在alsps.c中是alsp的上层部分,在epl2182_init之后调用
static struct platform_driver alsps_driver =
{
.probe      = alsps_probe,
.remove     = alsps_remove,    
.suspend    = alsps_suspend,
.resume     = alsps_resume,
.driver     = 
{
.name = ALSPS_PL_DEV_NAME,
        #ifdef CONFIG_OF
.of_match_table = alsps_of_match,
#endif
}
}; //平台driver结构体
 
alsps_init
    platform_driver_register(&alsps_driver) //注册平台驱动,在mt_devs.c中有平台device:platform_device alsps_sensor
        
alsps_probe  //匹配后调用它
    alsps_context_alloc_object
        alsps_context *obj = kzalloc(sizeof(*obj), GFP_KERNEL); //分配alsps_context 结构体,保存了很多属性
      
        初始化obj结构体,比如work的初始化:als_work_func,ps_work_func;定时器初始化,执行函数:als_poll,ps_poll分别执行schedule_work(&obj->report_als); schedule_work(&obj->report_ps);
        alsps_real_driver_init //初始化实际的alsps
            alsps_real_driver_init //
                alsps_init_list[i]->init(); //这就是具体alsps驱动注册的init函数,在这里调用了
    alsps_factory_device_init    //is_use_common_factory被设置为true,就会进行misc_register(&alsps_factory_device),这里不用。
    alsps_input_init //输入子系统的初始化,注册
        input_allocate_device
        input_register_device
    
 
 
四.应用读取sensor数据:
   als_store_active 和 ps_store_active启动sensor,然后上报数据,PS一般用中断,als一般用轮询!
 
 
 
五.Light sensor level和value的设置

[DESCRIPTION]
    Light sensor level和value的设置
[PLATFORM]
    MT6575 MT6577 MT6589
[SOLUTION]
    Als_level是从sensor读到的raw dataals_value是由als_level转换为上报android的值,以
ltr559为例:在cust_alsps.c中 :

该值要客制化,请联系sensor vender提供。

[DESCRIPTION]

  由于结构限制或者传感器本身原因,工厂模式下检测到ic出来的值变化不够明显,可检测的范围小等。导致自动背光效果不明显。

[SOLUTION]

      硬件上没有方法改动的话,建议合理的修改,cust_alsps.c中的.level和.value这2个数组的值,driver里处理数据的原理:
       从driver里传感器IC寄存器出来的数据是level值,根据此level值参照上述2个数组的对应关系,由level数组的下标取到.value数组的下标对应的值,然后上报value值给工厂模式和上层看到。

      所以需要您调cust_alsps.c里的那2个数组,如果是被遮挡而引起变化范围变小的话,应该是寄存器出来的level变小了,所以建议把cust-als.c里的level也相应的减小,value不变,则应该有所改善。多试几组减小.level的情况。

另外如果需要更细腻的背光等级,可以适当的把这2个数组加大,取值更连续一些。(这个映射还与android的value(LUX)--->255级背光的映射有关,也不是连续的)

请参考 frameworks\base\core\res\res\values\config.xml

六.兼容

当遇到两个sensor同一个i2c地址,只启用一个的时候,可以在注册的时候该一个地址,然后在probe中改回来就可以了。

 通过工程模式可以看到sensor的raw 打他,通过工厂测试模式可以看到所有senso人上报的数值。

 
 
七.工程测试模式中sensor的读取数据流程
    1.输入*987*0#进行测试,一般用于产线的测试
     epl2182_unlocked_ioctl   : 用的是poll(ps)
 
      2.*#*#3646633#*#*这样是可以读到sensor的原始数据,可以调试sensor是否有遮挡            
        epl2182_unlocked_ioctl 用的是poll
 
 
 
 
八.把ps改成轮询方式
   现在的机制是:
         1. PS单独开启的时候用中断;
          2.单独ALS是轮询
          3.PS与ALS一起开启的时候在als_get_data中轮询ALS,如果是中断模式还要轮询PS,因为轮询als的时候ps不会产生中断
 
   把PS也改下轮询:
         因为poll的时候会互相干扰,产生竞争,导致数据闪动,需要信号量来控制
        als_get_data
         mutex_lock(&epl2182_poll_mutex);
         ...............
         mutex_unlock(&epl2182_poll_mutex);
 
       ps_get_data
                       mutex_lock(&epl2182_poll_mutex);
                         ...............
                        mutex_unlock(&epl2182_poll_mutex);
 
     PS在打电话的时候不能休眠:加睡眠锁
       目前的driver架构是对于没有使用中断模式的距离传感器(cust_alsps.c .ps_polling=1)在驱动的i2c_probe里初始化一个wake lock,在Operate函数的ENABLE分支,如果是

enable的话就wake_lock(your_lock),disable的话就wake_unlock(your_lock)

 
 
 

Android ALSPS驱动分析的更多相关文章

  1. 【转】android电池(五):电池 充电IC(PM2301)驱动分析篇

    关键词:android 电池  电量计  PL2301任务初始化宏 power_supply 中断线程化 平台信息:内核:linux2.6/linux3.0系统:android/android4.0  ...

  2. 【转】android电池(四):电池 电量计(MAX17040)驱动分析篇

    关键词:android 电池  电量计  MAX17040 任务初始化宏 power_supply 平台信息:内核:linux2.6/linux3.0系统:android/android4.0 平台: ...

  3. Android USB驱动源码分析(-)

    Android USB驱动中,上层应用协议里最重要的一个文件是android/kernel/drivers/usb/gadget/android.c.这个文件实现USB的上层应用协议. 首先包含了一些 ...

  4. android电池(四):电池 电量计(MAX17040)驱动分析篇【转】

    本文转载自:http://blog.csdn.net/xubin341719/article/details/8969369 电池电量计,库仑计,用max17040这颗电量IC去计量电池电量,这种方法 ...

  5. Qualcomm Android display架构分析

    Android display架构分析(一) http://blog.csdn.net/BonderWu/archive/2010/08/12/5805961.aspx http://hi.baidu ...

  6. 高通Android display架构分析

    目录(?)[-] Kernel Space Display架构介绍 函数和数据结构介绍 函数和数据结构介绍 函数和数据结构介绍 数据流分析 初始化过程分析 User Space display接口 K ...

  7. s5k4ba摄像头驱动分析

    注释: 本驱动是基于S5PV310的,但是全天下的摄像头驱动都是采用V4L2,因此驱动框架流程基本差不多.其中fimc_init_camera()函数会回调.init函数,该函数主要就是通过IIC总线 ...

  8. Android源码分析(六)-----蓝牙Bluetooth源码目录分析

    一 :Bluetooth 的设置应用 packages\apps\Settings\src\com\android\settings\bluetooth* 蓝牙设置应用及设置参数,蓝牙状态,蓝牙设备等 ...

  9. Android源码分析(八)-----系统启动流程&IPC简述

    一 :系统启动流程图 从下往上依次启动linux kernel -->zygote-->SystemServer-->NativeService-->AndroidServic ...

随机推荐

  1. Docker结合.Net Core初步使用

    Docker是一项比较流行的容器化技术,可以让开发者将应用以及应用依赖的环境,依赖包一起打包到容器中,然后部署容器到生产环境就可以了,解决了应用程序部署到不同服务器环境带来的问题(很多开发人员都遇到过 ...

  2. 线程池SingleThreadPool

    只有一个核心线程,当被占用时,其他的任务需要进入队列等待 public class MainActivity extends AppCompatActivity { @Override protect ...

  3. Mac 搭建 Redis 集群

    date: 2020-09-24 16:24:00 updated: 2020-09-24 17:30:00 Mac 搭建 Redis 集群 参考文档 摘要 安装docker brew cask in ...

  4. Guava - 拯救垃圾代码,写出优雅高效,效率提升N倍

    最近在看一个同学代码的时候,发现代码中大量使用了 Google 开源的 Guava 核心库中的内容,让代码简单清晰了不少,故学习分享出 Guava 中我认为最实用的功能. Guava 项目是 Goog ...

  5. C1. Pokémon Army (easy version) 解析(DP)

    Codeforce 1420 C1. Pokémon Army (easy version) 解析(DP) 今天我們來看看CF1420C1 題目連結 題目 對於一個數列\(a\),選若干個數字,求al ...

  6. Java学习的第三十六天

    1.2.1 public class cjava { public static void main(String[]args) { int a,b; a='A'; b='B'; System.out ...

  7. 使用 IDEA 查看 JDK8 源码

    使用 idea 查看 oracle jdk 8 源码时发现 Unsafe 没有源码. 解决方法: 到 openjdk-8 下载页面:http://jdk.java.net/java-se-ri/8-M ...

  8. Linux 系统编程 学习 总结

    背景 整理了Liunx 关于 进程间通信的 很常见的知识. 目录 与 说明 Linux 系统编程 学习:000-有关概念 介绍了有关的基础概念,为以后的学习打下基础. Linux 系统编程 学习:00 ...

  9. [Luogu P4777] 【模板】扩展中国剩余定理(EXCRT) (扩展中国剩余定理)

    题面 传送门:洛咕 Solution 真*扩展中国剩余定理模板题.我怎么老是在做模板题啊 但是这题与之前不同的是不得不写龟速乘了. 还有两个重点 我们在求LCM的时候,记得先/gcd再去乘另外那个数, ...

  10. hdu3974 Assign the task线段树 dfs序

    题意: 无序的给编号为1-n的员工安排上下级, 操作一:给一个员工任务C,则该员工以及他的下级任务都更换为任务C 操作二:询问一个员工,返回他的任务   题解: 给一个员工任务,则他所在组都要改变,联 ...