以前写的驱动程序要另外写一个测试程序,这样的驱动程序就有很大的局限性,只能自己用,为了通用性,别人的应用程序也可以用我的驱动程序就要引入输入子系统。在这个驱动程序里设置了5个按键L, S, ENTER, LEFTSHIFT, ESC.设置这几个按键主要是为了方便测试。以下是驱动程序button_input.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/workqueue.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <mach/gpio.h>
static struct input_dev * button_dev;
static struct pin_desc *irq_pd = NULL;
static struct timer_list buttons_timer;
static irqreturn_t buttons_irq(int irq, void *dev_id)
{
irq_pd = (struct pin_desc *)dev_id;
mod_timer(&buttons_timer, jiffies + HZ/100);
return IRQ_RETVAL (IRQ_HANDLED);
}
struct pin_desc{
int irq;
char *name;
unsigned int pin;
unsigned int key_val;
};
struct pin_desc pins_desc[5] = {
{IRQ_EINT(0), "s1", S3C64XX_GPN(0), KEY_L},
{IRQ_EINT(1), "s2", S3C64XX_GPN(1), KEY_S},
{IRQ_EINT(2), "s3", S3C64XX_GPN(2), KEY_ENTER},
{IRQ_EINT(3), "s4", S3C64XX_GPN(3), KEY_LEFTSHIFT},
{IRQ_EINT(4), "s5", S3C64XX_GPN(4), KEY_ESC},
};
static void buttons_timer_function(unsigned long data)
{
struct pin_desc * pindesc = irq_pd;
unsigned int pinval;
if (!pindesc)
return;
pinval = gpio_get_value(pindesc->pin);
if (pinval)
{
/* 松开的 *//* 最后一个参数0表示松开1表示按下 */
input_event(button_dev, EV_KEY, pindesc->key_val, 0);
input_sync(button_dev);
}
else
{
/* 按下的 */
input_event(button_dev, EV_KEY, pindesc->key_val, 1);
input_sync(button_dev);
}
}
static int button_init(void)
{
int i = 0;
/*1. 分配一个input_dev结构体 */
button_dev = input_allocate_device();
/* 2.设置 能产生按键类事件*/
/* 哪类事件 */
set_bit(EV_KEY, button_dev->evbit);
/* 重复类事件 */
set_bit(EV_REP, button_dev->evbit);
/* 能产生哪些事件L,S,ENTER,SHIFT */
for (i = 0; i < 5; i++)
{
set_bit(pins_desc[i].key_val, button_dev->keybit);
}
/* 3.注册 */
input_register_device(button_dev);
/* 4.硬件相关的操作 */
init_timer(&buttons_timer);
buttons_timer.function = buttons_timer_function;
buttons_timer.expires = jiffies + HZ/100;
add_timer(&buttons_timer);
for (i = 0; i < 5; i++)
{
request_irq(pins_desc[i].irq, buttons_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, pins_desc[i].name, &pins_desc[i]);
}
return 0;
}
static void button_exit(void)
{
int i;
for (i = 0; i < 5; i++)
{
free_irq(pins_desc[i].irq, &pins_desc[i]);
}
del_timer(&buttons_timer);
input_unregister_device(button_dev);
input_free_device(button_dev);
}
module_init(button_init);
module_exit(button_exit);
MODULE_LICENSE("GPL");
测试
打开一个记事本有图有真相
这些字母是在开发板的LCD屏上通过开发板上的按键按下后显示出来的
如果按键足够多,就完全可以做出来一个像电脑键盘一样的驱动