libipa: camera_sensor_helper: add imx681
diff mbox series

Message ID 20260831180812.68940-1-lsa.uz@pm.me
State New
Headers show
Series
  • libipa: camera_sensor_helper: add imx681
Related show

Commit Message

Sergey Lebedev Aug. 31, 2026, 6:08 p.m. UTC
Without a helper the Sony IMX681 front camera on the Microsoft Surface
Pro 11 is unusable in the soft ISP: libcamera logs

  IPASoftIsp: Failed to create camera sensor helper for imx681

and then takes the raw V4L2 gain code for the gain itself. The AGC sees
an analogue gain of 1020, concludes the sensor is enormously
over-amplified and holds the exposure down. Same scene, same build, only
this helper differing:

              AGC believes            mean luma
  without     analogue-gain: 1020        23.8
  with        analogue-gain: 21.3       110.7

The gain model is the usual Sony form, and the driver states it:

  /* Gain formula: gain = 1024/(1024-code). */

Verified against the sensor rather than taken on trust, at fixed
exposure, on raw Bayer from the CSI-2 receiver:

  code      1024/(1024-code)     measured
     0                  1.00         1.00
   512                  2.00         1.91
   768                  4.00         3.79
   896                  8.00         7.51
   960                 16.00        15.05

Black level measured the same way, at minimum exposure and minimum
gain: median and mode both exactly 64 at 10 bits, so 4096.

Signed-off-by: Sergey Lebedev <lsa.uz@pm.me>
---
 src/ipa/libipa/camera_sensor_helper.cpp | 12 ++++++++++++
 1 file changed, 12 insertions(+)

Comments

Kieran Bingham Sept. 7, 2026, 7:26 p.m. UTC | #1
Hi Sergey,

Quoting Sergey Lebedev (2026-08-31 19:08:21)
> Without a helper the Sony IMX681 front camera on the Microsoft Surface
> Pro 11 is unusable in the soft ISP: libcamera logs
> 
>   IPASoftIsp: Failed to create camera sensor helper for imx681
> 
> and then takes the raw V4L2 gain code for the gain itself. The AGC sees
> an analogue gain of 1020, concludes the sensor is enormously
> over-amplified and holds the exposure down. Same scene, same build, only
> this helper differing:
> 
>               AGC believes            mean luma
>   without     analogue-gain: 1020        23.8
>   with        analogue-gain: 21.3       110.7
> 
> The gain model is the usual Sony form, and the driver states it:
> 
>   /* Gain formula: gain = 1024/(1024-code). */
> 
> Verified against the sensor rather than taken on trust, at fixed
> exposure, on raw Bayer from the CSI-2 receiver:
> 
>   code      1024/(1024-code)     measured
>      0                  1.00         1.00
>    512                  2.00         1.91
>    768                  4.00         3.79
>    896                  8.00         7.51
>    960                 16.00        15.05
> 
> Black level measured the same way, at minimum exposure and minimum
> gain: median and mode both exactly 64 at 10 bits, so 4096.
> 
> Signed-off-by: Sergey Lebedev <lsa.uz@pm.me>
> ---
>  src/ipa/libipa/camera_sensor_helper.cpp | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp
> --- a/src/ipa/libipa/camera_sensor_helper.cpp
> +++ b/src/ipa/libipa/camera_sensor_helper.cpp
> @@ -691,6 +691,18 @@ public:
>  };
>  REGISTER_CAMERA_SENSOR_HELPER("imx678", CameraSensorHelperImx678)
>  
> +class CameraSensorHelperImx681 : public CameraSensorHelper
> +{
> +public:
> +       CameraSensorHelperImx681()

I can't see any sign of a driver for this in the Linux Kernel.

 - https://lore.kernel.org/all/?q=imx681

Do you know if there is anyone working to upstream support for this
device?

--
Regards

Kieran


> +       {
> +               /* Measured on the sensor: 64 at 10bits. */
> +               blackLevel_ = 4096;
> +               gain_ = AnalogueGainLinear{ 0, 1024, -1, 1024 };
> +       }
> +};
> +REGISTER_CAMERA_SENSOR_HELPER("imx681", CameraSensorHelperImx681)
> +
>  class CameraSensorHelperImx708 : public CameraSensorHelper
>  {
>  public:
>
Sergey Lebedev Sept. 7, 2026, 8:02 p.m. UTC | #2
Kieran,

Your search is right: there is no imx681 driver upstream and no submission
I can find either.

One exists out of tree, and it works. André Gilerson wrote it —
AndreGilerson/linux-surface-kernel, branch v7.0-surface-devel,
drivers/media/i2c/imx681.c — with the register sequences reverse-engineered
from Windows I2C traces, which its header says outright. On this Surface
Pro 11 it probes, binds to the IPU7 ISYS and streams 3836x2640 at 30 fps,
and it is the driver every number in my patch was measured against. Not a
single-machine hack either: djmulder runs it on a Surface Pro 10, in
linux-surface#2153, "Front Camera (IMX681) Working at 1920x1320".

Nobody has taken it to linux-media. Demand is not hypothetical, though —
someone filed a gap report there for ACPI HID SONY0681 five days ago, from
the same model through the IPU7 staging path, and it still has no replies:

  https://lore.kernel.org/all/20260903080854.16266-1-germanpapulindez@gmail.com/

So I have written to André today to ask whether he means to submit it
himself, and to offer to do the submission work if he would rather not —
with the driver staying his, From: and Signed-off-by, and me carrying the
binding, the MAINTAINERS entry, the ipu-bridge entry and review. That is a
question I have put to him, not a plan I can announce: it is his code and
his call, and he may reasonably say no or say nothing.

Which means I am not asking you to take this helper now. Hold it, or drop
it and I will resend — a helper ahead of a driver is the wrong order and
you were right to stop it. If a driver does land I will come back with the
measurements unchanged, and if it does not, the patch should not go in at
all.

Sergey

Patch
diff mbox series

diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp
--- a/src/ipa/libipa/camera_sensor_helper.cpp
+++ b/src/ipa/libipa/camera_sensor_helper.cpp
@@ -691,6 +691,18 @@  public:
 };
 REGISTER_CAMERA_SENSOR_HELPER("imx678", CameraSensorHelperImx678)
 
+class CameraSensorHelperImx681 : public CameraSensorHelper
+{
+public:
+	CameraSensorHelperImx681()
+	{
+		/* Measured on the sensor: 64 at 10bits. */
+		blackLevel_ = 4096;
+		gain_ = AnalogueGainLinear{ 0, 1024, -1, 1024 };
+	}
+};
+REGISTER_CAMERA_SENSOR_HELPER("imx681", CameraSensorHelperImx681)
+
 class CameraSensorHelperImx708 : public CameraSensorHelper
 {
 public: