Demo entry 6644826

Code

   

Submitted by anonymous on Oct 07, 2017 at 05:36
Language: C. Code size: 2.7 kB.

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/input.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>

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

static const struct pin_desc pin_desc[]={
	{IRQ_EINT0,	 "S2",  S3C2410_GPF(0),	  KEY_L},
	{IRQ_EINT2,  "S3",  S3C2410_GPF(2),   KEY_S},
	{IRQ_EINT11, "S4",  S3C2410_GPG(3),   KEY_ENTER},
	{IRQ_EINT19, "S5",  S3C2410_GPG(11),  KEY_LEFTSHIFT},
};

static struct timer_list btn_timer;
static struct pin_desc *key_irq_desc=NULL;
static struct input_dev *input_dev=NULL;


static void btn_timer_func(unsigned long data) // 定时器处理函数
{
	struct pin_desc *key_desc = key_irq_desc;
	int pin_val;
	if(NULL==key_desc){
		return;
	}
	pin_val = s3c2410_gpio_getpin(key_desc->pin);
	if(pin_val)
	{
		// 上报事件,按键松开
		input_event(input_dev,EV_KEY,key_desc->key_val,0);
		input_sync(input_dev);
	}
	else
	{
		// 上报事件,按键按下	
		input_event(input_dev,EV_KEY,key_desc->key_val,1);
		input_sync(input_dev);
	}

}

irqreturn_t key_irq_handler(int irq, void *data) // 中断处理函数
{
	key_irq_desc = (struct pin_desc *)data;
	mod_timer(&btn_timer,jiffies+HZ/100);
	return IRQ_HANDLED;
}

static int __init key_init(void)
{
	int ret;
	int i;
	// 分配一个input_device结构体
	input_dev = input_allocate_device();
	if(NULL==input_dev){
		printk(KERN_ERR "input_allocate_device error.\n");
		return -ENOMEM;
	}
	// 设置结构体
	  // 设置能够产生那类事件
	  set_bit(EV_KEY,input_dev->evbit);
	  set_bit(EV_REP,input_dev->evbit);
	  //设置这类事件中的具体哪些事件
	  set_bit(KEY_L,input_dev->keybit);
	  set_bit(KEY_S,input_dev->keybit);
	  set_bit(KEY_ENTER,input_dev->keybit);
	  set_bit(KEY_LEFTSHIFT,input_dev->keybit);
	  input_dev->name = "key_input";

	// 注册该结构体
	  ret = input_register_device(input_dev);
	  if(ret!=0){
	  		printk(KERN_ERR "input_register_device error.\n");
	  		goto err1;
	  }

	// 硬件相关操作
	  for ( i = 0; i < ARRAY_SIZE(pin_desc); ++i)
	  {
	  	// 注册irq中断
	  	request_irq(pin_desc[i].irq,key_irq_handler,\
				IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,\
				pin_desc[i].name,(void*)&pin_desc[i]);
	  }
	  // 初始化定时器
	  init_timer(&btn_timer);
	  btn_timer.function = btn_timer_func;
	  add_timer(&btn_timer);
	return 0;
err1:
	input_free_device(input_dev);
	return ret;
}

static void __exit key_exit(void)
{
	int i;
	for (i = 0; i < ARRAY_SIZE(pin_desc); ++i)
	  {
	  	// 注册irq中断
	  	free_irq(pin_desc[i].irq,(void*)&pin_desc[i]);
	  }
	del_timer(&btn_timer);
	input_unregister_device(input_dev);

}

module_init(key_init);
module_exit(key_exit);

MODULE_LICENSE("GPL");

This snippet took 0.01 seconds to highlight.

Back to the Entry List or Home.

Delete this entry (admin only).