]> git.ipfire.org Git - thirdparty/openwrt.git/blob
c0f75ee4b901484867ac28a8c94aa1d2e6a1ee0a
[thirdparty/openwrt.git] /
1 From caebe4fe817b5079723e21430590460fbc842123 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 0501/1085] 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 | 41 +++++++++++++++++++++++++++-----------
14 1 file changed, 29 insertions(+), 12 deletions(-)
15
16 --- a/drivers/media/i2c/imx219.c
17 +++ b/drivers/media/i2c/imx219.c
18 @@ -199,6 +199,9 @@ struct imx219_mode {
19
20 /* 2x2 binning is used */
21 bool binning;
22 +
23 + /* Relative pixel clock rate factor for the mode. */
24 + unsigned int rate_factor;
25 };
26
27 static const struct cci_reg_sequence imx219_common_regs[] = {
28 @@ -404,6 +407,7 @@ static const struct imx219_mode supporte
29 .regs = mode_3280x2464_regs,
30 },
31 .binning = false,
32 + .rate_factor = 1,
33 },
34 {
35 /* 1080P 30fps cropped */
36 @@ -421,6 +425,7 @@ static const struct imx219_mode supporte
37 .regs = mode_1920_1080_regs,
38 },
39 .binning = false,
40 + .rate_factor = 1,
41 },
42 {
43 /* 2x2 binned 30fps mode */
44 @@ -438,6 +443,7 @@ static const struct imx219_mode supporte
45 .regs = mode_1640_1232_regs,
46 },
47 .binning = true,
48 + .rate_factor = 1,
49 },
50 {
51 /* 640x480 30fps mode */
52 @@ -455,6 +461,11 @@ static const struct imx219_mode supporte
53 .regs = mode_640_480_regs,
54 },
55 .binning = true,
56 + /*
57 + * This mode uses a special 2x2 binning that doubles the
58 + * internal pixel clock rate.
59 + */
60 + .rate_factor = 2,
61 },
62 };
63
64 @@ -546,7 +557,7 @@ static int imx219_set_ctrl(struct v4l2_c
65 break;
66 case V4L2_CID_EXPOSURE:
67 cci_write(imx219->regmap, IMX219_REG_EXPOSURE,
68 - ctrl->val, &ret);
69 + ctrl->val / imx219->mode->rate_factor, &ret);
70 break;
71 case V4L2_CID_DIGITAL_GAIN:
72 cci_write(imx219->regmap, IMX219_REG_DIGITAL_GAIN,
73 @@ -563,7 +574,7 @@ static int imx219_set_ctrl(struct v4l2_c
74 break;
75 case V4L2_CID_VBLANK:
76 cci_write(imx219->regmap, IMX219_REG_VTS,
77 - imx219->mode->height + ctrl->val, &ret);
78 + (imx219->mode->height + ctrl->val) / imx219->mode->rate_factor, &ret);
79 break;
80 case V4L2_CID_HBLANK:
81 cci_write(imx219->regmap, IMX219_REG_HTS,
82 @@ -704,13 +715,19 @@ static int imx219_enum_frame_size(struct
83 return 0;
84 }
85
86 +static unsigned long imx219_get_pixel_rate(struct imx219 *imx219)
87 +{
88 + return ((imx219->lanes == 2) ? IMX219_PIXEL_RATE :
89 + IMX219_PIXEL_RATE_4LANE) * imx219->mode->rate_factor;
90 +}
91 +
92 static int imx219_set_pad_format(struct v4l2_subdev *sd,
93 struct v4l2_subdev_state *sd_state,
94 struct v4l2_subdev_format *fmt)
95 {
96 struct imx219 *imx219 = to_imx219(sd);
97 const struct imx219_mode *mode;
98 - int exposure_max, exposure_def, hblank;
99 + int exposure_max, exposure_def, hblank, pixel_rate;
100 struct v4l2_mbus_framefmt *format;
101 struct v4l2_rect *crop;
102
103 @@ -762,6 +779,11 @@ static int imx219_set_pad_format(struct
104 IMX219_PPL_MAX - mode->width,
105 1, IMX219_PPL_MIN - mode->width);
106 __v4l2_ctrl_s_ctrl(imx219->hblank, hblank);
107 +
108 + /* Scale the pixel rate based on the mode specific factor */
109 + pixel_rate = imx219_get_pixel_rate(imx219);
110 + __v4l2_ctrl_modify_range(imx219->pixel_rate, pixel_rate,
111 + pixel_rate, 1, pixel_rate);
112 }
113 } else {
114 format = v4l2_subdev_get_pad_format(sd, sd_state, 1);
115 @@ -1120,11 +1142,6 @@ static const struct v4l2_subdev_ops imx2
116 };
117
118
119 -static unsigned long imx219_get_pixel_rate(struct imx219 *imx219)
120 -{
121 - return (imx219->lanes == 2) ? IMX219_PIXEL_RATE : IMX219_PIXEL_RATE_4LANE;
122 -}
123 -
124 /* Initialize control handlers */
125 static int imx219_init_controls(struct imx219 *imx219)
126 {
127 @@ -1132,7 +1149,7 @@ static int imx219_init_controls(struct i
128 struct v4l2_ctrl_handler *ctrl_hdlr;
129 unsigned int height = imx219->mode->height;
130 struct v4l2_fwnode_device_properties props;
131 - int exposure_max, exposure_def, hblank;
132 + int exposure_max, exposure_def, hblank, pixel_rate;
133 int i, ret;
134
135 ctrl_hdlr = &imx219->ctrl_handler;
136 @@ -1141,11 +1158,11 @@ static int imx219_init_controls(struct i
137 return ret;
138
139 /* By default, PIXEL_RATE is read only */
140 + pixel_rate = imx219_get_pixel_rate(imx219);
141 imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
142 V4L2_CID_PIXEL_RATE,
143 - imx219_get_pixel_rate(imx219),
144 - imx219_get_pixel_rate(imx219), 1,
145 - imx219_get_pixel_rate(imx219));
146 + pixel_rate, pixel_rate, 1,
147 + pixel_rate);
148
149 imx219->link_freq =
150 v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx219_ctrl_ops,