1. 通过key上报事件

#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;
};

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值