Linux input输入子系统demo驱动

在TP驱动代码分析中,接触到了input子系统,TP驱动将检测到的所有按键或者坐标都上报给了input子系统。Input子系统是所有I/O设备驱动的中间层,为上层提供了一个统一的界面。例如,在终端系统中,我们不需要去管有多少个键盘,多少个鼠标。它只要从input子系统中去取对应的事件(坐标,按键,鼠标移位等)就可以了。下面是一个input子系统的DEMO驱动,参考价值5颗星,这个是关键代码,有问题欢迎指出,不吝赐教,技术无边,多多交流。

DEMO驱动主要是注册一个input设备,通过工作队列每隔1秒向上层上报event事件。


	/*
	 *注意:此时会生成/dev/input/eventX // X 为 0  1 2 3
	 *测试:cat /proc/bus/input/devices会发现注册的设备
	 */
	#include <linux/module.h>
	#include <linux/device.h>
	#include <linux/hrtimer.h>
	#include <linux/i2c.h>
	#include <linux/interrupt.h>
	#include <linux/io.h>
	#include <linux/platform_device.h>
	#include <linux/async.h>
	#include <linux/irq.h>
	#include <linux/workqueue.h>
	#include <linux/proc_fs.h>
	#include <linux/input/mt.h>
	#include <asm/uaccess.h>
	#include <linux/version.h>
	#include <linux/slab.h>
	#include <linux/of_gpio.h>
	#include <linux/miscdevice.h>
	#include <linux/delay.h>
	#include <linux/input.h> //包含的头文件

	static struct input_dev *sensor_input_dev; //声明一个input设备结构体
	#define DEV_NAME "sensor_input_dev" //宏定义输入设备名称为sensor_input_dev
	
	static struct delayed_work send_event; //声明一个delayed_work结构体,延时工作队列

	static int temperature_report_value(struct input_dev *input, int data) //上报event的调用接口,对接到实际获取数据的接口函数
	{
		printk("%s:line=%d, after sensor_report_value data[%d][%x]\n",
					__func__,__LINE__, data, data);

	input_report_abs(input, ABS_THROTTLE, data);
	input_sync(input);

	return 0;
	}

	static int sensor_report_value(void)
	{	int ret;
	int result = 29; //对接到实际获取数据的接口函数,这里先随便整个数29

	ret = temperature_report_value(sensor_input_dev, result);
	printk("__%s(%d)__, ret = %d\n", __func__, __LINE__, ret);
	return 0;
	
	}

	static void send_event_workq(struct work_struct *work) //延时工作队列要做的事都在这里实现
	{
		int ret;

		ret = sensor_report_value();
		printk("__%s(%d)__, ret = %d\n", __func__, __LINE__, ret);
		schedule_delayed_work(&send_event, msecs_to_jiffies(1000)); //每隔一秒执行一次send_event_workq
	}


	static int __init test_init(void)
	{
		int ret;

	printk("%s init start\n", __func__);
	sensor_input_dev = input_allocate_device(); //分配输入设备,失败返回NULL
	sensor_input_dev -> name = DEV_NAME; //输入设备名字
	set_bit(EV_ABS, sensor_input_dev->evbit); //设置输入设备事件类型为绝对坐标事件
	input_set_abs_params(sensor_input_dev, ABS_THROTTLE, 100, 65535, 0, 0);
	//对于ABS_THROTTLE范围是100到65535,数据误差是+-0,中心平滑位置是0

	ret = input_register_device(sensor_input_dev); //将设备注册进输入子系统
	if (ret) {
		pr_err("input_register_device ret: %d\n", ret);
		input_free_device(sensor_input_dev);//释放内存
		return -1;
	}

	INIT_DELAYED_WORK(&send_event, send_event_workq); //初始化工作队列
	schedule_delayed_work(&send_event, msecs_to_jiffies(2000)); //2s后开启工作队列

    printk("%s init end\n", __func__);
    return 0;
	}

		static void __exit test_exit(void)
	{
	cancel_delayed_work_sync(&send_event); //取消工作队列
    input_unregister_device(sensor_input_dev); //注销input设备
	}

	module_init(test_init);
	module_exit(test_exit);

	MODULE_DESCRIPTION("For test input system driver");
	MODULE_AUTHOR("cai.zhongding");
	MODULE_LICENSE("GPL");

执行getevent可以看到event上报事件:

	rk3399_all:/ # getevent                                                    
	add device 1: /dev/input/event3
	   name:     "sensor_input_dev"
	add device 2: /dev/input/event2
 	  name:     "rk29-keypad"
	add device 3: /dev/input/event1
	  name:     "rockchip-cdndp-sound DP Jack"
	add device 4: /dev/input/event0
	  name:     "ff420030.pwm"
	/dev/input/event3: 0003 0006 00000a58
	/dev/input/event3: 0000 0000 00000000
	/dev/input/event3: 0003 0006 00000a56
	/dev/input/event3: 0000 0000 00000000
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零意@

您的打赏将是我继续创作的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值