Identity
| Part | SGMicro SGM3140 (1.5 A LED flash / torch driver) |
| Role | High-side current driver for the rear camera flash LED |
| Bus / address | GPIO-controlled, no bus interface |
| GPIO / IRQ | FLASH_EN = gpio4 RK_PC6 (bank 4 pin 22), FLASH_TORCH = gpio1 RK_PA3 (bank 1 pin 3), both active-high; pinctrl group flash_pins |
| Datasheet | SGMicro SGM3140 |
| Pine64 wiki | PinePhone Pro — Cameras |
| Schematic | sheet 13 (rear camera area) |
Status — ● working
DTS overlay in tree (src/sys/dts/arm64/overlays/sgm3140.dtso) wires
both FLASH_EN and FLASH_TORCH as gpioled(4) consumers via a
sibling compatible = "gpio-leds" node — FreeBSD has no driver for
the upstream sgmicro,sgm3140 compatible string, so we reuse the
existing two GPIOs through the standard gpio-leds binding instead.
Verified live on 2026-05-03 (kernel #140+, head b7ec39b):
/dev/led/flash and /dev/led/torch exist; echo 1 > /dev/led/flash
turns the rear flashlight on continuously (torch mode), and
/dev/led/flash + /dev/led/torch together produce a visible camera
strobe at 250 ms (the bench’s 80 ms pulse is real but too brief for
the eye). The overlay had to be added to
sys/modules/dtb/rockchip/Makefile ( b7ec39b dtb: build sgm3140 overlay as part of the rockchip dtb modules ) so
buildkernel actually emits sgm3140.dtbo, and the phone’s
fdt_overlays line in /boot/loader.conf had to grow sgm3140
beyond the original bcm-hostwake.
The part itself is a two-GPIO state machine, not a sensor. Linux’s
leds-sgm3140 driver treats the GPIO named enable as the chip
enable and the GPIO named flash as the mode/strobe line:
torch/brightness mode is enable=1, flash=0; flash/strobe mode is
enable=1, flash=1. Our gpioled overlay exposes those two raw lines as
/dev/led/flash (enable) and /dev/led/torch (flash/mode), which
makes this useful as a flashlight even though the cameras themselves are
person-years out.
Driver
- Our tree:
src/sys/dts/arm64/overlays/sgm3140.dtso— pure DT overlay, no C driver. Adds a root-levelcompatible = "gpio-leds"node with two children (flash,torch) that bind to the in-treegpioled(4)driver. - Linux mainline:
drivers/leds/leds-sgm3140.c— small driver registering an LED class device + V4L2 flash subdev. The LED-class side is the relevant reference for FreeBSD; the V4L2 side is moot until cameras land. Linux usesflash-gpios+enable-gpiosproperties on its own compatible; we expose the same two GPIOs through the genericgpio-ledsbinding instead, since FreeBSD has nosgmicro,sgm3140driver.
No I2C, no clocks, no regulators beyond what the rest of the camera
area already provides; the base DTS already has the flash_pins
pinctrl group, which our overlay reuses.
Parity verification
-
dmesgshould show twogpioledinstances at attach (one per child node), e.g.gpioledN: <GPIO LED>onsimplebus0. -
ls /dev/led/should list bothflashandtorch. -
Use the checked-in bounded bench helper instead of hand-writing GPIOs:
mise run debug:flash:sgm3140 -- status mise run debug:flash:sgm3140 -- torch mise run debug:flash:sgm3140 -- flashtorchdefaults to 300 ms;flashdefaults to 80 ms and is capped at 250 ms by the wrapper. Override withTORCH_MS=500orFLASH_MS=100if the first pass is too short to see. -
The helper treats
/dev/led/flashas the SGM3140 enable line and/dev/led/torchas the flash/mode line: torch mode setsflash=1, torch=0; flash mode setsflash=1, torch=1. Both paths trap exit and force both LED nodes low. -
Falsifier — no
/dev/led/entries after attach: thegpioledconsumer didn’t bind. Most likely causes: the overlay didn’t actually merge (checkkenv | grep fdt_overlaysand thebootverboseFDT log), or the GPIO bank/offset is wrong (re-derive fromRK_PC6=2*8+6= 22,RK_PA3=0*8+3= 3, both active-high). -
Falsifier —
/dev/led/{flash,torch}exist but the LED stays dark: polarity is inverted,flash_pinsisn’t being applied so the pads are still in their default mux, or the mode/enable interpretation is wrong. Sanity-check with a multimeter on the SGM3140 EN/TORCH pins.
Open work
- Decide whether to expose a single combined node with a mode sysctl
(flash pulse vs torch sustained) if raw
/dev/led/flash+/dev/led/torchproves too awkward for userland. - Smoke-test current draw on the bench before relying on it heavily — the SGM3140 will happily pull more than the battery wants if both GPIOs are misdriven (especially
FLASH_ENhigh without the strobe path correctly arbitrated).
Related
- What’s next: finish WiFi, then modem — camera roadmap context.
- IMX258 component reference — the camera that would eventually use the flash.
- Hardware reference — chip manifest.