输入子系统

输入核心

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 __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;
    ktime_t timestamp[INPUT_CLK_MAX];
    bool inhibited;
};

成员

name

设备的名称

phys

设备在系统层次结构中的物理路径

uniq

设备的唯一标识代码(如果设备有)

id

设备的 ID(struct input_id)

propbit

设备属性和怪癖的位图

evbit

设备支持的事件类型(EV_KEY,EV_REL 等)的位图

keybit

此设备拥有的按键/按钮的位图

relbit

设备的相对轴的位图

absbit

设备的绝对轴的位图

mscbit

设备支持的各种事件的位图

ledbit

设备上存在的 LED 的位图

sndbit

设备支持的声音效果的位图

ffbit

设备支持的力反馈效果的位图

swbit

设备上存在的开关的位图

hint_events_per_packet

设备在一个数据包中生成的平均事件数(在 EV_SYN/SYN_REPORT 事件之间)。事件处理程序使用它来估计保存事件所需的缓冲区大小。

keycodemax

键代码表的大小

keycodesize

键代码表中元素的大小

keycode

此设备的扫描码到键代码的映射

setkeycode

更改当前键映射的可选方法,用于实现稀疏键映射。如果未提供,将使用默认机制。该方法在持有 event_lock 时被调用,因此不得休眠

getkeycode

检索当前键映射的可选旧方法。

ff

如果设备支持力反馈效果,则与设备关联的力反馈结构

poller

如果设备设置为使用轮询模式,则与设备关联的轮询器结构

repeat_key

存储上次按下的键的代码;用于实现软件自动重复

timer

用于软件自动重复的定时器

rep

自动重复参数(延迟、速率)的当前值

mt

指向多点触控状态的指针

absinfo

包含有关绝对轴信息(当前值、最小值、最大值、平坦度、模糊度、分辨率)的 struct 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

表示输入设备被禁止。如果是这种情况,则输入核心将忽略设备生成的任何事件。当设备被禁止时会调用设备的 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;
};

成员

private

特定于驱动程序的数据

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

使用旧次要范围的驱动程序设置为 true

minor

此驱动程序可以提供的设备的 32 个旧次要范围的开头

name

处理程序的名称,显示在 /proc/bus/input/handlers 中

id_table

指向此驱动程序可以处理的 input_device_ids 表的指针

h_list

与处理程序关联的输入句柄列表

node

用于将驱动程序放置到 input_handler_list 上

描述

输入处理程序连接到输入设备并创建输入句柄。很可能在任何给定输入设备上同时连接了多个处理程序。它们都将获得设备生成的输入事件的副本。

相同的结构也用于实现输入过滤器。输入核心允许过滤器首先运行,如果任何过滤器指示该事件应被过滤(通过从其 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;
};

成员

private

处理程序特定的数据

open

显示句柄是否“打开”的计数器,即是否应传递来自其设备的事件

name

由创建它的处理程序赋予句柄的名称

dev

句柄附加到的输入设备

处理程序

通过此句柄与设备一起工作的处理程序

handle_events

事件序列处理程序。它由输入核心根据 handler 中指定的事件处理方法设置。请参阅 input_handle_setup_event_handler()。此方法由输入核心在禁用中断且持有 dev->event_lock 自旋锁的情况下调用,因此它可能不会休眠。

d_node

用于将句柄放置在设备的附加句柄列表上

h_node

用于将句柄放置在处理程序从中获取事件的句柄列表上

void input_set_events_per_packet(struct input_dev *dev, int n_events)

告知处理程序驱动程序事件速率

参数

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 *private;
    unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
    struct mutex mutex;
    int max_effects;
    struct ff_effect *effects;
    struct file *effect_owners[] ;
};

成员

上传

调用以将新效果上传到设备

擦除

调用以从设备中擦除效果

回放

调用以请求设备开始播放指定效果

set_gain

调用以设置指定增益

set_autocenter

调用以使设备自动居中

销毁

当父输入设备被销毁时由输入核心调用

private

驱动程序特定的数据,将自动释放

ffbit

设备真正支持的力反馈功能的位图(而不是像 input_dev->ffbit 中的那些模拟的位图)

mutex

用于序列化对设备的访问的互斥锁

max_effects

设备支持的最大效果数

效果

指向当前加载到设备中的效果数组的指针

effect_owners

效果所有者的数组;当拥有效果的文件句柄关闭时,效果将自动擦除

描述

每个力反馈设备都必须实现 upload() 和 playback() 方法;erase() 是可选的。只有当驱动程序设置了 FF_GAIN 和 FF_AUTOCENTER 位时,才需要实现 set_gain() 和 set_autocenter()。

请注意,playback()、set_gain() 和 set_autocenter() 在持有 dev->event_lock 自旋锁且中断关闭的情况下被调用,因此可能不会休眠。

void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)

报告新的输入事件

参数

struct input_dev *dev

生成事件的设备

unsigned int type

事件的类型

unsigned int code

事件代码

int value

事件的值

描述

实现各种输入设备的驱动程序应使用此函数来报告输入事件。另请参阅 input_inject_event()

注意

input_event() 可以在使用 input_allocate_device() 分配输入设备后立即安全使用,甚至在通过 input_register_device() 注册之前也可以使用,但该事件将不会到达任何输入处理程序。这种早期调用 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() 类似,但如果设备被“抓取”并且注入事件的句柄不是拥有该设备的句柄,则会忽略事件。

void input_alloc_absinfo(struct input_dev *dev)

分配 input_absinfo 结构体的数组

参数

struct input_dev *dev

发出绝对事件的输入设备

描述

如果调用者请求的 absinfo 结构体已被分配,则此函数不会执行任何操作。

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 中的扫描码

参数

const struct input_keymap_entry *ke

包含要转换的扫描码的键映射条目。

unsigned int *scancode

指向存储转换后的扫描码的位置的指针。

描述

此函数用于将存储在 struct keymap_entry 中的扫描码转换为旧式键映射处理方法可以理解的标量形式。这些方法期望扫描码表示为 ‘unsigned int’。

int input_get_keycode(struct input_dev *dev, struct input_keymap_entry *ke)

检索当前映射到给定扫描码的键码

参数

struct input_dev *dev

正在查询其键映射的输入设备

struct input_keymap_entry *ke

键映射条目

描述

任何有兴趣检索当前键映射的人都应调用此函数。目前,evdev 处理程序使用它。

int input_set_keycode(struct input_dev *dev, const struct input_keymap_entry *ke)

将键码属性分配给给定的扫描码

参数

struct input_dev *dev

正在更新其键映射的输入设备

const struct input_keymap_entry *ke

新的键映射条目

描述

任何需要更新当前键映射的人都应调用此函数。目前,键盘和 evdev 处理程序使用它。

void input_reset_device(struct input_dev *dev)

重置/恢复输入设备的状态

参数

struct input_dev *dev

需要重置其状态的输入设备

描述

此函数尝试重置已打开的输入设备的状态,并使内部状态和硬件状态彼此同步。我们将所有键标记为释放状态,恢复 LED 状态、重复率等。

struct input_dev *input_allocate_device(void)

为新的输入设备分配内存

参数

void

无参数

描述

返回准备好的 struct input_devNULL

注意

使用 input_free_device() 释放尚未注册的设备;input_unregister_device() 应被用于已注册的设备。

struct input_dev *devm_input_allocate_device(struct device *dev)

分配托管的输入设备

参数

struct device *dev

拥有正在创建的输入设备的设备

描述

返回准备好的 struct input_devNULL

托管的输入设备不需要显式注销或释放,因为当所有者设备从其驱动程序解除绑定(或绑定失败)时,将自动完成此操作。一旦分配了托管的输入设备,就可以像常规输入设备一样进行设置和注册。没有特殊的 devm_input_device_[un]register() 变体,常规变体适用于托管和非托管设备,如果您需要它们。但是,在大多数情况下,托管的输入设备不需要显式注销或释放。

注意

所有者设备被设置为输入设备的父设备,用户不应覆盖它。

void input_free_device(struct input_dev *dev)

释放 input_dev 结构占用的内存

参数

struct input_dev *dev

要释放的输入设备

描述

仅当尚未调用 input_register_device() 或调用失败时,才应使用此函数。一旦设备被注册,请使用 input_unregister_device(),并且一旦对设备的最后一个引用被删除,内存将被释放。

设备应由 input_allocate_device() 分配。

注意

如果存在对输入设备的引用,则在删除最后一个引用之前,不会释放内存。

void input_set_timestamp(struct input_dev *dev, ktime_t timestamp)

设置输入事件的时间戳

参数

struct input_dev *dev

要设置时间戳的输入设备

ktime_t timestamp

事件在 CLOCK_MONOTONIC 中发生的时间

描述

此函数旨在为输入系统提供事件实际发生时间的更准确时间。驱动程序应在获取时间戳后立即调用此函数,以确保在 input_set_timestamp 中正确完成时钟转换。

在获取时间戳和调用 input_set_timestamp 之间系统进入挂起状态可能会导致转换不准确。

ktime_t *input_get_timestamp(struct input_dev *dev)

获取输入事件的时间戳

参数

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。

void input_enable_softrepeat(struct input_dev *dev, int delay, int period)

启用软件自动重复

参数

struct input_dev *dev

输入设备

int delay

重复延迟

int period

重复周期

描述

在输入设备上启用软件自动重复。

int input_register_device(struct input_dev *dev)

向输入核心注册设备

参数

struct input_dev *dev

要注册的设备

描述

此函数向输入核心注册设备。设备必须使用 input_allocate_device() 分配,并在注册之前设置所有功能。如果函数失败,则必须使用 input_free_device() 释放该设备。一旦设备成功注册,就可以使用 input_unregister_device() 取消注册;在这种情况下不应调用 input_free_device()

请注意,此函数还用于注册托管输入设备(使用 devm_input_allocate_device() 分配的设备)。此类托管输入设备无需显式取消注册或释放,它们的拆卸由 devres 基础结构控制。还值得注意的是,托管输入设备的拆卸在内部是一个 2 步过程:已注册的托管输入设备首先被取消注册,但仍保留在内存中,并且仍然可以处理 input_event() 调用(尽管事件不会传递到任何地方)。托管输入设备的释放将在稍后发生,当 devres 堆栈被解开到进行设备分配的点时。

void input_unregister_device(struct input_dev *dev)

取消注册先前注册的设备

参数

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_baselegacy_num 参数来请求传统的次设备号,并指定如果传统范围中没有空闲 ID 时,是否允许从动态范围分配 ID。

void input_free_minor(unsigned int minor)

释放先前分配的次设备号

参数

unsigned int minor

要释放的次设备号

描述

此函数释放先前分配的输入次设备号,以便以后可以重复使用。

int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, struct file *file)

将效果上传到力反馈设备

参数

struct input_dev *dev

输入设备

struct ff_effect *effect

要上传的效果

struct file *file

效果的所有者

int input_ff_erase(struct input_dev *dev, int effect_id, 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

事件值

int input_ff_create(struct input_dev *dev, unsigned int max_effects)

创建力反馈设备

参数

struct input_dev *dev

支持力反馈的输入设备

unsigned int max_effects

设备支持的最大效果数

描述

此函数为输入设备的力反馈部分分配所有必要的内存,并安装所有默认处理程序。在调用此函数之前,应已设置好 dev->ffbit 。创建 ff 设备后,需要在注册输入设备之前设置其上传、擦除、播放和其他处理程序。

void input_ff_destroy(struct input_dev *dev)

释放输入设备的力反馈部分

参数

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*))

创建无内存的力反馈设备

参数

struct input_dev *dev

支持力反馈的输入设备

void *data

要传递到 play_effect 的驱动程序特定数据

int (*play_effect)(struct input_dev *, void *, struct ff_effect *)

用于播放 FF 效果的驱动程序特定方法

多点触摸库

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 插槽

flags

input_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。

void input_mt_destroy_slots(struct input_dev *dev)

释放输入设备的 MT 槽

参数

struct input_dev *dev

已分配 MT 槽的输入设备

描述

此函数仅在错误路径中需要,因为当设备被销毁时,输入核心会自动释放 MT 槽。

bool input_mt_report_slot_state(struct input_dev *dev, unsigned int tool_type, bool active)

报告接触状态

参数

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。

void input_mt_report_finger_count(struct input_dev *dev, int count)

报告接触次数

参数

struct input_dev *dev

已分配 MT 槽的输入设备

int count

接触次数

描述

通过 BTN_TOOL_FINGER、BTN_TOOL_DOUBLETAP、BTN_TOOL_TRIPLETAP 和 BTN_TOOL_QUADTAP 报告接触次数。

输入核心确保只有为此设备已设置的 KEY 事件才会产生输出。

void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)

通用指针模拟

参数

struct input_dev *dev

已分配 MT 槽的输入设备

bool use_count

报告活动接触次数作为手指计数

描述

通过 BTN_TOUCH、ABS_X、ABS_Y 和 ABS_PRESSURE 执行传统的指针模拟。如果 use_count 为 true,则模拟触摸板手指计数。

输入核心确保只有为此设备已设置的 KEY 和 ABS 轴才会产生输出。

void input_mt_drop_unused(struct input_dev *dev)

使此帧中未看到的槽失效

参数

struct input_dev *dev

已分配 MT 槽的输入设备

描述

解除自上次调用此函数以来未看到的所有槽。

void input_mt_sync_frame(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。如果找不到这样的分配,则将某些接触分配给未使用的槽。

成功时返回零,失败时返回负错误。

int input_mt_get_slot_by_key(struct input_dev *dev, int key)

返回与键匹配的槽

参数

struct input_dev *dev

已分配 MT 槽的输入设备

int 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 使用的代码/值的结构

sw.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*))

为输入设备设置稀疏键映射

参数

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)

报告与给定扫描码对应的事件

参数

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

成员

serio

PS/2 设备使用的 serio 端口

cmd_mutex

一个互斥锁,确保一次只执行一个命令

wait

一个等待队列,用于从 serio 中断处理程序发出完成信号

flags

各种内部标志,指示 PS/2 命令执行的阶段

cmdbuf

保存命令响应的缓冲区

cmdcnt

命令响应的未完成字节数

nak

设备拒绝命令时传输的字节

pre_receive_handler

检查通信错误并返回接收到的数据字节的处置方式 (enum ps2_disposition)

receive_handler

特定 PS/2 协议(如键盘或鼠标协议)的主处理程序

int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout)

向设备发送一个字节并等待确认

参数

struct ps2dev *ps2dev

要将数据发送到的 PS/2 设备

u8 byte

要发送到设备的数据

unsigned int timeout

发送数据和接收确认的超时时间

描述

该函数不处理重传,需要时,调用者应负责处理重传。

ps2_sendbyte() 只能从进程上下文中调用。

void ps2_begin_command(struct ps2dev *ps2dev)

标记复杂命令执行的开始

参数

struct ps2dev *ps2dev

正在执行命令的 PS/2 设备

描述

序列化复杂/复合命令。命令完成后,应调用 ps2_end_command()

void ps2_end_command(struct ps2dev *ps2dev)

标记复杂命令执行的结束

参数

struct ps2dev *ps2dev

正在执行命令的 PS/2 设备

void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout)

等待设备传输请求的字节数并丢弃它们

参数

struct ps2dev *ps2dev

应该清空的 PS/2 设备

size_t maxbytes

要清空的最大字节数

unsigned int timeout

清空设备的时间

bool ps2_is_keyboard_id(u8 id_byte)

根据已知的键盘 ID 列表检查接收到的 ID 字节

参数

u8 id_byte

应该检查的数据字节

int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command)

向 PS/2 设备发送命令

参数

struct ps2dev *ps2dev

应该执行命令的 PS/2 设备

u8 *param

一个缓冲区,其中包含要与命令一起发送的参数,或将存放命令执行结果的位置,或两者兼而有之

unsigned int command

命令字,它编码了命令本身,以及应该发送给设备的额外参数字节数和命令响应的预期长度

描述

未序列化。调用者应使用 ps2_begin_command()ps2_end_command() 来确保复杂命令的正确序列化。

int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command)

向 PS/2 设备发送命令

参数

struct ps2dev *ps2dev

应该执行命令的 PS/2 设备

u8 *param

一个缓冲区,其中包含要与命令一起发送的参数,或将存放命令执行结果的位置,或两者兼而有之

unsigned int command

命令字,它编码了命令本身,以及应该发送给设备的额外参数字节数和命令响应的预期长度

注意

ps2_command() 序列化命令执行,以便每次只能为一个单独端口或整个 8042 控制器执行一个命令。

int ps2_sliced_command(struct ps2dev *ps2dev, u8 command)

向鼠标发送扩展的 PS/2 命令

参数

struct ps2dev *ps2dev

应该执行命令的 PS/2 设备

u8 command

命令字节

描述

该命令使用高级设备(如罗技或 Synaptics 触摸板)理解的“切片”语法发送。该命令编码为: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 设备的驱动程序中。

irqreturn_t ps2_interrupt(struct serio *serio, u8 data, unsigned int flags)

PS/2 设备的通用中断处理程序

参数

struct serio *serio

设备的 serio 端口

u8 data

从设备接收的数据字节

unsigned int flags

诸如 SERIO_PARITYSERIO_TIMEOUT 之类的标志,指示数据传输的状态

描述

ps2_interrupt() 调用预接收处理程序,可选择处理来自设备的命令确认和响应,最后将数据传递给主协议处理程序以进行后续处理。