TINY210实现底板上button按键的输入子系统

Tiny210v2底板上面有八个按键,但是官方只提供了该按钮的驱动,并没有实现输入子系统,使得板上的八个按钮没有任何作用。这里就通过向内核添加该buttons的输入子系统驱动,使该八个按钮实现如普通键盘的键值功能,实现能上下左右,以及确认等功能,就像手机的音量键、关机键一样。

内核:采用友善提供的linux-3.0.8
编译环境:ubuntu 13.10
个人原创,转载请注明原文链接:
http://www.embbnux.com/2013/11/20/tiny210_kernel_button_input_system/
参考:
http://blog.csdn.net/girlkoo/article/details/8736243 

一、首先搞清楚该8个按键的对应引脚和中断
查得为:
S5PV210_GPH2(0) ; EINT16
S5PV210_GPH2(1) ; EINT17
S5PV210_GPH2(2) ; EINT18
S5PV210_GPH2(3) ; EINT19
S5PV210_GPH3(0) ; EINT24
S5PV210_GPH3(1) ; EINT25
S5PV210_GPH3(2) ; EINT26
S5PV210_GPH3(3) ; EINT27
规定键值依次为:  UP ; DOWM ; LEFT ; RIGHT ; SPACE ; i ; ESC ; ENTER ;
二、内核修改
首先在
/drivers/input/keyboard/ 下新建button210_key.c

#include <linux/types.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>

static struct input_dev *buttons_dev;
static struct timer_list timer;
struct button_desc* button_desc = NULL;

struct button_desc{
	char* name;
	unsigned int pin;
	unsigned int irq;
	unsigned int val;
};

static struct button_desc buttons_desc[8] = {
	[0] = {
		.name = "S1",
		.pin = S5PV210_GPH2(0),
		.irq = IRQ_EINT(16),
		.val = KEY_UP,
	},

	[1] = {
		.name = "S2",
		.pin = S5PV210_GPH2(1),
		.irq = IRQ_EINT(17),
		.val = KEY_DOWN,
	},

	[2] = {
		.name = "S3",
		.pin = S5PV210_GPH2(2),
		.irq = IRQ_EINT(18),
		.val = KEY_LEFT,
	},

	[3] = {
		.name = "S4",
		.pin = S5PV210_GPH2(3),
		.irq = IRQ_EINT(19),
		.val = KEY_RIGHT,
	},

	[4] = {
		.name = "S5",
		.pin = S5PV210_GPH3(0),
		.irq = IRQ_EINT(24),
		.val = KEY_SPACE,
	},

	[5] = {
		.name = "S6",
		.pin = S5PV210_GPH3(1),
		.irq = IRQ_EINT(25),
		.val = KEY_I,
	},

	[6] = {
		.name = "S7",
		.pin = S5PV210_GPH3(2),
		.irq = IRQ_EINT(26),
		.val = KEY_ESC,
	},

	[7] = {
		.name = "S8",
		.pin = S5PV210_GPH3(4),
		.irq = IRQ_EINT(27),
		.val = KEY_ENTER,
	},
};

static void timer_function(unsigned long data){
	if(button_desc == NULL)
		return;

	if(gpio_get_value(button_desc->pin)){
		input_event(buttons_dev, EV_KEY, button_desc->val, 0);
	}
	else{
		input_event(buttons_dev, EV_KEY, button_desc->val, 1);
	}
	input_sync(buttons_dev);
}

static irqreturn_t irq_handler(int irq, void *devid){
	button_desc = (struct button_desc*)devid;
	mod_timer(&timer, jiffies + HZ/100);
	return IRQ_RETVAL(IRQ_HANDLED);
}

static int buttons_init(void){
	int i;

	buttons_dev = input_allocate_device();
	if(buttons_dev == NULL){
		printk(KERN_ERR "Error: allocate input device failed!n");
		return -ENOMEM;
	}

	__set_bit(EV_KEY, buttons_dev->evbit);
	__set_bit(EV_REP, buttons_dev->evbit);

	__set_bit(KEY_UP,        buttons_dev->keybit);
	__set_bit(KEY_DOWN,        buttons_dev->keybit);
	__set_bit(KEY_LEFT,        buttons_dev->keybit);
	__set_bit(KEY_RIGHT,    buttons_dev->keybit);
	__set_bit(KEY_SPACE,    buttons_dev->keybit);
	__set_bit(KEY_I,       buttons_dev->keybit);
	__set_bit(KEY_ESC,     buttons_dev->keybit);
	__set_bit(KEY_ENTER,   buttons_dev->keybit);

	printk("1n");
	if(input_register_device(buttons_dev)){
		goto error_1;
	}

	printk("2n");
	init_timer(&timer);
	timer.function = timer_function;
	add_timer(&timer);

	printk("3n");
	for(i = 0; i != 8; ++i){
		if(request_irq(buttons_desc[i].irq, irq_handler,
			IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, buttons_desc[i].name, &buttons_desc[i])){
			goto error_2;
		}
	}
	printk("4n");

	return 0;

error_2:
	for(--i; i >= 0; --i){
		free_irq(buttons_desc[i].irq, &buttons_desc[i]);
	}
	input_unregister_device(buttons_dev);

error_1:
	input_free_device(buttons_dev);

	return -EBUSY;
}

static void buttons_exit(void){
	int i;
	for(i = 0; i != 8; ++i){
		free_irq(buttons_desc[i].irq, &buttons_desc[i]);
	}

	input_unregister_device(buttons_dev);
	input_free_device(buttons_dev);
}

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

修改该目录下的Kconfig文件,添加

config KEYBOARD_BUTTON210
      tristate "Buttons on TINY210 board"
      help
        UP ; DOWM  ; LEFT ; RIGHT ; SPACE ; i ; ESC ; ENTER ;

修改该目录的Makefile文件,添加

obj-$(CONFIG_KEYBOARD_BUTTON210)	+= button210_key.o

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Time limit is exhausted. Please reload the CAPTCHA.