1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *	Video for Linux Two
4  *
5  *	A generic video device interface for the LINUX operating system
6  *	using a set of device structures/vectors for low level operations.
7  *
8  *	This file replaces the videodev.c file that comes with the
9  *	regular kernel distribution.
10  *
11  * Author:	Bill Dirks <bill@thedirks.org>
12  *		based on code by Alan Cox, <alan@cymru.net>
13  */
14 
15 /*
16  * Video capture interface for Linux
17  *
18  *	A generic video device interface for the LINUX operating system
19  *	using a set of device structures/vectors for low level operations.
20  *
21  * Author:	Alan Cox, <alan@lxorguk.ukuu.org.uk>
22  *
23  * Fixes:
24  */
25 
26 /*
27  * Video4linux 1/2 integration by Justin Schoeman
28  * <justin@suntiger.ee.up.ac.za>
29  * 2.4 PROCFS support ported from 2.4 kernels by
30  *  Iñaki García Etxebarria <garetxe@euskalnet.net>
31  * Makefile fix by "W. Michael Petullo" <mike@flyn.org>
32  * 2.4 devfs support ported from 2.4 kernels by
33  *  Dan Merillat <dan@merillat.org>
34  * Added Gerd Knorrs v4l1 enhancements (Justin Schoeman)
35  */
36 
37 #include <linux/module.h>
38 #include <linux/types.h>
39 #include <linux/kernel.h>
40 #include <linux/mm.h>
41 #include <linux/string.h>
42 #include <linux/errno.h>
43 #include <linux/i2c.h>
44 #if defined(CONFIG_SPI)
45 #include <linux/spi/spi.h>
46 #endif
47 #include <linux/uaccess.h>
48 #include <asm/pgtable.h>
49 #include <asm/io.h>
50 #include <asm/div64.h>
51 #include <media/v4l2-common.h>
52 #include <media/v4l2-device.h>
53 #include <media/v4l2-ctrls.h>
54 
55 #include <linux/videodev2.h>
56 
57 MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
58 MODULE_DESCRIPTION("misc helper functions for v4l2 device drivers");
59 MODULE_LICENSE("GPL");
60 
61 /*
62  *
63  *	V 4 L 2   D R I V E R   H E L P E R   A P I
64  *
65  */
66 
67 /*
68  *  Video Standard Operations (contributed by Michael Schimek)
69  */
70 
71 /* Helper functions for control handling			     */
72 
73 /* Fill in a struct v4l2_queryctrl */
74 int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 _min, s32 _max, s32 _step, s32 _def)
75 {
76 	const char *name;
77 	s64 min = _min;
78 	s64 max = _max;
79 	u64 step = _step;
80 	s64 def = _def;
81 
82 	v4l2_ctrl_fill(qctrl->id, &name, &qctrl->type,
83 		       &min, &max, &step, &def, &qctrl->flags);
84 
85 	if (name == NULL)
86 		return -EINVAL;
87 
88 	qctrl->minimum = min;
89 	qctrl->maximum = max;
90 	qctrl->step = step;
91 	qctrl->default_value = def;
92 	qctrl->reserved[0] = qctrl->reserved[1] = 0;
93 	strscpy(qctrl->name, name, sizeof(qctrl->name));
94 	return 0;
95 }
96 EXPORT_SYMBOL(v4l2_ctrl_query_fill);
97 
98 /* I2C Helper functions */
99 
100 #if IS_ENABLED(CONFIG_I2C)
101 
102 void v4l2_i2c_subdev_set_name(struct v4l2_subdev *sd, struct i2c_client *client,
103 			      const char *devname, const char *postfix)
104 {
105 	if (!devname)
106 		devname = client->dev.driver->name;
107 	if (!postfix)
108 		postfix = "";
109 
110 	snprintf(sd->name, sizeof(sd->name), "%s%s %d-%04x", devname, postfix,
111 		 i2c_adapter_id(client->adapter), client->addr);
112 }
113 EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_set_name);
114 
115 void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
116 		const struct v4l2_subdev_ops *ops)
117 {
118 	v4l2_subdev_init(sd, ops);
119 	sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
120 	/* the owner is the same as the i2c_client's driver owner */
121 	sd->owner = client->dev.driver->owner;
122 	sd->dev = &client->dev;
123 	/* i2c_client and v4l2_subdev point to one another */
124 	v4l2_set_subdevdata(sd, client);
125 	i2c_set_clientdata(client, sd);
126 	v4l2_i2c_subdev_set_name(sd, client, NULL, NULL);
127 }
128 EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
129 
130 /* Load an i2c sub-device. */
131 struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
132 		struct i2c_adapter *adapter, struct i2c_board_info *info,
133 		const unsigned short *probe_addrs)
134 {
135 	struct v4l2_subdev *sd = NULL;
136 	struct i2c_client *client;
137 
138 	BUG_ON(!v4l2_dev);
139 
140 	request_module(I2C_MODULE_PREFIX "%s", info->type);
141 
142 	/* Create the i2c client */
143 	if (info->addr == 0 && probe_addrs)
144 		client = i2c_new_probed_device(adapter, info, probe_addrs,
145 					       NULL);
146 	else
147 		client = i2c_new_device(adapter, info);
148 
149 	/* Note: by loading the module first we are certain that c->driver
150 	   will be set if the driver was found. If the module was not loaded
151 	   first, then the i2c core tries to delay-load the module for us,
152 	   and then c->driver is still NULL until the module is finally
153 	   loaded. This delay-load mechanism doesn't work if other drivers
154 	   want to use the i2c device, so explicitly loading the module
155 	   is the best alternative. */
156 	if (client == NULL || client->dev.driver == NULL)
157 		goto error;
158 
159 	/* Lock the module so we can safely get the v4l2_subdev pointer */
160 	if (!try_module_get(client->dev.driver->owner))
161 		goto error;
162 	sd = i2c_get_clientdata(client);
163 
164 	/* Register with the v4l2_device which increases the module's
165 	   use count as well. */
166 	if (v4l2_device_register_subdev(v4l2_dev, sd))
167 		sd = NULL;
168 	/* Decrease the module use count to match the first try_module_get. */
169 	module_put(client->dev.driver->owner);
170 
171 error:
172 	/* If we have a client but no subdev, then something went wrong and
173 	   we must unregister the client. */
174 	if (client && sd == NULL)
175 		i2c_unregister_device(client);
176 	return sd;
177 }
178 EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board);
179 
180 struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
181 		struct i2c_adapter *adapter, const char *client_type,
182 		u8 addr, const unsigned short *probe_addrs)
183 {
184 	struct i2c_board_info info;
185 
186 	/* Setup the i2c board info with the device type and
187 	   the device address. */
188 	memset(&info, 0, sizeof(info));
189 	strscpy(info.type, client_type, sizeof(info.type));
190 	info.addr = addr;
191 
192 	return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, probe_addrs);
193 }
194 EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev);
195 
196 /* Return i2c client address of v4l2_subdev. */
197 unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd)
198 {
199 	struct i2c_client *client = v4l2_get_subdevdata(sd);
200 
201 	return client ? client->addr : I2C_CLIENT_END;
202 }
203 EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_addr);
204 
205 /* Return a list of I2C tuner addresses to probe. Use only if the tuner
206    addresses are unknown. */
207 const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
208 {
209 	static const unsigned short radio_addrs[] = {
210 #if IS_ENABLED(CONFIG_MEDIA_TUNER_TEA5761)
211 		0x10,
212 #endif
213 		0x60,
214 		I2C_CLIENT_END
215 	};
216 	static const unsigned short demod_addrs[] = {
217 		0x42, 0x43, 0x4a, 0x4b,
218 		I2C_CLIENT_END
219 	};
220 	static const unsigned short tv_addrs[] = {
221 		0x42, 0x43, 0x4a, 0x4b,		/* tda8290 */
222 		0x60, 0x61, 0x62, 0x63, 0x64,
223 		I2C_CLIENT_END
224 	};
225 
226 	switch (type) {
227 	case ADDRS_RADIO:
228 		return radio_addrs;
229 	case ADDRS_DEMOD:
230 		return demod_addrs;
231 	case ADDRS_TV:
232 		return tv_addrs;
233 	case ADDRS_TV_WITH_DEMOD:
234 		return tv_addrs + 4;
235 	}
236 	return NULL;
237 }
238 EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
239 
240 #endif /* defined(CONFIG_I2C) */
241 
242 #if defined(CONFIG_SPI)
243 
244 /* Load an spi sub-device. */
245 
246 void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
247 		const struct v4l2_subdev_ops *ops)
248 {
249 	v4l2_subdev_init(sd, ops);
250 	sd->flags |= V4L2_SUBDEV_FL_IS_SPI;
251 	/* the owner is the same as the spi_device's driver owner */
252 	sd->owner = spi->dev.driver->owner;
253 	sd->dev = &spi->dev;
254 	/* spi_device and v4l2_subdev point to one another */
255 	v4l2_set_subdevdata(sd, spi);
256 	spi_set_drvdata(spi, sd);
257 	/* initialize name */
258 	snprintf(sd->name, sizeof(sd->name), "%s %s",
259 		spi->dev.driver->name, dev_name(&spi->dev));
260 }
261 EXPORT_SYMBOL_GPL(v4l2_spi_subdev_init);
262 
263 struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev,
264 		struct spi_master *master, struct spi_board_info *info)
265 {
266 	struct v4l2_subdev *sd = NULL;
267 	struct spi_device *spi = NULL;
268 
269 	BUG_ON(!v4l2_dev);
270 
271 	if (info->modalias[0])
272 		request_module(info->modalias);
273 
274 	spi = spi_new_device(master, info);
275 
276 	if (spi == NULL || spi->dev.driver == NULL)
277 		goto error;
278 
279 	if (!try_module_get(spi->dev.driver->owner))
280 		goto error;
281 
282 	sd = spi_get_drvdata(spi);
283 
284 	/* Register with the v4l2_device which increases the module's
285 	   use count as well. */
286 	if (v4l2_device_register_subdev(v4l2_dev, sd))
287 		sd = NULL;
288 
289 	/* Decrease the module use count to match the first try_module_get. */
290 	module_put(spi->dev.driver->owner);
291 
292 error:
293 	/* If we have a client but no subdev, then something went wrong and
294 	   we must unregister the client. */
295 	if (!sd)
296 		spi_unregister_device(spi);
297 
298 	return sd;
299 }
300 EXPORT_SYMBOL_GPL(v4l2_spi_new_subdev);
301 
302 #endif /* defined(CONFIG_SPI) */
303 
304 /* Clamp x to be between min and max, aligned to a multiple of 2^align.  min
305  * and max don't have to be aligned, but there must be at least one valid
306  * value.  E.g., min=17,max=31,align=4 is not allowed as there are no multiples
307  * of 16 between 17 and 31.  */
308 static unsigned int clamp_align(unsigned int x, unsigned int min,
309 				unsigned int max, unsigned int align)
310 {
311 	/* Bits that must be zero to be aligned */
312 	unsigned int mask = ~((1 << align) - 1);
313 
314 	/* Clamp to aligned min and max */
315 	x = clamp(x, (min + ~mask) & mask, max & mask);
316 
317 	/* Round to nearest aligned value */
318 	if (align)
319 		x = (x + (1 << (align - 1))) & mask;
320 
321 	return x;
322 }
323 
324 static unsigned int clamp_roundup(unsigned int x, unsigned int min,
325 				   unsigned int max, unsigned int alignment)
326 {
327 	x = clamp(x, min, max);
328 	if (alignment)
329 		x = round_up(x, alignment);
330 
331 	return x;
332 }
333 
334 void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
335 			   unsigned int walign,
336 			   u32 *h, unsigned int hmin, unsigned int hmax,
337 			   unsigned int halign, unsigned int salign)
338 {
339 	*w = clamp_align(*w, wmin, wmax, walign);
340 	*h = clamp_align(*h, hmin, hmax, halign);
341 
342 	/* Usually we don't need to align the size and are done now. */
343 	if (!salign)
344 		return;
345 
346 	/* How much alignment do we have? */
347 	walign = __ffs(*w);
348 	halign = __ffs(*h);
349 	/* Enough to satisfy the image alignment? */
350 	if (walign + halign < salign) {
351 		/* Max walign where there is still a valid width */
352 		unsigned int wmaxa = __fls(wmax ^ (wmin - 1));
353 		/* Max halign where there is still a valid height */
354 		unsigned int hmaxa = __fls(hmax ^ (hmin - 1));
355 
356 		/* up the smaller alignment until we have enough */
357 		do {
358 			if (halign >= hmaxa ||
359 			    (walign <= halign && walign < wmaxa)) {
360 				*w = clamp_align(*w, wmin, wmax, walign + 1);
361 				walign = __ffs(*w);
362 			} else {
363 				*h = clamp_align(*h, hmin, hmax, halign + 1);
364 				halign = __ffs(*h);
365 			}
366 		} while (halign + walign < salign);
367 	}
368 }
369 EXPORT_SYMBOL_GPL(v4l_bound_align_image);
370 
371 const void *
372 __v4l2_find_nearest_size(const void *array, size_t array_size,
373 			 size_t entry_size, size_t width_offset,
374 			 size_t height_offset, s32 width, s32 height)
375 {
376 	u32 error, min_error = U32_MAX;
377 	const void *best = NULL;
378 	unsigned int i;
379 
380 	if (!array)
381 		return NULL;
382 
383 	for (i = 0; i < array_size; i++, array += entry_size) {
384 		const u32 *entry_width = array + width_offset;
385 		const u32 *entry_height = array + height_offset;
386 
387 		error = abs(*entry_width - width) + abs(*entry_height - height);
388 		if (error > min_error)
389 			continue;
390 
391 		min_error = error;
392 		best = array;
393 		if (!error)
394 			break;
395 	}
396 
397 	return best;
398 }
399 EXPORT_SYMBOL_GPL(__v4l2_find_nearest_size);
400 
401 int v4l2_g_parm_cap(struct video_device *vdev,
402 		    struct v4l2_subdev *sd, struct v4l2_streamparm *a)
403 {
404 	struct v4l2_subdev_frame_interval ival = { 0 };
405 	int ret;
406 
407 	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
408 	    a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
409 		return -EINVAL;
410 
411 	if (vdev->device_caps & V4L2_CAP_READWRITE)
412 		a->parm.capture.readbuffers = 2;
413 	if (v4l2_subdev_has_op(sd, video, g_frame_interval))
414 		a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
415 	ret = v4l2_subdev_call(sd, video, g_frame_interval, &ival);
416 	if (!ret)
417 		a->parm.capture.timeperframe = ival.interval;
418 	return ret;
419 }
420 EXPORT_SYMBOL_GPL(v4l2_g_parm_cap);
421 
422 int v4l2_s_parm_cap(struct video_device *vdev,
423 		    struct v4l2_subdev *sd, struct v4l2_streamparm *a)
424 {
425 	struct v4l2_subdev_frame_interval ival = {
426 		.interval = a->parm.capture.timeperframe
427 	};
428 	int ret;
429 
430 	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
431 	    a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
432 		return -EINVAL;
433 
434 	memset(&a->parm, 0, sizeof(a->parm));
435 	if (vdev->device_caps & V4L2_CAP_READWRITE)
436 		a->parm.capture.readbuffers = 2;
437 	else
438 		a->parm.capture.readbuffers = 0;
439 
440 	if (v4l2_subdev_has_op(sd, video, g_frame_interval))
441 		a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
442 	ret = v4l2_subdev_call(sd, video, s_frame_interval, &ival);
443 	if (!ret)
444 		a->parm.capture.timeperframe = ival.interval;
445 	return ret;
446 }
447 EXPORT_SYMBOL_GPL(v4l2_s_parm_cap);
448 
449 const struct v4l2_format_info *v4l2_format_info(u32 format)
450 {
451 	static const struct v4l2_format_info formats[] = {
452 		/* RGB formats */
453 		{ .format = V4L2_PIX_FMT_BGR24,   .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
454 		{ .format = V4L2_PIX_FMT_RGB24,   .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
455 		{ .format = V4L2_PIX_FMT_HSV24,   .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
456 		{ .format = V4L2_PIX_FMT_BGR32,   .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
457 		{ .format = V4L2_PIX_FMT_XBGR32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
458 		{ .format = V4L2_PIX_FMT_RGB32,   .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
459 		{ .format = V4L2_PIX_FMT_XRGB32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
460 		{ .format = V4L2_PIX_FMT_HSV32,   .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
461 		{ .format = V4L2_PIX_FMT_ARGB32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
462 		{ .format = V4L2_PIX_FMT_ABGR32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
463 		{ .format = V4L2_PIX_FMT_GREY,    .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
464 
465 		/* YUV packed formats */
466 		{ .format = V4L2_PIX_FMT_YUYV,    .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
467 		{ .format = V4L2_PIX_FMT_YVYU,    .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
468 		{ .format = V4L2_PIX_FMT_UYVY,    .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
469 		{ .format = V4L2_PIX_FMT_VYUY,    .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
470 
471 		/* YUV planar formats */
472 		{ .format = V4L2_PIX_FMT_NV12,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
473 		{ .format = V4L2_PIX_FMT_NV21,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
474 		{ .format = V4L2_PIX_FMT_NV16,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
475 		{ .format = V4L2_PIX_FMT_NV61,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
476 		{ .format = V4L2_PIX_FMT_NV24,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 },
477 		{ .format = V4L2_PIX_FMT_NV42,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 },
478 
479 		{ .format = V4L2_PIX_FMT_YUV410,  .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 },
480 		{ .format = V4L2_PIX_FMT_YVU410,  .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 },
481 		{ .format = V4L2_PIX_FMT_YUV411P, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 1 },
482 		{ .format = V4L2_PIX_FMT_YUV420,  .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
483 		{ .format = V4L2_PIX_FMT_YVU420,  .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
484 		{ .format = V4L2_PIX_FMT_YUV422P, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
485 
486 		/* YUV planar formats, non contiguous variant */
487 		{ .format = V4L2_PIX_FMT_YUV420M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
488 		{ .format = V4L2_PIX_FMT_YVU420M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
489 		{ .format = V4L2_PIX_FMT_YUV422M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
490 		{ .format = V4L2_PIX_FMT_YVU422M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
491 		{ .format = V4L2_PIX_FMT_YUV444M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 },
492 		{ .format = V4L2_PIX_FMT_YVU444M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 },
493 
494 		{ .format = V4L2_PIX_FMT_NV12M,   .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
495 		{ .format = V4L2_PIX_FMT_NV21M,   .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
496 		{ .format = V4L2_PIX_FMT_NV16M,   .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
497 		{ .format = V4L2_PIX_FMT_NV61M,   .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
498 
499 		/* Bayer RGB formats */
500 		{ .format = V4L2_PIX_FMT_SBGGR8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
501 		{ .format = V4L2_PIX_FMT_SGBRG8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
502 		{ .format = V4L2_PIX_FMT_SGRBG8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
503 		{ .format = V4L2_PIX_FMT_SRGGB8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
504 		{ .format = V4L2_PIX_FMT_SBGGR10,	.mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
505 		{ .format = V4L2_PIX_FMT_SGBRG10,	.mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
506 		{ .format = V4L2_PIX_FMT_SGRBG10,	.mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
507 		{ .format = V4L2_PIX_FMT_SRGGB10,	.mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
508 		{ .format = V4L2_PIX_FMT_SBGGR10ALAW8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
509 		{ .format = V4L2_PIX_FMT_SGBRG10ALAW8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
510 		{ .format = V4L2_PIX_FMT_SGRBG10ALAW8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
511 		{ .format = V4L2_PIX_FMT_SRGGB10ALAW8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
512 		{ .format = V4L2_PIX_FMT_SBGGR10DPCM8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
513 		{ .format = V4L2_PIX_FMT_SGBRG10DPCM8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
514 		{ .format = V4L2_PIX_FMT_SGRBG10DPCM8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
515 		{ .format = V4L2_PIX_FMT_SRGGB10DPCM8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
516 		{ .format = V4L2_PIX_FMT_SBGGR12,	.mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
517 		{ .format = V4L2_PIX_FMT_SGBRG12,	.mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
518 		{ .format = V4L2_PIX_FMT_SGRBG12,	.mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
519 		{ .format = V4L2_PIX_FMT_SRGGB12,	.mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
520 	};
521 	unsigned int i;
522 
523 	for (i = 0; i < ARRAY_SIZE(formats); ++i)
524 		if (formats[i].format == format)
525 			return &formats[i];
526 	return NULL;
527 }
528 EXPORT_SYMBOL(v4l2_format_info);
529 
530 static inline unsigned int v4l2_format_block_width(const struct v4l2_format_info *info, int plane)
531 {
532 	if (!info->block_w[plane])
533 		return 1;
534 	return info->block_w[plane];
535 }
536 
537 static inline unsigned int v4l2_format_block_height(const struct v4l2_format_info *info, int plane)
538 {
539 	if (!info->block_h[plane])
540 		return 1;
541 	return info->block_h[plane];
542 }
543 
544 void v4l2_apply_frmsize_constraints(u32 *width, u32 *height,
545 				    const struct v4l2_frmsize_stepwise *frmsize)
546 {
547 	if (!frmsize)
548 		return;
549 
550 	/*
551 	 * Clamp width/height to meet min/max constraints and round it up to
552 	 * macroblock alignment.
553 	 */
554 	*width = clamp_roundup(*width, frmsize->min_width, frmsize->max_width,
555 			       frmsize->step_width);
556 	*height = clamp_roundup(*height, frmsize->min_height, frmsize->max_height,
557 				frmsize->step_height);
558 }
559 EXPORT_SYMBOL_GPL(v4l2_apply_frmsize_constraints);
560 
561 int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt,
562 			u32 pixelformat, u32 width, u32 height)
563 {
564 	const struct v4l2_format_info *info;
565 	struct v4l2_plane_pix_format *plane;
566 	int i;
567 
568 	info = v4l2_format_info(pixelformat);
569 	if (!info)
570 		return -EINVAL;
571 
572 	pixfmt->width = width;
573 	pixfmt->height = height;
574 	pixfmt->pixelformat = pixelformat;
575 	pixfmt->num_planes = info->mem_planes;
576 
577 	if (info->mem_planes == 1) {
578 		plane = &pixfmt->plane_fmt[0];
579 		plane->bytesperline = ALIGN(width, v4l2_format_block_width(info, 0)) * info->bpp[0];
580 		plane->sizeimage = 0;
581 
582 		for (i = 0; i < info->comp_planes; i++) {
583 			unsigned int hdiv = (i == 0) ? 1 : info->hdiv;
584 			unsigned int vdiv = (i == 0) ? 1 : info->vdiv;
585 			unsigned int aligned_width;
586 			unsigned int aligned_height;
587 
588 			aligned_width = ALIGN(width, v4l2_format_block_width(info, i));
589 			aligned_height = ALIGN(height, v4l2_format_block_height(info, i));
590 
591 			plane->sizeimage += info->bpp[i] *
592 				DIV_ROUND_UP(aligned_width, hdiv) *
593 				DIV_ROUND_UP(aligned_height, vdiv);
594 		}
595 	} else {
596 		for (i = 0; i < info->comp_planes; i++) {
597 			unsigned int hdiv = (i == 0) ? 1 : info->hdiv;
598 			unsigned int vdiv = (i == 0) ? 1 : info->vdiv;
599 			unsigned int aligned_width;
600 			unsigned int aligned_height;
601 
602 			aligned_width = ALIGN(width, v4l2_format_block_width(info, i));
603 			aligned_height = ALIGN(height, v4l2_format_block_height(info, i));
604 
605 			plane = &pixfmt->plane_fmt[i];
606 			plane->bytesperline =
607 				info->bpp[i] * DIV_ROUND_UP(aligned_width, hdiv);
608 			plane->sizeimage =
609 				plane->bytesperline * DIV_ROUND_UP(aligned_height, vdiv);
610 		}
611 	}
612 	return 0;
613 }
614 EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt_mp);
615 
616 int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat,
617 		     u32 width, u32 height)
618 {
619 	const struct v4l2_format_info *info;
620 	int i;
621 
622 	info = v4l2_format_info(pixelformat);
623 	if (!info)
624 		return -EINVAL;
625 
626 	/* Single planar API cannot be used for multi plane formats. */
627 	if (info->mem_planes > 1)
628 		return -EINVAL;
629 
630 	pixfmt->width = width;
631 	pixfmt->height = height;
632 	pixfmt->pixelformat = pixelformat;
633 	pixfmt->bytesperline = ALIGN(width, v4l2_format_block_width(info, 0)) * info->bpp[0];
634 	pixfmt->sizeimage = 0;
635 
636 	for (i = 0; i < info->comp_planes; i++) {
637 		unsigned int hdiv = (i == 0) ? 1 : info->hdiv;
638 		unsigned int vdiv = (i == 0) ? 1 : info->vdiv;
639 		unsigned int aligned_width;
640 		unsigned int aligned_height;
641 
642 		aligned_width = ALIGN(width, v4l2_format_block_width(info, i));
643 		aligned_height = ALIGN(height, v4l2_format_block_height(info, i));
644 
645 		pixfmt->sizeimage += info->bpp[i] *
646 			DIV_ROUND_UP(aligned_width, hdiv) *
647 			DIV_ROUND_UP(aligned_height, vdiv);
648 	}
649 	return 0;
650 }
651 EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt);
652