1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
@page page_device_input_power Input power keys
# Power / restart key handlers (`RT_INPUT_POWER`)
**`input_power.c`** installs global **`rt_input_handler`** instances that map **`KEY_POWER`** and **`KEY_RESTART`** release events to **`rt_hw_cpu_shutdown()`** and **`rt_hw_cpu_reset()`**. Any input device that advertises these keys in its capability bitmap can trigger system power actions without a dedicated PMIC driver hook.
DM and keyboard drivers: @ref page_device_input_dm. Handler API: @ref page_device_input.
Source: **`components/drivers/input/input_power.c`**.
---
## Kconfig
| Option | Default | Role |
| --- | --- | --- |
| **`RT_INPUT_POWER`** | **y** | Build **`input_power.c`**, run **`input_event_power_init`** at env init |
Depends on **`RT_USING_INPUT`**. Disable on boards where **`KEY_POWER`** must only be handled by application code.
---
## Architecture
```
INIT_ENV_EXPORT(input_event_power_init)
|
+-- power_handler_install(KEY_POWER)
+-- power_handler_install(KEY_RESTART)
|
| (1) tmp_handler: identify=test, callback=power_input_callback
| rt_input_add_handler → scans all idevs, counts matches
v
(2) For each matching input device index:
alloc rt_input_handler[N]
identify=power_input_identify (binds to Nth device with key)
callback=power_input_callback
rt_input_add_handler
|
v
Any idev reports KEY_POWER/KEY_RESTART release (value==0)
→ rt_input_event → handler → shutdown/reset
```
| Phase | Behavior |
| --- | --- |
| **Probe pass** | Temporary handler increments **`cap.value`** for each **`rt_input_device`** with **`key_map[code]`** set |
| **Install pass** | One persistent handler per matching device; **`identify`** matches the **`current`**-th device |
| **Runtime** | **`power_input_callback`**: on **`value == 0`** (key release), call BSP hook |
Handlers return **`RT_TRUE`** from **`callback`** to stop further handler dispatch for that event.
---
## Key actions
| Linux code | Event | Action |
| --- | --- | --- |
| **`KEY_POWER`** (116) | **`EV_KEY`**, **`value == 0`** (release) | **`rt_hw_cpu_shutdown()`** |
| **`KEY_RESTART`** | **`EV_KEY`**, **`value == 0`** | **`rt_hw_cpu_reset()`** |
Press (**`value == 1`**) does nothing in **`input_power.c`** — only release triggers power ops.
BSP must implement **`rt_hw_cpu_shutdown`** / **`rt_hw_cpu_reset`** (weak symbols or SoC-specific).
---
## Interaction with drivers
- **`gpio-keys`** child with **`linux,code = <116>`** registers an **`inputN`** with **`KEY_POWER`** in **`key_map`** — power handler attaches automatically when **`RT_INPUT_POWER`** is on.
- **`ettus,e3x0-button`** reports **`KEY_POWER`** on IRQ — same path.
- Does **not** require a dedicated compatible string; only the **advertised key code** matters.
If multiple devices expose **`KEY_POWER`**, each gets its own handler instance; any of them can shut down the system on release.
---
## Disabling or overriding
| Goal | Approach |
| --- | --- |
| **No automatic shutdown** | Set **`RT_INPUT_POWER=n`** in Kconfig |
| **Custom policy** | Disable **`RT_INPUT_POWER`** and use **`rt_input_add_handler`** with higher priority logic, or handle **`KEY_POWER`** only in userspace via @ref page_device_input_uapi |
| **Hold-to-power-off** | Not implemented here — implement in driver (long-press timer) before reporting release |
---
## Pitfalls
| Issue | Mitigation |
| --- | --- |
| **Unexpected shutdown** | Any stray **`KEY_POWER`** release shuts down — verify DT **`linux,code`** and test harnesses |
| **Missing capability** | Driver must **`rt_input_set_capability(idev, EV_KEY, KEY_POWER)`** before register |
| **Press-only testing** | Release is required — press alone does not call shutdown |
| **No matching devices** | **`power_handler_install`** exits early if count is zero (no handlers allocated) |
---
## See also
- @ref page_device_input_dm — **`gpio-keys`** DT example with **`KEY_POWER`**
- @ref page_device_input
- `dt-bindings/input/linux-event-codes.h` (or **`event-codes.h`**)
|