一.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 也是本地开发的一神器:部署单机版 Pulsar 和集群架构 Redis

    原文链接:Docker 也是本地开发的一神器:部署单机版 Pulsar 和集群架构 Redis 一.前言: 现在互联网的技术架构中,不断出现各种各样的中间件,例如 MQ.Redis.Zookeeper ...

  2. Redis【二】 set|get那些事

    redis4.0.9 SET\GET方法 从哪里开始 server.c里面有每个redis命令对应的执行方法 如 struct redisCommand redisCommandTable[] = { ...

  3. uni-app h5端跨域问题解决

    例如我现在的项目运行在 http://localhost:8080,而我有个接口是 https://service.picasso.adesk.com/v1/wallpaper/album,发起请求就 ...

  4. 4G DTU在使用时有哪些注意事项?

    4G DTU是用来帮助工业设备快速连接4G网络的设备.众山物联网研发.生产的LTE660正是这样一款功能强大的4G联网"利器". DTU是英文Data Transfer unit的 ...

  5. 在PLC中开关量采集模块的作用

    PLC系统作为工业控制的基础设备在如今的现代化工厂应用中已经非常的广泛.许多工厂应用中,都需要对现场采集来的脉冲信号进行计数统计.如果是使用专用脉冲计数模块的话,价格会非常的昂贵,在很多采集低速脉冲信 ...

  6. Reverse for ‘password_reset_complete‘ not found. ‘password_reset_complete‘ is not a valid view funct

    关注公众号"轻松学编程"了解更多 原因 在使用xadmin与django 2版本以上修改密码时会报这个错,这是由于django修改密码成功后使用的是success_url参数,而x ...

  7. python解决百钱买百鸡

    百钱买百鸡 关注公众号"轻松学编程"了解更多. 现有100钱,公鸡5文钱一只,母鸡3文钱一只,小鸡一文钱3只 要求:公鸡.母鸡,小鸡都要有,把100文钱花完,买的鸡的数量正好是10 ...

  8. [P2114] [NOI2014]起床困难综合症 (位运算)

    题面 传送门:https://www.luogu.org/problemnew/show/P2114 Solution 一道很有意思的位运算题. 要做这一题,我们首先得了解一个很重要的特点 位运算过程 ...

  9. xshell连接windows10子系统ubuntu

    修改端口 cd /etc/ssh#备份sudo cp sshd_config sshd_config.baksudo vim sshd_config修改sshd_config Port 2233 #修 ...

  10. CSP-S 2020全国开放赛前冲刺模拟训练题1 T4 二维码

    组合 首先可以考虑一个状态合法的条件,可以发现的是最后得到的矩阵一定是至少有一行或是有一列全$0$或$1$,如果把这一列或这一行删掉那么将剩下的子矩阵拼接起来又是一个子问题,同样的也是至少有一列或一行 ...