124117ce8bfdd7a4e081d2d8838041eda2e86ed7
[openwrt/staging/blogic.git] /
1 From 055e3d70b0227e26d58b2efc4561eb21a3fbf640 Mon Sep 17 00:00:00 2001
2 From: Naushir Patuck <naush@raspberrypi.com>
3 Date: Tue, 8 Feb 2022 13:49:11 +0000
4 Subject: [PATCH] media: i2c: imx219: Scale the pixel clock rate for
5 the 640x480 mode
6
7 The 640x480 mode uses a special binning mode for high framerate operation where
8 the pixel rate is effectively doubled. Account for this when setting up the
9 pixel clock rate, and applying the vblank and exposure controls.
10
11 Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
12 ---
13 drivers/media/i2c/imx219.c | 33 ++++++++++++++++++++++++++-------
14 1 file changed, 26 insertions(+), 7 deletions(-)
15
16 --- a/drivers/media/i2c/imx219.c
17 +++ b/drivers/media/i2c/imx219.c
18 @@ -153,6 +153,9 @@ struct imx219_mode {
19
20 /* Default register values */
21 struct imx219_reg_list reg_list;
22 +
23 + /* Relative pixel clock rate factor for the mode. */
24 + unsigned int rate_factor;
25 };
26
27 /*
28 @@ -495,6 +498,7 @@ static const struct imx219_mode supporte
29 .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
30 .regs = mode_3280x2464_regs,
31 },
32 + .rate_factor = 1,
33 },
34 {
35 /* 1080P 30fps cropped */
36 @@ -511,6 +515,7 @@ static const struct imx219_mode supporte
37 .num_of_regs = ARRAY_SIZE(mode_1920_1080_regs),
38 .regs = mode_1920_1080_regs,
39 },
40 + .rate_factor = 1,
41 },
42 {
43 /* 2x2 binned 30fps mode */
44 @@ -527,6 +532,7 @@ static const struct imx219_mode supporte
45 .num_of_regs = ARRAY_SIZE(mode_1640_1232_regs),
46 .regs = mode_1640_1232_regs,
47 },
48 + .rate_factor = 1,
49 },
50 {
51 /* 640x480 30fps mode */
52 @@ -543,6 +549,11 @@ static const struct imx219_mode supporte
53 .num_of_regs = ARRAY_SIZE(mode_640_480_regs),
54 .regs = mode_640_480_regs,
55 },
56 + /*
57 + * This mode uses a special 2x2 binning that doubles the
58 + * the internal pixel clock rate.
59 + */
60 + .rate_factor = 2,
61 },
62 };
63
64 @@ -765,7 +776,8 @@ static int imx219_set_ctrl(struct v4l2_c
65 break;
66 case V4L2_CID_EXPOSURE:
67 ret = imx219_write_reg(imx219, IMX219_REG_EXPOSURE,
68 - IMX219_REG_VALUE_16BIT, ctrl->val);
69 + IMX219_REG_VALUE_16BIT,
70 + ctrl->val / imx219->mode->rate_factor);
71 break;
72 case V4L2_CID_DIGITAL_GAIN:
73 ret = imx219_write_reg(imx219, IMX219_REG_DIGITAL_GAIN,
74 @@ -785,7 +797,8 @@ static int imx219_set_ctrl(struct v4l2_c
75 case V4L2_CID_VBLANK:
76 ret = imx219_write_reg(imx219, IMX219_REG_VTS,
77 IMX219_REG_VALUE_16BIT,
78 - imx219->mode->height + ctrl->val);
79 + (imx219->mode->height + ctrl->val) /
80 + imx219->mode->rate_factor);
81 break;
82 case V4L2_CID_TEST_PATTERN_RED:
83 ret = imx219_write_reg(imx219, IMX219_REG_TESTP_RED,
84 @@ -957,7 +970,7 @@ static int imx219_set_pad_format(struct
85 struct imx219 *imx219 = to_imx219(sd);
86 const struct imx219_mode *mode;
87 struct v4l2_mbus_framefmt *framefmt;
88 - int exposure_max, exposure_def, hblank;
89 + int exposure_max, exposure_def, hblank, pixel_rate;
90 unsigned int i;
91
92 if (fmt->pad >= NUM_PADS)
93 @@ -1018,6 +1031,12 @@ static int imx219_set_pad_format(struct
94 hblank = IMX219_PPL_DEFAULT - mode->width;
95 __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank,
96 1, hblank);
97 +
98 + /* Scale the pixel rate based on the mode specific factor */
99 + pixel_rate =
100 + IMX219_PIXEL_RATE * imx219->mode->rate_factor;
101 + __v4l2_ctrl_modify_range(imx219->pixel_rate, pixel_rate,
102 + pixel_rate, 1, pixel_rate);
103 }
104 } else {
105 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
106 @@ -1362,7 +1381,7 @@ static int imx219_init_controls(struct i
107 struct v4l2_ctrl_handler *ctrl_hdlr;
108 unsigned int height = imx219->mode->height;
109 struct v4l2_fwnode_device_properties props;
110 - int exposure_max, exposure_def, hblank;
111 + int exposure_max, exposure_def, hblank, pixel_rate;
112 int i, ret;
113
114 ctrl_hdlr = &imx219->ctrl_handler;
115 @@ -1374,11 +1393,11 @@ static int imx219_init_controls(struct i
116 ctrl_hdlr->lock = &imx219->mutex;
117
118 /* By default, PIXEL_RATE is read only */
119 + pixel_rate = IMX219_PIXEL_RATE * imx219->mode->rate_factor;
120 imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
121 V4L2_CID_PIXEL_RATE,
122 - IMX219_PIXEL_RATE,
123 - IMX219_PIXEL_RATE, 1,
124 - IMX219_PIXEL_RATE);
125 + pixel_rate, pixel_rate,
126 + 1, pixel_rate);
127
128 imx219->link_freq =
129 v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx219_ctrl_ops,