通过定时器上报键值
定时器两要素:超时时间和超时处理函数
通过init_timer初始化一个timer_list,然后指定超时处理函数
在中断处理函数里调用mod_timer指定多少时间后执行超时处理函数
参考代码:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/major.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/io.h>
#include <linux/sched.h>
//#include <asm/irq.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#define TAG "keyvol"
#define INT_GPIO 91
#define MY_KEY_CODE KEY_T
struct timer_list key_timer_list;
static int irq;
static struct input_dev *kinput;
static int prevalue;
static int value;
volatile unsigned long *tlmm_gpio_cfg;
volatile unsigned long *tlmm_in_out;
static void key_timer_func(unsigned long data)
{
printk(TAG"%s\n", __func__);
value = *tlmm_in_out;
value &= 0x1;
if (value == prevalue) {
if (value) {
input_report_key(kinput, MY_KEY_CODE, 0);
input_sync(kinput);
printk(TAG"key is release\n");
} else {
input_report_key(kinput, MY_KEY_CODE, 1);
input_sync(kinput);
printk(TAG"key is press\n");
}
}
}
static irqreturn_t key_irq_thread(int irq, void *data)
{
printk(TAG"%s\n", __func__);
prevalue = *tlmm_in_out;
prevalue &= 0x1;
mod_timer(&key_timer_list, jiffies + msecs_to_jiffies(10));
return IRQ_HANDLED;
}
static int my_key_init(void)
{
int retval;
printk(TAG"%s %d\n", __func__, __LINE__);
kinput = input_allocate_device();
if (!kinput)
return -ENOMEM;
kinput->name = "keyt";
__set_bit(EV_KEY, kinput->evbit);
__set_bit(MY_KEY_CODE, kinput->keybit);
retval = input_register_device(kinput);
if(retval)
goto input_register_error;
tlmm_gpio_cfg = (volatile unsigned long *)ioremap(0x105B000, 8);
tlmm_in_out = tlmm_gpio_cfg + 1;
*tlmm_gpio_cfg |= 0x3;
irq = gpio_to_irq(INT_GPIO);
printk(TAG"%s irq is %d\n", __func__, irq);
retval = request_threaded_irq(irq, NULL, key_irq_thread, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |IRQF_ONESHOT, "vol_key", NULL);
printk(TAG"%s ret is %d\n", __func__, retval);
init_timer(&key_timer_list);
key_timer_list.function = key_timer_func;
return 0;
input_register_error:
input_free_device(kinput);
return retval;
}
static void key_exit(void)
{
ioremap(tlmm_gpio_cfg);
del_timer(&key_timer_list);
free_irq(irq, NULL);
input_unregister_device(kinput);
printk(TAG"%s %d\n", __func__, __LINE__);
}
module_init(my_key_init);
module_exit(key_exit);
MODULE_LICENSE("GPL");