[RK3288][Android6.0] 系统按键驱动流程分析【转】

本文转载自:http://blog.csdn.net/kris_fei/article/details/77894406

Rockchip的按键驱动位于 kernel/drivers/input/keyboard/rk_keys.c

默认支持的keys在dts中定义:

其中power key作为普通gpio,具有唤醒功能。而其他按键比如,volume up/down 可以通过adc精确读取到gpio的电压值,原理图如下:

 

和一般的按键一样,驱动是通过内核input子系统来将keys注册供用户空间使用

static int keys_probe(struct platform_device *pdev)
{
    input = devm_input_allocate_device(dev);
    input->name = "rk29-keypad";    /* pdev->name; */
    input->phys = "gpio-keys/input0";
    input->dev.parent = dev;

    input->id.bustype = BUS_HOST;
    input->id.vendor = 0x0001;
    input->id.product = 0x0001;
    input->id.version = 0x0100;

    error = input_register_device(input);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

dts keys的解析通过rk_keys_parse_dt()实现。而每个key都会注册一个定时器函数来处理状态变化并通知用户空间。

    for (i = 0; i < ddata->nbuttons; i++) {
        if (button->code) {
            setup_timer(&button->timer,
                    keys_timer, (unsigned long)button);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

keys_timer():

static void keys_timer(unsigned long _data)
{
    //普通gpio直接读取
    if (button->type == TYPE_GPIO)
        state = !!((gpio_get_value(button->gpio) ? 1 : 0) ^
               button->active_low);
    else
        //adc转成bool状态值
        state = !!button->adc_state;
    //状态变化上报事件
    if (button->state != state) {
        button->state = state;
        input_event(input, EV_KEY, button->code, button->state);
        input_event(input, EV_KEY, button->code, button->state);
        input_sync(input);
    }
    //10ms后启动定时器
    if (state)
        mod_timer(&button->timer, jiffies + DEBOUNCE_JIFFIES);
}

定时器会处理普通gpio和adc两种类型的按键,当状态变化时,会向用户空间上报当前事件、键值、状态。默认开机时,定时器处理函数因为检测不到状态变化而关闭退出。

定时器的开启有两个地方会被调用: 
1.系统开机会启一个工作队列,每100ms周期性调用一次检测有没有按键触发

static void adc_key_poll(struct work_struct *work)
{
    if (!ddata->in_suspend) {
        //读取adc电压
        result = rk_key_adc_iio_read(ddata);
        for (i = 0; i < ddata->nbuttons; i++) {
            //允许值有一定范围的漂移
            if (result < button->adc_value + DRIFT_ADVALUE &&
                result > button->adc_value - DRIFT_ADVALUE)
                button->adc_state = 1;
            else
                button->adc_state = 0;
            if (button->state != button->adc_state)
                mod_timer(&button->timer,
                      jiffies + DEBOUNCE_JIFFIES);
        }
    }
    //周期性调用。ADC_SAMPLE_JIFFIES为100ms
    schedule_delayed_work(&ddata->adc_poll_work, ADC_SAMPLE_JIFFIES);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

2. power key唤醒时中断处理会被触发

static irqreturn_t keys_isr(int irq, void *dev_id)
{
    //上报power key事件
    if (button->wakeup && pdata->in_suspend) {
        button->state = 1;
        input_event(input, EV_KEY, button->code, button->state);
        input_sync(input);
    }
    if (button->wakeup)
        wake_lock_timeout(&pdata->wake_lock, WAKE_LOCK_JIFFIES);
    mod_timer(&button->timer, jiffies + DEBOUNCE_JIFFIES);

    return IRQ_HANDLED;
}
时间: 2024-08-27 14:33:15

[RK3288][Android6.0] 系统按键驱动流程分析【转】的相关文章

Android 7.0 Power 按键处理流程

Android 7.0  Power 按键处理流程 Power按键的处理逻辑由PhoneWindowManager来完成,本文只关注PhoneWindowManager中与Power键相关的内容,其他系统按键的处理类似也是在PhoneWindowManager中处理的.理解了power按键的处理再看其他系统按键的逻辑会容易的多也简单的多. 一.Power按键的上报 Power按键的上报流程与其余的按键处理流程一致,在按下power按键后驱动上报按键经InputManagerService处理按键

Android6.0系统权限那些事

Android6.0带来了新的权限管理方式,本文主要来源于官方文档,加入了自己的理解,目的是想总结Android6.0权限管理的新方式,其他部分可能主要是总结式的带过,后续再详细分析. 一.Security Architecture(安全体系结构) Android安全体系结构的核心是: 默认情况下没有任何应用有权限去执行对其他应用.操作系统.用户有不利影响的操作.这是一个核心的设计理念.记住这句话对后面的权限管理可以很好的理解. 正式由于这样的设计理念,默认情况下应用不能去读写用户的私有数据(比

Android6.0系统添加那些新特性

??? 北京时间9月30日凌晨在美国旧金山举行2015年秋季新品公布会.在公布会上代号为"Marshmallow(棉花糖)"的安卓6.0系统正式推出.新系统的总体设计风格依旧保持扁平化的MeterialDesign风格. Android6.0在对软件体验与执行性能上进行了大幅度的优化.安卓权限系统被又一次设计了. ??? 全新的Android M相比眼下的Android Lollipop(5.0)有二十项重大的改进: ? ? 原文博客请參考:点击打开链接 ??? 一:App Permi

9.6 Binder系统_驱动情景分析_server的多线程实现

当多个client对server发出请求的时候,如果server忙不过来的时候会创建多线程来处理请求 那么忙不过来由谁来判断? server进程有个binder_proc结构体,其里面有todo链表(放有client发过来的数据),并且会唤醒等待在binder_proc.wait上的线程,如果有线程在wait上等待,表面server进程忙的过来:如果wait上空了,就表面server太忙了,驱动会向应用程序反馈 (1)驱动判断是否忙不过来 (2)驱动向APP发请求:创建新线程 (3)APP创建新

[RK3288][Android6.0] Display驱动初始化流程小结【转】

本文转载自:http://blog.csdn.net/kris_fei/article/details/52584903 Platform: RK3288OS: Android 6.0Kernel: 3.10.92 以MIPI DSI接口的lcd为例. rk_screen.c:读取lcd timing参数.lcd_mipi.c:屏幕mipi配置信息.rk_fb.c:fb驱动.rk3288_lcdc.clcdc controller驱动.rk32_mipi_dsi.c:dsi controller

[RK3288][Android6.0] 调试笔记 --- 通用GPIO驱动控制LED【转】

本文转载自:http://m.blog.csdn.net/kris_fei/article/details/69553422 Platform: ROCKCHIPOS: Android 6.0Kernel: 3.10.92 由于板子没有lcd无法得知sd卡升级是否完成,因此使用LED显示.Recovery中升级完成后控制GPIO输出高电平点亮LED. 系统自带GPIO控制驱动:内核已经自带了通用GPIO驱动,可以直接在用户空间操作.路径: /sys/class/gpio[email protec

[RK3288][Android6.0] 调试笔记 --- 替换系统签名【转】

本文转载自:http://blog.csdn.net/kris_fei/article/details/55100299 Platform: RK3288OS: Android 6.0Kernel: 3.10.92 由于项目的apk安装需要shareid为system的权限(不需要高权限的apk是可以正常安装的),一开始我用的是releasekey,导致签名文件不匹配无法安装,因此就替换系统默认platform签名文件. 生成新的签名文件方法参考rk3288/build/target/produ

(原创)android6.0系统Healthd深入分析

概述 Healthd是android4.4之后提出来的一种中介模型,该模型向下监听来自底层的电池事件,向上传递电池数据信息给Framework层的BatteryService用以计算电池电量相关状态信息,BatteryServcie通过传递来的数据来计算电池电量显示,剩余电量,电量级别等信息,如果收到过温报警或者严重低电报警等信息,系统会直接关机,保护硬件. 主模块处理流程 Healthd模块代码是在system/core/healthd/,其模块入口在healthd的main函数,函数代码如下

android休眠唤醒驱动流程分析【转】

转自:http://blog.csdn.net/hanmengaidudu/article/details/11777501 标准linux休眠过程: l        power management notifiers are executed with PM_SUSPEND_PREPARE l        tasks are frozen l        target system sleep state is announced to the platform-handling co