[PATCH 08/13] media: i2c: Add hblank control to ov8865

Daniel Scally
2021-07-22T20:35:00Z

Add a V4L2_CID_HBLANK control to the ov8865 driver. This is read only
with timing control intended to be done via vblanking alone.

Signed-off-by: Daniel Scally <djrscally@gmail.com>
---

One of the modes defined in this driver actually has HTS as a _lower_ value
than output_size_x, which means the usual hblank = (hts - output_size_y) formula
doesn't make sense. That seems really strange to me, but the Windows driver
does it too so my understanding must be lacking there...I handled that by
flooring hblank at 0, but there may be a much better way of doing this.

drivers/media/i2c/ov8865.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index daead1fc9314..e1d3c0d50fdc 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -660,6 +660,7 @@ struct ov8865_state {
struct ov8865_ctrls {
struct v4l2_ctrl *link_freq;
struct v4l2_ctrl *pixel_rate;
+ struct v4l2_ctrl *hblank;
struct v4l2_ctrl *vblank;

struct v4l2_ctrl_handler handler;
@@ -2500,6 +2501,7 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
const struct v4l2_ctrl_ops *ops = &ov8865_ctrl_ops;
const struct ov8865_mode *mode = sensor->state.mode;
unsigned int vblank_max, vblank_def;
+ unsigned int hblank;
int ret;

v4l2_ctrl_handler_init(handler, 32);
@@ -2536,6 +2538,13 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
0, 0, ov8865_test_pattern_menu);

/* Blanking */
+ hblank = mode->hts < mode->output_size_x ? 0 : mode->hts - mode->output_size_x;
+ ctrls->hblank = v4l2_ctrl_new_std(handler, ops, V4L2_CID_HBLANK, hblank,
+ hblank, 1, hblank);
+
+ if (ctrls->hblank)
+ ctrls->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
vblank_max = OV8865_TIMING_MAX_VTS - mode->output_size_y;
vblank_def = mode->vts - mode->output_size_y;
ctrls->vblank = v4l2_ctrl_new_std(handler, ops, V4L2_CID_VBLANK,
@@ -2682,6 +2691,7 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
struct v4l2_mbus_framefmt *mbus_format = &format->format;
const struct ov8865_mode *mode;
u32 mbus_code = 0;
+ unsigned int hblank;
unsigned int index;
int ret = 0;

@@ -2726,6 +2736,10 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
OV8865_TIMING_MAX_VTS - mode->output_size_y,
1, mode->vts - mode->output_size_y);

+ hblank = mode->hts < mode->output_size_x ? 0 : mode->hts - mode->output_size_x;
+ __v4l2_ctrl_modify_range(sensor->ctrls.hblank, hblank, hblank, 1,
+ hblank);
+
complete:
mutex_unlock(&sensor->mutex);

--
2.25.1