* [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