On Tue Oct 14 19:40:09 2025 +0200, Hans de Goede wrote:
> During sensor calibration I noticed that with the hflip control set
> to false/disabled the image was mirrored.
> 
> So it seems that the horizontal flip control is inverted and needs to
> be set to 1 to not flip (just like the similar problem recently fixed
> on the ov08x40 sensor).
> 
> Invert the hflip control to fix the sensor mirroring by default.
> 
> As the comment above the newly added OV01A10_MEDIA_BUS_FMT define explains
> the control being inverted also means that the native Bayer-order of
> the sensor actually is GBRG not BGGR, but so as to not break userspace
> the Bayer-order is kept at BGGR.
> 
> Fixes: 0827b58dabff ("media: i2c: add ov01a10 image sensor driver")
> Cc: [email protected]
> Signed-off-by: Hans de Goede <[email protected]>
> Tested-by: Mehdi Djait <[email protected]> # Dell XPS 9315
> Reviewed-by: Mehdi Djait <[email protected]>
> Signed-off-by: Sakari Ailus <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/i2c/ov01a10.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

---

diff --git a/drivers/media/i2c/ov01a10.c b/drivers/media/i2c/ov01a10.c
index 141cb6f75b55..e5df01f97978 100644
--- a/drivers/media/i2c/ov01a10.c
+++ b/drivers/media/i2c/ov01a10.c
@@ -75,6 +75,15 @@
 #define OV01A10_REG_X_WIN              0x3811
 #define OV01A10_REG_Y_WIN              0x3813
 
+/*
+ * The native ov01a10 bayer-pattern is GBRG, but there was a driver bug 
enabling
+ * hflip/mirroring by default resulting in BGGR. Because of this bug Intel's
+ * proprietary IPU6 userspace stack expects BGGR. So we report BGGR to not 
break
+ * userspace and fix things up by shifting the crop window-x coordinate by 1
+ * when hflip is *disabled*.
+ */
+#define OV01A10_MEDIA_BUS_FMT          MEDIA_BUS_FMT_SBGGR10_1X10
+
 struct ov01a10_reg {
        u16 address;
        u8 val;
@@ -185,14 +194,14 @@ static const struct ov01a10_reg sensor_1280x800_setting[] 
= {
        {0x380e, 0x03},
        {0x380f, 0x80},
        {0x3810, 0x00},
-       {0x3811, 0x08},
+       {0x3811, 0x09},
        {0x3812, 0x00},
        {0x3813, 0x08},
        {0x3814, 0x01},
        {0x3815, 0x01},
        {0x3816, 0x01},
        {0x3817, 0x01},
-       {0x3820, 0xa0},
+       {0x3820, 0xa8},
        {0x3822, 0x13},
        {0x3832, 0x28},
        {0x3833, 0x10},
@@ -411,7 +420,7 @@ static int ov01a10_set_hflip(struct ov01a10 *ov01a10, u32 
hflip)
        int ret;
        u32 val, offset;
 
-       offset = hflip ? 0x9 : 0x8;
+       offset = hflip ? 0x8 : 0x9;
        ret = ov01a10_write_reg(ov01a10, OV01A10_REG_X_WIN, 1, offset);
        if (ret)
                return ret;
@@ -420,8 +429,8 @@ static int ov01a10_set_hflip(struct ov01a10 *ov01a10, u32 
hflip)
        if (ret)
                return ret;
 
-       val = hflip ? val | FIELD_PREP(OV01A10_HFLIP_MASK, 0x1) :
-               val & ~OV01A10_HFLIP_MASK;
+       val = hflip ? val & ~OV01A10_HFLIP_MASK :
+                     val | FIELD_PREP(OV01A10_HFLIP_MASK, 0x1);
 
        return ov01a10_write_reg(ov01a10, OV01A10_REG_FORMAT1, 1, val);
 }
@@ -610,7 +619,7 @@ static void ov01a10_update_pad_format(const struct 
ov01a10_mode *mode,
 {
        fmt->width = mode->width;
        fmt->height = mode->height;
-       fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
+       fmt->code = OV01A10_MEDIA_BUS_FMT;
        fmt->field = V4L2_FIELD_NONE;
        fmt->colorspace = V4L2_COLORSPACE_RAW;
 }
@@ -751,7 +760,7 @@ static int ov01a10_enum_mbus_code(struct v4l2_subdev *sd,
        if (code->index > 0)
                return -EINVAL;
 
-       code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
+       code->code = OV01A10_MEDIA_BUS_FMT;
 
        return 0;
 }
@@ -761,7 +770,7 @@ static int ov01a10_enum_frame_size(struct v4l2_subdev *sd,
                                   struct v4l2_subdev_frame_size_enum *fse)
 {
        if (fse->index >= ARRAY_SIZE(supported_modes) ||
-           fse->code != MEDIA_BUS_FMT_SBGGR10_1X10)
+           fse->code != OV01A10_MEDIA_BUS_FMT)
                return -EINVAL;
 
        fse->min_width = supported_modes[fse->index].width;
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to