#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
#include <linux/gpio.h>
#include <linux/errno.h>
#include <linux/input.h>
#include <linux/bitops.h>
int irq;
int key2_gpio = 0;
struct input_dev *my_dev = NULL;
irqreturn_t key2_irq_handler(int irq, void *data) //cat /dev/input/xxx
{
input_event(my_dev,EV_KEY,KEY_2,0);
input_sync(my_dev);
input_event(my_dev,EV_KEY,KEY_2,1);
input_sync(my_dev);
//printk("enter inrq\n");
return IRQ_HANDLED;
}
static int __init key_init(void)
{
struct device_node * np = NULL;
int ret = 0;
np = of_find_node_by_path("/key2-gpio");
if(np == NULL){
printk("%s,%d of_find_node_by_path FAIL...\n",__func__,__LINE__);
return -ENOMEM;
}
key2_gpio = of_get_named_gpio(np,"key2",0);
if(key2_gpio < 0 ){
printk("%s,%d of_get_named_gpio FAIL...\n",__func__,__LINE__);
return -EINVAL;
}
irq = gpio_to_irq(key2_gpio);
if(irq < 0 ){
printk("%s,%d gpio_to_irq FAIL...\n",__func__,__LINE__);
return -EINVAL;
}
ret = request_irq(irq,key2_irq_handler,IRQF_TRIGGER_FALLING,"key2",NULL);
if(ret < 0 ){
printk("%s,%d request_irq FAIL...\n",__func__,__LINE__);
return -EINVAL;
}
my_dev = input_allocate_device();
if(my_dev == NULL){
printk("%s,%d input_allocate_device FAIL...\n",__func__,__LINE__);
return -ENOMEM;
}
set_bit(EV_KEY,my_dev->evbit);//type
set_bit(KEY_2,my_dev->keybit);//CODE
ret= input_register_device(my_dev);
if(ret < 0 ){
printk("%s,%d input_register_device FAIL...\n",__func__,__LINE__);
return -EINVAL;
}
printk("%s,%d\n",__func__,__LINE__);
return 0;
}
static void __exit key_exit(void)
{
input_unregister_device(my_dev);
input_free_device(my_dev);
free_irq(irq,NULL);
printk("%s,%d\n",__func__,__LINE__);
}
module_init(key_init);
module_exit(key_exit);
MODULE_LICENSE("GPL");
1. 先看下设备数节点的获取,用于获取中断号。
2. 有里中断号,再看下中断的处理。
3. input的函数API
(1)struct input_dev *input_allocate_device(void)
功能:分配input_dev设备对象
参数:无
返回值:成功:struct input_dev 失败:NULL
(2)static inline void set_bit(int nr, volatile void *addr)
功能:对input_dev完成相关事件类型与时间代码支持的设置
参数:nr:具体待填充的数据
addr:待填充数据的被填充地址
返回值:无
//struct input_dev dev;
//set_bit(EV_KEY,dev.evbit);
(3)int input_register_device(struct input_dev *dev)
功能:注册input_dev对象
参数:dev:input_dev的指针对象
返回值:成功:0 失败:error
(4)void input_unregister_device(struct input_dev *dev)
功能:注销input_dev对象
参数:dev:input_dev的指针对象
返回值:无
(5)void input_free_device(struct input_dev *dev)
功能:释放input_dev对象
参数:dev:input_dev的指针对象
返回值:无
(6)void input_event(struct input_dev *dev,unsigned int type, unsigned int code, int value)
功能:完成input的事件上报
参数:dev:input_dev的指针对象
type:待上报的事件类型
code:待上报的事件代码
value:待上报的事件值
返回值:无
(7)void input_sync();//同步 告诉此次报告结束
struct input_dev {
const char *name;//名称
unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; //该输入设备能够上报的事件的type EV_KEY
unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];//该输入设备能够上报的事件的code KEY_1 ,KEY2
unsigned long relbit[BITS_TO_LONGS(REL_CNT)];
unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
struct input_handle __rcu *grab;//核心层对象
struct device dev;
struct list_head h_list;//负责连接至input_handle
struct list_head node;//负责连接input_dev --->input_dev_list
};
struct input_handler {
void *private;
void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
void (*events)(struct input_handle *handle,
const struct input_value *vals, unsigned int count);
bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
bool (*match)(struct input_handler *handler, struct input_dev *dev);
int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
void (*disconnect)(struct input_handle *handle);
void (*start)(struct input_handle *handle);
bool legacy_minors;
int minor;
const char *name;
const struct input_device_id *id_table;
struct list_head h_list;
struct list_head node;
};
struct input_handle {
void *private;
int open;
const char *name;
struct input_dev *dev; // 设备驱动层
struct input_handler *handler; // 功能实现,软件事件处理层
struct list_head d_node;
struct list_head h_node;
};