输入子系统框架的驱动程序步骤:
1. 分配一个input_dev结构体
2. 设置
3. 注册
4. 硬件相关的代码,比如中断注册,定时器注册等等。
下面分别介绍下相关实现代码
1.分配一个input_dev结构体
input_dev在
struct input_dev {
const char *name;
const char *phys;
const char *uniq;
struct input_id id;
unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
unsigned long relbit[BITS_TO_LONGS(REL_CNT)];
unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
.......
}
/*1.分配一个input_dev结构*/
buttons_dev = input_allocate_device();
if (!buttons_dev)
{
printk("input_allocate failed!\n");
error = -ENOMEM;
return error;
}
/*2.设置
2.1 设置按键能产生哪类事件 */
set_bit(EV_KEY, buttons_dev->evbit);
set_bit(EV_REP, buttons_dev->evbit);
/* 2.2 设置能产生这类操作的哪些事件 */
set_bit(KEY_A, buttons_dev->keybit);
set_bit(KEY_B, buttons_dev->keybit);
set_bit(KEY_L, buttons_dev->keybit);
set_bit(KEY_S, buttons_dev->keybit);
set_bit(KEY_ENTER, buttons_dev->keybit);
set_bit(KEY_LEFTSHIFT, buttons_dev->keybit);
EV_KEY & EV_REP表示按键类,可重复
3.注册
error = input_register_device(buttons_dev);
if (error)
{
printk("input_register_device failed!\n");
error = -ENOMEM;
return error;
}
/*3.硬件相关配置*/
/*3.1初始化定时器*/
init_timer(&buttons_timer);
buttons_timer.function = mini2440_timer_handler;
add_timer(&buttons_timer);
/*3.2中断配置*/
for(i=0;i
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static struct input_dev *buttons_dev;
static struct timer_list buttons_timer;
#define BUTTON_NUM 6
struct button_irq_desc {
int irq;
int pin;
int pin_val;
char *name;
};
static struct button_irq_desc button_irqs [] = {
{IRQ_EINT8 , S3C2410_GPG(0) , KEY_A , "KEY0"},
{IRQ_EINT11, S3C2410_GPG(3) , KEY_B , "KEY1"},
{IRQ_EINT13, S3C2410_GPG(5) , KEY_L , "KEY2"},
{IRQ_EINT14, S3C2410_GPG(6) , KEY_S , "KEY3"},
{IRQ_EINT15, S3C2410_GPG(7) , KEY_ENTER, "KEY4"},
{IRQ_EINT19, S3C2410_GPG(11), KEY_LEFTSHIFT, "KEY5"},
};
struct button_irq_desc * irq_pq;
static irqreturn_t button_irq(int irq, void *dev_id)
{
irq_pq = (struct button_irq_desc *)dev_id;
mod_timer(&buttons_timer,jiffies+HZ/100);
return IRQ_RETVAL(IRQ_HANDLED);
}
static void mini2440_timer_handler(unsigned long dat)
{
struct button_irq_desc * pindesc = irq_pq;
unsigned int pinval;
if(!pindesc)
return;
pinval = s3c2410_gpio_getpin(pindesc->pin);
if (pinval)
{
/* 松开 ,最后一个参数设置为0*/
input_event(buttons_dev,EV_KEY,pindesc->pin_val,0);
input_sync(buttons_dev);
}
else
{
/* 按下 ,最后一个参数设置为1*/
input_event(buttons_dev,EV_KEY,pindesc->pin_val,1);
input_sync(buttons_dev);
}
}
static int mini2440_buttons_init(void)
{
int error,i;
/*1.分配一个input_dev结构*/
buttons_dev = input_allocate_device();
if (!buttons_dev)
{
printk("input_allocate failed!\n");
error = -ENOMEM;
return error;
}
/*2.设置
2.1 设置按键能产生哪类事件 */
set_bit(EV_KEY, buttons_dev->evbit);
set_bit(EV_REP, buttons_dev->evbit);
/* 2.2 设置能产生这类操作的哪些事件 */
set_bit(KEY_A, buttons_dev->keybit);
set_bit(KEY_B, buttons_dev->keybit);
set_bit(KEY_L, buttons_dev->keybit);
set_bit(KEY_S, buttons_dev->keybit);
set_bit(KEY_ENTER, buttons_dev->keybit);
set_bit(KEY_LEFTSHIFT, buttons_dev->keybit);
error = input_register_device(buttons_dev);
if (error)
{
printk("input_register_device failed!\n");
error = -ENOMEM;
return error;
}
/*3.硬件相关配置*/
/*3.1初始化定时器*/
init_timer(&buttons_timer);
buttons_timer.function = mini2440_timer_handler;
add_timer(&buttons_timer);
/*3.2中断配置*/
for(i=0;i
注意此时的event1路径在/dev/input下,非韦老师视频中的/dev/目录下。
使用hexdump命令测试
hexdump相关代码:
struct input_event {
struct timeval time; //时间
__u16 type; //类
__u16 code; //类下事件的值
__s32 value; //0-松开, 1-按下,2-重复
};
struct timeval {
__kernel_time_t tv_sec; //秒
__kernel_suseconds_t tv_usec; //微秒
};