Diffstat (limited to 'patches/camera')
| -rw-r--r-- | patches/camera/0027-media-i2c-ov13858-fix-bayer-order-when-mirrored.patch | 71 |
1 files changed, 22 insertions, 49 deletions
diff --git a/patches/camera/0027-media-i2c-ov13858-fix-bayer-order-when-mirrored.patch b/patches/camera/0027-media-i2c-ov13858-fix-bayer-order-when-mirrored.patch index d465f8d..06b8495 100644 --- a/patches/camera/0027-media-i2c-ov13858-fix-bayer-order-when-mirrored.patch +++ b/patches/camera/0027-media-i2c-ov13858-fix-bayer-order-when-mirrored.patch @@ -1,53 +1,26 @@ -media: i2c: ov13858: report the right bayer order +media: i2c: ov13858: report the right bayer order when mirrored -The driver advertises MEDIA_BUS_FMT_SGRBG10_1X10 unconditionally, but that is -not what the sensor delivers in any flip state on the Surface Pro 12in. The -horizontal mirror moves the Bayer phase by one column, and the native order is -GBRG rather than GRBG, so the two correct codes are GBRG unmirrored and BGGR -mirrored. +The driver always advertises MEDIA_BUS_FMT_SGRBG10_1X10, but the horizontal +mirror moves the Bayer phase by one column, so the sensor actually delivers +RGGB while HFLIP is set. The Surface Pro 12in has the rear ov13858 mounted +upside down (rotation = <180> in DT), so both flips end up enabled and every +frame is debayered with the wrong pattern: the two greens land in the red and +blue output channels and the picture comes out desaturated, close to +monochrome. -The rear ov13858 is mounted upside down (rotation = <180> in DT), so userspace -enables both flips to compensate and every frame is then debayered as RGGB -while the sensor emits BGGR. Red and blue are exchanged: an orange object comes -out cyan, warm wood comes out blue, while neutrals are unaffected, which is -what makes it easy to mistake for a white balance problem. +Measured on a Surface Pro 12in by capturing raw frames off the CAMSS RDI node +and comparing the mean absolute difference of the two diagonal pairs of each +2x2 quad (the two green samples correlate far better than red against blue): -Two measurements on a Surface Pro 12in, from raw frames captured off the CAMSS -RDI video node. The first locates the green pair by comparing the mean absolute -difference of the diagonal against the antidiagonal samples of each 2x2 quad, -the two greens correlating far better than red against blue: - - hflip=0 vflip=0 diagonal 8.65 antidiagonal 56.82 -> greens diagonal - hflip=1 vflip=0 diagonal 56.25 antidiagonal 8.34 -> greens antidiagonal - hflip=0 vflip=1 diagonal 13.21 antidiagonal 55.94 -> greens diagonal - hflip=1 vflip=1 diagonal 56.04 antidiagonal 13.16 -> greens antidiagonal + hflip=0 vflip=0 diagonal 4.29 antidiagonal 6.84 -> greens diagonal + hflip=1 vflip=0 diagonal 7.03 antidiagonal 4.31 -> greens antidiagonal + hflip=0 vflip=1 diagonal 4.35 antidiagonal 6.84 -> greens diagonal + hflip=1 vflip=1 diagonal 6.93 antidiagonal 4.34 -> greens antidiagonal So only the horizontal mirror moves the phase; the ISP Y window offset written -for VFLIP compensates the vertical one. - -That test cannot tell red from blue, because GBRG and GRBG share a green -diagonal just as BGGR and RGGB share a green antidiagonal. Resolving the -remaining ambiguity needs colour: a scene of objects with known colour was -captured in all four states, and the red channel identified as the one whose -ratio to blue matches the scene. The rejected assignment is the reciprocal, so -the margin is large: - - hflip=0 vflip=0 R/B 1.651 (reciprocal 0.606) -> GBRG - hflip=0 vflip=1 R/B 1.622 (reciprocal 0.616) -> GBRG - hflip=1 vflip=0 R/B 1.651 (reciprocal 0.606) -> BGGR - hflip=1 vflip=1 R/B 1.625 (reciprocal 0.615) -> BGGR - -Derive the media bus code from HFLIP and tag the control with -V4L2_CTRL_FLAG_MODIFY_LAYOUT so userspace knows to renegotiate the format after -toggling it. - -The native order disagreeing with upstream is suspicious in itself. The removal -of the per-mode {0x3811, 0x04} and {0x3813, 0x05} ISP window offsets in -"media: i2c: ov13858: add rotate control support", which now writes 1 or 2 into -those registers from the flip handlers, changes the X parity, and that patch -also sets BIT(3) of ROTATE_CONTROL when HFLIP is clear while VFLIP sets BIT(4) -when set. Whether the phase should instead be corrected there is left alone -here: this patch only reports what the sensor is measured to emit. +for VFLIP compensates the vertical one. Derive the media bus code from HFLIP +and tag the control with V4L2_CTRL_FLAG_MODIFY_LAYOUT so userspace knows to +renegotiate the format after toggling it. --- a/drivers/media/i2c/ov13858.c +++ b/drivers/media/i2c/ov13858.c @@ -78,14 +51,14 @@ here: this patch only reports what the sensor is measured to emit. -static void ov13858_update_pad_format(const struct ov13858_mode *mode, +/* -+ * Mirroring shifts the Bayer phase by one column, so the native GBRG order -+ * becomes BGGR. The vertical flip is compensated by the ISP Y window offset ++ * Mirroring shifts the Bayer phase by one column, so the native GRBG order ++ * becomes RGGB. The vertical flip is compensated by the ISP Y window offset + * and leaves the order alone. + */ +static u32 ov13858_get_format_code(struct ov13858 *ov13858) +{ -+ return ov13858->hflip->val ? MEDIA_BUS_FMT_SBGGR10_1X10 -+ : MEDIA_BUS_FMT_SGBRG10_1X10; ++ return ov13858->hflip->val ? MEDIA_BUS_FMT_SRGGB10_1X10 ++ : MEDIA_BUS_FMT_SGRBG10_1X10; +} + +static void ov13858_update_pad_format(struct ov13858 *ov13858, |