【Linux 驱动】IMX6ULL input驱动

1. input子系统介绍

input 子系统分为 input 驱动层、input 核心层、input 事件处理层,最终给用户空间提供可访问的设备节点。

  • 驱动层:输入设备的具体驱动程序,比如按键驱动程序,向内核层报告输入内容
  • 核心层:承上启下,为驱动层提供输入设备注册和操作接口。通知事件层对输入事件进行处理。
  • 事件层:主要和用户空间进行交互。

2. 重要结构体

2.1 struct input_dev

/*** struct input_dev - represents an input device* @name: name of the device* @phys: physical path to the device in the system hierarchy* @uniq: unique identification code for the device (if device has it)* @id: id of the device (struct input_id)* @propbit: bitmap of device properties and quirks* @evbit: bitmap of types of events supported by the device (EV_KEY,*	EV_REL, etc.)* @keybit: bitmap of keys/buttons this device has* @relbit: bitmap of relative axes for the device* @absbit: bitmap of absolute axes for the device* @mscbit: bitmap of miscellaneous events supported by the device* @ledbit: bitmap of leds present on the device* @sndbit: bitmap of sound effects supported by the device* @ffbit: bitmap of force feedback effects supported by the device* @swbit: bitmap of switches present on the device* @hint_events_per_packet: average number of events generated by the*	device in a packet (between EV_SYN/SYN_REPORT events). Used by*	event handlers to estimate size of the buffer needed to hold*	events.* @keycodemax: size of keycode table* @keycodesize: size of elements in keycode table* @keycode: map of scancodes to keycodes for this device* @getkeycode: optional legacy method to retrieve current keymap.* @setkeycode: optional method to alter current keymap, used to implement*	sparse keymaps. If not supplied default mechanism will be used.*	The method is being called while holding event_lock and thus must*	not sleep* @ff: force feedback structure associated with the device if device*	supports force feedback effects* @repeat_key: stores key code of the last key pressed; used to implement*	software autorepeat* @timer: timer for software autorepeat* @rep: current values for autorepeat parameters (delay, rate)* @mt: pointer to multitouch state* @absinfo: array of &struct input_absinfo elements holding information*	about absolute axes (current value, min, max, flat, fuzz,*	resolution)* @key: reflects current state of device's keys/buttons* @led: reflects current state of device's LEDs* @snd: reflects current state of sound effects* @sw: reflects current state of device's switches* @open: this method is called when the very first user calls*	input_open_device(). The driver must prepare the device*	to start generating events (start polling thread,*	request an IRQ, submit URB, etc.)* @close: this method is called when the very last user calls*	input_close_device().* @flush: purges the device. Most commonly used to get rid of force*	feedback effects loaded into the device when disconnecting*	from it* @event: event handler for events sent _to_ the device, like EV_LED*	or EV_SND. The device is expected to carry out the requested*	action (turn on a LED, play sound, etc.) The call is protected*	by @event_lock and must not sleep* @grab: input handle that currently has the device grabbed (via*	EVIOCGRAB ioctl). When a handle grabs a device it becomes sole*	recipient for all input events coming from the device* @event_lock: this spinlock is is taken when input core receives*	and processes a new event for the device (in input_event()).*	Code that accesses and/or modifies parameters of a device*	(such as keymap or absmin, absmax, absfuzz, etc.) after device*	has been registered with input core must take this lock.* @mutex: serializes calls to open(), close() and flush() methods* @users: stores number of users (input handlers) that opened this*	device. It is used by input_open_device() and input_close_device()*	to make sure that dev->open() is only called when the first*	user opens device and dev->close() is called when the very*	last user closes the device* @going_away: marks devices that are in a middle of unregistering and*	causes input_open_device*() fail with -ENODEV.* @dev: driver model's view of this device* @h_list: list of input handles associated with the device. When*	accessing the list dev->mutex must be held* @node: used to place the device onto input_dev_list* @num_vals: number of values queued in the current frame* @max_vals: maximum number of values queued in a frame* @vals: array of values queued in the current frame* @devres_managed: indicates that devices is managed with devres framework*	and needs not be explicitly unregistered or freed.*/
struct input_dev {const char *name;const char *phys;const char *uniq;struct input_id id;unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];unsigned long evbit[BITS_TO_LONGS(EV_CNT)];unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];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)];unsigned int hint_events_per_packet;unsigned int keycodemax;unsigned int keycodesize;void *keycode;int (*setkeycode)(struct input_dev *dev,const struct input_keymap_entry *ke,unsigned int *old_keycode);int (*getkeycode)(struct input_dev *dev,struct input_keymap_entry *ke);struct ff_device *ff;unsigned int repeat_key;struct timer_list timer;int rep[REP_CNT];struct input_mt *mt;struct input_absinfo *absinfo;unsigned long key[BITS_TO_LONGS(KEY_CNT)];unsigned long led[BITS_TO_LONGS(LED_CNT)];unsigned long snd[BITS_TO_LONGS(SND_CNT)];unsigned long sw[BITS_TO_LONGS(SW_CNT)];int (*open)(struct input_dev *dev);void (*close)(struct input_dev *dev);int (*flush)(struct input_dev *dev, struct file *file);int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);struct input_handle __rcu *grab;spinlock_t event_lock;struct mutex mutex;unsigned int users;bool going_away;struct device dev;struct list_head	h_list;struct list_head	node;unsigned int num_vals;unsigned int max_vals;struct input_value *vals;bool devres_managed;
};
  • evbit 表示输入事件类型,比如同步事件、按键事件等
#define EV_SYN 0x00 /* 同步事件 */
#define EV_KEY 0x01 /* 按键事件 */
#define EV_REL 0x02 /* 相对坐标事件 */
#define EV_ABS 0x03 /* 绝对坐标事件 */
#define EV_MSC 0x04 /* 杂项(其他)事件 */
#define EV_SW 0x05 /* 开关事件 */
#define EV_LED 0x11 /* LED */
#define EV_SND 0x12 /* sound(声音) */
#define EV_REP 0x14 /* 重复事件 */
#define EV_FF 0x15 /* 压力事件 */
#define EV_PWR 0x16 /* 电源事件 */
#define EV_FF_STATUS 0x17 /* 压力状态事件 */
  • keybit、relbit 等等都是存放不同事件对应的值,比如keybit支持KEY_1、KEY_2等
#define KEY_RESERVED 0
#define KEY_ESC 1
#define KEY_1 2
#define KEY_2 3
#define KEY_3 4
#define KEY_4 5
#define KEY_5 6
#define KEY_6 7
#define KEY_7 8
#define KEY_8 9
#define KEY_9 10
#define KEY_0 11
......
#define BTN_TRIGGER_HAPPY39 0x2e6
#define BTN_TRIGGER_HAPPY40 0x2e7

2.2 struct input_handler

/*** struct input_handler - implements one of interfaces for input devices* @private: driver-specific data* @event: event handler. This method is being called by input core with*	interrupts disabled and dev->event_lock spinlock held and so*	it may not sleep* @events: event sequence handler. This method is being called by*	input core with interrupts disabled and dev->event_lock*	spinlock held and so it may not sleep* @filter: similar to @event; separates normal event handlers from*	"filters".* @match: called after comparing device's id with handler's id_table*	to perform fine-grained matching between device and handler* @connect: called when attaching a handler to an input device* @disconnect: disconnects a handler from input device* @start: starts handler for given handle. This function is called by*	input core right after connect() method and also when a process*	that "grabbed" a device releases it* @legacy_minors: set to %true by drivers using legacy minor ranges* @minor: beginning of range of 32 legacy minors for devices this driver*	can provide* @name: name of the handler, to be shown in /proc/bus/input/handlers* @id_table: pointer to a table of input_device_ids this driver can*	handle* @h_list: list of input handles associated with the handler* @node: for placing the driver onto input_handler_list** Input handlers attach to input devices and create input handles. There* are likely several handlers attached to any given input device at the* same time. All of them will get their copy of input event generated by* the device.** The very same structure is used to implement input filters. Input core* allows filters to run first and will not pass event to regular handlers* if any of the filters indicate that the event should be filtered (by* returning %true from their filter() method).** Note that input core serializes calls to connect() and disconnect()* methods.*/
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;
};

2.3 设备获取、上报数据:struct input_event

/** The event structure itself*/struct input_event {struct timeval time;__u16 type;__u16 code;__s32 value;
};struct timeval {__kernel_time_t		tv_sec;		/* seconds */__kernel_suseconds_t	tv_usec;	/* microseconds */
};
  • time:事件发生时间
  • type:事件类型,EV_KEY、EV_ABS等
  • code:事件码,KEY_1、KEY_2等
  • value:值,比如 EV_KEY 事件中 value 就是按键值,表示按键有没有被按下,如果为 1 的话说明按键按下,如果为 0 的话说明按键没有被按下或者按键松开了

3. input 内部实现

  •  和platform总线驱动相似,左右两边依次比较,如果匹配,则调用input_handler结构体的connect函数

3.1 input 驱动编写流程

static int __init input_init(void)
{int err;err = class_register(&input_class);if (err) {pr_err("unable to register input_dev class\n");return err;}err = input_proc_init();if (err)goto fail1;err = register_chrdev_region(MKDEV(INPUT_MAJOR, 0),INPUT_MAX_CHAR_DEVICES, "input");if (err) {pr_err("unable to register char major %d", INPUT_MAJOR);goto fail2;}return 0;fail2:	input_proc_exit();fail1:	class_unregister(&input_class);return err;
}static void __exit input_exit(void)
{input_proc_exit();unregister_chrdev_region(MKDEV(INPUT_MAJOR, 0),INPUT_MAX_CHAR_DEVICES);class_unregister(&input_class);
}subsys_initcall(input_init);
module_exit(input_exit);
  • 注册一个 input 类,这样系统启动以后就会在/sys/class 目录下有一个 input 子目录

  •  注册一个主设备号为INPUT_MAJOR(13)的字符驱动,后续在使用 input 子系统处理输入设备的时候就不需要去注册字符设备了,我们只需要向系统注册一个 input_device 即可

3.2 input_dev(ft5x06.c)注册过程

 3.3 struct input_handler(evdev.c)注册过程

3.4 input_register_device

 3.5 input_register_handler

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/393539.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV图像滤波(5)二维卷积滤波函数filter2D()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::filter2D() 函数用于对图像应用二维卷积滤波器。这个函数可以用来实现多种图像处理操作,如模糊、锐化、边缘检测等。它通过将一个…

stm32应用、项目、调试

主要记录实际使用中的一些注意点。 1.LCD1602 电路图: 看手册:电源和背光可以使用5v或者3.3v,数据和控制引脚直接和单片机引脚连接即可。 单片机型号:stm32c031c6t6 可以直接使用推完输出连接D0--D7,RS,EN,RW引脚,3…

Linux--网络层IP

IP协议 IP协议,全称Internet Protocol(互联网协议),是TCP/IP协议族中的核心协议之一,用于在互联网络上进行数据的传输。IP协议的主要功能是确保数据从一个网络节点(如计算机、服务器、路由器等&#xff09…

OpenDataLab:人工智能开放数据平台

作者:CSDN _养乐多_ 本文将介绍一个人工智能开放数据平台,OpenDataLab。 文章目录 一、OpenDataLab介绍二、下载 一、OpenDataLab介绍 官网链接: OpenDataLab:https://opendatalab.com/ 这里面有很多数据集,包括计…

CCIA2024“网络安全优秀创新成果大赛-哈尔滨分站赛”优胜奖,花落谁家?

近日,“2024 年网络安全优秀创新成果大赛 - 哈尔滨分站赛”评选结果正式公布。此次大赛由黑龙江省委网信办指导,中国网络安全产业联盟主办,哈尔滨工业大学网络空间安全学院承办。开源网安代码审核平台 CodeSec 凭借在 AI 方向的创新能力和极高…

JavaEE: 进程和线程

文章目录 进程线程的概念和区别总结如何创建线程1.继承Thread重写run2.实现Runnable重写run3.继承Thread重写run,通过匿名内部类来实现4. 实现Runnable重写run,通过匿名内部类来实现5.基于lambda表达式来创建 虚拟线程 并发编程: 通过写特殊的代码,把多个CPU核心都利…

Mojo使用调试工具(Visual Studio Code)详解

Visual Studio Code 的 Mojo 扩展使您可以将 VS Code 的内置调试器与 Mojo 程序一起使用。(Mojo 扩展还支持调试 C、C++ 和 Objective-C。) 有关 VS Code 调试功能的完整介绍,请参阅 Visual Studio Code 中的调试。 本文介绍了可通过 Mojo 扩展获得的功能,以及 Mojo 调试…

层次分析法(评价类问题)

目录 本文章内容来自: 层次分析法模型讲解(附matlab和python代码) 【数学建模快速入门】数模加油站 江北_哔哩哔哩_bilibili 一. 概念 二. 适用的问题范围 三. 层次分析法的四个步骤 四. 对应代码 本文章内容来自: 层次分析法模型讲解(附matlab和…

【面试题】串联所有单词的子串,找到所有符合条件的串联子串的起始索引

串联所有单词的子串,找到所有符合条件的串联子串的起始索引 面试学习 一、题目 串联所有单词的子串 二、解题思路 2.1 定义子串长度 所有字符串 words 的长度是相同的,假设为 L。那么一个有效的串联子串的总长度应该是 L * len(words)。 2.2 滑动窗…

解决Minizip压缩后解压时的头部错误问题

最近,在处理文件压缩的任务时,我遇到了一个有趣的问题。使用Minizip库进行文件压缩后,在解压过程中收到了一个关于"头部错误"的警告。尽管这个警告看似令人担忧,但解压操作最终仍然能够成功完成文件的解压。这引发了我的…

BM1反转链表[栈+头插法]

题目要求如下: 问题比较简单,就是将链表中的值进行反转即可。 一种比较简单的方式是使用栈链表的方式来实现,下面是相应的代码: #include <stdio.h> #include <stdlib.h> int arr[10001] {0}; struct ListNode* ReverseList(struct ListNode* head ) {if (head …

编译运行 Byconity

我的系统是centos&#xff0c;因此用他们的docker编译并用他们的docker-compose运行&#xff0c;以下流程亲测可跑&#xff1a; 拉取并编译 https://github.com/ByConity/ByConity/tree/master/docker/debian/dev-env 运行 https://github.com/ByConity/ByConity/blob/master/d…

Day-16 SpringBoot原理

SpingBoot原理 在前面十多天的课程当中&#xff0c;我们学习的都是web开发的技术使用&#xff0c;都是面向应用层面的&#xff0c;我们学会了怎么样去用。而我们今天所要学习的是web后端开发的最后一个篇章springboot原理篇&#xff0c;主要偏向于底层原理。 我们今天的课程安…

20240807 每日AI必读资讯

&#x1f468;‍&#x1f4bc;马斯克再发难、OpenAI 高层巨变&#xff1a;两大核心人物离职&#xff0c;总裁休长假到年底 - OpenAI 联合创始人 John Schulman 官宣离职&#xff0c;加入原是竞品公司的 Anthropic - 陪伴 OpenAI 共同成长 9 年的总裁兼联合创始人 Greg Brockm…

事务和索引(面试常问)

面试常问&#xff1a; 一、数据库隔离级别&#xff1f;事务隔离级别解决的问题&#xff1f; 答&#xff1a;1.数据库隔离级别&#xff1a; READ_UNCOMMITTED 读未提交 READ_COMMITTED 读提交&#xff08;不可重复读&#xff09; REPEATABLE_READ 可重复读 SERIALIZABLE 串行化…

sed 简易使用指南

sed 简易使用指南 1 sed 介绍2 查找3 替换4 反向引用5 删除6 cai&#xff08;菜&#xff09; 导言&#xff1a; 笔者之前花了较多时间学习并整理了sed命令相关的内容&#xff0c;以及一些进阶内容。但是&#xff0c;到后来使用也就只记得那么几个简单的选项&#xff0c;再高级的…

6-8 残差网络(ResNet)

随着我们设计越来越深的网络&#xff0c;深刻理解“新添加的层如何提升神经网络的性能”变得至关重要。更重要的是设计网络的能力&#xff0c;在这种网络中&#xff0c;添加层会使网络更具表现力&#xff0c; 为了取得质的突破&#xff0c;我们需要一些数学基础知识。 残差网络…

【虚拟化】KVM使用virt-manager部署及管理虚拟机

目录 一、KVM 概述 二、KVM工作原理 三、部署KVM 四、新建虚拟机步骤 4.1 创建存储池并创建存储卷 4.1.1 创建存储池 4.1.2 创建存储卷 4.3 创建ISO存储池 4.4 生成新的虚拟机 一、KVM 概述 KVM 是 Kernel-based Virtual Machine 的缩写&#xff0c;是一种用于虚拟化的…

大模型微调深入研究

在本博文系列的前一部分中&#xff0c;我们探讨了情境学习的概念&#xff0c;这是一种克服大型语言模型 (LLM) 的“舒适区”限制的强大方法。我们讨论了如何使用这些技术来转换任务并将其移回模型的专业领域&#xff0c;从而提高性能并与有用性、诚实性和无害性的关键设计原则保…

WebBench源码分析

WebBench 源码解析 一、前言 WebBench 作为一款网站性能测试工具&#xff0c;其源码蕴含着丰富的技术细节和逻辑流程。本文将深入剖析其安装编译过程以及关键函数的核心逻辑。 二、安装编译 1. 克隆代码到本地仓库 git clone https://github.com/EZLippi/WebBench.git2. 编…