304fd5097ff2ac07c175af5e16f17a7d2423bbe2
[openwrt/staging/neocturne.git] /
1 From fd31edb90963d91390b372153028fab79e7f060e Mon Sep 17 00:00:00 2001
2 From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
3 Date: Mon, 17 Oct 2022 12:44:27 +0200
4 Subject: [PATCH] media: i2c: imx290: Rename, extend and expand usage
5 of imx290_pixfmt
6
7 Upstream commit 10591fe63691
8
9 The imx290_pixfmt structure contains information about formats,
10 currently limited to the bpp value. Extend it with the register settings
11 for each format, and rename it to imx290_format_info to make its purpose
12 clearer. Add a function named imx290_format_info() to look up format
13 info for a media bus code, and use it through the code. This allows
14 dropping the imx290 bpp field as the value is now looked up dynamically.
15
16 The error handling in imx290_setup_format() can also be dropped, as the
17 format is guaranteed by imx290_set_fmt() to be valid.
18
19 Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
20 Acked-by: Alexander Stein <alexander.stein@ew.tq-group.com>
21 Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
22 Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
23 ---
24 drivers/media/i2c/imx290.c | 99 ++++++++++++++++++++++----------------
25 1 file changed, 58 insertions(+), 41 deletions(-)
26
27 --- a/drivers/media/i2c/imx290.c
28 +++ b/drivers/media/i2c/imx290.c
29 @@ -182,7 +182,6 @@ struct imx290 {
30 struct media_pad pad;
31
32 const struct imx290_mode *current_mode;
33 - u8 bpp;
34
35 struct regulator_bulk_data supplies[IMX290_NUM_SUPPLIES];
36 struct gpio_desc *rst_gpio;
37 @@ -414,16 +413,41 @@ static inline int imx290_modes_num(const
38 return ARRAY_SIZE(imx290_modes_4lanes);
39 }
40
41 -struct imx290_pixfmt {
42 +struct imx290_format_info {
43 u32 code;
44 u8 bpp;
45 + const struct imx290_regval *regs;
46 + unsigned int num_regs;
47 };
48
49 -static const struct imx290_pixfmt imx290_formats[] = {
50 - { MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
51 - { MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
52 +static const struct imx290_format_info imx290_formats[] = {
53 + {
54 + .code = MEDIA_BUS_FMT_SRGGB10_1X10,
55 + .bpp = 10,
56 + .regs = imx290_10bit_settings,
57 + .num_regs = ARRAY_SIZE(imx290_10bit_settings),
58 + }, {
59 + .code = MEDIA_BUS_FMT_SRGGB12_1X12,
60 + .bpp = 12,
61 + .regs = imx290_12bit_settings,
62 + .num_regs = ARRAY_SIZE(imx290_12bit_settings),
63 + }
64 };
65
66 +static const struct imx290_format_info *imx290_format_info(u32 code)
67 +{
68 + unsigned int i;
69 +
70 + for (i = 0; i < ARRAY_SIZE(imx290_formats); ++i) {
71 + const struct imx290_format_info *info = &imx290_formats[i];
72 +
73 + if (info->code == code)
74 + return info;
75 + }
76 +
77 + return NULL;
78 +}
79 +
80 /* -----------------------------------------------------------------------------
81 * Register access
82 */
83 @@ -516,40 +540,31 @@ static int imx290_set_data_lanes(struct
84 }
85
86 static int imx290_set_black_level(struct imx290 *imx290,
87 + const struct v4l2_mbus_framefmt *format,
88 unsigned int black_level, int *err)
89 {
90 + unsigned int bpp = imx290_format_info(format->code)->bpp;
91 +
92 return imx290_write(imx290, IMX290_BLKLEVEL,
93 - black_level >> (16 - imx290->bpp), err);
94 + black_level >> (16 - bpp), err);
95 }
96
97 static int imx290_setup_format(struct imx290 *imx290,
98 const struct v4l2_mbus_framefmt *format)
99 {
100 - const struct imx290_regval *regs;
101 - unsigned int num_regs;
102 + const struct imx290_format_info *info;
103 int ret;
104
105 - switch (format->code) {
106 - case MEDIA_BUS_FMT_SRGGB10_1X10:
107 - regs = imx290_10bit_settings;
108 - num_regs = ARRAY_SIZE(imx290_10bit_settings);
109 - break;
110 - case MEDIA_BUS_FMT_SRGGB12_1X12:
111 - regs = imx290_12bit_settings;
112 - num_regs = ARRAY_SIZE(imx290_12bit_settings);
113 - break;
114 - default:
115 - dev_err(imx290->dev, "Unknown pixel format\n");
116 - return -EINVAL;
117 - }
118 + info = imx290_format_info(format->code);
119
120 - ret = imx290_set_register_array(imx290, regs, num_regs);
121 + ret = imx290_set_register_array(imx290, info->regs, info->num_regs);
122 if (ret < 0) {
123 dev_err(imx290->dev, "Could not set format registers\n");
124 return ret;
125 }
126
127 - return imx290_set_black_level(imx290, IMX290_BLACK_LEVEL_DEFAULT, &ret);
128 + return imx290_set_black_level(imx290, format,
129 + IMX290_BLACK_LEVEL_DEFAULT, &ret);
130 }
131
132 /* ----------------------------------------------------------------------------
133 @@ -560,6 +575,8 @@ static int imx290_set_ctrl(struct v4l2_c
134 {
135 struct imx290 *imx290 = container_of(ctrl->handler,
136 struct imx290, ctrls);
137 + const struct v4l2_mbus_framefmt *format;
138 + struct v4l2_subdev_state *state;
139 int ret = 0;
140
141 /*
142 @@ -575,6 +592,9 @@ static int imx290_set_ctrl(struct v4l2_c
143 if (!pm_runtime_get_if_in_use(imx290->dev))
144 return 0;
145
146 + state = v4l2_subdev_get_locked_active_state(&imx290->sd);
147 + format = v4l2_subdev_get_pad_format(&imx290->sd, state, 0);
148 +
149 switch (ctrl->id) {
150 case V4L2_CID_ANALOGUE_GAIN:
151 ret = imx290_write(imx290, IMX290_GAIN, ctrl->val, NULL);
152 @@ -587,7 +607,7 @@ static int imx290_set_ctrl(struct v4l2_c
153
154 case V4L2_CID_TEST_PATTERN:
155 if (ctrl->val) {
156 - imx290_set_black_level(imx290, 0, &ret);
157 + imx290_set_black_level(imx290, format, 0, &ret);
158 usleep_range(10000, 11000);
159 imx290_write(imx290, IMX290_PGCTRL,
160 (u8)(IMX290_PGCTRL_REGEN |
161 @@ -596,8 +616,8 @@ static int imx290_set_ctrl(struct v4l2_c
162 } else {
163 imx290_write(imx290, IMX290_PGCTRL, 0x00, &ret);
164 usleep_range(10000, 11000);
165 - imx290_set_black_level(imx290, IMX290_BLACK_LEVEL_DEFAULT,
166 - &ret);
167 + imx290_set_black_level(imx290, format,
168 + IMX290_BLACK_LEVEL_DEFAULT, &ret);
169 }
170 break;
171
172 @@ -627,6 +647,7 @@ static const char * const imx290_test_pa
173 };
174
175 static void imx290_ctrl_update(struct imx290 *imx290,
176 + const struct v4l2_mbus_framefmt *format,
177 const struct imx290_mode *mode)
178 {
179 unsigned int hblank = mode->hmax - mode->width;
180 @@ -636,7 +657,7 @@ static void imx290_ctrl_update(struct im
181
182 /* pixel rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
183 pixel_rate = link_freq * 2 * imx290->nlanes;
184 - do_div(pixel_rate, imx290->bpp);
185 + do_div(pixel_rate, imx290_format_info(format->code)->bpp);
186
187 __v4l2_ctrl_s_ctrl(imx290->link_freq, mode->link_freq_index);
188 __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate, pixel_rate);
189 @@ -838,8 +859,7 @@ static int imx290_enum_frame_size(struct
190 const struct imx290 *imx290 = to_imx290(sd);
191 const struct imx290_mode *imx290_modes = imx290_modes_ptr(imx290);
192
193 - if ((fse->code != imx290_formats[0].code) &&
194 - (fse->code != imx290_formats[1].code))
195 + if (!imx290_format_info(fse->code))
196 return -EINVAL;
197
198 if (fse->index >= imx290_modes_num(imx290))
199 @@ -860,7 +880,6 @@ static int imx290_set_fmt(struct v4l2_su
200 struct imx290 *imx290 = to_imx290(sd);
201 const struct imx290_mode *mode;
202 struct v4l2_mbus_framefmt *format;
203 - unsigned int i;
204
205 mode = v4l2_find_nearest_size(imx290_modes_ptr(imx290),
206 imx290_modes_num(imx290), width, height,
207 @@ -869,23 +888,17 @@ static int imx290_set_fmt(struct v4l2_su
208 fmt->format.width = mode->width;
209 fmt->format.height = mode->height;
210
211 - for (i = 0; i < ARRAY_SIZE(imx290_formats); i++)
212 - if (imx290_formats[i].code == fmt->format.code)
213 - break;
214 + if (!imx290_format_info(fmt->format.code))
215 + fmt->format.code = imx290_formats[0].code;
216
217 - if (i >= ARRAY_SIZE(imx290_formats))
218 - i = 0;
219 -
220 - fmt->format.code = imx290_formats[i].code;
221 fmt->format.field = V4L2_FIELD_NONE;
222
223 format = v4l2_subdev_get_pad_format(sd, sd_state, 0);
224
225 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
226 imx290->current_mode = mode;
227 - imx290->bpp = imx290_formats[i].bpp;
228
229 - imx290_ctrl_update(imx290, mode);
230 + imx290_ctrl_update(imx290, &fmt->format, mode);
231 }
232
233 *format = fmt->format;
234 @@ -976,10 +989,11 @@ static const struct media_entity_operati
235 static int imx290_subdev_init(struct imx290 *imx290)
236 {
237 struct i2c_client *client = to_i2c_client(imx290->dev);
238 + const struct v4l2_mbus_framefmt *format;
239 + struct v4l2_subdev_state *state;
240 int ret;
241
242 imx290->current_mode = &imx290_modes_ptr(imx290)[0];
243 - imx290->bpp = imx290_formats[0].bpp;
244
245 v4l2_i2c_subdev_init(&imx290->sd, client, &imx290_subdev_ops);
246 imx290->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
247 @@ -1008,7 +1022,10 @@ static int imx290_subdev_init(struct imx
248 goto err_ctrls;
249 }
250
251 - imx290_ctrl_update(imx290, imx290->current_mode);
252 + state = v4l2_subdev_lock_and_get_active_state(&imx290->sd);
253 + format = v4l2_subdev_get_pad_format(&imx290->sd, state, 0);
254 + imx290_ctrl_update(imx290, format, imx290->current_mode);
255 + v4l2_subdev_unlock_state(state);
256
257 return 0;
258