輸入子系統

輸入核心

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

keycode 表的大小

keycodesize

keycode 表中元素的大小

keycode

此裝置的掃描碼到 keycode 的對映

setkeycode

用於更改當前 keymap 的可選方法,用於實現稀疏 keymap。 如果未提供,將使用預設機制。 該方法在持有 event_lock 時被呼叫,因此不得休眠

getkeycode

用於檢索當前 keymap 的可選舊方法。

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

事件處理程式,用於傳送 _to_ 裝置的事件,例如 EV_LED 或 EV_SND。 期望裝置執行請求的操作 (開啟 LED,播放聲音等)。 呼叫受 event_lock 保護,不得休眠

grab

當前已抓取裝置的輸入控制代碼 (透過 EVIOCGRAB ioctl)。 當控制代碼抓取裝置時,它將成為來自該裝置的所有輸入事件的唯一接收者

event_lock

當輸入核心接收並處理裝置的新事件時 (在 input_event() 中) 獲取此自旋鎖。 在裝置已向輸入核心註冊後訪問和/或修改裝置引數 (例如 keymap 或 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

控制代碼附加到的輸入裝置

handler

透過此控制代碼與裝置一起使用的處理程式

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

成員

upload

呼叫以將新效果上傳到裝置

erase

呼叫以從裝置中擦除效果

playback

呼叫以請求裝置開始播放指定的效果

set_gain

呼叫以設定指定的增益

set_autocenter

呼叫以自動對中裝置

destroy

在銷燬父輸入裝置時由輸入核心呼叫

private

驅動程式特定資料,將自動釋放

ffbit

裝置真正支援的力反饋能力點陣圖 (不是像 input_dev->ffbit 中那樣模擬的)

mutex

用於序列化對裝置的訪問的互斥鎖

max_effects

裝置支援的最大效果數

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_allocate_device() 分配輸入裝置後立即安全地使用 input_event(),甚至在使用 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 複製到另一個 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

包含要轉換的掃描碼的 keymap 條目。

unsigned int *scancode

指向應儲存轉換後的掃描碼的位置的指標。

描述

此函式用於將 struct keymap_entry 中儲存的掃描碼轉換為舊版 keymap 處理方法可以理解的標量形式。 這些方法希望掃描碼錶示為 “unsigned int”。

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

檢索當前對映到給定掃描碼的鍵碼

引數

struct input_dev *dev

正在查詢其 keymap 的輸入裝置

struct input_keymap_entry *ke

keymap 條目

描述

任何有興趣檢索當前 keymap 的人都應呼叫此函式。 目前,evdev 處理程式使用它。

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

將鍵碼分配給給定的掃描碼

引數

struct input_dev *dev

正在更新其 keymap 的輸入裝置

const struct input_keymap_entry *ke

新的 keymap 條目

描述

任何需要更新當前 keymap 的人都應呼叫此函式。 目前,鍵盤和 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 基礎架構控制。 同樣值得注意的是,託管輸入裝置的拆卸在內部是一個兩步過程:註冊的託管輸入裝置首先被登出,但保留在記憶體中並且仍然可以處理 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_base** 和 **legacy_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;
};

成員

鍵盤對映

指向使用 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() 呼叫預接收處理程式,可選地處理來自裝置的命令確認和響應,最後將資料傳遞給主協議處理程式以供進一步處理。