This repository contains open-source reimplementations of the Ingenic TX-ISP kernel drivers for T23, T31, T40, and T41 cameras. The active cross-SoC refactoring work targets all four device-tested drivers. T31 is organized as a modular driver. T23, T40, and T41 retain large recovered core sources, but their modules now have separate adapters for shared facilities where applicable.
The project goal is behavioral equivalence with the OEM driver while
supporting both Ingenic's unmodified proprietary libimp.so and the fully
open OpenIMP userspace stack.
This is not a greenfield camera pipeline. It is a reverse-engineering and compatibility effort that combines:
- open-source kernel-driver development
- OEM binary analysis
libimp.soABI compatibility work- image-quality tuning and calibration recovery
Download the 4:5 portrait version for social sharing.
This is a current, same-scene A/B from a Wyze Video Doorbell v2 using the T31X SoC and SC301IOT sensor. The frames were captured 98 seconds apart on August 15, 2026:
- Left: OEM TX-ISP driver with OEM
libimp.so - Right: Open TX-ISP at
a103ec61with OpenIMP at7c6ca71
Both stacks produced a stable 1920x1080 stream through the same Raptor userspace. The full-open result is now close to the OEM daylight rendering; the remaining visible difference in this scene is primarily exposure/color response around the sunlit foreground and deep plant shadows. This checkpoint is deliberately scoped to this camera, sensor, mode, and lighting condition.
The project has moved beyond basic probe and stream bring-up. T31/SC301IOT is the strongest validated path and now has a working fully open capture stack, OEM-like daylight image quality, and persistent runtime flip control.
| SoC | Current validation |
|---|---|
| T23 | Device-tested vendor-kernel path with live capture and shared registry, layout, ABI, and tuning primitives; broader sensor and image-quality validation continues. |
| T31 | Device-tested on vendor Linux 3.10 and compatibility-tested on mainline Linux 7.1; OEM libimp.so and OpenIMP both stream, with near-OEM daylight parity demonstrated on SC301IOT. |
| T40 | Recovered core is integrated with shared adapters; color-path, tuning, and device-matrix work remain active. |
| T41 | Device-tested 2.5K open-stack baseline plus V4L2 MMAP and DMA-BUF capture; image-quality and delivered-FPS work remain active. |
- kernel module architecture is in place
- major ISP subdevices exist and probe
- core MMIO mapping and IRQ ownership are understood
- stream bring-up is functional enough for live video
- tuning infrastructure and many ISP blocks are implemented
- the T31/SC301IOT pipeline streams with either OEM
libimp.soor OpenIMP - T31 daylight color and lens-shading behavior on the Wyze Video Doorbell v2 are close to the current OEM reference
- T31 GIB, DMSC, LSC, ADR, AE-statistics preservation, and runtime register sequencing have been aligned with observed OEM behavior on SC301IOT
- T31 H/V flip controls now update the real MSCA output-arbitration register while preserving channel-enable bits
- T31 builds on both the vendor 3.10 kernel and the mainline Linux 7.1 compatibility path
- common interpolation/fixed-point primitives are used by T23, T31, and T41
- T23, T31, and T41 share one typed sensor-registry implementation
- T31 and T41 share a configurable frame-boundary day/night state machine
- T23 and T31 share ordered register-profile and bypass-mask primitives
- T23 and T31 share validated ordered callback plans for tuning sequences
- T23, T31, and T41 share checked proprietary tuning wire layouts, response packers, and scalar-versus-pointer command descriptors
- T23, T31, and T41 share overflow-checked NV12 stride, private aggregate-line, UV-offset, and sizeimage calculation while retaining per-SoC alignment policy
- T23 and T31 share checked MDNS working/reference/UV/tiny-plane layout while retaining their distinct allocation ABIs and register ownership
- T23, T31, and T41 share checked NV12 DMA binding, including allocation length, complete 32-bit address-range, and Y/UV plane validation before QBUF reaches hardware
- the private frame-channel and future public V4L2 adapters now share an allocation-free queue core for buffer ownership, completion ordering, sequence/timestamp metadata, errors, and deterministic STREAMOFF recovery
- T23, T31, and T41 share the proven frame-channel event namespace and exact
legacy-
V/T41-Tprivate ioctl envelopes without conflating the generation-specific events above buffer completion; the common contract also owns the fixed 20-byte request-buffer wire object and legacy stream command IDs - T23, T31, T40, and T41 share checked 32-bit pad and active-link offsets, including the event callback slot used for remote frame-channel dispatch
- T31 applies evidence-backed SC2336 day/night DMSC correction profiles
- T23, T40, and T41 link recovered cores with logical shared-library adapter objects
- reverse-engineered architecture and tuning docs now exist in-tree
- the T31/SC301IOT daylight result is not a claim of universal OEM parity
- night/IR, WDR, extreme exposure, and additional sensor combinations still need comparable OEM-versus-open validation
- some tuning tables on other sensors and SoCs remain synthetic or only partially reconstructed
- several ISP blocks still need broader parity testing or better OEM-derived calibration data
- OpenIMP streaming quality, rate control, and long-duration stability need a wider device matrix even though the current T31 path is functional
If you want the detailed status and finish plan, start with docs/IMAGE_TUNING_PRD.md.
docs/T31_ISP_ARCHITECTURE.md— current hardware / driver architecture notesdocs/DRIVER_REUSE_PLAN.md— cross-SoC commonality map and staged reuse plandocs/SHARED_DRIVER_LIBRARY.md— landed shared interfaces, adapters, invariants, and device matrixdriver/t31/README.md— T31 file ownership, validated SC2336 state, tuning ABI, and known gapsdocs/IMAGE_TUNING_PRD.md— plan for finishing image tuning and remaining workdocs/ISP_PERFORMANCE_BENCHMARK.md— reproducible on-device CPU, memory, throughput, IRQ, and module-size baselinedocs/T41_OPEN_PERFORMANCE_BASELINE_20260806.md— first 2.5K open-stack T41 baseline and configured-versus-delivered FPS findingdocs/V4L2_CAPTURE_PATH.md— additive V4L2 capture architecture, landed queue core, and adapter phasesdriver/t31/REGMAP_ADR_YDNS.md— ADR / YDNS register-map notesdriver/t31/TX_ISP_VIDEO_S_STREAM_VERIFIED.md— stream-control verification notesexternal/ingenic-sdk/3.10/isp/t31/OEM_TUNING_BLOB_MANIFEST.md— current map of recovered vs synthetic tuning data
| Path | Purpose |
|---|---|
driver/ |
Per-SoC open-source ISP kernel-driver implementations |
driver/include/tx_isp/ |
Reviewed cross-SoC interfaces and primitives |
driver/common/ |
Shared kernel implementation with explicit SoC adapters |
driver/t23/ |
T23 recovered driver and tuning data |
driver/t31/ |
T31 ISP kernel-driver implementation |
driver/t31/include/ |
T31-local headers and data structures |
driver/t40/ |
T40 recovered driver, shared-library adapters, and tuning data |
driver/t41/ |
T41 recovered driver and tuning data |
external/ingenic-sdk/ |
Sensor and SDK reference material |
docs/ |
High-level project documentation and planning |
OEM-tx-isp-t31.ko |
OEM reference kernel module |
Important driver files:
driver/common/tx_isp_sinfo.c— shared sensor registry and procfs lifecycledriver/common/tx_isp_daynight.c— configurable day/night transition shelldriver/common/tx_isp_callback_plan.c— validated ordered callback executiondriver/common/tx_isp_reg_profile.c— ordered register profiles and bypass-mask mergedriver/common/tx_isp_tuning_abi.c— checked libimp envelopes, reply packers, and command descriptorsdriver/common/tx_isp_frame_layout.c— checked NV12 and T23/T31 MDNS geometrydriver/common/tx_isp_subdev.c— checked graph endpoint resolution and generation-neutral pad-link validation, initialization, and connectiondriver/common/tx_isp_remote_event.c— checked pad-to-remote-handler route resolution shared by the recovered T23, T40, and T41 dispatchersdriver/common/tx_isp_state.c— value-level recovered subdevice readiness policy with generation-local field adaptersdriver/include/tx_isp/tx_isp_math.h— shared fixed-point/interpolation primitivesdriver/include/tx_isp/tx_isp_sinfo.h— typed registry configuration and lifecycle interfacedriver/include/tx_isp/tx_isp_subdev.h— graph wire records, resolver interface, and shared link-state operationsdriver/include/tx_isp/tx_isp_remote_event.h— remote-event adapter, resolved-target, and failure-status contractdriver/include/tx_isp/tx_isp_state.h— layout-independent subdevice state evaluation interfacedriver/include/tx_isp/tx_isp_tuning_abi.h— generation-aware proprietary control wire ABIdriver/include/tx_isp/tx_isp_frame_abi.h— exact 32-bit frame-buffer wire layout and generation-aware state flagsdriver/include/tx_isp/tx_isp_frame_channel.h— shared frame-channel event IDs, generation-qualified ioctl envelopes, and ioctl decodersdriver/include/tx_isp/tx_isp_frame_format.h— compiler-independent 112/116-byte frame-image format ABIdriver/include/tx_isp/tx_isp_frame_layout.h— alignment-parametric NV12 and MDNS layout interfacedriver/t23/tx_isp_t23_core.cand adapter objects — T23 recovered core with shared math, registry, and register-profile facilitiesdriver/t31/tx_isp_module.c— module init/exit, platform resources, shared register helpersdriver/t31/tx_isp_core.c— core probe, memory mappings, ISR path, first-frame logicdriver/t31/tx_isp_tuning.c— tuning subsystem, per-block init, parameter handling, image pipeline controldriver/t31/tx_isp_csi.c/driver/t31/tx_isp_vic.c/driver/t31/tx_isp_vin.c/driver/t31/tx_isp_fs.c— CSI/VIC/VIN/frame-source subdevicesdriver/t40/tx_isp_t40_recovered.cand adapter objects — T40 recovered core with shared subdevice graph, remote-event, link-state, and readiness policydriver/t41/tx_isp_t41_recovered.cand adapter objects — T41 recovered core with shared day/night, math, and registry facilities
- Replace the proprietary TX-ISP kernel drivers on supported T23/T31/T40/T41 devices
- Preserve compatibility with Ingenic's
libimp.so - Support a fully open kernel-and-userspace path with OpenIMP
- Match OEM register sequencing and control behavior closely
- Recover or reconstruct enough OEM tuning content for acceptable image quality
- Document the hardware and bring-up process so the work is maintainable
- Active target SoCs: Ingenic T23, T31, T40, and T41
- Kernel focus: Linux 3.10.14 vendor trees (T23/T31), Linux 4.4.94 vendor trees (T40/T41), and the active T31 mainline compatibility path
- Userspace ABI targets: Ingenic
libimp.soand OpenIMP - Sensor support model: OEM-style sensor drivers and compatible sensor integrations from the Ingenic SDK ecosystem
The local build helper selects a per-SoC driver with SOC:
SOC=t23 ./build_local.sh
SOC=t31 ./build_local.sh
SOC=t40 ./build_local.sh
SOC=t41 ./build_local.shROOT, KDIR, and CROSS can be supplied for the matching vendor kernel and
toolchain. See the comments in build_local.sh for details.
Host-side tests for shared, kernel-independent primitives run with:
make -C tests checkThe project works best when changes are driven by evidence, not guesswork.
Recommended workflow:
- identify the relevant open-source code path in
driver/ - compare against the OEM binary behavior
- confirm
libimp.soexpectations when ioctl or struct ABI is involved - make the smallest safe parity change
- validate with logs, images, and targeted diffs
The new architecture and PRD docs capture the current high-level understanding so this work can continue systematically instead of rediscovering the same facts.
This project is solving several problems at once:
- hardware bring-up and clock/reset ordering
- platform/subdevice modeling
- reverse-engineering OEM register sequences
- reproducing runtime tuning behavior
- recovering missing calibration/tuning tables
Even when streaming works, image quality can still be wrong if one of the following is off:
- CFA/demosaic phase
- block enable/bypass state
- LUT programming path
- tuning table contents
- day/night or WDR bank selection
Current limitations are mostly in coverage and repeatable parity across sensors, modes, and lighting, not basic driver existence. The T31/SC301IOT daylight checkpoint above is the first full-open path to reach near-OEM image quality.
Known classes of remaining work include:
- remaining color/exposure differences under difficult mixed and backlit light
- OEM-calibrated table recovery for additional sensors and denoise/WDR banks
- mode-complete validation for day/night, IR, WDR, and sensor flip combinations
- long-duration full-open streaming and encoder-quality validation across the supported SoCs
Contributions are welcome, especially when they are grounded in one of these:
- OEM binary analysis
libimp.soABI validation- concrete hardware validation logs/captures
- recovery of tuning/calibration data
- improvements to documentation and reproducibility
If you are making behavioral changes, please document:
- what OEM evidence supports the change
- which files/functions were updated
- how the change was validated
- any remaining uncertainty
Thanks to the work and prior art from the broader Ingenic / Thingino / Wyze reverse-engineering community, especially:
This project is licensed under the GNU General Public License (GPLv3).

