smart210驱动(8)keys-input

keys-input.c

/*
* linux-3.10.27
* arm-linux-gcc-4.5.1
*
* @ keys driver (input subsystem)
* @ ref : gpio_keys.c (drivers\input\keyboard)
*/

#include <linux/module.h>
#include <linux/init.h>   /* module_init, ... */
#include <linux/kernel.h> /* everything */

#include <linux/cdev.h>   /* cdev_init, ... */
#include <linux/fs.h>     /* file_operations,  */
#include <linux/device.h>  /* class_create,... */
#include <linux/platform_device.h>
#include <linux/slab.h>   /* kmalloc, ... */
#include <asm/io.h>       /* ioremap,... */

#include <linux/uaccess.h>   /* copy_from_user, ... */

#include <linux/irq.h>      /* IRQ_EINT(x), ... */
#include <linux/gpio.h>
#include <linux/interrupt.h>  /* irq_request(),IRQF_xxx, ... */

#include <linux/input.h>

/*
* GPIO OF KEY FOR SMART210
*  K1  - GPH2-0  - EXINT16
*  K2  - GPH2-1  - EXINT17
*  K3  - GPH2-2  - EXINT18
*  K4  - GPH2-3  - EXINT19
*  K5  - GPH3-0  - EXINT24 
*  K6  - GPH3-1  - EXINT25
*  K7  - GPH3-2  - EXINT26
*  K8  - GPH3-3  - EXINT27
*
*  LOW MEANS PRESSED
*
*/

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

static const struct keys_data keys_res[] =
{
	{S5PV210_GPH2(0), IRQ_EINT(16),KEY_L, "K1"},
	{S5PV210_GPH2(1), IRQ_EINT(17),KEY_S, "K2"},
	{S5PV210_GPH2(2), IRQ_EINT(18),KEY_P, "K3"},
	{S5PV210_GPH2(3), IRQ_EINT(19),KEY_W, "K4"},
	{S5PV210_GPH3(0), IRQ_EINT(24),KEY_T, "K5"},
	{S5PV210_GPH3(1), IRQ_EINT(25),KEY_D, "K6"},
	{S5PV210_GPH3(2), IRQ_EINT(26),KEY_C, "K7"},
	{S5PV210_GPH3(3), IRQ_EINT(27),KEY_ENTER, "K8"},
};

static struct input_dev *keys_dev;
static struct keys_data *pdata;
static struct timer_list keys_timer;

irqreturn_t mykeys_handler(int irq, void *dev_id)
{
	pdata = (struct keys_data *)dev_id;
	//pr_info("%s pressed.\n", pdata->name);

	mod_timer(&keys_timer, jiffies+HZ/100);
	
	return IRQ_RETVAL(IRQ_HANDLED);
}

static void keys_timer_function(unsigned long data)
{
	unsigned int pinval;
	pinval = gpio_get_value(pdata->pin);
	if (pinval){
		/* unpressed */
		input_event(keys_dev, EV_KEY, pdata->key_val, 0);
		input_sync(keys_dev);
	}
	else {
		/* pressed */
		input_event(keys_dev, EV_KEY, pdata->key_val, 1);
		input_sync(keys_dev);
	}
}

static int keys_input_init(void)
{
	int ret ,i = 0;
	int irq;

	pr_info("%s called.\n", __func__);

	keys_dev = input_allocate_device();
	if (!keys_dev){
		return -ENOMEM;
	}

	keys_dev->name = "mykeys";

	keys_dev->id.bustype = BUS_HOST;
	keys_dev->id.vendor = 0x0001;
	keys_dev->id.product = 0x0001;
	keys_dev->id.version = 0x0100;
	
	set_bit(EV_KEY, keys_dev->evbit);
	set_bit(EV_REP, keys_dev->evbit);

	set_bit(KEY_L, keys_dev->keybit);
	set_bit(KEY_S, keys_dev->keybit);
	set_bit(KEY_P, keys_dev->keybit);
	set_bit(KEY_W, keys_dev->keybit);
	set_bit(KEY_T, keys_dev->keybit);
	set_bit(KEY_D, keys_dev->keybit);
	set_bit(KEY_C, keys_dev->keybit);
	set_bit(KEY_ENTER, keys_dev->keybit);

	
	ret = input_register_device(keys_dev);
	if (ret){
		input_free_device(keys_dev);
		return ret;
	}

	init_timer(&keys_timer);
	keys_timer.function = keys_timer_function;
	add_timer(&keys_timer);

	//gpio_to_irq(unsigned gpio)

	for (i = 0; i < 8; i++){
		//irq = gpio_to_irq(keys_res[i].pin);
		
		if(request_irq(keys_res[i].irq, mykeys_handler, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,
			keys_res[i].name, (void *)&keys_res[i]))
			break;
	}
	
	return 0;
}

static void keys_input_exit(void)
{
	int i = 0;
	pr_info("%s called.\n", __func__);

	for (i = 7; i >= 0 ; i--){
		free_irq(keys_res[i].irq, (void *)&keys_res[i]);
	}
	del_timer(&keys_timer);
	input_unregister_device(keys_dev);
	input_free_device(keys_dev);	
}

module_init(keys_input_init);
module_exit(keys_input_exit);
MODULE_LICENSE("GPL");

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值