#include <linux/init.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/gpio.h>
#include <plat/gpio-cfg.h>
/*1.硬件私有结构体*/
struct button_resource {
unsigned long gpio;
int irq;
char *name;
int code;
};
//初始化按键信息
static struct button_resource btn_info[] = {
[0] = {
.gpio = S5PV210_GPH0(0),
.irq = IRQ_EINT(0),
.name = "KEY_L",
.code = KEY_L
},
[1] = {
.gpio = S5PV210_GPH0(1),
.irq = IRQ_EINT(1),
.name = "KEY_S",
.code = KEY_S
},
[2] = {
.gpio = S5PV210_GPH0(2),
.irq = IRQ_EINT(2),
.name = "KEY_ENTER",
.code = KEY_ENTER
},
};
//定义一个struct input_dev指针
static struct input_dev *btn_dev;
//中断处理函数
static irqreturn_t button_isr(int irq,
void *dev_id)
{
/*1.获取每个按键的按键信息*/
struct button_resource *pbtn =
(struct button_resource *)dev_id;
unsigned int pinstatus;
/*2.获取按键状态*/
pinstatus = gpio_get_value(pbtn->gpio);
/*3.上报按键信息*/
/*3.1 唤醒休眠的进程*/
/*3.2 将数据信息上报给核心层*/
if (pinstatus == 1) {
//松开
input_event(btn_dev, EV_KEY, pbtn->code, 0);
input_sync(btn_dev);
} else {
//按下
input_event(btn_dev, EV_KEY, pbtn->code, 1);
input_sync(btn_dev);
}
return IRQ_HANDLED;
}
static int button_init(void)
{ int i;
/*1.分配input_dev*/
btn_dev = input_allocate_device();
/*2.初始化input_dev*/
/*2.1指定一个名称*/
btn_dev->name = "tarena_button";
/*2.2指定上报哪类事件*/
set_bit(EV_KEY, btn_dev->evbit); //按键类事件
set_bit(EV_REP, btn_dev->evbit); //重复类事件
/*2.3指定按键类事件的哪些事件*/
for (i = 0; i < ARRAY_SIZE(btn_info); i++) {
set_bit(btn_info[i].code, btn_dev->keybit);
}
/*3.注册input_dev*/
input_register_device(btn_dev);
/*4.申请GPIO和注册中断*/
for (i = 0; i < ARRAY_SIZE(btn_info); i++) {
gpio_request(btn_info[i].gpio,
btn_info[i].name);
request_irq(btn_info[i].irq,
button_isr,
IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,
btn_info[i].name,
&btn_info[i]);
}
return 0;
}
static void button_exit(void)
{
int i;
/*1.释放GPIO和中断*/
for (i = 0; i < ARRAY_SIZE(btn_info); i++) {
free_irq(btn_info[i].irq, &btn_info[i]);
gpio_free(btn_info[i].gpio);
}
/*2.卸载input_dev*/
input_unregister_device(btn_dev);
/*3.释放input_dev*/
input_free_device(btn_dev);
}
module_init(button_init);
module_exit(button_exit);
MODULE_LICENSE("GPL v2");
*******************************************************************************
测试代码:
*******************************************************************************
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h>
int main(int argc, char *argv[])
{
//定义用户和驱动交互的数据元
struct input_event button;
int fd;
fd = open(argv[1], O_RDWR);
if (fd < 0) {
printf("open failed.\n");
return -1;
}
while(1) {
read(fd, &button, sizeof(button));
printf("type = %#x, code = %#x, value = %#x\n",
button.type, button.code, button.value);
}
close(fd);
}