Message ID | 20241029-imx219_fixes-v1-2-b45dc3658b4e@ideasonboard.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | media: i2c: imx219: Fixes for blanking and pixel rate | expand |
Hi Jai, On Tue, Oct 29, 2024 at 02:27:36PM +0530, Jai Luthra wrote: > From: Dave Stevenson <dave.stevenson@raspberrypi.com> > > The HBLANK control was read-only, and always configured such > that the sensor HTS register was 3448. This limited the maximum > exposure time that could be achieved to around 1.26 secs. > > Make HBLANK read/write so that the line time can be extended, > and thereby allow longer exposures (and slower frame rates). > Retain the overall HTS setting when changing modes rather than > resetting it to a default. It looks like this changes horizontal blanking at least in some cases. Does this also work as expected in binned modes, for instance? Many sensors have image quality related issues on untested albeit functional line length values. So my question is: how has this been validated? > > Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> > Signed-off-by: Jai Luthra <jai.luthra@ideasonboard.com> > --- > drivers/media/i2c/imx219.c | 35 +++++++++++++++++++++++------------ > 1 file changed, 23 insertions(+), 12 deletions(-) > > diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c > index f98aad74fe584a18e2fe7126f92bf294762a54e3..de9230d4ad81f085640be254db9391ae7ad20773 100644 > --- a/drivers/media/i2c/imx219.c > +++ b/drivers/media/i2c/imx219.c > @@ -76,8 +76,10 @@ > > #define IMX219_VBLANK_MIN 32 > > -/* HBLANK control - read only */ > -#define IMX219_PPL_DEFAULT 3448 > +/* HBLANK control range */ > +#define IMX219_PPL_MIN 3448 > +#define IMX219_PPL_MAX 0x7ff0 > +#define IMX219_REG_HTS CCI_REG16(0x0162) > > #define IMX219_REG_LINE_LENGTH_A CCI_REG16(0x0162) > #define IMX219_REG_X_ADD_STA_A CCI_REG16(0x0164) > @@ -422,6 +424,10 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) > cci_write(imx219->regmap, IMX219_REG_VTS, > format->height + ctrl->val, &ret); > break; > + case V4L2_CID_HBLANK: > + cci_write(imx219->regmap, IMX219_REG_HTS, > + format->width + ctrl->val, &ret); > + break; > case V4L2_CID_TEST_PATTERN_RED: > cci_write(imx219->regmap, IMX219_REG_TESTP_RED, > ctrl->val, &ret); > @@ -496,12 +502,11 @@ static int imx219_init_controls(struct imx219 *imx219) > V4L2_CID_VBLANK, IMX219_VBLANK_MIN, > IMX219_VTS_MAX - mode->height, 1, > mode->vts_def - mode->height); > - hblank = IMX219_PPL_DEFAULT - mode->width; > + hblank = IMX219_PPL_MIN - mode->width; > imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, > - V4L2_CID_HBLANK, hblank, hblank, > + V4L2_CID_HBLANK, hblank, > + IMX219_PPL_MIN - mode->width, > 1, hblank); > - if (imx219->hblank) > - imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; > exposure_max = mode->vts_def - 4; > exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ? > exposure_max : IMX219_EXPOSURE_DEFAULT; > @@ -842,6 +847,7 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, > crop->top = (IMX219_NATIVE_HEIGHT - crop->height) / 2; > > if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { > + u32 prev_hts = format->width + imx219->hblank->val; > int exposure_max; > int exposure_def; > int hblank; > @@ -861,13 +867,18 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, > exposure_max, imx219->exposure->step, > exposure_def); > /* > - * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank > - * depends on mode->width only, and is not changeble in any > - * way other than changing the mode. > + * Retain PPL setting from previous mode so that the > + * line time does not change on a mode change. > + * Limits have to be recomputed as the controls define > + * the blanking only, so PPL values need to have the > + * mode width subtracted. > */ > - hblank = IMX219_PPL_DEFAULT - mode->width; > - __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1, > - hblank); > + hblank = prev_hts - mode->width; > + __v4l2_ctrl_modify_range(imx219->hblank, > + IMX219_PPL_MIN - mode->width, > + IMX219_PPL_MAX - mode->width, > + 1, IMX219_PPL_MIN - mode->width); > + __v4l2_ctrl_s_ctrl(imx219->hblank, hblank); > } > > return 0; >
Hi Jai, Dave On Tue, Oct 29, 2024 at 02:27:36PM +0530, Jai Luthra wrote: > From: Dave Stevenson <dave.stevenson@raspberrypi.com> > > The HBLANK control was read-only, and always configured such > that the sensor HTS register was 3448. This limited the maximum > exposure time that could be achieved to around 1.26 secs. > > Make HBLANK read/write so that the line time can be extended, > and thereby allow longer exposures (and slower frame rates). > Retain the overall HTS setting when changing modes rather than > resetting it to a default. > > Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> > Signed-off-by: Jai Luthra <jai.luthra@ideasonboard.com> > --- > drivers/media/i2c/imx219.c | 35 +++++++++++++++++++++++------------ > 1 file changed, 23 insertions(+), 12 deletions(-) > > diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c > index f98aad74fe584a18e2fe7126f92bf294762a54e3..de9230d4ad81f085640be254db9391ae7ad20773 100644 > --- a/drivers/media/i2c/imx219.c > +++ b/drivers/media/i2c/imx219.c > @@ -76,8 +76,10 @@ > > #define IMX219_VBLANK_MIN 32 > > -/* HBLANK control - read only */ > -#define IMX219_PPL_DEFAULT 3448 > +/* HBLANK control range */ > +#define IMX219_PPL_MIN 3448 > +#define IMX219_PPL_MAX 0x7ff0 nit: I wold have rather made these two either both hex or both decimal (my preference is for hex as it matches the registers 0x1144-0x1147 registers) Also, yes: min_line_length_pck = 0x0d78 = 3448 but: min_line_blanking_pck = 0xa8 = 168 But as the max supported output width is 3280 and (3448 - 168 = 3280) I think it's fine listing PLL_MIN only > +#define IMX219_REG_HTS CCI_REG16(0x0162) > > #define IMX219_REG_LINE_LENGTH_A CCI_REG16(0x0162) > #define IMX219_REG_X_ADD_STA_A CCI_REG16(0x0164) > @@ -422,6 +424,10 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) > cci_write(imx219->regmap, IMX219_REG_VTS, > format->height + ctrl->val, &ret); > break; > + case V4L2_CID_HBLANK: > + cci_write(imx219->regmap, IMX219_REG_HTS, > + format->width + ctrl->val, &ret); According to Sakari's comment, should you in the next patch scale hblank by the rate factor has done for vts and pixel rate ? > + break; > case V4L2_CID_TEST_PATTERN_RED: > cci_write(imx219->regmap, IMX219_REG_TESTP_RED, > ctrl->val, &ret); > @@ -496,12 +502,11 @@ static int imx219_init_controls(struct imx219 *imx219) > V4L2_CID_VBLANK, IMX219_VBLANK_MIN, > IMX219_VTS_MAX - mode->height, 1, > mode->vts_def - mode->height); > - hblank = IMX219_PPL_DEFAULT - mode->width; > + hblank = IMX219_PPL_MIN - mode->width; > imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, > - V4L2_CID_HBLANK, hblank, hblank, > + V4L2_CID_HBLANK, hblank, > + IMX219_PPL_MIN - mode->width, Can't you use 'hblank' again here ? > 1, hblank); > - if (imx219->hblank) > - imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; > exposure_max = mode->vts_def - 4; > exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ? > exposure_max : IMX219_EXPOSURE_DEFAULT; > @@ -842,6 +847,7 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, > crop->top = (IMX219_NATIVE_HEIGHT - crop->height) / 2; > > if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { > + u32 prev_hts = format->width + imx219->hblank->val; > int exposure_max; > int exposure_def; > int hblank; > @@ -861,13 +867,18 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, > exposure_max, imx219->exposure->step, > exposure_def); > /* > - * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank > - * depends on mode->width only, and is not changeble in any > - * way other than changing the mode. > + * Retain PPL setting from previous mode so that the > + * line time does not change on a mode change. > + * Limits have to be recomputed as the controls define > + * the blanking only, so PPL values need to have the > + * mode width subtracted. Two years ago I wrote this https://patchwork.linuxtv.org/project/linux-media/patch/20221121181515.34008-2-jacopo@jmondi.org/ which hasn't progressed since then but I presume was based on some sort of consensus. Is it worth a respin ? > */ > - hblank = IMX219_PPL_DEFAULT - mode->width; > - __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1, > - hblank); > + hblank = prev_hts - mode->width; And as far as I can tell mode->width == format->width because of the above imx219_update_pad_format(imx219, mode, &fmt->format, fmt->format.code); format = v4l2_subdev_state_get_format(state, 0); *format = fmt->format; so here you have u32 prev_hts = format->width + imx219->hblank->val; hblank = (format->widht + imx219->hblank->val) - format->width; so that: hblank == imx219->hblank->val; > + __v4l2_ctrl_modify_range(imx219->hblank, > + IMX219_PPL_MIN - mode->width, > + IMX219_PPL_MAX - mode->width, > + 1, IMX219_PPL_MIN - mode->width); > + __v4l2_ctrl_s_ctrl(imx219->hblank, hblank); So here you're writing hblank to the same value (clamped by the framework in the new limits). So you're not retaining line lenght but the blanking value, which seems to contradict the comment. Or am I missing something here ? Thanks j > } > > return 0; > > -- > 2.47.0 > >
Hi Sakari On Fri, 1 Nov 2024 at 08:48, Sakari Ailus <sakari.ailus@linux.intel.com> wrote: > > Hi Jai, > > On Tue, Oct 29, 2024 at 02:27:36PM +0530, Jai Luthra wrote: > > From: Dave Stevenson <dave.stevenson@raspberrypi.com> > > > > The HBLANK control was read-only, and always configured such > > that the sensor HTS register was 3448. This limited the maximum > > exposure time that could be achieved to around 1.26 secs. > > > > Make HBLANK read/write so that the line time can be extended, > > and thereby allow longer exposures (and slower frame rates). > > Retain the overall HTS setting when changing modes rather than > > resetting it to a default. > > It looks like this changes horizontal blanking at least in some cases. Does > this also work as expected in binned modes, for instance? > > Many sensors have image quality related issues on untested albeit > functional line length values. > > So my question is: how has this been validated? Validated by Sony, or others? I've tested a range of values in all modes and not observed any image quality issues. From previous discussions with Sony, they always provide their big spreadsheet of register values for the specific mode and frame rate requested. I don't think they even officially state that changing VTS/FRM_LENGTH_LINES to change the framerate is permitted. There are some Sony datasheets (eg imx258) that state "set to X. Any other value please confirm with Sony", but that isn't the case for the imx219 datasheet. I take that as it is permitted within the defined ranges. Dave > > > > Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> > > Signed-off-by: Jai Luthra <jai.luthra@ideasonboard.com> > > --- > > drivers/media/i2c/imx219.c | 35 +++++++++++++++++++++++------------ > > 1 file changed, 23 insertions(+), 12 deletions(-) > > > > diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c > > index f98aad74fe584a18e2fe7126f92bf294762a54e3..de9230d4ad81f085640be254db9391ae7ad20773 100644 > > --- a/drivers/media/i2c/imx219.c > > +++ b/drivers/media/i2c/imx219.c > > @@ -76,8 +76,10 @@ > > > > #define IMX219_VBLANK_MIN 32 > > > > -/* HBLANK control - read only */ > > -#define IMX219_PPL_DEFAULT 3448 > > +/* HBLANK control range */ > > +#define IMX219_PPL_MIN 3448 > > +#define IMX219_PPL_MAX 0x7ff0 > > +#define IMX219_REG_HTS CCI_REG16(0x0162) > > > > #define IMX219_REG_LINE_LENGTH_A CCI_REG16(0x0162) > > #define IMX219_REG_X_ADD_STA_A CCI_REG16(0x0164) > > @@ -422,6 +424,10 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) > > cci_write(imx219->regmap, IMX219_REG_VTS, > > format->height + ctrl->val, &ret); > > break; > > + case V4L2_CID_HBLANK: > > + cci_write(imx219->regmap, IMX219_REG_HTS, > > + format->width + ctrl->val, &ret); > > + break; > > case V4L2_CID_TEST_PATTERN_RED: > > cci_write(imx219->regmap, IMX219_REG_TESTP_RED, > > ctrl->val, &ret); > > @@ -496,12 +502,11 @@ static int imx219_init_controls(struct imx219 *imx219) > > V4L2_CID_VBLANK, IMX219_VBLANK_MIN, > > IMX219_VTS_MAX - mode->height, 1, > > mode->vts_def - mode->height); > > - hblank = IMX219_PPL_DEFAULT - mode->width; > > + hblank = IMX219_PPL_MIN - mode->width; > > imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, > > - V4L2_CID_HBLANK, hblank, hblank, > > + V4L2_CID_HBLANK, hblank, > > + IMX219_PPL_MIN - mode->width, > > 1, hblank); > > - if (imx219->hblank) > > - imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; > > exposure_max = mode->vts_def - 4; > > exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ? > > exposure_max : IMX219_EXPOSURE_DEFAULT; > > @@ -842,6 +847,7 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, > > crop->top = (IMX219_NATIVE_HEIGHT - crop->height) / 2; > > > > if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { > > + u32 prev_hts = format->width + imx219->hblank->val; > > int exposure_max; > > int exposure_def; > > int hblank; > > @@ -861,13 +867,18 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, > > exposure_max, imx219->exposure->step, > > exposure_def); > > /* > > - * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank > > - * depends on mode->width only, and is not changeble in any > > - * way other than changing the mode. > > + * Retain PPL setting from previous mode so that the > > + * line time does not change on a mode change. > > + * Limits have to be recomputed as the controls define > > + * the blanking only, so PPL values need to have the > > + * mode width subtracted. > > */ > > - hblank = IMX219_PPL_DEFAULT - mode->width; > > - __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1, > > - hblank); > > + hblank = prev_hts - mode->width; > > + __v4l2_ctrl_modify_range(imx219->hblank, > > + IMX219_PPL_MIN - mode->width, > > + IMX219_PPL_MAX - mode->width, > > + 1, IMX219_PPL_MIN - mode->width); > > + __v4l2_ctrl_s_ctrl(imx219->hblank, hblank); > > } > > > > return 0; > > > > -- > Kind regards, > > Sakari Ailus
Hi Dave, On Thu, Nov 07, 2024 at 12:43:52PM +0000, Dave Stevenson wrote: > Hi Sakari > > On Fri, 1 Nov 2024 at 08:48, Sakari Ailus <sakari.ailus@linux.intel.com> wrote: > > > > Hi Jai, > > > > On Tue, Oct 29, 2024 at 02:27:36PM +0530, Jai Luthra wrote: > > > From: Dave Stevenson <dave.stevenson@raspberrypi.com> > > > > > > The HBLANK control was read-only, and always configured such > > > that the sensor HTS register was 3448. This limited the maximum > > > exposure time that could be achieved to around 1.26 secs. > > > > > > Make HBLANK read/write so that the line time can be extended, > > > and thereby allow longer exposures (and slower frame rates). > > > Retain the overall HTS setting when changing modes rather than > > > resetting it to a default. > > > > It looks like this changes horizontal blanking at least in some cases. Does > > this also work as expected in binned modes, for instance? > > > > Many sensors have image quality related issues on untested albeit > > functional line length values. > > > > So my question is: how has this been validated? > > Validated by Sony, or others? > I've tested a range of values in all modes and not observed any image > quality issues. Somehow at least. :-) > > From previous discussions with Sony, they always provide their big > spreadsheet of register values for the specific mode and frame rate > requested. I don't think they even officially state that changing > VTS/FRM_LENGTH_LINES to change the framerate is permitted. > There are some Sony datasheets (eg imx258) that state "set to X. Any > other value please confirm with Sony", but that isn't the case for the > imx219 datasheet. I take that as it is permitted within the defined > ranges. I'm not that much concerned of vertical blanking, changing that within the valid range has effects on the image itself very seldom. Horizontal blanking is different though and this is what the patch makes changeable, including a change in the default value. Of course there are big differences between sensors here.
Hi Sakari On Fri, 8 Nov 2024 at 10:30, Sakari Ailus <sakari.ailus@linux.intel.com> wrote: > > Hi Dave, > > On Thu, Nov 07, 2024 at 12:43:52PM +0000, Dave Stevenson wrote: > > Hi Sakari > > > > On Fri, 1 Nov 2024 at 08:48, Sakari Ailus <sakari.ailus@linux.intel.com> wrote: > > > > > > Hi Jai, > > > > > > On Tue, Oct 29, 2024 at 02:27:36PM +0530, Jai Luthra wrote: > > > > From: Dave Stevenson <dave.stevenson@raspberrypi.com> > > > > > > > > The HBLANK control was read-only, and always configured such > > > > that the sensor HTS register was 3448. This limited the maximum > > > > exposure time that could be achieved to around 1.26 secs. > > > > > > > > Make HBLANK read/write so that the line time can be extended, > > > > and thereby allow longer exposures (and slower frame rates). > > > > Retain the overall HTS setting when changing modes rather than > > > > resetting it to a default. > > > > > > It looks like this changes horizontal blanking at least in some cases. Does > > > this also work as expected in binned modes, for instance? > > > > > > Many sensors have image quality related issues on untested albeit > > > functional line length values. > > > > > > So my question is: how has this been validated? > > > > Validated by Sony, or others? > > I've tested a range of values in all modes and not observed any image > > quality issues. > > Somehow at least. :-) > > > > > From previous discussions with Sony, they always provide their big > > spreadsheet of register values for the specific mode and frame rate > > requested. I don't think they even officially state that changing > > VTS/FRM_LENGTH_LINES to change the framerate is permitted. > > There are some Sony datasheets (eg imx258) that state "set to X. Any > > other value please confirm with Sony", but that isn't the case for the > > imx219 datasheet. I take that as it is permitted within the defined > > ranges. > > I'm not that much concerned of vertical blanking, changing that within the > valid range has effects on the image itself very seldom. Horizontal > blanking is different though and this is what the patch makes changeable, > including a change in the default value. Of course there are big > differences between sensors here. The intention was that the default value shouldn't change, and as the overall PIXELS_PER_LINE value was meant to be retained on a mode change the value used should only change if an application changes V4L2_CID_HBLANK. If I blundered in the implementation of that, then that should be fixed (I know Jacopo made comments, but I haven't had a chance to investigate). I doubt we'd get validation from Sony beyond the contents of the datasheet. Potentially as the sensor is so old they don't have the information or engineers involved. I'm happy to set up a test system and capture a set of images with HBLANK from min to max at some increment. With the same exposure and gain they should all be identical as long as there isn't any movement (rolling shutter with longer readout times and all that). Would that be satisfactory? For contrast, the IMX290 datasheet states that VMAX shall be fixed at 0x465 for all-pixel mode / 0x2ee for 720p mode, and HMAX should be changed for frame rate control. As you say, sensors differ. Dave > -- > Kind regards, > > Sakari Ailus
Hi Dave, On Mon, Nov 11, 2024 at 07:37:56PM +0000, Dave Stevenson wrote: > Hi Sakari > > On Fri, 8 Nov 2024 at 10:30, Sakari Ailus <sakari.ailus@linux.intel.com> wrote: > > > > Hi Dave, > > > > On Thu, Nov 07, 2024 at 12:43:52PM +0000, Dave Stevenson wrote: > > > Hi Sakari > > > > > > On Fri, 1 Nov 2024 at 08:48, Sakari Ailus <sakari.ailus@linux.intel.com> wrote: > > > > > > > > Hi Jai, > > > > > > > > On Tue, Oct 29, 2024 at 02:27:36PM +0530, Jai Luthra wrote: > > > > > From: Dave Stevenson <dave.stevenson@raspberrypi.com> > > > > > > > > > > The HBLANK control was read-only, and always configured such > > > > > that the sensor HTS register was 3448. This limited the maximum > > > > > exposure time that could be achieved to around 1.26 secs. > > > > > > > > > > Make HBLANK read/write so that the line time can be extended, > > > > > and thereby allow longer exposures (and slower frame rates). > > > > > Retain the overall HTS setting when changing modes rather than > > > > > resetting it to a default. > > > > > > > > It looks like this changes horizontal blanking at least in some cases. Does > > > > this also work as expected in binned modes, for instance? > > > > > > > > Many sensors have image quality related issues on untested albeit > > > > functional line length values. > > > > > > > > So my question is: how has this been validated? > > > > > > Validated by Sony, or others? > > > I've tested a range of values in all modes and not observed any image > > > quality issues. > > > > Somehow at least. :-) > > > > > > > > From previous discussions with Sony, they always provide their big > > > spreadsheet of register values for the specific mode and frame rate > > > requested. I don't think they even officially state that changing > > > VTS/FRM_LENGTH_LINES to change the framerate is permitted. > > > There are some Sony datasheets (eg imx258) that state "set to X. Any > > > other value please confirm with Sony", but that isn't the case for the > > > imx219 datasheet. I take that as it is permitted within the defined > > > ranges. > > > > I'm not that much concerned of vertical blanking, changing that within the > > valid range has effects on the image itself very seldom. Horizontal > > blanking is different though and this is what the patch makes changeable, > > including a change in the default value. Of course there are big > > differences between sensors here. > > The intention was that the default value shouldn't change, and as the > overall PIXELS_PER_LINE value was meant to be retained on a mode > change the value used should only change if an application changes > V4L2_CID_HBLANK. If I blundered in the implementation of that, then > that should be fixed (I know Jacopo made comments, but I haven't had a > chance to investigate). I guess I misread the patch. It indeed should be the same. > > I doubt we'd get validation from Sony beyond the contents of the > datasheet. Potentially as the sensor is so old they don't have the > information or engineers involved. > I'm happy to set up a test system and capture a set of images with > HBLANK from min to max at some increment. With the same exposure and > gain they should all be identical as long as there isn't any movement > (rolling shutter with longer readout times and all that). Would that > be satisfactory? Sounds good to me. I just thought how it actually had been tested. :-) > > For contrast, the IMX290 datasheet states that VMAX shall be fixed at > 0x465 for all-pixel mode / 0x2ee for 720p mode, and HMAX should be > changed for frame rate control. As you say, sensors differ.
diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index f98aad74fe584a18e2fe7126f92bf294762a54e3..de9230d4ad81f085640be254db9391ae7ad20773 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -76,8 +76,10 @@ #define IMX219_VBLANK_MIN 32 -/* HBLANK control - read only */ -#define IMX219_PPL_DEFAULT 3448 +/* HBLANK control range */ +#define IMX219_PPL_MIN 3448 +#define IMX219_PPL_MAX 0x7ff0 +#define IMX219_REG_HTS CCI_REG16(0x0162) #define IMX219_REG_LINE_LENGTH_A CCI_REG16(0x0162) #define IMX219_REG_X_ADD_STA_A CCI_REG16(0x0164) @@ -422,6 +424,10 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) cci_write(imx219->regmap, IMX219_REG_VTS, format->height + ctrl->val, &ret); break; + case V4L2_CID_HBLANK: + cci_write(imx219->regmap, IMX219_REG_HTS, + format->width + ctrl->val, &ret); + break; case V4L2_CID_TEST_PATTERN_RED: cci_write(imx219->regmap, IMX219_REG_TESTP_RED, ctrl->val, &ret); @@ -496,12 +502,11 @@ static int imx219_init_controls(struct imx219 *imx219) V4L2_CID_VBLANK, IMX219_VBLANK_MIN, IMX219_VTS_MAX - mode->height, 1, mode->vts_def - mode->height); - hblank = IMX219_PPL_DEFAULT - mode->width; + hblank = IMX219_PPL_MIN - mode->width; imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_HBLANK, hblank, hblank, + V4L2_CID_HBLANK, hblank, + IMX219_PPL_MIN - mode->width, 1, hblank); - if (imx219->hblank) - imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; exposure_max = mode->vts_def - 4; exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ? exposure_max : IMX219_EXPOSURE_DEFAULT; @@ -842,6 +847,7 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, crop->top = (IMX219_NATIVE_HEIGHT - crop->height) / 2; if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { + u32 prev_hts = format->width + imx219->hblank->val; int exposure_max; int exposure_def; int hblank; @@ -861,13 +867,18 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, exposure_max, imx219->exposure->step, exposure_def); /* - * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank - * depends on mode->width only, and is not changeble in any - * way other than changing the mode. + * Retain PPL setting from previous mode so that the + * line time does not change on a mode change. + * Limits have to be recomputed as the controls define + * the blanking only, so PPL values need to have the + * mode width subtracted. */ - hblank = IMX219_PPL_DEFAULT - mode->width; - __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1, - hblank); + hblank = prev_hts - mode->width; + __v4l2_ctrl_modify_range(imx219->hblank, + IMX219_PPL_MIN - mode->width, + IMX219_PPL_MAX - mode->width, + 1, IMX219_PPL_MIN - mode->width); + __v4l2_ctrl_s_ctrl(imx219->hblank, hblank); } return 0;