All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 0/2] media: i2c: Surface Pro 7+ camera flip fixes
@ 2026-07-20 14:28 ` Jakob Berg Jespersen
  2026-07-20 14:28   ` [PATCH RFC 1/2] media: i2c: ov8865: fix horizontal flip control polarity Jakob Berg Jespersen
                     ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Jakob Berg Jespersen @ 2026-07-20 14:28 UTC (permalink / raw)
  To: Sakari Ailus, Mauro Carvalho Chehab, Daniel Scally
  Cc: Hans de Goede, Fernando Rimoli, Tooraj Taraz, Joseph V. Lavigne,
	linux-media, linux-kernel, Jakob Berg Jespersen

This RFC series fixes two horizontal-flip issues on the front and rear
cameras of the Microsoft Surface Pro 7+ (Tiger Lake IPU6, ACPI/ipu-bridge).
Both were found and validated on real hardware (Surface Pro 7+, Fedora 44,
kernel 7.0.12) and have been in daily use on that machine for over a
month; each is described in detail in its own patch.

  1/2  media: i2c: ov8865: fix horizontal flip control polarity
  2/2  media: i2c: ov5693: fix horizontal flip polarity and Bayer phase

Both camera sensors on this device are mounted with a 180 degree rotation
(ACPI SSDB rotation 180), so libcamera requests HFLIP=1+VFLIP=1 to
correct the mount. Both patches address the same class of bug on the two
OmniVision sensors: the FORMAT2 FLIP_HORZ bits un-mirror a
natively-mirrored readout, so the V4L2_CID_HFLIP control is inverted. I
isolated this with a live 4-state flip/image matrix on the streaming
sensor (details in each patch). The ov5693 patch (2/2) additionally
compensates the Bayer phase, since clearing the flip bits shifts the
sampling one column off the fixed SBGGR10 the driver reports.

Why RFC:
 * Both polarity fixes change behavior for every existing user of
   these sensors, not just the SP7+, so confirmation of the flip
   direction from other-platform users could be considered before
   this is applied. Colors were verified unaffected on the SP7+.
 * For the ov5693 Bayer compensation I used a window-offset approach that
   keeps the mbus code fixed and userspace untouched; the alternative
   idiom is a flip-dependent mbus code + V4L2_CTRL_FLAG_MODIFY_LAYOUT on
   the flip controls (similar to that of imx219 from what I understand).
   Maintainer preference welcome.

Note: bringing these cameras up on the Surface Pro 7+ takes two
prerequisites this series does not itself depend on. The ov5693 front
camera streams on IPU6 only with a MIPI_CTRL00 (0x4800) clock-lane-gate
write, posted by Fernando Rimoli as "[PATCH v2 0/3] media: Enable the
OV5693 front camera on IPU6 Surface devices" [1] (confirmed here on the
SP7+); and the ov8865 rear camera probes only with an int3472 regulator
patch I posted separately to platform-drivers-x86 [2]. This series is
independent of both: it concerns only image orientation and color, not
bring-up.

I discovered these issues independently, though the motivation to work on
the Surface cameras came from the linux-surface community. I'd like to
credit two parallel efforts there on the same hardware family: Tooraj
Taraz observed both the inverted-feed and power-cycling quirks while
adding Surface Pro 9 camera support out of tree [3], and Joseph V.
Lavigne posted an RFC enabling the ov8865 power supply on the Surface
Pro 7+ itself [4]. These are among my first kernel patches; I read their
work closely only while writing this up and have not drawn on their code
here.

[1] https://lore.kernel.org/linux-media/20260717132021.18034-1-fernandorimoli11@gmail.com/
[2] https://lore.kernel.org/platform-driver-x86/20260719-sp7plus-int3472-v1-1-521a43f5c191@berg.pm/
[3] https://github.com/linux-surface/linux-surface/pull/1867
[4] https://github.com/linux-surface/linux-surface/pull/2201

Signed-off-by: Jakob Berg Jespersen <dev@berg.pm>
---
Jakob Berg Jespersen (2):
      media: i2c: ov8865: fix horizontal flip control polarity
      media: i2c: ov5693: fix horizontal flip polarity and Bayer phase

 drivers/media/i2c/ov5693.c | 22 +++++++++++++++++++++-
 drivers/media/i2c/ov8865.c |  8 +++++++-
 2 files changed, 28 insertions(+), 2 deletions(-)
---
base-commit: a52e6f7923c17a672135b485ffd96fbd72f46267
change-id: 20260720-sp7plus-ov-flips-b6cc645236b6

Best regards,
--  
Jakob Berg Jespersen <dev@berg.pm>


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH RFC 1/2] media: i2c: ov8865: fix horizontal flip control polarity
  2026-07-20 14:28 ` [PATCH RFC 0/2] media: i2c: Surface Pro 7+ camera flip fixes Jakob Berg Jespersen
@ 2026-07-20 14:28   ` Jakob Berg Jespersen
  2026-07-20 14:28   ` [PATCH RFC 2/2] media: i2c: ov5693: fix horizontal flip polarity and Bayer phase Jakob Berg Jespersen
  2026-07-22 22:14   ` [PATCH RFC 0/2] media: i2c: Surface Pro 7+ camera flip fixes Bryan O'Donoghue
  2 siblings, 0 replies; 5+ messages in thread
From: Jakob Berg Jespersen @ 2026-07-20 14:28 UTC (permalink / raw)
  To: Sakari Ailus, Mauro Carvalho Chehab, Daniel Scally
  Cc: Hans de Goede, Fernando Rimoli, Tooraj Taraz, Joseph V. Lavigne,
	linux-media, linux-kernel, Jakob Berg Jespersen

The ov8865's native readout is horizontally mirrored and the
FORMAT2 FLIP_HORZ bits (reg 0x3821) un-mirror it: with the bits
cleared the image is mirrored, with them set it is not. The driver
maps V4L2_CID_HFLIP=1 to setting the bits, so requesting a flip
produces an unflipped image and vice versa.

This is user-visible on the Surface Pro 7+ rear camera (mounted with a
180 degree rotation, SSDB degree=180): libcamera requests HFLIP=1+VFLIP=1
to undo the mount rotation and gets a horizontally flipped image.

Verified by a live 4-state flip/image matrix on the streaming sensor:

  hflip=0 vflip=0 -> 180 degree rotation (both flips)
  hflip=1 vflip=0 -> vertical flip only
  hflip=0 vflip=1 -> correct image
  hflip=1 vflip=1 -> horizontal flip only

(vertical flip = reflection over a horizontal mirror line, as on water;
horizontal flip = reflection over a vertical mirror line, as in a mirror)

which is only consistent with an inverted HFLIP and a correct VFLIP.

Invert the polarity so HFLIP=0 yields the unflipped image.

Signed-off-by: Jakob Berg Jespersen <dev@berg.pm>
---
 drivers/media/i2c/ov8865.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index c6d53c3d55ca..901ea7c16395 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -2204,8 +2204,14 @@ static int ov8865_flip_horz_configure(struct ov8865_sensor *sensor, bool enable)
 	u8 bits = OV8865_FORMAT2_FLIP_HORZ_ISP_EN |
 		  OV8865_FORMAT2_FLIP_HORZ_SENSOR_EN;
 
+	/*
+	 * The sensor's native readout is horizontally mirrored; the
+	 * FLIP_HORZ bits un-mirror it. Map the control so that HFLIP=0
+	 * yields an unmirrored image (verified on Surface Pro 7+ rear
+	 * camera by a live flip-control/image matrix test).
+	 */
 	return ov8865_update_bits(sensor, OV8865_FORMAT2_REG, bits,
-				  enable ? bits : 0);
+				  enable ? 0 : bits);
 }
 
 /* Test Pattern */

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH RFC 2/2] media: i2c: ov5693: fix horizontal flip polarity and Bayer phase
  2026-07-20 14:28 ` [PATCH RFC 0/2] media: i2c: Surface Pro 7+ camera flip fixes Jakob Berg Jespersen
  2026-07-20 14:28   ` [PATCH RFC 1/2] media: i2c: ov8865: fix horizontal flip control polarity Jakob Berg Jespersen
@ 2026-07-20 14:28   ` Jakob Berg Jespersen
  2026-07-20 17:39     ` Fernando Rimoli
  2026-07-22 22:14   ` [PATCH RFC 0/2] media: i2c: Surface Pro 7+ camera flip fixes Bryan O'Donoghue
  2 siblings, 1 reply; 5+ messages in thread
From: Jakob Berg Jespersen @ 2026-07-20 14:28 UTC (permalink / raw)
  To: Sakari Ailus, Mauro Carvalho Chehab, Daniel Scally
  Cc: Hans de Goede, Fernando Rimoli, Tooraj Taraz, Joseph V. Lavigne,
	linux-media, linux-kernel, Jakob Berg Jespersen

Like the ov8865 (see previous patch), the ov5693's native readout is
horizontally mirrored and the FORMAT2 FLIP_HORZ bits (reg 0x3821)
un-mirror it: with the bits cleared the image is mirrored, with them set
it is not. The vendor init table sets the bits by default (0x3821 =
0x1e). The driver maps V4L2_CID_HFLIP=1 to setting the bits, so
requesting a flip produces an unflipped image and vice versa.

This is user-visible on the Surface Pro 7+ front camera (mounted with a
180 degree rotation, SSDB degree=180): libcamera requests HFLIP=1+VFLIP=1
to undo the mount rotation and gets a horizontally flipped image.

Verified the same way as the ov8865, with a live 4-state flip/image
matrix on the streaming sensor giving the same result: an inverted HFLIP
with a correct VFLIP.

Invert the polarity so HFLIP=0 yields the unflipped image (bits set) and
HFLIP=1 the flipped one (bits cleared).

Clearing the bits also shifts the Bayer sampling by one column: the
fixed SBGGR10 mbus code the driver reports is only correct for the
bits-set orientation, so the HFLIP=1 state has the wrong colors.
Compensate by shifting the ISP output window (reg 0x3810) one column in
that state only: OFFSET_START_X = 1 when HFLIP=1, 0 otherwise. There is
a spare column to shift into because the crop end is programmed
inclusively (crop end = crop start + width). Validated on the SP7+:
correct geometry and colors in both flip states.

Signed-off-by: Jakob Berg Jespersen <dev@berg.pm>
---
 drivers/media/i2c/ov5693.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
index 4cc796bbee92..95dc6af45125 100644
--- a/drivers/media/i2c/ov5693.c
+++ b/drivers/media/i2c/ov5693.c
@@ -375,8 +375,28 @@ static int ov5693_flip_horz_configure(struct ov5693_device *ov5693,
 		  OV5693_FORMAT2_FLIP_HORZ_SENSOR_EN;
 	int ret;
 
+	/*
+	 * The sensor's native readout is horizontally mirrored; the
+	 * FLIP_HORZ bits un-mirror it. Map the control so that HFLIP=0
+	 * yields an unmirrored image (verified on Surface Pro 7+ front
+	 * camera by a live flip-control/image matrix test, matching the
+	 * same behaviour found on the ov8865).
+	 */
 	ret = cci_update_bits(ov5693->regmap, OV5693_FORMAT2_REG, bits,
-			      enable ? bits : 0, NULL);
+			      enable ? 0 : bits, NULL);
+	if (ret)
+		return ret;
+
+	/*
+	 * Clearing the FLIP_HORZ bits shifts the Bayer sampling by one
+	 * column relative to the orientation the init table (0x3821 = 0x1e)
+	 * and the reported SBGGR10 mbus code assume, which corrupts colors.
+	 * Offset the ISP output window by one column in that state to keep
+	 * the BGGR phase; the crop window always has one spare column
+	 * (crop end = start + width, inclusive).
+	 */
+	ret = cci_write(ov5693->regmap, OV5693_OFFSET_START_X_REG,
+			enable ? 1 : 0, NULL);
 	if (ret)
 		return ret;
 

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH RFC 2/2] media: i2c: ov5693: fix horizontal flip polarity and Bayer phase
  2026-07-20 14:28   ` [PATCH RFC 2/2] media: i2c: ov5693: fix horizontal flip polarity and Bayer phase Jakob Berg Jespersen
@ 2026-07-20 17:39     ` Fernando Rimoli
  0 siblings, 0 replies; 5+ messages in thread
From: Fernando Rimoli @ 2026-07-20 17:39 UTC (permalink / raw)
  To: Jakob Berg Jespersen
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Daniel Scally, Hans de Goede,
	Tooraj Taraz, Joseph V . Lavigne, linux-media, linux-kernel,
	Fernando Rimoli

Tested this ov5693 patch on a Surface Pro 9 (Alder Lake IPU6, ov5693 front
camera).

I reproduced your 4-state flip/image matrix on the SP9 via raw V4L2 (capturing
SBGGR10 straight from the ISYS node, so libcamera's rotation handling is out of
the path and I could drive HFLIP/VFLIP directly). Unpatched, the matrix matched
yours: the correct image is at HFLIP=0/VFLIP=1, and the state libcamera
actually uses to undo the 180-degree mount (HFLIP=1+VFLIP=1) comes out
horizontally mirrored.

With this patch applied, the correct, un-mirrored image moves to
HFLIP=1+VFLIP=1 (what libcamera requests now yields the right
orientation). That confirms the inverted-HFLIP / correct-VFLIP conclusion on a
second IPU6 platform.

I did not separately validate the Bayer-phase column offset (my simple debayer
couldn't isolate it), so this Tested-by is for the HFLIP polarity behaviour.

Tested-by: Fernando Rimoli <fernandorimoli11@gmail.com>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH RFC 0/2] media: i2c: Surface Pro 7+ camera flip fixes
  2026-07-20 14:28 ` [PATCH RFC 0/2] media: i2c: Surface Pro 7+ camera flip fixes Jakob Berg Jespersen
  2026-07-20 14:28   ` [PATCH RFC 1/2] media: i2c: ov8865: fix horizontal flip control polarity Jakob Berg Jespersen
  2026-07-20 14:28   ` [PATCH RFC 2/2] media: i2c: ov5693: fix horizontal flip polarity and Bayer phase Jakob Berg Jespersen
@ 2026-07-22 22:14   ` Bryan O'Donoghue
  2 siblings, 0 replies; 5+ messages in thread
From: Bryan O'Donoghue @ 2026-07-22 22:14 UTC (permalink / raw)
  To: Jakob Berg Jespersen, Sakari Ailus, Mauro Carvalho Chehab,
	Daniel Scally
  Cc: Hans de Goede, Fernando Rimoli, Tooraj Taraz, Joseph V. Lavigne,
	linux-media, linux-kernel

On 20/07/2026 15:28, Jakob Berg Jespersen wrote:
> This RFC series fixes two horizontal-flip issues on the front and rear
> cameras of the Microsoft Surface Pro 7+ (Tiger Lake IPU6, ACPI/ipu-bridge).
> Both were found and validated on real hardware (Surface Pro 7+, Fedora 44,
> kernel 7.0.12) and have been in daily use on that machine for over a
> month; each is described in detail in its own patch.
 From a pure process point of view.

Anything that fixes a bug should have a Fixes: and a Cc: stable, 
especially granular stuff like in this series.

Please add both.

---
bod

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-07-22 22:14 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <Q5OH0unwBM9QICxTJXBm1W7LkqYpiGtPRvNqI8FMsDW63Z1AgVArhC3__6dhY4hjrsuDCsbMfvArNyf_qB0Akw==@protonmail.internalid>
2026-07-20 14:28 ` [PATCH RFC 0/2] media: i2c: Surface Pro 7+ camera flip fixes Jakob Berg Jespersen
2026-07-20 14:28   ` [PATCH RFC 1/2] media: i2c: ov8865: fix horizontal flip control polarity Jakob Berg Jespersen
2026-07-20 14:28   ` [PATCH RFC 2/2] media: i2c: ov5693: fix horizontal flip polarity and Bayer phase Jakob Berg Jespersen
2026-07-20 17:39     ` Fernando Rimoli
2026-07-22 22:14   ` [PATCH RFC 0/2] media: i2c: Surface Pro 7+ camera flip fixes Bryan O'Donoghue

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.