dffae37774756f493c5a793f1521f0714c8dd380
[openwrt/staging/ansuel.git] /
1 From 9c3cf1138410254184dd863ab2177d1f8d6c652b Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Fri, 10 Mar 2023 17:27:10 +0000
4 Subject: [PATCH] media: i2c: imx219: make HBLANK r/w to allow longer
5 exposures
6
7 The HBLANK control was read-only, and always configured such
8 that the sensor HTS register was 3448. This limited the maximum
9 exposure time that could be achieved to around 1.26 secs.
10
11 Make HBLANK read/write so that the line time can be extended,
12 and thereby allow longer exposures (and slower frame rates).
13 Retain the overall HTS setting when changing modes rather than
14 resetting it to a default.
15
16 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
17 ---
18 drivers/media/i2c/imx219.c | 37 ++++++++++++++++++++++++-------------
19 1 file changed, 24 insertions(+), 13 deletions(-)
20
21 --- a/drivers/media/i2c/imx219.c
22 +++ b/drivers/media/i2c/imx219.c
23 @@ -63,8 +63,10 @@
24 #define IMX219_FLL_STEP 1
25 #define IMX219_FLL_DEFAULT 0x0c98
26
27 -/* HBLANK control - read only */
28 -#define IMX219_PPL_DEFAULT 3448
29 +/* HBLANK control range */
30 +#define IMX219_PPL_MIN 3448
31 +#define IMX219_PPL_MAX 0x7ff0
32 +#define IMX219_REG_HTS 0x0162
33
34 /* Exposure control */
35 #define IMX219_REG_EXPOSURE 0x015a
36 @@ -191,8 +193,6 @@ static const struct imx219_reg imx219_co
37 {0x479b, 0x0e},
38
39 /* Frame Bank Register Group "A" */
40 - {0x0162, 0x0d}, /* Line_Length_A */
41 - {0x0163, 0x78},
42 {0x0170, 0x01}, /* X_ODD_INC_A */
43 {0x0171, 0x01}, /* Y_ODD_INC_A */
44
45 @@ -679,6 +679,11 @@ static int imx219_set_ctrl(struct v4l2_c
46 IMX219_REG_VALUE_16BIT,
47 imx219->mode->height + ctrl->val);
48 break;
49 + case V4L2_CID_HBLANK:
50 + ret = imx219_write_reg(imx219, IMX219_REG_HTS,
51 + IMX219_REG_VALUE_16BIT,
52 + imx219->mode->width + ctrl->val);
53 + break;
54 case V4L2_CID_TEST_PATTERN_RED:
55 ret = imx219_write_reg(imx219, IMX219_REG_TESTP_RED,
56 IMX219_REG_VALUE_16BIT, ctrl->val);
57 @@ -837,6 +842,8 @@ static int imx219_set_pad_format(struct
58 *framefmt = fmt->format;
59 } else if (imx219->mode != mode ||
60 imx219->fmt.code != fmt->format.code) {
61 + u32 prev_hts = imx219->mode->width + imx219->hblank->val;
62 +
63 imx219->fmt = fmt->format;
64 imx219->mode = mode;
65 /* Update limits and set FPS to default */
66 @@ -854,13 +861,19 @@ static int imx219_set_pad_format(struct
67 exposure_max, imx219->exposure->step,
68 exposure_def);
69 /*
70 - * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank
71 - * depends on mode->width only, and is not changeble in any
72 - * way other than changing the mode.
73 + * Retain PPL setting from previous mode so that the
74 + * line time does not change on a mode change.
75 + * Limits have to be recomputed as the controls define
76 + * the blanking only, so PPL values need to have the
77 + * mode width subtracted.
78 */
79 - hblank = IMX219_PPL_DEFAULT - mode->width;
80 - __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1,
81 - hblank);
82 + hblank = prev_hts - mode->width;
83 + __v4l2_ctrl_modify_range(imx219->hblank,
84 + IMX219_PPL_MIN - mode->width,
85 + IMX219_PPL_MAX - mode->width,
86 + 1,
87 + IMX219_PPL_MIN - mode->width);
88 + __v4l2_ctrl_s_ctrl(imx219->hblank, hblank);
89 }
90
91 mutex_unlock(&imx219->mutex);
92 @@ -1263,12 +1276,10 @@ static int imx219_init_controls(struct i
93 V4L2_CID_VBLANK, IMX219_VBLANK_MIN,
94 IMX219_VTS_MAX - height, 1,
95 imx219->mode->vts_def - height);
96 - hblank = IMX219_PPL_DEFAULT - imx219->mode->width;
97 + hblank = IMX219_PPL_MIN - imx219->mode->width;
98 imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
99 V4L2_CID_HBLANK, hblank, hblank,
100 1, hblank);
101 - if (imx219->hblank)
102 - imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
103 exposure_max = imx219->mode->vts_def - 4;
104 exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
105 exposure_max : IMX219_EXPOSURE_DEFAULT;