6410之输入子系统(2)

编写代码可以参考:Gpio_keys.c (drivers\input\keyboard)

代码如下:

#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 <linux/gpio.h>


struct input_dev *buttons_dev;
struct timer_list buttons_timer;
struct pin_desc * irq_pd;

struct pin_desc{
	unsigned int pin;
	unsigned int irq;
	unsigned char *name;
	unsigned int key_val;
};

struct pin_desc pins_desc[4] = {
	{S3C64XX_GPN(0),IRQ_EINT(0),"L",KEY_L},
	{S3C64XX_GPN(1),IRQ_EINT(1),"S",KEY_S},
	{S3C64XX_GPN(2),IRQ_EINT(2),"Enter",KEY_ENTER},
	{S3C64XX_GPN(3),IRQ_EINT(3),"LeftShift",KEY_LEFTSHIFT},
};

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(buttons_dev, EV_KEY, pindesc->key_val, 0);
		input_sync(buttons_dev);
	}
	else
	{
		/* 按下 */
		input_event(buttons_dev, EV_KEY, pindesc->key_val, 1);
		input_sync(buttons_dev);
	}
}

static irqreturn_t buttons_irq(int irq, void *dev_id)
{
	/* 10ms后启动定时器 */
	irq_pd = (struct pin_desc *)dev_id;
	mod_timer(&buttons_timer, jiffies+HZ/100);
	return IRQ_RETVAL(IRQ_HANDLED);
}	
static int buttons_init(void)
{
	int i;

	/* 1. 分配一个input_dev结构体
	*/
	buttons_dev = input_allocate_device();;

	/* 2. 设置 */

	/* 2.1 设置使用那类事件 */
	set_bit(EV_KEY, buttons_dev->evbit);
	set_bit(EV_REP, buttons_dev->evbit);

	/* 2.2 能产生这类事件的哪些事件: L,S,ENTER,LEFTSHIT */
	set_bit(KEY_L, buttons_dev->keybit);  //字母"L"
	set_bit(KEY_S, buttons_dev->keybit);  //字母"S"
	set_bit(KEY_ENTER, buttons_dev->keybit);  //Enter键
	set_bit(KEY_LEFTSHIFT, buttons_dev->keybit);  // 左边的shift按键

	/* 3. 注册 */
	input_register_device(buttons_dev);

	/* 4. 硬件相关的操作 */

	init_timer(&buttons_timer);//初始化定时器
	buttons_timer.function = buttons_timer_function;//定时器处理函数
	add_timer(&buttons_timer);//将定时器告诉内核

	for (i = 0; i < 4; i++)
	{
		request_irq(pins_desc[i].irq, buttons_irq, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, pins_desc[i].name, &pins_desc[i]);
	}

	return 0;

}



static void buttons_exit(void)
{
	int i;
	for (i = 0; i < 4; i++)
	{
		free_irq(pins_desc[i].irq, &pins_desc[i]);
	}

	del_timer(&buttons_timer);
	input_unregister_device(buttons_dev);
	input_free_device(buttons_dev);	
}


module_init(buttons_init);
module_exit(buttons_exit);
MODULE_LICENSE("GPL");

执行:

/test # exec 0</dev/tty1
按下按键就会出现下面的现象:

/test # ls

6410之输入子系统(2)_第1张图片

你可能感兴趣的:(input)