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