Add SoI JXK06 sensor driver for T23 SoC - #1
Open
tensorcrush wants to merge 15 commits into
Open
Conversation
This was referenced Aug 15, 2026
Values decoded from the vendor sensor_jxk06_t23.ko (jxk06_attr, jxk06_again_lut, jxk06_init_regs_*) rather than carried over from t31: - mipi.clk 800 -> 400 - mipi.settle_time_apative_en 0 -> 1 - max_again 259142 -> 324678, again_lut extended to 0x4f (80 entries) - total_width 2432 -> 3000, one_line_expr_in_us 22 -> 17 total_width = HTS(0x21:0x20) * 2 and total_height = VTS(0x23:0x22). All three vendor modes then land on 86.4 MHz, matching SENSOR_SUPPORT_SCLK_4M, and the vendor default mode 1440x1440@15fps (HTS=1920 VTS=1500) reproduces its static attr exactly (3840 / 1500). Also fix the TX_SENSOR_MAX_FPS_15 path in sensor_set_fps, which left sclk unshifted and so computed half the correct VTS, and drop the unused SENSOR_MAX_WIDTH/HEIGHT defines.
themactep
requested changes
Aug 15, 2026
|
|
||
| struct tx_isp_sensor_attribute sensor_attr={ | ||
| .name = SENSOR_NAME, | ||
| .chip_id = 0x0852, |
Contributor
There was a problem hiding this comment.
should be set via SENSOR_CHIP_ID
| static __init int init_sensor(void) | ||
| { | ||
| int ret = 0; | ||
|
|
Contributor
There was a problem hiding this comment.
sensor_common_init(&sensor_info);
is missing
| static __exit void exit_sensor(void) | ||
| { | ||
| private_i2c_del_driver(&sensor_driver); | ||
| } |
Contributor
There was a problem hiding this comment.
sensor_common_exit();
is missing
| static int shvflip = 1; | ||
| module_param(shvflip, int, S_IRUGO); | ||
| MODULE_PARM_DESC(shvflip, "Sensor HV Flip Enable interface"); | ||
|
|
Contributor
There was a problem hiding this comment.
static struct sensor_info sensor_info = {
.name = SENSOR_NAME,
.chip_id = SENSOR_CHIP_ID,
.version = SENSOR_VERSION,
.min_fps = SENSOR_OUTPUT_MIN_FPS,
.max_fps = SENSOR_OUTPUT_MAX_FPS,
.actual_fps = 0,
.chip_i2c_addr = SENSOR_I2C_ADDRESS,
.width = SENSOR_MAX_WIDTH,
.height = SENSOR_MAX_HEIGHT,
};
is missing
t23 had no jxk06 IQ file, so INSTALL_SENSOR_BIN silently installed nothing and the resulting image shipped an empty /usr/share/sensor. This is the tuning blob from the stock firmware of the Aobocam A12 (HW_ZY_T2G2_1MK1_V5), which runs the JXK06 on a T23DL. It is 176288 bytes, the same size as every other t23 IQ file in this directory.
The VIC reported "hor err" on every channel and libimp died right after the pipeline configured 2304x1296: the link could not deliver a full line before the horizontal timer expired. Required lane rate is active_pixels * bpp / lanes / line_period. At 2304x1296 that is 2304 * 10 / 2 / 17us = 678 Mbps, but mipi.clk was 400. The 400 came from the vendor blob's static attr, which describes its 1440x1440@15fps default mode, where 1440 px over a 22us line only needs 327 Mbps. Use 800, matching what the t31 driver runs for its own large mode.
On real hardware 2304x1296 floods the VIC with "hor err" on every line and no frame ever reaches the ISP, while the same board switched to win_sizes[0] stops erroring after six lines. Raising the lane rate to 800 Mbps did not help, so the fault is not link bandwidth. Fall back to the configuration the vendor blob itself boots in, which is the only one whose attr is known byte for byte: win_sizes[0] 1440x1440@15fps, image_t 1440x1440, mipi.clk 400, total 3840x1500, one_line_expr_in_us 22, integration limit 1496 2304x1296 stays in win_sizes and its register table is unchanged, so it can be revisited once the VIC timing for that mode is understood.
With the VIC finally quiet, rvd still died with sensor_set_vflip() enable: 0x0, val: 0x20. do_page_fault() thingino#2: sending SIGSEGV to rvd for invalid read access from 00000b38, epc/ra in libimp.so after building both encoders, so the fault is inside libimp rather than the pipeline description. probe forced attr->expo_fs = 1, which is a t31 habit: the t23 ports of jxk04 and jxk05 drop the field entirely and the vendor blob ships it as 0. The small fault address looks like a null base plus member offset, consistent with libimp following an exposure-frame-sync path this SoC does not implement.
The static attr describes win_sizes[0] (1440x1440@15fps), so selecting win_sizes[1] left the ISP configured for a 1440-wide frame while the sensor sent 2304, and the VIC raised "hor err" on every line. Fill in the 2304x1296 geometry when that mode is picked: image_t 2304x1296, total 3000x1440, one_line_expr_in_us 17, integration limit 1436 total_width is HTS * 2 and a line lasts HTS / 86.4 MHz, the same rule the vendor's own 1440x1440 values follow. Default to the native 2304x1296 mode; sensor_max_fps=15 still selects 1440x1440, so both are reachable at load time without a rebuild.
On hardware the bottom fifth of every frame is garbage: the break is sharp, sits at the same place on both the main and the sub stream, and does not follow a vertical flip, so the ISP is being told the sensor sends more lines than it really does. Finding the true figure needs trying several values, and a rebuild per attempt is impractical on a camera that can only be reflashed by hand. Expose the geometry as parameters instead: ovr_win, ovr_twidth, ovr_theight, ovr_total_width, ovr_total_height, ovr_line_us, ovr_clk Each defaults to -1, which keeps whatever the selected win_size implies, so behaviour is unchanged unless a value is passed. probe logs the resulting geometry so what the ISP was told is visible in dmesg.
Dumping the vendor blob's jxk06_attr and ours side by side leaves only two differing words in the whole mipi region: mipi_sc.mipi_vcomp_en vendor 1 ours 0 mipi_sc.data_type_value vendor 0x2b ours 0 0x2b is the CSI-2 data type for RAW10. Without vertical compensation the bottom fifth of every frame came back as noise, and without the data type the VIC rejected every line of the 1920x1080 and 2304x1296 modes.
probe in the vendor blob memcpy()s a 124 byte Jxk06_mipi template over the whole mipi field, so the template wins over whatever the static jxk06_attr holds. Comparing against the template instead: settle_time_apative_en 0, not 1 mipi_sc.mipi_vcomp_en 0 mipi_sc.data_type_value 0 and the disassembly of its per-mode branches gives mipi.clk 216 for both 2304x1296 and 1920x1080, against 400 for 1440x1440. The rest of the per-mode geometry it writes matches what was already here. Also expose settle/vcomp/data_type as parameters so the remaining horizontal errors on the wide modes can be probed without a rebuild.
With settle_time_apative_en back to the template's 0 the VIC finally accepts 2304x1296, but both modes still turn to noise partway down the frame: at row ~1115 of 1296, and ~1123 of 1440. Register 0x2f:0x2e in the vendor tables reads 1116 and 1134 for those modes, so the sensor appears to stop there and the ISP keeps writing rows that never arrive. Add ovr_win_w / ovr_win_h to trim the selected win_size, so the real height can be confirmed on hardware before it is written down.
Sweeping the window height on hardware puts the end of usable data at row 1120: at 1116 the framesource refuses to start, at 1128 a corner of noise is left, and at 1152 a visible strip. 1120 gives a clean frame in both modes, and matches register 0x2f:0x2e, which reads 1116 for 2304x1296 and 1134 for 1440x1440. So the modes are 2304x1120 and 1440x1120 rather than the advertised 1296 and 1440 lines. Everything below that row was noise before.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds `3.10.14/sensor-src/t23/jxk06.c` — port of the existing T31 JXK06 driver adapted to the T23 sensor SDK conventions.
Context
The SoI JXK06 is a 3MP (2560×1440 native) rolling-shutter CMOS sensor, I²C addr 0x40, sold widely in Chinese Ingenic-T23 IP cameras (e.g. Aobocam A12 / Hopeway rebrand). The T31 and T41 driver trees already carry it; the T23 tree previously did not, so those boards had no upstream option.
What's done
Testing
Compiled cleanly against the T23 kernel 3.10.14 build (module `sensor_jxk06_t23.ko`).
Full end-to-end runtime test with a companion defconfig is pending — my local build environment (WSL1 buildroot) produces images that don't boot WiFi even with an unmodified upstream defconfig, so I can't validate the sensor pipeline locally. Ready for CI validation.
Companion PR