输入子系统¶
输入核心¶
-
struct input_value¶
输入值表示
定义:
struct input_value {
__u16 type;
__u16 code;
__s32 value;
};
成员
type值的类型(EV_KEY、EV_ABS 等)
code值的编码
value值
-
struct input_dev¶
表示一个输入设备
定义:
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;
struct input_dev_poller *poller;
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 *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;
ktime_t timestamp[INPUT_CLK_MAX];
bool inhibited;
};
成员
name设备名称
phys设备在系统层级中的物理路径
uniq设备的唯一识别码(如果设备具有)
id设备的 ID(
struct input_id)propbit设备属性和特殊行为(quirks)的位图
evbit设备支持的事件类型位图(EV_KEY、EV_REL 等)
keybit此设备拥有的按键/按钮位图
relbit设备的相对轴位图
absbit设备的绝对轴位图
mscbit设备支持的杂项事件位图
ledbit设备上存在的 LED 位图
sndbit设备支持的声音效果位图
ffbit设备支持的力反馈效果位图
swbit设备上存在的开关位图
hint_events_per_packet设备在一个数据包中(EV_SYN/SYN_REPORT 事件之间)生成的平均事件数。事件处理程序使用它来估算容纳事件所需的缓冲区大小。
keycodemax按键码(keycode)表的大小
keycodesize按键码(keycode)表中元素的大小
keycode此设备的扫描码(scancode)到按键码(keycode)的映射表
setkeycode用于修改当前键图(keymap)的可选方法,用于实现稀疏键图。如果未提供,将使用默认机制。该方法在持有 event_lock 时被调用,因此绝对不能休眠
getkeycode用于检索当前键图的可选传统方法。
ff如果设备支持力反馈效果,则为与该设备关联的力反馈结构
poller如果设备被设置为使用轮询模式,则为与该设备关联的轮询器(poller)结构
repeat_key存储上一次按下的按键码;用于实现软件自动重复
timer用于软件自动重复的定时器
rep自动重复参数(延迟、速率)的当前值
mt指向多点触控状态的指针
absinfostruct input_absinfo元素数组,保存关于绝对轴的信息(当前值、最小值、最大值、平滑度、模糊度、分辨率)key反映设备按键/按钮的当前状态
led反映设备 LED 的当前状态
snd反映声音效果的当前状态
sw反映设备开关的当前状态
open当第一个用户调用
input_open_device()时,会调用此方法。驱动程序必须准备好设备以开始生成事件(启动轮询线程、请求 IRQ、提交 URB 等)。open() 的意义是开始向输入核心提供事件。close当最后一个用户调用
input_close_device()时,会调用此方法。close() 的意义是停止向输入核心提供事件。flush清除设备。最常用于在与设备断开连接时,清除加载到设备中的力反馈效果
event发送“至”设备的事件(如 EV_LED 或 EV_SND)的事件处理程序。设备应当执行所请求的操作(打开 LED、播放声音等)。该调用受 event_lock 保护,且绝对不能休眠
grab当前独占(通过 EVIOCGRAB ioctl)该设备的输入句柄。当句柄独占一个设备时,它将成为来自该设备的所有输入事件的唯一接收者
event_lock当输入核心接收并处理设备的全新事件时(在
input_event()中),将获取此自旋锁。在设备向输入核心注册后,访问和/或修改设备参数(如键图或 absmin、absmax、absfuzz 等)的代码必须获取此锁。mutex序列化对 open()、close() 和
flush()方法的调用users存储打开此设备的普通用户(输入处理程序)数量。它被
input_open_device()和input_close_device()用于确保仅在第一个用户打开设备时才调用 dev->open(),在最后一个用户关闭设备时才调用 dev->close()going_away标记正在进行注销的设备,并导致 input_open_device*() 失败并返回 -ENODEV。
dev驱动模型视角下的该设备
h_list与设备关联的输入句柄列表。访问该列表时必须持有 dev->mutex
node用于将设备放入 input_dev_list
num_vals在当前帧中排队的数值数量
max_vals在一帧中排队的最大数值数量
vals在当前帧中排队的数值数组
devres_managed表示设备由 devres 框架管理,不需要显式注销或释放。
timestamp用于存储由驱动程序调用的 input_set_timestamp 设置的时间戳
inhibited表示输入设备处于禁止(inhibited)状态。在这种情况下,输入核心会忽略设备生成的任何事件。设备在被禁止时会调用其 close(),在解除禁止时会调用其 open()。
-
struct input_handler¶
实现输入设备的接口之一
定义:
struct input_handler {
void *private;
void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
unsigned int (*events)(struct input_handle *handle, 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 passive_observer;
bool legacy_minors;
int minor;
const char *name;
const struct input_device_id *id_table;
struct list_head h_list;
struct list_head node;
};
成员
私有驱动程序特定数据
event事件处理程序。该方法由输入核心在禁用中断且持有 dev->event_lock 自旋锁的情况下调用,因此它不能休眠
events事件序列处理程序。该方法由输入核心在禁用中断且持有 dev->event_lock 自旋锁的情况下调用,因此它不能休眠。该方法必须返回传递给它的事件数量。
filter类似于 event;将普通事件处理程序与“过滤器”分开。
match在将设备的 id 与处理程序的 id_table 进行比较后调用,以在设备和处理程序之间执行细粒度的匹配
connect将处理程序连接到输入设备时调用
disconnect将处理程序与输入设备断开连接
start为给定的句柄启动处理程序。此函数由输入核心在紧随
connect()方法之后,以及“独占”设备的进程释放该设备时调用passive_observer对于在存在其他用户时仅对观察来自设备的数据流感兴趣的驱动程序,将其设置为
true。当为其句柄调用input_open_device()时,此类驱动程序不会导致底层硬件设备启动legacy_minors对于使用传统次设备号(minor)范围的驱动程序,将其设置为
trueminor此驱动程序可以提供的设备的 32 个传统次设备号范围的起点
name处理程序的名称,将显示在 /proc/bus/input/handlers 中
id_table指向此驱动程序可以处理的 input_device_ids 表的指针
h_list与该处理程序关联的输入句柄列表
node用于将驱动程序放入 input_handler_list
描述
输入处理程序连接 to 输入设备并创建输入句柄。在任何给定的输入设备上,可能同时连接了多个处理程序。它们都将获得该设备生成的输入事件的副本。
完全相同的结构也用于实现输入过滤器。输入核心允许过滤器首先运行,如果任何过滤器指示应过滤该事件(通过从其 filter() 方法中返回 true),则不会将事件传递给常规处理程序。
请注意,输入核心会序列化对 connect() 和 disconnect() 方法的调用。
-
struct input_handle¶
将输入设备与输入处理程序连接起来
定义:
struct input_handle {
void *private;
int open;
const char *name;
struct input_dev *dev;
struct input_handler *handler;
unsigned int (*handle_events)(struct input_handle *handle, struct input_value *vals, unsigned int count);
struct list_head d_node;
struct list_head h_node;
};
成员
私有处理程序特定数据
open显示句柄是否“打开”的计数器,即是否应该从其设备传递事件
name创建该句柄的处理程序赋予该句柄的名称
dev句柄所连接的输入设备
handler通过此句柄与设备协作的处理程序
handle_events事件序列处理程序。它由输入核心根据 handler 中指定的事件处理方法进行设置。参见
input_handle_setup_event_handler()。该方法由输入核心在禁用中断且持有 dev->event_lock 自旋锁的情况下调用,因此它不能休眠。d_node用于将句柄放入设备的已连接句柄列表中
h_node用于将句柄放入处理程序的句柄列表中,处理程序从该列表中获取事件
参数
struct input_dev *dev驱动程序使用的输入设备
int n_events对
input_sync()的两次调用之间的平均事件数
描述
如果设备发送的事件速率异常大,请使用此函数设置预期的事件速率。这将允许处理程序为事件流设置适当的缓冲区大小,以尽量减少信息丢失。
-
struct ff_device¶
输入设备的力反馈部分
定义:
struct ff_device {
int (*upload)(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old);
int (*erase)(struct input_dev *dev, int effect_id);
int (*playback)(struct input_dev *dev, int effect_id, int value);
void (*set_gain)(struct input_dev *dev, u16 gain);
void (*set_autocenter)(struct input_dev *dev, u16 magnitude);
void (*destroy)(struct ff_device *);
void (*stop)(struct ff_device *);
void *private;
unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
struct mutex mutex;
int max_effects;
struct ff_effect *effects;
struct file *effect_owners[];
};
成员
upload调用以向设备上传新效果
erase调用以从设备中擦除效果
playback调用以请求设备开始播放指定的效果
set_gain调用以设置指定的增益
set_autocenter调用以使设备自动居中
destroy当父输入设备正在被销毁时,由输入核心调用
stop当父输入设备正在被注销时,由输入核心调用
私有驱动程序特定的数据,将自动释放
ffbit设备真正支持的力反馈能力的位图(不像 input_dev->ffbit 中那样是模拟的)
mutex用于序列化设备访问的互斥锁(mutex)
max_effects设备支持的最大效果数量
effects指向当前加载到设备中的效果数组的指针
effect_owners效果所有者数组;当拥有某个效果的文件句柄关闭时,该效果将被自动擦除
描述
每个力反馈设备都必须实现 upload() 和 playback() 方法;erase() 是可选的。set_gain() 和 set_autocenter() 仅在驱动程序设置了 FF_GAIN 和 FF_AUTOCENTER 位时才需要实现。
请注意,playback()、set_gain() 和 set_autocenter() 在调用时,dev->event_lock 自旋锁处于持有状态且中断关闭,因此不能休眠。
参数
struct input_dev *dev生成该事件的设备
unsigned int type事件的类型
unsigned int code事件代码
int value事件的值
描述
该函数应由实现各种输入设备的驱动程序用于报告输入事件。另请参阅 input_inject_event()。
注意
在通过 input_allocate_device() 分配输入设备后,即使在通过 input_register_device() 注册设备之前,也可以安全地使用 input_event(),但该事件不会到达任何输入处理程序。对此类早期调用的 input_event() 可用于“植入”开关的初始状态或绝对轴的初始位置等。
-
void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)¶
从输入处理程序发送输入事件
参数
struct input_handle *handle用于发送事件的输入句柄
unsigned int type事件的类型
unsigned int code事件代码
int value事件的值
描述
类似于 input_event(),但如果设备已被“独占”且注入事件的句柄不是拥有该设备的句柄,则会忽略该事件。
参数
struct input_dev *dev发送绝对事件的输入设备
描述
如果调用者请求的 absinfo struct the 已经分配,此函数将不执行任何操作。
-
void input_copy_abs(struct input_dev *dst, unsigned int dst_axis, const struct input_dev *src, unsigned int src_axis)¶
将 absinfo 从一个 input_dev 复制到另一个
参数
struct input_dev *dst要将绝对值(abs)设置复制到的目标输入设备
unsigned int dst_axis选择目标轴的 ABS_* 值
const struct input_dev *src要从中复制绝对值(abs)设置的源输入设备
unsigned int src_axis选择源轴的 ABS_* 值
描述
通过从指定的源输入设备的源轴复制设置,来为选定的目标轴设置 absinfo。这对于例如在触摸屏/笔组合硬件中为手写笔输入设备进行设置非常有用,其中笔使用与触摸屏相同的坐标。
-
int input_grab_device(struct input_handle *handle)¶
独占设备以供专属使用
参数
struct input_handle *handle希望拥有该设备的输入句柄
描述
当设备被输入句柄独占时,该设备生成的所有事件仅传递给该句柄。此外,在设备被独占期间,由其他输入句柄注入的事件将被忽略。
-
void input_release_device(struct input_handle *handle)¶
释放先前独占的设备
参数
struct input_handle *handle拥有该设备的输入句柄
描述
释放之前独占的设备,以便其他输入句柄可以开始接收输入事件。释放后,连接到该设备的所有处理程序都将调用其 start() 方法,以便它们有机会将设备状态与系统其余部分进行同步。
-
int input_open_device(struct input_handle *handle)¶
打开输入设备
参数
struct input_handle *handle访问设备所通过的句柄
描述
当输入处理程序希望开始接收来自给定输入设备的事件时,应调用此函数。
-
void input_close_device(struct input_handle *handle)¶
关闭输入设备
参数
struct input_handle *handle访问设备所通过的句柄
描述
当输入处理程序希望停止接收来自给定输入设备的事件时,应调用此函数。
-
int input_scancode_to_scalar(const struct input_keymap_entry *ke, unsigned int *scancode)¶
转换
struct input_keymap_entry中的扫描码(scancode)
参数
const struct input_keymap_entry *ke包含要转换的扫描码的键图条目。
unsigned int *scancode指向用于存储转换后的扫描码的位置的指针。
描述
此函数用于将存储在 struct keymap_entry 中的扫描码转换为传统键图处理方法所能理解的标量形式。这些方法期望扫描码表示为“unsigned int”。
-
int input_default_setkeycode(struct input_dev *dev, const struct input_keymap_entry *ke, unsigned int *old_keycode)¶
默认的 setkeycode 方法
参数
struct input_dev *dev正在更新键图的输入设备。
const struct input_keymap_entry *ke新键图条目。
unsigned int *old_keycode指向用于存储旧按键码的位置的指针。
描述
此函数是 input_dev.setkeycode() 方法的默认实现。它通常在驱动程序不提供其自身实现时使用,但它也被导出以便驱动程序可以对其进行扩展。
调用该函数时必须持有 input_dev.event_lock。
返回
成功时返回 0,失败时返回负错误码。
参数
struct input_dev *dev正在查询键图的输入设备
struct input_keymap_entry *ke键图条目
描述
任何有兴趣检索当前键图的人都应该调用此函数。目前 evdev 处理程序正在使用它。
参数
struct input_dev *dev正在更新键图的输入设备
const struct input_keymap_entry *ke新键图条目
描述
任何需要更新当前键图的人都应该调用此函数。目前键盘和 evdev 处理程序正在使用它。
参数
struct input_dev *dev需要重置其状态的输入设备
描述
此函数尝试重置已打开输入设备的状态,并使内部状态与硬件状态相互同步。我们将所有按键标记为已释放,恢复 LED 状态、重复速率等。
参数
void无参数
描述
返回准备好的 struct input_dev 或 NULL。
注意
使用 input_free_device() 释放尚未注册的设备;对于已经注册的设备,应使用 input_unregister_device()。
参数
struct device *dev拥有正在创建的输入设备的设备
描述
返回准备好的 struct input_dev 或 NULL。
托管的输入设备不需要显式注销或释放,因为当所有者设备与其驱动程序解绑(或绑定失败)时,这会自动完成。一旦分配了托管输入设备,它就可以像常规输入设备一样进行设置和注册。不需要特殊的 devm_input_device_[un]register() 变体,如果需要,常规方法对托管和非托管设备都适用。然而,在大多数情况下,托管输入设备不需要显式注销或释放。
注意
所有者设备被设置为输入设备的父设备,用户不应覆盖它。
参数
struct input_dev *dev要释放的输入设备
描述
仅在尚未调用 input_register_device() 或其调用失败时,才应使用此函数。一旦设备注册成功,请使用 input_unregister_device(),在删除对该设备的最后一个引用后,其内存将被释放。
设备应由 input_allocate_device() 分配。
注意
如果存在对输入设备的引用,则在丢弃最后一个引用之前不会释放内存。
参数
struct input_dev *dev要为其设置时间戳的输入设备
ktime_t timestamp事件发生时在 CLOCK_MONOTONIC 下的时间
描述
此函数旨在向输入系统提供事件实际发生时更准确的时间。驱动程序应在获取到时间戳后立即调用此函数,以确保正确执行 input_set_timestamp 中的时钟转换。
系统在获取时间戳和调用 input_set_timestamp 之间进入休眠状态,可能会导致转换不准确。
参数
struct input_dev *dev要从中获取时间戳的输入设备
描述
有效的时间戳是非零值的时间戳。
-
void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code)¶
将设备标记为具备处理某种事件的能力
参数
struct input_dev *dev能够发送或接收事件的设备
unsigned int type事件类型(EV_KEY、EV_REL 等...)
unsigned int code事件代码
描述
除了在相应的能力位图中设置对应位之外,该函数还会调整 dev->evbit。
参数
struct input_dev *dev输入设备
int delay重复延迟
int period重复周期
描述
在输入设备上启用软件自动重复。
参数
struct input_dev *dev要注册的设备
描述
此函数向输入核心注册设备。在注册之前,设备必须通过 input_allocate_device() 分配,并设置好其所有能力。如果函数失败,必须使用 input_free_device() 释放该设备。一旦设备成功注册,可以使用 input_unregister_device() 进行注销;在这种情况下不应调用 input_free_device()。
请注意,此函数也用于注册托管的输入设备(即通过 devm_input_allocate_device() 分配的设备)。此类托管输入设备无需显式注销或释放,其销毁由 devres 基础设施控制。同样值得注意的是,托管输入设备的销毁在内部是一个两步过程:首先注销已注册的托管输入设备,但它仍留在内存中,并且仍然可以处理 input_event() 调用(尽管事件不会发送到任何地方)。托管输入设备的释放稍后会发生,即当 devres 栈回溯到进行设备分配的位置时。
参数
struct input_dev *dev要注销的设备
描述
此函数注销一个输入设备。一旦设备注销,调用者不应尝试访问它,因为其随时可能会被释放。
-
int input_register_handler(struct input_handler *handler)¶
注册一个新的输入处理程序
参数
struct input_handler *handler要注册的处理程序
描述
此函数为系统中的输入设备注册一个新的输入处理程序(接口),并将其连接到与该处理程序兼容的所有输入设备。
-
void input_unregister_handler(struct input_handler *handler)¶
注销一个输入处理程序
参数
struct input_handler *handler要注销的处理程序
描述
此函数将处理程序与其输入设备断开连接,并将其从已知处理程序列表中移除。
-
int input_handler_for_each_handle(struct input_handler *handler, void *data, int (*fn)(struct input_handle*, void*))¶
句柄迭代器
参数
struct input_handler *handler要迭代的输入处理程序
void *data用于回调的数据
int (*fn)(struct input_handle *, void *)为每个句柄调用的函数
描述
遍历 bus 的设备列表,并为每个设备调用 fn,向其传递 data,并在 fn 返回非零值时停止。该函数使用 RCU 遍历列表,因此可以在原子上下文中使用。fn 回调是在 RCU 临界区内调用的,因此绝对不能休眠。
-
int input_register_handle(struct input_handle *handle)¶
注册一个新的输入句柄
参数
struct input_handle *handle要注册的句柄
描述
此函数将一个新的输入句柄放入设备和处理程序的列表中,以便一旦使用 input_open_device() 将其打开,事件就可以通过它流动。
此函数应当在处理程序的 connect() 方法中被调用。
-
void input_unregister_handle(struct input_handle *handle)¶
注销一个输入句柄
参数
struct input_handle *handle要注销的句柄
描述
此函数从设备和处理程序的列表中移除输入句柄。
此函数应当在处理程序的 disconnect() 方法中被调用。
-
int input_get_new_minor(int legacy_base, unsigned int legacy_num, bool allow_dynamic)¶
分配一个新的输入次设备号
参数
int legacy_base要搜索的传统范围起点
unsigned int legacy_num传统范围的大小
bool allow_dynamic是否我们也可以从动态范围中获取 ID
描述
此函数从输入主设备命名空间分配一个新的设备次设备号。调用者可以通过指定 legacy_base 和 legacy_num 参数来请求传统次设备号,并可指定在传统范围中没有空闲 ID 时,是否可以从动态范围分配 ID。
-
void input_free_minor(unsigned int minor)¶
释放先前分配的次设备号
参数
unsigned int minor要释放的次设备号
描述
此函数释放先前分配的输入次设备号,以便日后可以重复使用。
参数
struct input_dev *dev输入设备
struct ff_effect *effect要上传的效果
struct file *file效果的所有者
参数
struct input_dev *dev要从中擦除效果的输入设备
int effect_id要擦除的效果的 id
struct file *file请求的声称所有者
描述
此函数从指定的设备中擦除力反馈效果。只有当该效果是通过请求擦除的同一个文件句柄上传时,该效果才会被擦除。
-
int input_ff_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)¶
力反馈事件的通用处理程序
参数
struct input_dev *dev要将效果发送到的输入设备
unsigned int type事件类型(除 EV_FF 之外的任何事件都会被忽略)
unsigned int code事件代码
int value事件值
参数
struct input_dev *dev支持力反馈的输入设备
unsigned int max_effects设备支持的最大效果数量
描述
此函数为输入设备的力反馈部分分配所有必要的内存并安装所有默认处理程序。在调用此函数之前,应该已经设置好 dev->ffbit。创建力反馈设备后,您需要在注册输入设备之前设置其上传(upload)、擦除(erase)、播放(playback)和其他处理程序
参数
struct input_dev *dev支持力反馈的输入设备
描述
此函数仅在错误路径中需要,因为当设备被销毁时,输入核心将自动释放力反馈结构。
-
int input_ff_create_memless(struct input_dev *dev, void *data, int (*play_effect)(struct input_dev*, void*, struct ff_effect*))¶
创建无内存(memoryless)力反馈设备
参数
struct input_dev *dev支持力反馈的输入设备
void *data要传递到 play_effect 中的驱动程序特定数据
int (*play_effect)(struct input_dev *, void *, struct ff_effect *)用于播放力反馈效果的驱动程序特定方法
多点触控库¶
-
struct input_mt_slot¶
表示输入多点触控(MT)插槽的状态
定义:
struct input_mt_slot {
int abs[ABS_MT_LAST - ABS_MT_FIRST + 1];
unsigned int frame;
unsigned int key;
};
成员
abs保存该插槽的 ABS_MT 轴的当前值
frame上一次调用
input_mt_report_slot_state()的帧key此插槽的可选驱动程序指定
-
struct input_mt¶
被跟踪触点的状态
定义:
struct input_mt {
int trkid;
int num_slots;
int slot;
unsigned int flags;
unsigned int frame;
int *red;
struct input_mt_slot slots[];
};
成员
trkid存储下一个触点的多点触控(MT)跟踪 ID
num_slots设备使用的多点触控(MT)插槽数量
slot当前正在传输的多点触控(MT)插槽
flagsinput_mt 操作标志
frame每次调用
input_mt_sync_frame()时递增red内核内跟踪的简化开销矩阵
slots保存被跟踪触点当前值的插槽数组
-
struct input_mt_pos¶
触点位置
定义:
struct input_mt_pos {
s16 x, y;
};
成员
x水平坐标
y垂直坐标
-
int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots, unsigned int flags)¶
初始化多点触控(MT)输入插槽
参数
struct input_dev *dev支持多点触控(MT)事件和手指跟踪的输入设备
unsigned int num_slots设备使用的插槽数量
unsigned int flags核心中要处理的多点触控(mt)任务
描述
此函数为输入设备中的多点触控(MT)插槽处理分配所有必要的内存,准备好供使用的 ABS_MT_SLOT 和 ABS_MT_TRACKING_ID 事件,并设置适当的缓冲区。根据设置的标志,它还会执行指针模拟和帧同步。
可被重复调用。如果尝试使用不同的插槽数量进行重新初始化,则返回 -EINVAL。
参数
struct input_dev *dev已分配多点触控(MT)插槽的输入设备
描述
此函数仅在错误路径中需要,因为当设备被销毁时,输入核心将自动释放多点触控(MT)插槽。
参数
struct input_dev *dev已分配多点触控(MT)插槽的输入设备
unsigned int tool_type在该插槽中使用的工具类型
bool active如果触点处于活动状态则为 true,否则为 false
描述
通过 ABS_MT_TRACKING_ID 报告触点,并可选择是否通过 ABS_MT_TOOL_TYPE 报告。如果 active 为 true 且插槽当前处于非活动状态,或者工具类型发生了改变,则会为该插槽分配一个新的跟踪 ID。只有在设置了相应的 absbit 字段时,才会报告工具类型。
如果触点处于活动状态,则返回 true。
参数
struct input_dev *dev已分配多点触控(MT)插槽的输入设备
int count触点的数量
描述
通过 BTN_TOOL_FINGER、BTN_TOOL_DOUBLETAP、BTN_TOOL_TRIPLETAP 和 BTN_TOOL_QUADTAP 报告触点数量。
输入核心可确保仅为该设备设置好的 KEY 事件才会产生输出。
参数
struct input_dev *dev已分配多点触控(MT)插槽的输入设备
bool use_count将活动触点的数量报告为手指数量
描述
通过 BTN_TOUCH、ABS_X、ABS_Y 和 ABS_PRESSURE 执行传统指针模拟。如果 use_count 为 true,则会模拟触摸板手指数量。
输入核心可确保仅为该设备设置好的 KEY 事件和 ABS 轴才会产生输出。
参数
struct input_dev *dev已分配多点触控(MT)插槽的输入设备
描述
释放自上次调用此函数以来未见到的所有插槽。
参数
struct input_dev *dev已分配多点触控(MT)插槽的输入设备
描述
关闭当前帧并为新帧准备内部状态。根据标志,将未使用的插槽标记为非活动状态并执行指针模拟。
-
int input_mt_assign_slots(struct input_dev *dev, int *slots, const struct input_mt_pos *pos, int num_pos, int dmax)¶
执行最佳匹配分配
参数
struct input_dev *dev已分配多点触控(MT)插槽的输入设备
int *slots要填充的插槽分配列表
const struct input_mt_pos *pos要匹配的位置数组
int num_pos位置数量
int dmax最大 ABS_MT_POSITION 位移(零表示无限大)
描述
对当前触点执行最佳匹配,并返回插槽分配列表。新触点将被分配给未使用的插槽。
分配是均衡的,以便所有坐标位移都低于欧几里得距离 dmax。如果找不到此类分配,某些触点将被分配给未使用的插槽。
成功时返回零,失败时返回负错误码。
参数
struct input_dev *dev已分配多点触控(MT)插槽的输入设备
int key所寻找插槽的键(key)
描述
如果给定键(key)的插槽存在,则返回该插槽,否则在第一个未使用的插槽上设置该键并返回。
如果找不到可用插槽,则返回 -1。请注意,为了使此函数正常工作,必须在每一帧调用 input_mt_sync_frame()。
矩阵键盘/小键盘¶
-
struct matrix_keymap_data¶
矩阵键盘的键图
定义:
struct matrix_keymap_data {
const uint32_t *keymap;
unsigned int keymap_size;
};
成员
keymap指向由
KEY()宏编码的、代表键图的 uint32 值数组的指针keymap_size此键图中已初始化的条目数
描述
该结构体应由平台代码使用,以向实现矩阵式小键盘/键盘的驱动程序提供键图。
稀疏键图支持¶
-
struct key_entry¶
在稀疏键图中使用的键图条目
定义:
struct key_entry {
int type;
u32 code;
union {
u16 keycode;
struct {
u8 code;
u8 value;
} sw;
};
};
成员
type按键条目的类型(KE_KEY、KE_SW、KE_VSW、KE_END);允许驱动程序使用其自有的私有定义来扩展该列表。
code用于标识按钮/开关的设备特定数据
{unnamed_union}匿名
keycode分配给按键/按钮的 KEY_* 代码
sw由 KE_SW 和 KE_VSW 使用的包含代码/值的
structsw.code分配给开关的 SW_* 代码
sw.value当切换 KE_SW 开关时,即使在输入中也应发送的值。KE_VSW 开关忽略此字段,并期望驱动程序为事件提供值。
描述
该结构体定义了某些输入设备所使用的稀疏键图中的一个条目,对于这些设备,传统的基于表的方法并不适用。
-
struct key_entry *sparse_keymap_entry_from_scancode(struct input_dev *dev, unsigned int code)¶
执行稀疏键图查找
参数
struct input_dev *dev使用稀疏键图的输入设备
unsigned int code扫描码
描述
此函数用于在使用稀疏键图的输入设备中执行 struct key_entry 查找。
-
struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev, unsigned int keycode)¶
执行稀疏键图查找
参数
struct input_dev *dev使用稀疏键图的输入设备
unsigned int keycode按键码
描述
此函数用于在使用稀疏键图的输入设备中执行 struct key_entry 查找。
-
int sparse_keymap_setup(struct input_dev *dev, const struct key_entry *keymap, int (*setup)(struct input_dev*, struct key_entry*))¶
为输入设备设置稀疏按键映射(sparse keymap)
参数
struct input_dev *dev输入设备
const struct key_entry *keymap以
key_entry结构体数组形式表示的按键映射,并以KE_END类型的条目结尾int (*setup)(struct input_dev *, struct key_entry *)可用于根据设备需求调整按键映射条目的函数,可以为
NULL
描述
该函数计算大小并分配原始按键映射的副本,然后适当地设置输入设备事件位。当不再需要分配的按键映射副本时,它会被自动释放。
-
void sparse_keymap_report_entry(struct input_dev *dev, const struct key_entry *ke, unsigned int value, bool autorelease)¶
报告与给定按键条目对应的事件
参数
struct input_dev *dev应当报告事件的输入设备
const struct key_entry *ke描述事件的按键条目
unsigned int value应当报告的值(对于
KE_SW条目会被忽略)bool autorelease指示在报告按下事件后是否应立即为
KE_KEY条目发送释放事件,所有其他类型的条目将忽略此参数
描述
此函数用于报告由给定的 struct key_entry 描述的输入事件。
-
bool sparse_keymap_report_event(struct input_dev *dev, unsigned int code, unsigned int value, bool autorelease)¶
报告与给定扫描码(scancode)对应的事件
参数
struct input_dev *dev使用稀疏键图的输入设备
unsigned int code扫描码
unsigned int value应当报告的值(对于
KE_SW条目会被忽略)bool autorelease指示在报告按下事件后是否应立即为
KE_KEY条目发送释放事件,所有其他类型的条目将忽略此参数
描述
此函数用于在输入设备中查找稀疏按键映射并报告相应的事件。如果查找成功则返回 true,否则返回 false。
PS/2 协议支持¶
-
enum ps2_disposition¶
指示接收到的字节应如何处理
常量
PS2_PROCESS传递给主协议处理程序,进行正常处理
PS2_IGNORE忽略(跳过)该字节
PS2_ERROR不处理该字节,中止正在执行的命令
-
struct ps2dev¶
代表一个使用 PS/2 协议的设备
定义:
struct ps2dev {
struct serio *serio;
struct mutex cmd_mutex;
wait_queue_head_t wait;
unsigned long flags;
u8 cmdbuf[8];
u8 cmdcnt;
u8 nak;
ps2_pre_receive_handler_t pre_receive_handler;
ps2_receive_handler_t receive_handler;
};
成员
serioPS/2 设备所使用的 serio 端口
cmd_mutex一个用于确保一次只能执行一个命令的互斥锁
wait一个用于从 serio 中断处理程序发送完成信号的等待队列
flags用于指示 PS/2 命令执行各个阶段的各种内部标志
cmdbuf保存命令响应的缓冲区
cmdcnt命令响应中未决的/待接收的字节数
nak设备拒绝命令时传输的一个字节
pre_receive_handler检查通信错误并返回接收到的数据字节的处理方式(
enum ps2_disposition)receive_handler特定 PS/2 协议(如键盘或鼠标协议)的主处理程序
参数
struct ps2dev *ps2dev要向其发送数据的 PS/2 设备
u8 byte要发送给设备的数据
unsigned int timeout发送数据和接收确认的超时时间
描述
该函数不处理重传,调用者应在需要时自行处理。
ps2_sendbyte() 只能在进程上下文中调用。
参数
struct ps2dev *ps2dev正在执行命令的 PS/2 设备
参数
struct ps2dev *ps2dev应被清空(drain)数据的 PS/2 设备
size_t maxbytes要清空的最大字节数
unsigned int timeout清空设备数据的时间限制
-
bool ps2_is_keyboard_id(u8 id_byte)¶
根据已知键盘 ID 列表检查接收到的 ID 字节
参数
u8 id_byte需要检查的数据字节
参数
struct ps2dev *ps2dev应执行该命令的 PS/2 设备
u8 *param一个缓冲区,包含要与命令一起发送的参数,和/或用于存放命令执行结果的位置,或两者皆是
unsigned int command对命令本身进行编码的命令字,以及应发送给设备的附加参数字节数和预期的命令响应长度
描述
未进行串行化处理。调用者应使用 ps2_begin_command() 和 ps2_end_command() 来确保复杂命令的正确串行化。
参数
struct ps2dev *ps2dev应执行该命令的 PS/2 设备
u8 *param一个缓冲区,包含要与命令一起发送的参数,和/或用于存放命令执行结果的位置,或两者皆是
unsigned int command对命令本身进行编码的命令字,以及应发送给设备的附加参数字节数和预期的命令响应长度
注意
ps2_command() 会对命令执行进行串行化,使得单个端口或整个 8042 控制器一次只能执行一个命令。
参数
struct ps2dev *ps2dev应执行该命令的 PS/2 设备
u8 command命令字节
描述
该命令使用罗技或 Synaptics 触摸板等高级设备能够理解的“切片(sliced)”语法发送。命令编码为:0xE6 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu,其中 (rr*64)+(ss*16)+(tt*4)+uu 即为对应的命令。
-
void ps2_init(struct ps2dev *ps2dev, struct serio *serio, ps2_pre_receive_handler_t pre_receive_handler, ps2_receive_handler_t receive_handler)¶
初始化 ps2dev 结构体
参数
struct ps2dev *ps2dev要被初始化的结构体
struct serio *serio与该 PS/2 设备关联的 serio 端口
ps2_pre_receive_handler_t pre_receive_handler用于检查基本通信状态的验证处理程序
ps2_receive_handler_t receive_handler主协议处理程序
描述
准备 ps2dev 结构体,以便在 PS/2 设备的驱动程序中使用。
参数
struct serio *serio该设备的 serio 端口
u8 data从设备接收到的数据字节
unsigned int flags诸如
SERIO_PARITY或SERIO_TIMEOUT之类的标志,用于指示数据传输的状态
描述
ps2_interrupt() 调用预接收处理程序,视情况处理来自设备的命令确认和响应,最后将数据传递给主协议处理程序以供后续处理。