[RK3288][Android6.0] 系統按鍵驅動流程分析【轉】

來源:互聯網
上載者:User

標籤:關閉   rk3288   syn   type   i++   log   schedule   uil   按鍵   

本文轉載自: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;}

[RK3288][Android6.0] 系統按鍵驅動流程分析【轉】

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.