Skip to main content

Chip Catalogue

The SDK ships 80 chip drivers under chips/<part>/, described by 84 manifests under metadata/chips/. Each driver is independent, opt-in, and named after the chip's natural manufacturer name (no alp_ prefix — that's reserved for SDK-level abstractions). The four manifests without a driver are declared planned (Murata radio modules that are BOM candidates only) — the manifest/driver parity is CI-enforced, so a manifest can't quietly imply code that doesn't exist.

The Tier-0 drivers (on-module silicon for AEN / V2N / V2N-M1, plus the EVK board-side parts) carry the [ABI-STABLE] annotation and ride the SDK's normal ABI guarantees. The drivers added in the §D ecosystem expansion are marked [ABI-EXPERIMENTAL].

No chip driver is silicon-validated yet

Every chip manifest in the tree declares verification.hil_silicon: untested. There are no exceptions — not the on-module Tier-0 parts, not the drivers with the richest feature coverage. Treat every lifecycle sequence, register value, and timing number in this catalogue as paper-correct until the v1.0 verification sweep lands.

What the drivers do have is host-side smoke coverage: null_arg_guard-style contract tests that prove a driver rejects NULL arguments, refuses calls on an uninitialised context, and bounds-checks its tables. Those are argument-validation contract tests, not simulated bus transactions — they say nothing about whether the part works.

(One nearby claim is genuine but belongs elsewhere: the GD32 bridge's boot-select, dual-bank erase, and background-erase OTA paths are silicon-validated. That's bridge firmware, not the gd32g553 chip driver, which remains partial / untested.)

Driver status vocabulary

Every manifest carries a driver_status: — the single source of truth for how complete a driver is. A CI gate keeps each C header's @par Driver status: label in lockstep with its manifest, so a header can't misreport what's implemented.

StatusMeaning
completeThe driver's intended surface is implemented
partialA useful subset works; the manifest's inline comment names what's deferred
stubSkeleton only — compiles and validates arguments
plannedManifest exists, no driver code yet

Roughly 30 drivers each are complete, partial, and stub, plus the 4 planned. These four words are the whole vocabulary, enforced by scripts/check_chip_header_status.py.

Two honest caveats about that gate: the header status tag is optional (only about 32 of 80 headers carry one — the gate skips the rest), and the JSON schema types driver_status as a free string, so the vocabulary is enforced on headers rather than on the manifests themselves. The status definitions in the table above are this page's editorial reading — the SDK doesn't ship a glossary for them.

Opting in

Two equivalent ways to enable a chip driver:

# board.yaml — recommended
chips:
- lsm6dso
- ssd1306
# prj.conf — manual
CONFIG_ALP_SDK_CHIP_LSM6DSO=y
CONFIG_ALP_SDK_CHIP_SSD1306=y

The board.yaml path is preferred because it lets the loader cross-check that the SoM actually routes the bus the chip needs.

Driver shape

Every driver follows the same shape:

#include <alp/chips/<part>.h>

<part>_t ctx;
<part>_init(&ctx, bus, address_or_handle);

// Per-feature getters / setters
<part>_<op>(&ctx, ...);

_init() ACK-probes the chip on its bus. If the chip isn't populated, _init returns ALP_ERR_NOT_READY; well-written firmware handles this gracefully.

Catalogue (selected)

Sensors

DriverPartBusUse
lsm6dsoST LSM6DSOI²C / SPI6-axis IMU
bmi323Bosch BMI323I²C / SPI6-axis IMU
icm42670TDK ICM-42670I²C / SPI6-axis IMU
lis2dw12ST LIS2DW12I²C / SPI3-axis accelerometer
bmp581Bosch BMP581I²CBarometric pressure
bme280Bosch BME280I²CT/RH/pressure
tmp112TI TMP112I²CTemperature (on every Alp Lab SoM)
ina236TI INA236I²CCurrent / voltage monitor

Power

DriverPartNotes
act8760Qorvo ACT88760-120.E1Primary PMIC (V2N family). Datasheet-verified two-slave register map (ADD1: master + Buck1–6; ADD2: Buck7 + LDOs). act8760_rail_get/set_vset() program the VSET0 slot only — DVS slots go via the raw register helpers.
da9292Renesas DA9292Secondary PMIC (V2N family). Register map verified against datasheet Rev 2.2. Fault pins (INT / TW) land on Renesas pads, not the GD32 — read them with da9292_get_fault_pins() or register-level via BRD_I2C.
tps628640TI TPS628640Optional / DEEPX rail bucks
pca9451aNXP PCA9451APrimary PMIC (i.MX 93 / E1M-NX9101). Probe (ACK-only DEV_ID read), raw register R/W, INT1 latched-interrupt decode, and per-rail enable/voltage on all 6 bucks + 5 LDOs. See the caveat below.
note
pca9451a — the E1M-NX9101 board doesn't exist on the bench yet

driver_status: partial. The register map is transcribed from the upstream Linux pca9450-regulator.c (which lists the PCA9451A type), and the driver has never been exercised on real E1M-NX9101 silicon — that board isn't on the bench yet. Every number and sequencing decision is paper-correct only, validated by host-side unit tests against NULL-arg / uninitialised-context / table-bounds properties, not against a real transceiver. Silicon validation is deferred to the NX9101 HiL bring-up.

Clocks + RTC

DriverPartNotes
clk_5l35023bRenesas / IDT 5L35023BClock generator (V2N family)
rv3028c7Micro Crystal RV-3028-C7Battery-backed RTC (every Alp Lab SoM)

Storage + memory

DriverPartNotes
eeprom_24c128Onsemi N24S128128-byte SoM manifest EEPROM

Connectivity

DriverPartNotes
cc3501eTI CC3501EWi-Fi 6 + BLE 5.4 coprocessor (AEN family); SDK-embedded bridge firmware over SPI/SDIO — Wi-Fi/BLE, GPIO proxy, OTA-over-bridge
murata_lbee5hy2fyMurata LBEE5HY2FY-922Wi-Fi 6 + BLE 5.4 combo (V2N family)
rtl8211fdiRealtek RTL8211FDIGigabit Ethernet PHY (×2 on V2N)
murata_lbee0zz2klMurata LBEE0ZZ2KLplanned — SDIO radio, BOM candidate, no driver code
murata_lbee5pl2dlMurata LBEE5PL2DLplanned — SDIO radio, BOM candidate, no driver code
murata_lbes0zz2llMurata LBES0ZZ2LLplanned — SDIO radio, BOM candidate, no driver code
murata_lbes5pl2elMurata LBES5PL2ELplanned — SDIO radio, BOM candidate, no driver code

Security

DriverPartNotes
optiga_trust_mInfineon OPTIGA Trust MSecure element (every Alp Lab SoM). Probe-only — see below.
warning
optiga_trust_m is scoped to probe-only

The driver is deliberately limited to confirming the part is wired correctly. It does: compile, validate its public arguments, and probe the chip by reading the I2C_STATE register.

It does not send OPEN_APPLICATION, or implement product-info (Coprocessor UID) or raw-APDU transport — those entry points are declared so you can compile against the planned surface, but they return ALP_ERR_NOSUPPORT after argument validation. No CalcSign, GenKeyPair, or ECDH. The full APDU transport lands when Infineon's host library is integrated; the probe-only contract is pinned by a test so it can't drift silently.

If you're planning a secure-boot or attestation flow around this part, the crypto operations are not available yet. (Its machine-readable driver_status is partial — "probe-only" is a prose refinement, not a status tier.)

Co-processors + bridges

DriverPartNotes
gd32g553GD GD32G553V2N supervisor MCU (8 PWM, 8 ADC, 2 DAC, 4 QEnc, 18 GPIO)
deepx_dxm1DEEPX DX-M1NPU (V2N-M1 only) — bring_up sequencer
gd32_swdbit-bang controllerSWD recovery for the GD32 bridge
pi3dbs12212Diodes PI3DBS12212APCIe mux — routes the lanes to the DEEPX NPU or the external slot (V2N-M1); deepx_dxm1_bring_up() drives it

IO + UI

DriverPartNotes
tcal9538NXP TCAL95388-bit I/O expander — also drives the register-compatible TCA6408A / PCA9538 (see below)
ssd1306Solomon SSD1306Monochrome 128×64 OLED
ssd1331Solomon SSD1331Small colour OLED
ov5640OmniVision OV56405 MP MIPI CSI camera
cam_mux_pi3wvr626Diodes PI3WVR626Camera input mux — GPIO-driven select shim
tas2563TI TAS2563Class-D speaker amplifier
pdm_micPDM microphone helperFront-end for <alp/audio.h>
button_ledhelperComposite button + LED widget driver

tcal9538_init() accepts two strap families: the TCA9538 / TCAL9538 A1A0 range 0x70..0x73 (TCAL9538_I2C_ADDR_BASE), and — as of v0.11.0 — the register-compatible TCA6408A / PCA9538 single-A0 range 0x20..0x21 (TCAL9538_I2C_ADDR_ALT_BASE). The alt part is the E1M EVK's U35 alt-population (TCA6408ARSVR, R112 fitted / R145 DNP); 0x20 is bench-confirmed on the E1M EVK. On the E1M EVK's default population the expander sits on ALP_E1M_I2C0 at 0x72 (A1=1, A0=0). Pass 0 for the address to fall back to TCAL9538_I2C_ADDR_BASE.

The §D ecosystem set

The drivers added under the chip-and-library ecosystem design. Every entry below ships with header + _init/probe + Kconfig + metadata YAML + NULL-arg ZTEST.

The [UNTESTED] markers below mean no HiL silicon bring-up — which, per the warning at the top of this page, is currently true of every driver in the catalogue, not just these. What distinguishes this set is the [ABI-EXPERIMENTAL] annotation: their APIs may still change. Check each driver's driver_status: in metadata/chips/<id>.yaml for how much of its surface is actually implemented — many here are stub.

Camera sensors [UNTESTED]

DriverPartBus / interfaceNotes
ov2640OmniVision OV2640DVP2 MP general-purpose
ov5645OmniVision OV5645MIPI CSI-25 MP autofocus
ov7670OmniVision OV7670DVPVGA cost-sensitive
ov9281OmniVision OV9281MIPI CSI-21 MP global-shutter mono
ar0234onsemi AR0234MIPI CSI-21080p global-shutter
imx219Sony IMX219MIPI CSI-28 MP — RPi Cam v2
imx477Sony IMX477MIPI CSI-212 MP — RPi HQ Camera
gc2145GalaxyCore GC2145DVP2 MP cost-sensitive

Camera SerDes [UNTESTED]

DriverPartStandard
ti_ds90ub953_954TI DS90UB953 / 954FPD-Link III
maxim_max9295_9296Maxim MAX9295 / 9296GMSL2

Displays [UNTESTED]

DriverPartNotes
st7789Sitronix ST7789240×240 / 240×320 SPI TFT
ili9341Ilitek ILI9341240×320 SPI TFT
ili9488Ilitek ILI9488320×480 SPI TFT
ra8875RAiO RA88755–7″ TFT controller w/ resistive touch
sh1106Sino Wealth SH1106128×64 mono OLED — drop-in alt to SSD1306
il3820Solomon IL38204.2″ tri-colour e-paper
gdew0154t8GoodDisplay 1.54″1.54″ e-paper

External NPU [UNTESTED]

DriverPartNotes
hailo_8lHailo-8LM.2 PCIe NPU — host-side bring-up sequence

Industrial sensing [UNTESTED]

DriverPartClass
bmp390Bosch BMP390Barometric pressure
ms5611TE MS5611Barometric pressure
lps22hbST LPS22HBBarometric pressure
vl53l1xST VL53L1XTime-of-flight distance
vl53l5cxST VL53L5CX8×8 ToF array
a02yyuwDFRobot A02YYUWUltrasonic distance (UART)
tsl2591AMS TSL2591Ambient light (2-channel)
veml7700Vishay VEML7700Ambient light (16-bit)
qmc5883lQST QMC5883L3-axis magnetometer
as5048a_bAMS AS5048 A/BMagnetic rotary encoder (I²C)
mt6701MagnTek MT6701Magnetic rotary encoder (I²C)
hx711Avia HX71124-bit strain-gauge ADC
max31855Maxim MAX31855Thermocouple → signed milli-C
max31865Maxim MAX31865RTD (PT100/PT1000) — 15-bit + fault

Motor / actuator control [UNTESTED]

DriverPartNotes
drv8833TI DRV8833Dual H-bridge
drv8825TI DRV8825Stepper driver (STEP/DIR)
tmc2209Trinamic TMC2209Stepper w/ UART tuning (CRC-8)
a4988Allegro A4988Stepper driver

Cellular / RF / GNSS [UNTESTED]

DriverPartClass
quectel_bg95Quectel BG95LTE-M / NB-IoT modem (AT)
quectel_bg77Quectel BG77LTE-M / NB-IoT modem (AT)
ublox_sara_r5u-blox SARA-R5LTE-M modem (AT)
semtech_sx1262Semtech SX1262LoRa radio (opcode)
semtech_sx1276Semtech SX1276LoRa radio (register)
ublox_neo_m9nu-blox NEO-M9NGNSS (UART NMEA)
ublox_max_m10su-blox MAX-M10SGNSS (UART NMEA)
atgm336hZhongkewei ATGM336HGNSS (UART NMEA)
atecc608bMicrochip ATECC608BCrypto co-processor (ATCA)

Audio [UNTESTED]

DriverPartNotes
ics_43434InvenSense ICS-43434MEMS mic (I²S)
inmp441InvenSense INMP441MEMS mic (I²S, cost-sensitive)
wm8960Cirrus / Wolfson WM8960Stereo codec (I²C config + I²S)
tlv320aic3204TI TLV320AIC3204Premium stereo codec w/ miniDSP
max98357aADI MAX98357A3W class-D mono amp
es8388Everest ES8388Stereo codec (China-domestic)

Browse the full per-driver metadata under metadata/chips/; each .yaml carries verification: status alongside vendor / MPN / bus / Kconfig binding.

Driver status

Each driver carries a status field in its metadata/chips/<part>.yaml:

StatusMeaning
stubHeader exists; calls return ALP_ERR_NOSUPPORT.
partialCore operations implemented; some advanced features pending.
completeFull feature coverage; HW-verified.

The current per-driver status is tracked in docs/test-plan.md.

Per-SoM populated chips

Which drivers are populated on each SoM family:

DriverAENV2NV2N-M1N93
cc3501e
murata_lbee5hy2fy
rtl8211fdi✓×2✓×2
gd32g553
deepx_dxm1
act8760 / da9292
pca9451a
rv3028c7TBD
optiga_trust_mTBD
eeprom_24c128TBD
tmp112TBD

Each EVK populates its own board-side chip set. The two overlap (e.g. bmp581, bmi323, icm42670, tas2563, ina236, tcal9538) but differ: the E1M EVK carries lsm6dso, the ssd1306 / ssd1331 OLEDs, and an on-board ov5640 + cam_mux, whereas the E1M-X EVK drives MIPI-DSI panels and exposes dedicated CSI camera connectors instead. Declare preset: e1m-evk or e1m-x-evk in board.yaml to pick up that board's set.

Idiomatic usage

#include <alp/peripheral.h>
#include <alp/chips/lsm6dso.h>

alp_i2c_t *bus = alp_i2c_open(&(alp_i2c_config_t){
.bus_id = 0u,
.bitrate_hz = 400000u,
});

lsm6dso_t imu;
if (lsm6dso_init(&imu, bus, LSM6DSO_I2C_ADDR_LOW) != ALP_OK) {
printk("[lsm6dso] init failed\n");
return;
}

/* ODR and full-scale are set together, in one call per sensor. */
if (lsm6dso_set_accel(&imu, LSM6DSO_ODR_104_HZ, LSM6DSO_ACCEL_FS_2G) != ALP_OK) {
printk("[lsm6dso] set_accel rejected\n");
return;
}

lsm6dso_axes_t a;
while (1) {
lsm6dso_read_accel(&imu, &a);
printk("ax=%d ay=%d az=%d\n", a.x, a.y, a.z);
k_msleep(10);
}

The address is strap-selected: LSM6DSO_I2C_ADDR_LOW is 0x6A (SDO/SA0 tied low), LSM6DSO_I2C_ADDR_HIGH is 0x6B. Gyro is symmetric — lsm6dso_set_gyro() + lsm6dso_read_gyro() into the same lsm6dso_axes_t; lsm6dso_read_temp() yields a raw int16_t.

v0.11.0: IMU config calls validate their enum arguments

bmi323_set_accel / _set_gyro, icm42670_set_accel / _set_gyro, lsm6dso_set_accel / _set_gyro and lis2dw12_set_accel now return ALP_ERR_INVAL when an ODR or full-scale argument is not a declared enum member, and they validate before any bus write.

Previously these masked the argument straight into the register field: where an enum's declared members didn't fill that field, an undeclared value was written to the chip as a reserved hardware encoding and the call still returned ALP_OK. If you passed a computed or cast value rather than a named enumerator, a call that used to "succeed" may now correctly fail — check the return.

icm42670_odr_t is sparse (it declares 0x0, 0x4..0x8, 0xA..0xF), so the reserved encodings inside its range are rejected too. Enums whose declared values already fill their register field (icm42670 / lsm6dso / lis2dw12 full-scale, tmp112_rate_t) are unchanged, as are a4988 / drv8825 / lis2dw12_mode_t, which already validated.

See also

Questions about this page? Discuss in Community Forum