一.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. 3. Distributional Reinforcement Learning with Quantile Regression

    C51算法理论上用Wasserstein度量衡量两个累积分布函数间的距离证明了价值分布的可行性,但在实际算法中用KL散度对离散支持的概率进行拟合,不能作用于累积分布函数,不能保证Bellman更新收敛 ...

  2. Java数据结构-01顺序表

    一.定义 线性表是一种线性结构,它是具有相同类型的n(n≥0)个数据元素组成的有限序列. 二.存储分类 1.顺序存储: ①简述:是指将线性表中的各个元素依次存放在一组地址连续的存储单元中,通常将这种方 ...

  3. 关于transition中嵌套keep-alive的问题解决

    需求:在使用keep-alive的同时使用transition动画效果 最开始是这样写的,但是发现报错,而且动画效果失效 <transition name="container-rig ...

  4. 【16】进大厂必须掌握的面试题-100个python面试

    我们整理了Python面试的主要问题清单,分为7个部分: 基本面试问题 OOPS面试问题 基本的Python程序 Python库面试问题 数据分析面试题 选择题(MCQ) 基本的Python面试问题 ...

  5. python pickle 模块的使用详解

    用于序列化的两个模块 json:用于字符串和Python数据类型间进行转换 pickle: 用于python特有的类型和python的数据类型间进行转换 json提供四个功能:dumps,dump,l ...

  6. Flask中的RESTFul

    RESTFul 1.什么是RESTFul? 1.1 简介 REST即表述性状态传递(英文:Representational State Transfer, 简称REST)是Roy Fielding博士 ...

  7. Python3网络学习案例一:Ping详解

    1. 使用Ping做什么 ping用于确定本地主机是否能与另一台主机成功交换(发送与接收)数据包,再根据返回的信息,就可以推断TCP/IP参数是否设置正确,以及运行是否正常.网络是否通畅等. 2. 效 ...

  8. mysql运维-slave_skip_errors

    1 简介    mysql在主从复制过程中,由于各种的原因,从服务器可能会遇到执行BINLOG中的SQL出错的情况,在默认情况下,服务器会停止复制进程,不再进行同步,等到用户自行来处理.    sla ...

  9. ERP的权限管理的操作与设计--开源软件诞生24

    赤龙ERP用户与权限管理讲解--第24篇 用日志记录"开源软件"的诞生 [进入地址 点亮星星]----祈盼着一个鼓励 博主开源地址: 码云:https://gitee.com/re ...

  10. 1+X云计算 应用商城系统(gpmall)-遇到的问题以及解决办法

    1+X云计算 应用商城系统(gpmall)-遇到的问题以及解决办法 问题1: 关于网站访问(打不开或者连接不上服务器的问题): 没有关闭selinux和防火墙,是访问不了网站 [root@mall ~ ...