Documentation
On this page

Subsystems

Keys

Power and volume: the keypad and the PMIC's key inputs.

Hardware

Three keys on two controllers. Volume down is on the SoC’s keypad (0x10010000, interrupt SPI 73): the controller scans the matrix itself (LK sets it up for its boot menu) and holds one bit per matrix position in KP_MEM1 to KP_MEM5, 0 meaning pressed. Volume down is bit 1 of KP_MEM1 here. Power and volume up are the PMIC’s inputs (PWRKEY and HOMEKEY), read from TOPSTATUS (bits 1 and 3, 0 meaning pressed). The PMIC is an MT6366 with the MT6358’s register layout; its wrapper is at 0x1000d000.

Driver

MTKKeypad.cpp takes the keypad’s edge interrupt through the GIC driver and posts a consumer-control HID event for each mapped bit; changes of unmapped bits are logged once, which is how a new board’s map is found. MT6358Keys.cpp is a child of MT6358PMIC.cpp on the PMIC wrapper (MTKPwrap.cpp): it takes the PMIC’s press and release interrupts and re-reads the state, so a lost edge cannot leave a key stuck. The loader reads the same keys before XNU for the safe boot and the boot menu.

Device tree

/arm-io/keypad (keymap <1, volume down>), /arm-io/eint, and /arm-io/pwrap/pmic/keys (keymap <0 power, 1 volume up>; the PMIC’s interrupt is EINT 144). HID usages are 0xe9 volume up, 0xea volume down, 0x30 power. See Device tree.

Boot-arguments

None. (mp_hid_test runs a test timer on the button service.)

Status

device.conf: works: power and volume: volume down on the keypad, volume up and power on the PMIC.

Seen: volume up, volume down and power, each down and up (smoke run 3).

Known issues

None recorded. Holding Volume Down at boot is read by mtkloader for the safe boot, not by these drivers.

Source files

iokit/Kernel/arm/hid/MTKKeypad.cpp, MT6358Keys.cpp, iokit/Kernel/arm/MT6358PMIC.cpp, MTKPwrap.cpp, MTKEINT.cpp of the kernel at 76b737c; tools/mkadt.py of mapple_build at f7431bb.

Applies to realme 8i (spaced), release 1 · Updated 15 November 2026