Re: [PATCH v2 2/2] media: i2c: ov5693: fix horizontal flip polarity and Bayer phase
From: D. Manresa
Date: Fri Aug 28 2026 - 19:18:34 EST
On Wed, 29 Jul 2026, Jakob Berg Jespersen wrote:
> The sensor's native readout is horizontally mirrored and the FORMAT2
> FLIP_HORZ bits (reg 0x3821) un-mirror it; the init table sets them by
> default (0x3821 = 0x1e). The driver sets those bits for V4L2_CID_HFLIP=1,
> so the control is inverted: HFLIP=1 yields the un-mirrored image and
> HFLIP=0 the mirrored one. Invert the polarity so HFLIP=0 yields the
> unflipped image.
Tested on the front camera of a Surface Pro 7+ (OV5693 behind an IPU6,
patch applied on v6.19 sources, loaded on a linux-surface 6.19.8 kernel),
Bayer phases read from raw 2592x1944 captures. Partial results - the
polarity fix checks out, the 0x3810 compensation appears to sit on the
wrong flip state on my unit:
1) The polarity inversion is correct. Independent confirmation: the
register tables inside the vendor Windows driver (ov5693.sys from the
Surface MSI) keep the 0x3821 FLIP_HORZ bits set in every mode
(0x3821 = 0x1e/0x1f), and Windows delivers the un-mirrored image; with
your patch HFLIP=0 keeps them set, as the init table intends. HFLIP
also toggles the mirror geometry correctly in both directions here.
2) The 0x3810 write does what the commit message says in the relative
sense: the two flip states come out with the SAME Bayer phase, so
toggling HFLIP no longer changes the colours.
3) However, on my unit BOTH states then decode as GBRG, one column off the
reported SBGGR10. I measured the four register combinations
independently (phase identified from raw frames by green-pair
statistics and confirmed by demosaicing a known-colour scene under each
hypothesis):
FLIP_HORZ bits set + 0x3810=0 (your HFLIP=0): GBRG
FLIP_HORZ bits cleared + 0x3810=1 (your HFLIP=1): GBRG
FLIP_HORZ bits cleared + 0x3810=0: BGGR (clean)
FLIP_HORZ bits set + 0x3810=1: does not stream
i.e. here it is the un-mirrored readout (bits set) that carries the
one-column phase shift, and the mirrored readout that is SBGGR-clean -
the opposite of what the patch compensates. The last row is why the
compensation cannot simply be moved to the other state: with the
FLIP_HORZ bits set the sensor refuses to stream with a one-column
window offset (perpetual "Frame sync error" on the IPU6 CSI-2
receiver, reproduced across repeated attempts); shifting the crop
window by one column instead should work, but I have not tested that.
4) For completeness: in the 2x2-binned readout the Surface uses for
video (a downstream patch of mine, not in mainline), the mirror does
not move the Bayer phase at all - same behaviour I measured on the
OV8865 - so there the 0x3810 parity must stay constant across flip
states.
Since you and Fernando verified colours correct in both flip states on
your units, and point 3 is exactly the opposite assignment, maybe the
two of us are not decoding the same thing - or the modules differ. Could
you double-check the absolute phase at HFLIP=0 on your unit from a raw
capture of a known-colour scene (not through an ISP that may be
auto-correcting, and not with the sensor's test pattern - on my unit the
colour-bar generator is inserted after the flip/window stage and shows
the same order and phase in every flip state, so it cannot see this)?
Happy to test a v3. For patch 1/2 of this series everything checks out
on my unit; sent a Tested-by there separately.
D. Manresa <dmanresa@xxxxxxxxx>