Add Doxygen pages for RT-Thread device-model drivers: platform/OFW, DM core (bus, dm, power), clk/regulator/reset/power-domain, PCI/PIC, Phye, DMA/hwcache, block/SCSI/ATA/NVMe/UFS/SDIO, SCMI, RPMsg, mailbox, NVMem, NUMA, syscon, thermal, input/LED/IIO/graphic, and related power/charger/supply docs. Expand device-driver INDEX.md with ~90 @subpage entries so all new pages appear in the driver chapter navigation. Update existing UART/SPI/RTC/pin/framework/dtc pages: UART docs moved from serial/ to uart/ (uart + uart_dm + uart_earlycon); SPI and RTC gain DM companion pages; pin links to pin_dm; framework points at DM topics. Focus on registration/probe flow and in-tree APIs; no standalone VirtIO subsystem page (transport code still incomplete). Test plan: build Doxygen for documentation/ and verify device-driver INDEX links resolve without missing @ref/@subpage warnings. Signed-off-by: GuEe-GUI <2991707448@qq.com>
9.0 KiB
Executable File
@page page_device_input_dm Input device model (DM)
Input subsystem under RT_USING_DM
The input core (components/drivers/input/input.c) is built only when RT_USING_INPUT is enabled. That Kconfig option depends on RT_USING_DM — there is no legacy non-DM input stack in-tree. Drivers publish Linux-style EV_* events through struct rt_input_device; consumers attach via rt_input_add_handler or POSIX /dev/inputN (@ref page_device_input_uapi).
Event reporting API, polling rules, and pitfalls: @ref page_device_input.
| Topic | Page |
|---|---|
Userspace open/read/ioctl |
@ref page_device_input_uapi |
rt_touch_device bridge |
@ref page_device_input_touch |
KEY_POWER / KEY_RESTART shutdown/reset |
@ref page_device_input_power |
Sources:
| File | Role |
|---|---|
input.c |
Global device list, rt_dm_ida naming (input0…), rt_input_device_register |
input_power.c |
@ref page_device_input_power |
input_touch.c |
@ref page_device_input_touch |
input_uapi.c |
@ref page_device_input_uapi |
keyboard/, joystick/, touchscreen/, misc/ |
OFW platform/SPI drivers |
Kconfig / build
| Option | Role |
|---|---|
RT_USING_DM |
Parent — input cannot be enabled without DM |
RT_USING_INPUT |
Core input.c; selects RT_USING_ADT + bitmap ADT |
RT_INPUT_POWER |
@ref page_device_input_power (default y) |
RT_INPUT_UAPI |
@ref page_device_input_uapi |
RT_INPUT_KEYBOARD |
gpio-keys, adc-keys (see sub-options) |
RT_INPUT_JOYSTICK |
adc-joystick |
RT_INPUT_TOUCHSCREEN |
@ref page_device_input_touch |
RT_INPUT_MISC |
e.g. ettus,e3x0-button |
SOC_DM_INPUT_*_DIR |
BSP adds more platform drivers via osource in sub-Kconfig |
Unlike @ref page_device_i2c_dm, input has no dedicated rt_bus. Each hardware block is a normal struct rt_platform_driver (or struct rt_spi_driver) that embeds or owns struct rt_input_device and calls rt_input_device_register from probe.
Architecture
Device tree node (compatible = "gpio-keys", "adc-keys", …)
|
| platform bus match (rt_ofw_node_id) or SPI bus match
v
driver probe(pdev)
|
| parse OFW (gpios, io-channels, irq, …)
| rt_input_set_capability(idev, EV_KEY|EV_ABS, code)
| optional: rt_input_setup_polling / rt_input_setup_touch
v
rt_input_device_register(idev)
|
| rt_dm_ida_alloc → name "inputN"
| rt_device_register (RT_Device_Class_Char, DEACTIVATE)
| [RT_INPUT_UAPI] input_uapi_init
| list on input_device_nodes
v
[RT_INPUT_TOUCHSCREEN] input_touch_register → rt_touch_device
[RT_INPUT_POWER] global KEY_POWER / KEY_RESTART handlers
|
v
Hardware IRQ / timer poll → rt_input_report_* → rt_input_sync
|
v
rt_input_event → handlers / UAPI queue
| Layer | Object | Notes |
|---|---|---|
| Input device | struct rt_input_device |
Embeds struct rt_device parent; capabilities in bitmaps |
| DM naming | input_ida in input.c |
rt_dm_dev_set_name(&idev->parent, "input%u", id) |
| Platform binding | RT_PLATFORM_DRIVER_EXPORT |
Probe/remove on struct rt_platform_device |
| SPI touch | RT_SPI_DRIVER_EXPORT |
e.g. ADS7846 — see @ref page_device_input_touch |
Core registration (input.c)
rt_err_t rt_input_device_register(struct rt_input_device *idev);
rt_err_t rt_input_device_unregister(struct rt_input_device *idev);
| Step | Behavior |
|---|---|
| Allocate ID | rt_dm_ida_alloc(&input_ida) — failure → -RT_EFULL |
| Init lists / lock | Per-device handler_nodes, rt_spinlock |
| Register char dev | RT_Device_Class_Char, flag RT_DEVICE_FLAG_DEACTIVATE |
| Post-register | Start poller timer if idev->poller; input_touch_register; UAPI fops if enabled |
| Unregister | Refcount check; UAPI/touch teardown; rt_dm_ida_free |
Driver pattern — embed input at a known offset:
struct my_input {
struct rt_input_device parent;
/* private */
};
static void my_report(struct my_input *mi)
{
rt_input_report_key(&mi->parent, KEY_ENTER, 1);
rt_input_sync(&mi->parent);
}
Use rt_container_of(idev, struct my_input, parent) in poll/IRQ callbacks.
In-tree OFW drivers
| Compatible / binding | Driver file | Bus | Summary |
|---|---|---|---|
gpio-keys |
keyboard/keys-gpio.c |
platform | Parent node; each child → one inputN per key |
adc-keys |
keyboard/keys-adc.c |
platform | io-channels via @ref page_device_iio_dm; polling |
adc-joystick |
joystick/js-adc.c |
platform | Per-child reg, IIO, EV_ABS polling |
ti,ads7846 … ti,xpt2046 |
touchscreen/ts-ads7846.c |
SPI | @ref page_device_input_touch |
ettus,e3x0-button |
misc/button-e3x0.c |
platform | IRQ press/release → KEY_POWER |
gpio-keys (platform + children)
- Parent
compatible = "gpio-keys"; subnodes are individual buttons. - Each child:
rt_ofw_get_named_pin, property matching*,code$(e.g.linux,code), optionaldebounce-interval. - One
rt_input_deviceper child (not one device for the whole parent).
adc-keys / adc-joystick (IIO consumers)
- Resolve ADC through
rt_iio_channel_get_by_name/rt_iio_channel_get_by_index(@ref page_device_iio_dm). - Default
poll-interval200 ms if property missing.
ADS7846 family (SPI)
RT_SPI_DRIVER_EXPORT(ads7846_driver); regulator, IRQ, worker thread.- DT axis/touch properties consumed by
input_touch_parse— @ref page_device_input_touch.
Device tree examples
GPIO key (child node)
gpio-keys {
compatible = "gpio-keys";
power-key {
label = "Power";
gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
linux,code = <116>; /* KEY_POWER — see page_device_input_power */
debounce-interval = <15>;
};
};
ADC resistor ladder
adc-keys {
compatible = "adc-keys";
io-channels = <&saradc 0>;
io-channel-names = "buttons";
poll-interval = <100>;
keyup-threshold-microvolt = <1800000>;
up {
press-threshold-microvolt = <500000>;
linux,code = <103>; /* KEY_UP */
};
};
SPI resistive touch
touch: touchscreen@0 {
compatible = "ti,ads7846";
reg = <0>;
interrupt-parent = <&gpio1>;
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
ti,x-min = /bits/ 16 <0>;
ti,x-max = /bits/ 16 <4095>;
ti,y-min = /bits/ 16 <0>;
ti,y-max = /bits/ 16 <4095>;
vcc-supply = <®_3v3>;
};
(SPI reg / spi-max-frequency belong on the child under the SPI controller node per your BSP.)
New platform input driver checklist
- Enable
RT_USING_DM,RT_USING_OFW,RT_USING_INPUT(and subsystem menu if you add underkeyboard/etc.). struct rt_platform_driverwithofw_ids[]matching Linux binding where possible.- In
probe: allocate driver private struct withstruct rt_input_deviceembedded first (or pointer field). rt_input_set_capabilityfor everytype/codeyou will report; forEV_ABS, callrt_input_set_absinfo(after capability allocatesabsinfo).- IRQ or
rt_input_setup_polling— pollerpollmust not block (@ref page_device_input). - On each logical event frame:
rt_input_report_*thenrt_input_sync. rt_input_device_registeronly when hardware is ready; store private data inpdev->parent.user_dataorrt_ofw_data(np)forremove.remove: stop IRQ/poller,rt_input_device_unregister, free memory.RT_PLATFORM_DRIVER_EXPORT(drv)(orRT_SPI_DRIVER_EXPORTon SPI slaves).
Pitfalls
| Issue | Mitigation |
|---|---|
Missing rt_input_sync |
Consumers see partial frames — always end with rt_input_sync. |
| Capability after register | Set capabilities before rt_input_device_register. |
EV_ABS without absinfo |
Call rt_input_set_capability(EV_ABS, axis) then rt_input_set_absinfo. |
| Unregister with open UAPI fd | Close /dev/inputN first — @ref page_device_input_uapi |
| gpio-keys child vs parent | Driver registers per child; do not expect one input0 for the whole node. |
| IIO channel NULL | Fix DT io-channels — @ref page_device_iio_dm |
| Power handler surprise | @ref page_device_input_power |
See also
- @ref page_device_input
- @ref page_device_input_uapi
- @ref page_device_input_touch
- @ref page_device_input_power
- @ref page_device_iio_dm
- @ref page_device_bus
components/drivers/include/drivers/input.hcomponents/drivers/input/Kconfig