From 1463b371aff0682c70141f7521db13cc4bbf3016 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Tue, 3 Sep 2019 17:11:44 -0300 Subject: media: ov6650: Fix stored crop rectangle not in sync with hardware The driver stores crop rectangle settings supposed to be in line with hardware state in a device private structure. Since the driver initial submission, crop rectangle width and height settings are not updated correctly when rectangle offset settings are applied on hardware. If an error occurs while the device is updated, the stored settings my no longer reflect hardware state and consecutive calls to .get_selection() as well as .get/set_fmt() may return incorrect information. That in turn may affect ability of a bridge device to use correct DMA transfer settings if such incorrect informamtion on active frame format returned by .get/set_fmt() is used. Assuming a failed update of the device means its actual settings haven't changed, update crop rectangle width and height settings stored in the device private structure correctly while the rectangle offset is successfully applied on hardware so the stored values always reflect actual hardware state to the extent possible. Fixes: 2f6e2404799a ("[media] SoC Camera: add driver for OV6650 sensor") Signed-off-by: Janusz Krzysztofik Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov6650.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media/i2c') diff --git a/drivers/media/i2c/ov6650.c b/drivers/media/i2c/ov6650.c index 126a662be301..16887049f0cd 100644 --- a/drivers/media/i2c/ov6650.c +++ b/drivers/media/i2c/ov6650.c @@ -491,6 +491,7 @@ static int ov6650_set_selection(struct v4l2_subdev *sd, ret = ov6650_reg_write(client, REG_HSTRT, sel->r.left >> 1); if (!ret) { + priv->rect.width += priv->rect.left - sel->r.left; priv->rect.left = sel->r.left; ret = ov6650_reg_write(client, REG_HSTOP, (sel->r.left + sel->r.width) >> 1); @@ -500,6 +501,7 @@ static int ov6650_set_selection(struct v4l2_subdev *sd, ret = ov6650_reg_write(client, REG_VSTRT, sel->r.top >> 1); } if (!ret) { + priv->rect.height += priv->rect.top - sel->r.top; priv->rect.top = sel->r.top; ret = ov6650_reg_write(client, REG_VSTOP, (sel->r.top + sel->r.height) >> 1); -- cgit v1.2.3