Skip to content

RFC: media: add IMX681/SONY0681 support tested on Surface Pro 12 (Intel) - #176

Draft
zR-JB wants to merge 2 commits into
linux-surface:v6.19-surface-develfrom
zR-JB:sp12-imx681-rfc
Draft

RFC: media: add IMX681/SONY0681 support tested on Surface Pro 12 (Intel)#176
zR-JB wants to merge 2 commits into
linux-surface:v6.19-surface-develfrom
zR-JB:sp12-imx681-rfc

Conversation

@zR-JB

@zR-JB zR-JB commented Aug 12, 2026

Copy link
Copy Markdown

Purpose

This is intentionally opened as a draft/RFC rather than a merge-ready replacement for #164.

The goal is to bring the Sony IMX681 / SONY0681 front-camera work onto the current v6.19-surface-devel base using the reduced implementation independently validated on Surface Pro 12 Intel, then coordinate with the existing Surface Pro 11 work so that both generations can ultimately share one driver.

Provenance and relationship to #164

This is not a from-scratch IMX681 driver. It is based substantially on Andre Gilerson's Surface Pro 11 Intel camera work in #164.

The IMX681 driver and SONY0681 bridge entry were introduced there in commit b7469c4fa7714bb90ed59648397ef9a62bcae177. The exact later PR-head imx681.c used as the primary comparison point for the SP12 adaptation was 8ab9347b169233b08950086f49dafd1d58bb5bbf/drivers/media/i2c/imx681.c.

The SP12 version retains the core V4L2 architecture, register definitions, trace-derived 3844x2640 RAW10 initialization sequence, 7552/3177 timing, two-lane CSI-2 model, 969.6 MHz link frequency, 387.84 MHz pixel rate, exposure/gain registers, format/selection handling, stream start/stop structure, and SONY0681 ACPI match from that work. MODULE_AUTHOR("Andre Gilerson <andre.gilerson@gmail.com>") is retained.

I have intentionally not added Co-developed-by: or Signed-off-by: tags for Andre without his confirmation. Before this is treated as merge-ready or considered for mainline, I would like to coordinate authorship/DCO with him.

SP12 adaptation

Compared with the SP11 implementation, this RFC narrows the driver to behavior independently verified on Surface Pro 12 Intel: a required 19.2 MHz clock, verified avdd and reset GPIO, two-lane D-PHY validation, the single verified 969.6 MHz mode, the actual ~16.16 fps timing, fixed HBLANK/VBLANK, raw analogue-gain code 0..960, no kernel-side gain conversion, no unverified digital-gain or test-pattern V4L2 controls.

That makes the architecture very explicit:

IMX681 hardware register
        ↓
kernel exposes raw 0..960 code
        ↓
libcamera CameraSensorHelper
        ↓
physical gain / AGC

Those choices may also be appropriate for SP11, but that has not yet been runtime-validated. In particular, the power-resource differences should be checked on SP11 before treating this as a common final driver.

The second commit adds only the generic SONY0681 / 969.6 MHz ipu-bridge entry. The lane count continues to come from firmware SSDB.

SP12 testing

Tested on Surface Pro for Business 13in 12th Ed Intel with Panther Lake / IPU7.

The front SONY0681 / IMX681 probes successfully, streams 3844x2640 RAW10 over two-lane D-PHY at 969.6 MHz link frequency, exposes a 387.84 MHz pixel rate, works through libcamera Simple + SoftISP, GStreamer, PipeWire/portal and GNOME Snapshot, and the physical privacy LED follows stream state. Repeated camera open/close also works.

The analogue-gain register 0x0204 was independently measured on SP12. The driver therefore exposes its raw 0..960 code unchanged and leaves conversion to physical gain to userspace.

The previously investigated processed-image corruption was localized to the libcamera GPU Software ISP path and is separate from this kernel enablement.

Optional libcamera helper

The kernel driver intentionally exposes the IMX681 analogue-gain register as the raw 0..960 sensor code. On SP12, register 0x0204 was measured to follow:

gain = 1024 / (1024 - code)

For libcamera, the corresponding optional CameraSensorHelper is:

diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp
index 9457d62..3a9a259 100644
--- a/src/ipa/libipa/camera_sensor_helper.cpp
+++ b/src/ipa/libipa/camera_sensor_helper.cpp
@@ -654,6 +654,17 @@ public:
 };
 REGISTER_CAMERA_SENSOR_HELPER("imx678", CameraSensorHelperImx678)
 
+class CameraSensorHelperImx681 : public CameraSensorHelper
+{
+public:
+	CameraSensorHelperImx681()
+	{
+		/* Measured on Surface Pro 12: gain = 1024 / (1024 - code). */
+		gain_ = AnalogueGainLinear{ 0, 1024, -1, 1024 };
+	}
+};
+REGISTER_CAMERA_SENSOR_HELPER("imx681", CameraSensorHelperImx681)
+
 class CameraSensorHelperImx708 : public CameraSensorHelper
 {
 public:

This helper was tested separately with libcamera on SP12 and allows AGC to interpret the raw kernel control as physical gain without adding sensor-specific gain conversion to the kernel driver.

It is not part of this kernel PR and would be submitted separately to libcamera.

Existing Surface Pro 11 work and primary code ancestor: #164.

Surface Pro 12 tracking and detailed measurements: linux-surface/linux-surface#2144.

Related Surface Pro 12 camera work

Jan Baisch added 2 commits August 12, 2026 22:23
Add a V4L2 sensor driver for the Sony IMX681, including the SONY0681
ACPI ID used by Microsoft Surface devices.

This implementation is based substantially on Andre Gilerson's Surface
Pro 11 Intel IMX681 driver from linux-surface#164, introduced in
commit b7469c4 ("media: Add Surface Pro 11 (Intel IPU7) camera
support").

The V4L2 driver structure, register definitions, trace-derived
3844x2640 RAW10 initialization sequence, 7552/3177 timing, two-lane
CSI-2 model, 969.6 MHz link frequency, 387.84 MHz pixel rate,
exposure/gain registers, format and selection handling, stream
start/stop structure, and SONY0681 match originate from or closely
follow that work.

For Surface Pro 12 Intel, narrow the implementation to resources and
behavior independently verified on that machine. Require a 19.2 MHz
clock, avdd and reset GPIO, validate a two-lane D-PHY endpoint and the
969.6 MHz link frequency, keep blanking fixed, expose analogue gain as
the raw sensor register code from 0 through 960, omit unverified
digital-gain and test-pattern controls, and simplify runtime-PM and
stream-error handling.

The resulting driver probes and streams the SONY0681 front camera on
Surface Pro 12 Intel at 3844x2640 RAW10. Surface Pro 11 compatibility
with the reduced resource model still needs validation; the intention
is to converge on one shared IMX681 driver for both generations.

Original work:
linux-surface#164
linux-surface@b7469c4

Signed-off-by: Jan Baisch <jan.baisch@protonmail.com>
Add the SONY0681 ACPI HID with the 969.6 MHz link frequency used by the
Sony IMX681 driver. The CSI lane count is obtained separately from
firmware SSDB.

This HID and link-frequency pairing originates from Andre Gilerson's
Surface Pro 11 Intel camera work in linux-surface#164, introduced in
commit b7469c4 ("media: Add Surface Pro 11 (Intel IPU7) camera
support").

The same configuration was independently validated on Surface Pro 12
Intel with its two-lane D-PHY IMX681 front camera.

Original work:
linux-surface#164
linux-surface@b7469c4

Signed-off-by: Jan Baisch <jan.baisch@protonmail.com>
@zR-JB

zR-JB commented Aug 12, 2026

Copy link
Copy Markdown
Author

@AndreGilerson I opened this deliberately as an RFC because the IMX681 driver is substantially based on your SP11 work in #164. I independently tested a reduced version on SP12 and would much rather converge on one shared SP11/SP12 driver than create a competing implementation.

The main thing I would especially appreciate your input/testing on is whether the stricter SP12 resource model (19.2 MHz clock + avdd + reset), fixed blanking, and raw 0..960 analogue-gain handling also make sense on SP11. I have not added any Co-developed-by: or Signed-off-by: tags for you without your confirmation, just give me your attribution preferences not sure how to best deal with it.

@AndreGilerson

Copy link
Copy Markdown

@zR-JB thanks for the additional input. I am sadly at the moment in the process of finishing my dissertation and I will not be able to look into this until that is done.

About the attribution thing, just go ahead with whatever feels best to you. I would appreciate it if my name could appear somewhere at some point if my work contributed, but have no specific preferences.

I will be back at the end of September, and i am currently happily daily driving my https://github.com/AndreGilerson/linux-surface-kernel/tree/v7.0-surface-devel branch with the v7.0 kernel that fixed for me some of the additional sleep and hibernation features on the S11.

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.

2 participants