Identity
| Part | Tablet-mode switch and lid/hall sensor |
| Role | Keyboard/tablet mode and cover-open/closed state |
| Bus / address | gpio-keys FDT child nodes |
| GPIO / IRQ | Tablet mode: GPIO4_A4, active high; Hall sensor: GPIO0_A6, active low on v2.0 |
| DTS event type | linux,input-type = <EV_SW> |
| DTS event codes | SW_TABLET_MODE and SW_LID |
Status — ◐ partial
The PineTab2 DTS does not describe these as normal keyboard buttons.
Both nodes are switch events: SW_TABLET_MODE for keyboard/tablet
state, and SW_LID for the v2.0 hall sensor. FreeBSD’s stock
gpiokeys(4) path only treated linux,code as EV_KEY, which is
right for power and volume buttons but wrong for these two tablet
signals.
The local patch makes gpiokeys(4) read optional linux,input-type.
Plain buttons still default to EV_KEY; EV_SW nodes advertise switch
capabilities with evdev_support_sw() and report state with
evdev_push_sw() instead of inventing keyboard scan codes.
Hardware proof is still pending. The first tablet session should verify
that /dev/input/event* exposes SW_TABLET_MODE and SW_LID, then
capture open/closed and keyboard-attached/detached transitions with
evemu-record or libinput debug-events.
Patch
sys/dev/gpio/gpiokeys.c
#define SCAN_RELEASE 0x80 #define SCAN_CHAR(c) ((c) & 0x7f) #define GPIOKEYS_LINUX_EV_KEY 0x01 #define GPIOKEYS_LINUX_EV_SW 0x05 #define GPIOKEYS_GLOBAL_NMOD 8 /* units */ #define GPIOKEYS_GLOBAL_NKEYCODE 6 /* units */ #define GPIOKEYS_GLOBAL_IN_BUF_SIZE (2*(GPIOKEYS_GLOBAL_NMOD + (2*GPIOKEYS_GLOBAL_NKEYCODE))) /* bytes */ struct mtx mtx; #ifdef EVDEV_SUPPORT uint32_t evcode; uint32_t evtype; #endif uint32_t keycode; int autorepeat; #ifdef EVDEV_SUPPORT if (key->evcode != GPIOKEY_NONE && (evdev_rcpt_mask & EVDEV_RCPT_HW_KBD) != 0) { evdev_push_key(sc->sc_evdev, key->evcode, pressed); if (key->evtype == EV_SW) evdev_push_sw(sc->sc_evdev, key->evcode, pressed); else evdev_push_key(sc->sc_evdev, key->evcode, pressed); evdev_sync(sc->sc_evdev); } if (evdev_is_grabbed(sc->sc_evdev)) { pcell_t prop; char *name; uint32_t code; uint32_t evtype; int err; const char *key_name; key->parent_sc = sc; callout_init_mtx(&key->debounce_callout, &key->mtx, 0); callout_init_mtx(&key->repeat_callout, &key->mtx, 0); key->keycode = GPIOKEY_NONE; #ifdef EVDEV_SUPPORT key->evcode = GPIOKEY_NONE; key->evtype = EV_KEY; #endif name = NULL; if (OF_getprop_alloc(node, "label", (void **)&name) == -1) key->keycode = fdt32_to_cpu(prop); else if ((OF_getprop(node, "linux,code", &prop, sizeof(prop))) > 0) { code = fdt32_to_cpu(prop); key->keycode = gpiokey_map_linux_code(code); if (key->keycode == GPIOKEY_NONE) device_printf(sc->sc_dev, "<%s> failed to map linux,code value 0x%x\n", key_name, code); evtype = GPIOKEYS_LINUX_EV_KEY; if (OF_getprop(node, "linux,input-type", &prop, sizeof(prop)) > 0) evtype = fdt32_to_cpu(prop); if (evtype == GPIOKEYS_LINUX_EV_SW) { #ifdef EVDEV_SUPPORT key->evcode = code; evdev_support_key(sc->sc_evdev, code); key->evcode = code; key->evtype = EV_SW; evdev_support_event(sc->sc_evdev, EV_SW); evdev_support_sw(sc->sc_evdev, code); #else device_printf(sc->sc_dev, "<%s> EV_SW requires evdev support\n", key_name); #endif } else if (evtype == GPIOKEYS_LINUX_EV_KEY) { key->keycode = gpiokey_map_linux_code(code); if (key->keycode == GPIOKEY_NONE) device_printf(sc->sc_dev, "<%s> failed to map linux,code value 0x%x\n", key_name, code); #ifdef EVDEV_SUPPORT key->evcode = code; key->evtype = EV_KEY; evdev_support_key(sc->sc_evdev, code); #endif } else { device_printf(sc->sc_dev, "<%s> unsupported linux,input-type value 0x%x\n", key_name, evtype); } } else device_printf(sc->sc_dev, "<%s> no linux,code or freebsd,code property\n", Bring-Up Predicate
After booting the PineTab2 kernel:
sysctl -a | grep gpiokeys
libinput debug-events
Expected first-pass evidence:
- The
gpio-keysdevice attaches without “unsupported linux,input-type” messages. - Toggling the keyboard attachment changes
SW_TABLET_MODE. - Moving the cover or a magnet over the hall sensor changes
SW_LID. - Neither switch produces stray key presses through the keyboard path.
Open Work
- Record the active polarity and event values on real hardware.
- Decide userland policy: tablet-mode probably controls keyboard-cover
assumptions, while
SW_LIDcan feed screen blanking once display power management exists.