Phase 03b2 — Boot Mode Selection (Hall Sensor)
Status: ✅ Complete — ABL v2.4 confirmed working.
Close the magnetic cover during power-on → 3 seconds → TWRP. Cover open → normal Android boot.
The Note Air 1 has no volume buttons. Without this, any Android bootloop requires battery drain (hours) to reach PBL 9008. The hall sensor is the only available boot-time input mechanism.
Hardware: Hall Sensor GPIO 105
| Field | Value |
|---|---|
| GPIO | 105 (0x69) — from DTS: irq-gpio = <0xa1 0x69 0x00> |
| DTS node | onyx_hall, compatible = “onyx,onyx-hall” |
| TLMM south tile base | 0x03100000 (mainline kernel mapping) |
| GPIO_IN_OUT register | 0x03169004 = 0x03100000 + (105 × 0x1000) + 0x04 |
| bit0 = 1 | Cover OPEN |
| bit0 = 0 | Cover CLOSED |
Critical: Use south tile address, not flat address
The DTS shows base address 0x03000000. This flat address is XPU-blocked from ABL — raw MmioRead32(0x03069004) causes an indefinite bus stall. The south tile address (0x03169004) is correctly mapped and confirmed working in v2.4. ABL v2.1 used the flat address and bricked the device — recovery required full battery drain + cold-boot PBL 9008.
ABL Implementation
/* In LinuxLoaderEntry(), after GetKeyPress(), before GetRebootReason() */
UINT32 HallVal = MmioRead32(NA1_HALL_GPIO_IN_OUT); /* 0x03169004 */
if (!(HallVal & 0x1)) { /* cover closed */
MicroSecondDelay(3000000); /* wait 3s */
HallVal = MmioRead32(NA1_HALL_GPIO_IN_OUT);
if (!(HallVal & 0x1)) { /* still closed */
BootIntoRecovery = TRUE;
}
}
GCD memory mapping required before MmioRead32: call gDS->GetMemorySpaceDescriptor(); if unmapped, add via gDS->AddMemorySpace() + SetMemorySpaceAttributes(EFI_MEMORY_UC).
Test Matrix (all confirmed)
| Test | Expected | Result |
|---|---|---|
| Cover open, power on | Android boots normally | ✅ |
| Cover closed + power on for 3s | TWRP loads | ✅ |
| Cover closed briefly (<3s) | Normal boot (debounce) | ✅ |
| TWRP → Reboot System | Android boots | ✅ |
| TWRP → ADB | Shell works | ✅ |
| fastboot oem reboot-recovery | TWRP loads | ✅ |