Control 137 LEDs directly from your terminal. No SDK. No app sandbox. Pure sysfs.
v1.0.0 · Nothing Phone (4a) Pro · Magisk Module · Shell + Web
GlyphCLI is a Magisk module that gives you raw, unrestricted control over the 137-LED matrix on the Nothing Phone (4a) Pro. It bypasses the Ketchum SDK entirely, writing directly to the AW20144 sysfs interface. Includes 30+ commands, a web control panel, a background daemon, audio visualizer, games, and text rendering on a 13x13 circular grid.
| Component | Details |
|---|---|
| LED Controller | AW20144 (LITEON) |
| Bus | I2C-0, address 0x0020 |
| Chip ID | 0x74, Hardware T0 |
| Physical LEDs | 137 (circular mask of 13x13 grid) |
| Brightness | 12-bit PWM per LED (0-4095), 8-bit global (0-255) |
| Red Indicator | Separate PMIC LED at /sys/class/leds/red |
| sysfs Path | /sys/class/leds/matrix-leds/ |
| Target Device | Nothing Phone (4a) Pro — A069P / FroggerPro |
The 13x13 logical grid has 169 cells, but only 137 are physically wired. The circular mask cuts the corners:
Row 0: 5 LEDs cols 4-8 · · · · o o o o o · · · ·
Row 1: 9 LEDs cols 2-10 · · o o o o o o o o o · ·
Row 2: 11 LEDs cols 1-11 · o o o o o o o o o o o ·
Row 3: 11 LEDs cols 1-11 · o o o o o o o o o o o ·
Row 4: 13 LEDs cols 0-12 o o o o o o o o o o o o o
Row 5: 13 LEDs cols 0-12 o o o o o o o o o o o o o
Row 6: 13 LEDs cols 0-12 o o o o o o o o o o o o o
Row 7: 13 LEDs cols 0-12 o o o o o o o o o o o o o
Row 8: 13 LEDs cols 0-12 o o o o o o o o o o o o o
Row 9: 11 LEDs cols 1-11 · o o o o o o o o o o o ·
Row 10: 11 LEDs cols 1-11 · o o o o o o o o o o o ·
Row 11: 9 LEDs cols 2-10 · · o o o o o o o o o · ·
Row 12: 5 LEDs cols 4-8 · · · · o o o o o · · · ·
5 + 9 + 11 + 11 + 13×5 + 11 + 11 + 9 + 5 = 137
Physical LED indices run sequentially left-to-right, top-to-bottom: row 0 is indices 0-4, row 1 is 5-13, and so on through row 12 at 132-136. See the full coordinate map in glyph-svg/nothing-glyph-map.json.
Flash through Magisk Manager:
GlyphCLI-v1.0.0.zip
Or via adb:
adb push GlyphCLI-v1.0.0.zip /data/local/tmp/
adb shell su -c magisk --install-module /data/local/tmp/GlyphCLI-v1.0.0.zipNo reboot required. All commands require root (su).
|
|
|
|
|
The red indicator LED is on a separate PMIC controller, independent of the 137-LED Glyph matrix. |
|
|
Uses a 5x7 bitmap font rendered onto rows 3-9 of the grid. |
|
|
|
|
|
All animations run until Ctrl+C.
|
|
|
|
|
|
|
|
|
|
|
|
Modes: |
|
|
Access the web panel at |
|
|
|
|
Fill |
Gradient |
Wave |
Breathe |
|
Snake |
Rain |
Fireworks |
Heartbeat |
|
Rings |
Spiral |
Equalizer |
Alternate |
|
Print — HI |
Number — 42 |
Clock — Digital |
Clock — Analog |
|
Game of Life |
Pong |
Dice — 5 |
Morse — SOS |
|
Battery — 75% |
CPU — 60% |
Progress — 60% |
Nothing Logo |
The Nothing Phone (4a) Pro uses a 13x13 logical grid, but only 137 of the 169 positions have physical LEDs. The remaining 32 cells at the four corners are dead — they fall outside the circular PCB mask.
Each LED is addressed by a physical index (0-136) that runs sequentially through the grid, skipping dead cells. The kernel driver in leds_aw20144 handles the 169-to-137 mapping internally when the Nothing SDK sends a full 13x13 array. GlyphCLI bypasses this and writes the 137 physical values directly.
The full coordinate map with pixel positions, row/column assignments, and physical indices is available in glyph-svg/nothing-glyph-map.json.
The Glyph LED matrix is driven by an AW20144 LED controller from LITEON, connected via I2C at bus 0, address 0x0020. The kernel module leds_aw20144 exposes the following sysfs interface at /sys/class/leds/matrix-leds/:
| File | Purpose |
|---|---|
frame_brightness |
Write 137 space-separated values (0-4095), one per physical LED |
brightness |
Global brightness (0-255) |
single_brightness |
Set one LED: write "index value" |
operating_mode |
Power on (1) / off (0) |
effect |
Firmware effects (e.g. aw20144_all_rgb_on.bin) |
imax |
Maximum current control (0-15) |
Nothing SDK Path:
App --> GlyphMatrixManager --> IGlyphService (AIDL) --> NtGlyphServiceImpl --> sysfs
com.nothing.ketchum
GlyphCLI Path:
Shell ---------> sysfs (direct, no middleware)
Nothing's SDK (com.nothing.ketchum) sends a 13x13 (169-element) brightness array through the IGlyphService AIDL interface. The service writes to the AW20144 kernel driver, which maps the 169 logical pixels to 137 physical LEDs. GlyphCLI skips all of that and writes the 137 values directly via sysfs.
Start the web server:
su -c glyph server startThe server binds to 0.0.0.0:8080 using toybox nc and serves a self-contained HTML panel. Access it from any browser on the same network at http://<phone-ip>:8080.
| Method | Endpoint | Body | Description |
|---|---|---|---|
| GET | /api/status |
— | Returns JSON with mode, brightness, frame, battery, CPU, RAM, temp, daemon status |
| POST | /api/cmd |
{"cmd":"...", "args":"..."} |
Execute any glyph command |
| POST | /api/pixel |
{"led": N, "brightness": V} |
Set a single LED |
| POST | /api/frame |
{"frame": [v0, v1, ...v136]} |
Write a full 137-value frame |
The web panel provides a visual 13x13 grid where you can tap individual LEDs, launch animations, view system stats, and control the daemon — all from your browser.
The AW20144 LED controller was discovered by probing a rooted Nothing Phone (4a) Pro:
- The
aw882xxentries in logcat are the audio smart PA (speaker amplifier), not LEDs - The
aw86927is the haptic motor driver - The actual LED driver is
aw20144at I2C-0 address0x0020 - Chip ID reads as
0x74, hardware version T0, manufacturer LITEON - Decompiled
GlyphNotification.apkand traced through thecom.nothing.ketchumSDK - Device model
A069Pmaps to SDK codename25111p(internal name: FroggerPro) - The SDK uses 12-bit brightness values (0-4095) per pixel
frame_num 137indmesgconfirmed the physical LED count- The 13x13 to 137 mapping is handled in the kernel driver, not in userspace
- The red indicator LED is on a separate PMIC controller at
/sys/class/leds/redwith hardware timer blink support
Adding new patterns: Write a new cmd_<name> function in system/bin/glyph. Use fb_clear, fb_set_led, fb_set_pixel, and fb_flush to manipulate the framebuffer. For animations, add a trap 'cmd_off; exit 0' INT TERM and loop with _sleep_ms.
SVG testing on desktop: The glyph-svg/nothing-glyph-blank.svg template can be used to preview patterns without a phone. Each <rect> has data-index, data-row, and data-col attributes for programmatic control. Run python3 generate_readme_assets.py to regenerate all showcase SVGs after making changes.
Web panel: Edit system/etc/glyph-web/panel.html for the web interface. It is a single self-contained HTML file with inline CSS and JavaScript.
MIT