Skip to content

patches: Add kernel 7.0 support with Surface Pro 10 camera patches - #2156

Open
djmulder wants to merge 20 commits into
linux-surface:masterfrom
djmulder:feature/surface-pro-10-cameras
Open

patches: Add kernel 7.0 support with Surface Pro 10 camera patches#2156
djmulder wants to merge 20 commits into
linux-surface:masterfrom
djmulder:feature/surface-pro-10-cameras

Conversation

@djmulder

Copy link
Copy Markdown

This PR adds patches/7.0/ based on the 6.19 patch set, with the following
additions to 0013-cameras.patch for Microsoft Surface Pro 10 (Meteor Lake):

New driver:

  • Sony IMX681 sensor driver supporting both Surface Pro 10 (MTL, 380.8 MHz
    C-PHY) and Surface Pro 11 (LNL, 969.6 MHz D-PHY) with platform-specific
    PLL selection at stream-on time

ipu-bridge:

  • SONY0681 entry with C-PHY bus type and dual link frequencies
  • OVTID858 (OV13858) rear camera entry
  • device_reprobe() to fix probe ordering race condition

INT3472:

  • GPIO type 0x08 (DVDD) and 0x10 (DOVDD) support with proper named
    constants, replacing the SP9 magic number workaround
  • CLK_IS_CRITICAL and always-on regulator constraints

OV13858:

  • Reset GPIO handling for SP10

Tested on Surface Pro 10 for Business (MSHW0520/MSHW0521), Ubuntu 26.04,
kernel 7.0.0-15-generic. Both sensors probe successfully. Rear camera
produces frames (ISP tuning pending). Front camera probes but produces
black frames pending C-PHY support in ipu6-isys-dwc-phy.c.

djmulder added 3 commits May 29, 2026 15:32
Add patches/7.0/ based on 6.19 patch set with the following additions
to 0013-cameras.patch:

- Add Sony IMX681 sensor driver supporting both Surface Pro 10 (MTL,
  380.8 MHz C-PHY) and Surface Pro 11 (LNL, 969.6 MHz D-PHY)
- Add ipu-bridge entries for SONY0681 (C-PHY, dual freq) and OVTID858
- Add INT3472 GPIO type 0x08 (DVDD) and 0x10 (DOVDD) support,
  replacing the SP9 magic number workaround with proper constants
- Add INT3472 CLK_IS_CRITICAL and always-on regulator constraints
- Add OV13858 reset GPIO handling for Surface Pro 10

Tested on Surface Pro 10 (MSHW0520/MSHW0521) with Ubuntu 26.04 /
kernel 7.0.0-15-generic.
Remove development debug messages from SP10 camera patches:
- Remove verbose dev_info calls from imx681, ov13858, int3472
- Downgrade ipu-bridge sensor connection messages to dev_dbg
- Keep meaningful messages (reset GPIO toggle, probe success)
The OV13858 rear camera on Surface Pro 10 (Microsoft Surface Pro 10
for Business) is mounted 180° rotated. Add a DMI match entry so
ipu-bridge reports the correct rotation to libcamera/v4l2.

Patchset: cameras
@djmulder
djmulder marked this pull request as draft May 30, 2026 18:20
@djmulder
djmulder marked this pull request as ready for review May 30, 2026 18:21
djmulder added 3 commits June 1, 2026 09:54
Adds work-in-progress patch for IPU6EP-MTL C-PHY support needed
for the IMX681 front camera on Surface Pro 10 for Business.

The patch implements the C-PHY detection and routing infrastructure
but still needs correct DWC PHY IFC register values for C-PHY mode.
All kernel driver infrastructure correct. Blocked on Linux firmware
not supporting C-PHY. See contrib/surface-pro-10-cphy/README.md.
djmulder added 3 commits June 4, 2026 18:20
HUB_FW register investigation confirmed: HUB_FW[4] stays 0 even for
working D-PHY port 0, so it is not the blocker. The firmware simply
does not process C-PHY data for PORT_4/src=4, and rejects PORT_6/src=6
with FW_INTERNAL_CONSISTENCY error. All kernel infrastructure correct.
…se=0

ETL trace analysis confirmed Windows driver uses:
src=6 (CSI2_3PH_CPHY_PORT0), vc=0, isl_use=0, sensor_type=14, nlanes=2

This is identical to what we tried. Linux firmware rejects src=6 with
FW_INTERNAL_CONSISTENCY error. isl_use=1/2/3 cause INVALID_STREAM_CONFIG.
The Linux firmware binary is confirmed as the sole blocker.
Key findings from extended debugging session:

1. SIP registers use isp->base (full BAR0), not isys->pdata->base (ISYS sub-region)
2. SIP1_RXA/RXB_CTRL bit 0 can be written but doesn't affect data flow
3. FB_PORT_CFG (0x238054) is firmware-controlled read-only
4. SETTLE timing registers at SIP1+0x18 don't accept writes for 2-trio config
5. Writing SIP registers corrupts hardware state across reboots - DO NOT write
6. CTRL0_IRQ_STATUS and UNISPART_IRQ both read 0 for working D-PHY (firmware clears)
7. D-PHY timing (SETTLE_D1=0x37) is set by firmware, not driver

Root cause confirmed: firmware does not process C-PHY data for src=4.
All kernel-side hardware is correctly configured. Awaiting firmware update.
djmulder added 9 commits June 20, 2026 20:01
Key changes:
- Add 2x2 binning (BINNING_MODE=1, BINNING_TYPE=0x22) for 1920x1320 output
  Full 3840x2640 overflows the IPU6 stream2mmio DMA FIFO on 2 D-PHY lanes
  Windows uses binned mode exclusively through stream2mmio
- Fix Bayer phase: SGRBG -> SRGGB (confirmed via 4-phase comparison)
- Fix bus type: CPHY -> DPHY (sensor uses D-PHY despite port 4 C-PHY capability)
- Fix ipu-bridge: SONY0681 uses IPU_SENSOR_CONFIG (DPHY) not CPHY
- Reduce default exposure from max (3169) to moderate (500)
- Reduce analog gain from max (0x1FF) to low (0x20)
- Reduce digital gain from 8x to 1x
- Add diagnostic register readbacks for debugging
Strip all register readback diagnostics, forced exposure hacks,
and verbose logging from start_streaming. Driver is clean for review.
915 lines (was 1073).
- IMAGE_ORIENTATION 0x0101=0x01 (h_mirror) for correct upright image
- Bayer phase SGRBG matches h_mirror output
- Center digital crop X offset (962px) since only vertical binning active
- Increase default exposure (1500 lines) and gain (128) for indoor use
- Remove all diagnostic debug output (915 lines, was 1073)
Horizontal binning (0x0901=0x22) is rejected by the sensor — only
vertical binning activates (reads back 0x02 not 0x22). Windows uses
vendor-proprietary register sequences for full 2x2 binning that we
cannot extract from the driver binary.

Working config: vertical-only binning with centered digital crop.
Sensor outputs 3844x1320 (vertical 2x), digital crop centers 1920x1320.
MIPI line width is 1920 pixels (2400 bytes), well within DMA FIFO limit.

Tested: Windows 2016x1136 mode with full-width array + 2x2 binning
produces error 8 — sensor still outputs 4032 pixels per MIPI line
because horizontal binning is inactive.
The IMX681 rejects horizontal binning (0x0901=0x22 writes but only
vertical binning activates). Following the IMX258 approach: use the
CCS digital scaler (SCALE_MODE=1, SCALE_M=32 = 0.5x) for horizontal
reduction. The sensor now internally scales 3844→1920 before MIPI
output, giving full field of view without the DIG_CROP_X_OFFSET hack.

Also added BINNING_WEIGHTING=0x08 (0x0902) per IMX258 reference.

Result: full wide-angle field of view, no error 8, no cropping needed.
Root cause of v_flip exposure failure found: CCS frame length register
(0x0340) must be written separately AFTER streaming starts when v_flip
is active. Writing it together with the Sony vendor FLL (0x022A) in
the pre-streaming init sequence results in exposure stuck at black level.

Config: 0x0101=0x03 (h_mirror+v_flip), SBGGR10, 1920x1136
- Vertical binning 2x, Windows Y crop (376..2647)
- Centered digital crop (offset=962) for horizontal framing
- SCALE_M disabled (incompatible with v_flip — exposure drops)
- Post-streaming CCS FLL write enables proper exposure with v_flip
- DMI rotation=180 for SONY0681 handles final orientation in apps
- ipu-bridge: Replace dmi_first_match() with loop to correctly apply
  rotation=180 for all matched sensors (OVTID858 and SONY0681)
- ipu-bridge: Add SONY0681 DMI entry for Surface Pro 10 rotation
- ipu-bridge: Remove cphy ternary, always use D-PHY for SONY0681
- imx681: Return EPROBE_DEFER on chip ID 0x0000 (sensor not yet
  powered) to allow kernel to retry probe automatically
- int3472: Add INT3472_GPIO_TYPE_DVDD (0x08) define in discrete.c
  since it is missing from upstream int3472.h
@djmulder

Copy link
Copy Markdown
Author

Correction + status update to the PR description above

Two things in the original PR description are now known to be wrong and should not be relied on:

  1. The IMX681 is D-PHY, not C-PHY. The earlier C-PHY assumption came from unreliable ETL byte-pattern analysis. Confirmed D-PHY by the module datasheet (two data lane pairs + dedicated clock lane) and empirically: MTL firmware rejects the C-PHY stream-source enum values entirely; the working path is src=4 (CSI2_3PH_PORTA) with the D-PHY PHY init. The ipu-bridge entry should use a plain D-PHY config, not the C-PHY macro.
  2. The front camera is no longer producing black frames — it works. 1920×1136, real scene content, ~15.85 fps, usable in Teams.

One caveat about the camera patch in its current form: it sets IMX681_ANA_GAIN_MAX 1020 and an init analog gain of 0x0060. On this sensor the analog gain register is inverted/broken (higher code = less signal), so these values produce a very dark image, and the high max can make the libcamera Sony gain helper compute a negative gain that crashes the IPA. Analog gain should be locked at 0; see my latest comment on #2153 for the measurements. I'll push corrected patches once I've settled the analog-gain root cause and rebuilt against the current kernel.

djmulder added 2 commits June 28, 2026 11:52
Register 0x0204 is inverted on this sensor: hardware code 0 gives
maximum gain (16x) and code 960 gives minimum gain (1x).

Fix by inverting the logical code before writing to hardware:
  hw_code = 960 - logical_code

This makes AGC behave correctly: requesting higher gain codes
produces brighter images as expected. Also:
- ANA_GAIN_MAX: 1020 -> 960 (valid hardware range)
- Init default: 0x0060 -> 0x0000 (hw code 0 = maximum brightness)
@djmulder

Copy link
Copy Markdown
Author

Updated patch pushed (feature/surface-pro-10-cameras):

  • Fix analog gain register 0x0204 inversion: hardware code 0=16x, 960=1x.
    Driver now inverts logical->hardware mapping so AGC works correctly.
  • ANA_GAIN_MAX: 1020 -> 960 (valid range)
  • Init default gain: 0x0060 -> 0x0000 (start at maximum brightness)

Camera now works well in Teams on Linux Mint 22.3 / kernel 7.0.0-14.
Image quality is good in normal indoor lighting. Remaining limitation
is grain in high dynamic range scenes (bright window behind subject) —
this is a software ISP limitation, not driver-specific.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant