mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-26 08:51:13 +00:00
106 lines
3.8 KiB
Diff
106 lines
3.8 KiB
Diff
|
From 9c3cf1138410254184dd863ab2177d1f8d6c652b Mon Sep 17 00:00:00 2001
|
||
|
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
||
|
Date: Fri, 10 Mar 2023 17:27:10 +0000
|
||
|
Subject: [PATCH] media: i2c: imx219: make HBLANK r/w to allow longer
|
||
|
exposures
|
||
|
|
||
|
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>
|
||
|
---
|
||
|
drivers/media/i2c/imx219.c | 37 ++++++++++++++++++++++++-------------
|
||
|
1 file changed, 24 insertions(+), 13 deletions(-)
|
||
|
|
||
|
--- a/drivers/media/i2c/imx219.c
|
||
|
+++ b/drivers/media/i2c/imx219.c
|
||
|
@@ -63,8 +63,10 @@
|
||
|
#define IMX219_FLL_STEP 1
|
||
|
#define IMX219_FLL_DEFAULT 0x0c98
|
||
|
|
||
|
-/* 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 0x0162
|
||
|
|
||
|
/* Exposure control */
|
||
|
#define IMX219_REG_EXPOSURE 0x015a
|
||
|
@@ -191,8 +193,6 @@ static const struct imx219_reg imx219_co
|
||
|
{0x479b, 0x0e},
|
||
|
|
||
|
/* Frame Bank Register Group "A" */
|
||
|
- {0x0162, 0x0d}, /* Line_Length_A */
|
||
|
- {0x0163, 0x78},
|
||
|
{0x0170, 0x01}, /* X_ODD_INC_A */
|
||
|
{0x0171, 0x01}, /* Y_ODD_INC_A */
|
||
|
|
||
|
@@ -679,6 +679,11 @@ static int imx219_set_ctrl(struct v4l2_c
|
||
|
IMX219_REG_VALUE_16BIT,
|
||
|
imx219->mode->height + ctrl->val);
|
||
|
break;
|
||
|
+ case V4L2_CID_HBLANK:
|
||
|
+ ret = imx219_write_reg(imx219, IMX219_REG_HTS,
|
||
|
+ IMX219_REG_VALUE_16BIT,
|
||
|
+ imx219->mode->width + ctrl->val);
|
||
|
+ break;
|
||
|
case V4L2_CID_TEST_PATTERN_RED:
|
||
|
ret = imx219_write_reg(imx219, IMX219_REG_TESTP_RED,
|
||
|
IMX219_REG_VALUE_16BIT, ctrl->val);
|
||
|
@@ -837,6 +842,8 @@ static int imx219_set_pad_format(struct
|
||
|
*framefmt = fmt->format;
|
||
|
} else if (imx219->mode != mode ||
|
||
|
imx219->fmt.code != fmt->format.code) {
|
||
|
+ u32 prev_hts = imx219->mode->width + imx219->hblank->val;
|
||
|
+
|
||
|
imx219->fmt = fmt->format;
|
||
|
imx219->mode = mode;
|
||
|
/* Update limits and set FPS to default */
|
||
|
@@ -854,13 +861,19 @@ static int imx219_set_pad_format(struct
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
mutex_unlock(&imx219->mutex);
|
||
|
@@ -1263,12 +1276,10 @@ static int imx219_init_controls(struct i
|
||
|
V4L2_CID_VBLANK, IMX219_VBLANK_MIN,
|
||
|
IMX219_VTS_MAX - height, 1,
|
||
|
imx219->mode->vts_def - height);
|
||
|
- hblank = IMX219_PPL_DEFAULT - imx219->mode->width;
|
||
|
+ hblank = IMX219_PPL_MIN - imx219->mode->width;
|
||
|
imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
|
||
|
V4L2_CID_HBLANK, hblank, hblank,
|
||
|
1, hblank);
|
||
|
- if (imx219->hblank)
|
||
|
- imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
|
||
|
exposure_max = imx219->mode->vts_def - 4;
|
||
|
exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
|
||
|
exposure_max : IMX219_EXPOSURE_DEFAULT;
|