linux驅動開發:input子系統一

input子系統開發:按鍵是一種標準的輸入設備,實驗以按鍵來分析,實現簡單的input子系統.

未完成.

實驗代碼:實現一個按鍵的功能

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <asm/uaccess.h>
#include <linux/input.h>
#include <asm/io.h>
#include <linux/kernel.h>
#include <mach/gpio.h>
#include <linux/irq.h>
#include <asm/bitops.h>
#include <mach/irqs.h>


#define _HIGH               1
#define _LOW                0

#define _ZERO               0
enum button_event 
{
    _EV_UP,
    _EV_DOWN,
};

struct buttons_desc
{
    unsigned int irq;           // button irq  num
    int gpio;           //PHY button Addr
    int keycode;        // button keycode
    char *name;         // button name
};

static struct buttons_desc buttons_array[] =
{
    {IRQ_EINT0,S5PV210_GPH2(0),KEY_ENTER,"LEFT"},
#if 0   
    { S5PV210_GPH2(0), 0, "KEY0" },
    { S5PV210_GPH2(1), 1, "KEY1" },
    { S5PV210_GPH2(2), 2, "KEY2" },
    { S5PV210_GPH2(3), 3, "KEY3" },
    { S5PV210_GPH3(0), 4, "KEY4" },
    { S5PV210_GPH3(1), 5, "KEY5" },
    { S5PV210_GPH3(2), 6, "KEY6" },
    { S5PV210_GPH3(3), 7, "KEY7" },
#endif
};
/*****irq use****/
volatile struct buttons_desc *g_buttons_desc_info = NULL;
/*****input device use****/
static struct input_dev *buttons_input_dev =NULL;

/*****timer use****/
static struct timer_list buttons_timer;

/******func start******/



/******button irq******/

static irqreturn_t smart210_buttons_irq(int irq, void* dev_id)
{
    //get whitch key trigger the irq
    g_buttons_desc_info =(volatile struct buttons_desc*)dev_id;
    //Eliminate key jitter,delay 10 ms to get key value
    mod_timer(&buttons_timer,jiffies + HZ/30);
    return IRQ_HANDLED;
}
/******timer del func******/
static void buttons_timer_func(unsigned long data)
{
    int uc_keysta =0;
    struct buttons_desc *uc_buttons_desc =(struct buttons_desc *)g_buttons_desc_info;

    if(!uc_buttons_desc)
    {
        return;
    }

    //get the pin level :high /low
    //pree up 0,pree down 1
    if(gpio_get_value(uc_buttons_desc->gpio) == _HIGH)
    {
        uc_keysta =_EV_UP;
    }
    else
    {
        uc_keysta =_EV_DOWN;
    }

    input_event(buttons_input_dev,EV_KEY, uc_buttons_desc->keycode,uc_keysta);
    input_event(buttons_input_dev,EV_SYN, _ZERO,_ZERO);


}
static int __init smart210_buttons_init(void)
{
    int ret=0;

    //1.alloc input dev device
    buttons_input_dev = input_allocate_device();
    if (!buttons_input_dev) 
    {
        ret = -ENOMEM;
        printk("1.error allocate input device!\n");
        goto err_allocate_input_dev;
    }
    //2.set up the input dev param,Report event
    //EV_KEY :key event
    //EV_SYN: sync event
    set_bit(EV_KEY,buttons_input_dev->evbit);
    set_bit(EV_SYN,buttons_input_dev->evbit);
    set_bit(EV_REP,buttons_input_dev->evbit);
    //set EV_KEY key code
    set_bit(buttons_array[0].keycode,buttons_input_dev->keybit);
    //set input dev name
    buttons_input_dev->name = "buttons";

    //3.register device
    ret = input_register_device(buttons_input_dev);
    if(ret) 
    {
        printk("2.error to register input device!\n");
        goto err_register_input_dev;
    }


/******special func user add for different input device*********/

    //4.irq request
    ret =request_irq(gpio_to_irq(buttons_array[0].gpio),smart210_buttons_irq,IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,buttons_array[0].name,&buttons_array[0]);

    if(ret) 
    {
        printk("3.error to request irq !\n");
        goto err_request_irq;
    }
    //5.timer initial
    init_timer(&buttons_timer);
    buttons_timer.function =buttons_timer_func;
    add_timer(&buttons_timer);

    return 0;
err_request_irq:
    input_unregister_device(buttons_input_dev);
err_register_input_dev:
err_allocate_input_dev:
    input_free_device(buttons_input_dev);
    return ret;
}

static void __exit smart210_buttons_exit(void)
{
    del_timer(&buttons_timer);

    free_irq(buttons_array[0].irq,&buttons_array[0]);

    input_unregister_device(buttons_input_dev);

    input_free_device(buttons_input_dev);
}

module_init(smart210_buttons_init);
module_exit(smart210_buttons_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("User");

實驗現象:

一個按鍵已經調試通過。好久沒有更新博客了,並不是沒有堅持,半途而廢。而是從網上找了些視頻,一直在研究視頻。
上面的例子也是按照視頻中做的。所以好久沒有動手,只是想讓自己對驅動開發的理解,對內核的理解深一些,而不是簡單的照貓畫虎。應該近期開始逐漸慢慢更新博客。同樣按照自己的學習進度來,但難免還是會很慢,畢竟摸着石頭過河還是很累的,而且還有工作要做,所以自己的時間其實很少。
加油,爲了部落~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章