xref: /linux/drivers/media/v4l2-core/v4l2-common.c (revision 07fdad3a93756b872da7b53647715c48d0f4a2d0)
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/clk.h>
38 #include <linux/clkdev.h>
39 #include <linux/clk-provider.h>
40 #include <linux/module.h>
41 #include <linux/types.h>
42 #include <linux/kernel.h>
43 #include <linux/mm.h>
44 #include <linux/string.h>
45 #include <linux/errno.h>
46 #include <linux/uaccess.h>
47 #include <asm/io.h>
48 #include <asm/div64.h>
49 #include <media/v4l2-common.h>
50 #include <media/v4l2-device.h>
51 #include <media/v4l2-ctrls.h>
52 
53 #include <linux/videodev2.h>
54 
55 /*
56  *
57  *	V 4 L 2   D R I V E R   H E L P E R   A P I
58  *
59  */
60 
61 /*
62  *  Video Standard Operations (contributed by Michael Schimek)
63  */
64 
65 /* Helper functions for control handling			     */
66 
67 /* Fill in a struct v4l2_queryctrl */
68 int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 _min, s32 _max, s32 _step, s32 _def)
69 {
70 	const char *name;
71 	s64 min = _min;
72 	s64 max = _max;
73 	u64 step = _step;
74 	s64 def = _def;
75 
76 	v4l2_ctrl_fill(qctrl->id, &name, &qctrl->type,
77 		       &min, &max, &step, &def, &qctrl->flags);
78 
79 	if (name == NULL)
80 		return -EINVAL;
81 
82 	qctrl->minimum = min;
83 	qctrl->maximum = max;
84 	qctrl->step = step;
85 	qctrl->default_value = def;
86 	qctrl->reserved[0] = qctrl->reserved[1] = 0;
87 	strscpy(qctrl->name, name, sizeof(qctrl->name));
88 	return 0;
89 }
90 EXPORT_SYMBOL(v4l2_ctrl_query_fill);
91 
92 /* Clamp x to be between min and max, aligned to a multiple of 2^align.  min
93  * and max don't have to be aligned, but there must be at least one valid
94  * value.  E.g., min=17,max=31,align=4 is not allowed as there are no multiples
95  * of 16 between 17 and 31.  */
96 static unsigned int clamp_align(unsigned int x, unsigned int min,
97 				unsigned int max, unsigned int align)
98 {
99 	/* Bits that must be zero to be aligned */
100 	unsigned int mask = ~((1 << align) - 1);
101 
102 	/* Clamp to aligned min and max */
103 	x = clamp(x, (min + ~mask) & mask, max & mask);
104 
105 	/* Round to nearest aligned value */
106 	if (align)
107 		x = (x + (1 << (align - 1))) & mask;
108 
109 	return x;
110 }
111 
112 static unsigned int clamp_roundup(unsigned int x, unsigned int min,
113 				   unsigned int max, unsigned int alignment)
114 {
115 	x = clamp(x, min, max);
116 	if (alignment)
117 		x = round_up(x, alignment);
118 
119 	return x;
120 }
121 
122 void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
123 			   unsigned int walign,
124 			   u32 *h, unsigned int hmin, unsigned int hmax,
125 			   unsigned int halign, unsigned int salign)
126 {
127 	*w = clamp_align(*w, wmin, wmax, walign);
128 	*h = clamp_align(*h, hmin, hmax, halign);
129 
130 	/* Usually we don't need to align the size and are done now. */
131 	if (!salign)
132 		return;
133 
134 	/* How much alignment do we have? */
135 	walign = __ffs(*w);
136 	halign = __ffs(*h);
137 	/* Enough to satisfy the image alignment? */
138 	if (walign + halign < salign) {
139 		/* Max walign where there is still a valid width */
140 		unsigned int wmaxa = __fls(wmax ^ (wmin - 1));
141 		/* Max halign where there is still a valid height */
142 		unsigned int hmaxa = __fls(hmax ^ (hmin - 1));
143 
144 		/* up the smaller alignment until we have enough */
145 		do {
146 			if (halign >= hmaxa ||
147 			    (walign <= halign && walign < wmaxa)) {
148 				*w = clamp_align(*w, wmin, wmax, walign + 1);
149 				walign = __ffs(*w);
150 			} else {
151 				*h = clamp_align(*h, hmin, hmax, halign + 1);
152 				halign = __ffs(*h);
153 			}
154 		} while (halign + walign < salign);
155 	}
156 }
157 EXPORT_SYMBOL_GPL(v4l_bound_align_image);
158 
159 const void *
160 __v4l2_find_nearest_size_conditional(const void *array, size_t array_size,
161 				     size_t entry_size, size_t width_offset,
162 				     size_t height_offset, s32 width,
163 				     s32 height,
164 				     bool (*func)(const void *array,
165 						  size_t index,
166 						  const void *context),
167 				     const void *context)
168 {
169 	u32 error, min_error = U32_MAX;
170 	const void *best = NULL;
171 	size_t i;
172 
173 	if (!array)
174 		return NULL;
175 
176 	for (i = 0; i < array_size; i++, array += entry_size) {
177 		const u32 *entry_width = array + width_offset;
178 		const u32 *entry_height = array + height_offset;
179 
180 		if (func && !func(array, i, context))
181 			continue;
182 
183 		error = abs(*entry_width - width) + abs(*entry_height - height);
184 		if (error > min_error)
185 			continue;
186 
187 		min_error = error;
188 		best = array;
189 		if (!error)
190 			break;
191 	}
192 
193 	return best;
194 }
195 EXPORT_SYMBOL_GPL(__v4l2_find_nearest_size_conditional);
196 
197 int v4l2_g_parm_cap(struct video_device *vdev,
198 		    struct v4l2_subdev *sd, struct v4l2_streamparm *a)
199 {
200 	struct v4l2_subdev_frame_interval ival = { 0 };
201 	int ret;
202 
203 	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
204 	    a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
205 		return -EINVAL;
206 
207 	if (vdev->device_caps & V4L2_CAP_READWRITE)
208 		a->parm.capture.readbuffers = 2;
209 	if (v4l2_subdev_has_op(sd, pad, get_frame_interval))
210 		a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
211 	ret = v4l2_subdev_call_state_active(sd, pad, get_frame_interval, &ival);
212 	if (!ret)
213 		a->parm.capture.timeperframe = ival.interval;
214 	return ret;
215 }
216 EXPORT_SYMBOL_GPL(v4l2_g_parm_cap);
217 
218 int v4l2_s_parm_cap(struct video_device *vdev,
219 		    struct v4l2_subdev *sd, struct v4l2_streamparm *a)
220 {
221 	struct v4l2_subdev_frame_interval ival = {
222 		.interval = a->parm.capture.timeperframe
223 	};
224 	int ret;
225 
226 	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
227 	    a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
228 		return -EINVAL;
229 
230 	memset(&a->parm, 0, sizeof(a->parm));
231 	if (vdev->device_caps & V4L2_CAP_READWRITE)
232 		a->parm.capture.readbuffers = 2;
233 	else
234 		a->parm.capture.readbuffers = 0;
235 
236 	if (v4l2_subdev_has_op(sd, pad, get_frame_interval))
237 		a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
238 	ret = v4l2_subdev_call_state_active(sd, pad, set_frame_interval, &ival);
239 	if (!ret)
240 		a->parm.capture.timeperframe = ival.interval;
241 	return ret;
242 }
243 EXPORT_SYMBOL_GPL(v4l2_s_parm_cap);
244 
245 const struct v4l2_format_info *v4l2_format_info(u32 format)
246 {
247 	static const struct v4l2_format_info formats[] = {
248 		/* RGB formats */
249 		{ .format = V4L2_PIX_FMT_BGR24,   .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
250 		{ .format = V4L2_PIX_FMT_RGB24,   .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
251 		{ .format = V4L2_PIX_FMT_HSV24,   .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
252 		{ .format = V4L2_PIX_FMT_BGR32,   .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
253 		{ .format = V4L2_PIX_FMT_XBGR32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
254 		{ .format = V4L2_PIX_FMT_BGRX32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
255 		{ .format = V4L2_PIX_FMT_RGB32,   .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
256 		{ .format = V4L2_PIX_FMT_XRGB32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
257 		{ .format = V4L2_PIX_FMT_RGBX32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
258 		{ .format = V4L2_PIX_FMT_HSV32,   .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
259 		{ .format = V4L2_PIX_FMT_ARGB32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
260 		{ .format = V4L2_PIX_FMT_RGBA32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
261 		{ .format = V4L2_PIX_FMT_ABGR32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
262 		{ .format = V4L2_PIX_FMT_BGRA32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
263 		{ .format = V4L2_PIX_FMT_RGB565,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
264 		{ .format = V4L2_PIX_FMT_RGB565X, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
265 		{ .format = V4L2_PIX_FMT_RGB555,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
266 		{ .format = V4L2_PIX_FMT_BGR666,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
267 		{ .format = V4L2_PIX_FMT_BGR48_12, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 6, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
268 		{ .format = V4L2_PIX_FMT_BGR48, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 6, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
269 		{ .format = V4L2_PIX_FMT_RGB48, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 6, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
270 		{ .format = V4L2_PIX_FMT_ABGR64_12, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 8, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
271 		{ .format = V4L2_PIX_FMT_RGBA1010102, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
272 		{ .format = V4L2_PIX_FMT_RGBX1010102, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
273 		{ .format = V4L2_PIX_FMT_ARGB2101010, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
274 
275 		/* YUV packed formats */
276 		{ .format = V4L2_PIX_FMT_YUYV,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
277 		{ .format = V4L2_PIX_FMT_YVYU,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
278 		{ .format = V4L2_PIX_FMT_UYVY,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
279 		{ .format = V4L2_PIX_FMT_VYUY,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
280 		{ .format = V4L2_PIX_FMT_Y210,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
281 		{ .format = V4L2_PIX_FMT_Y212,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
282 		{ .format = V4L2_PIX_FMT_Y216,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
283 		{ .format = V4L2_PIX_FMT_YUV48_12, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 6, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
284 		{ .format = V4L2_PIX_FMT_MT2110T, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 5, 10, 0, 0 }, .bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 2,
285 		  .block_w = { 16, 8, 0, 0 }, .block_h = { 32, 16, 0, 0 }},
286 		{ .format = V4L2_PIX_FMT_MT2110R, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 5, 10, 0, 0 }, .bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 2,
287 		  .block_w = { 16, 8, 0, 0 }, .block_h = { 32, 16, 0, 0 }},
288 
289 		/* YUV planar formats */
290 		{ .format = V4L2_PIX_FMT_NV12,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
291 		{ .format = V4L2_PIX_FMT_NV21,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
292 		{ .format = V4L2_PIX_FMT_NV15,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 5, 10, 0, 0 }, .bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 2 },
293 		{ .format = V4L2_PIX_FMT_NV16,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
294 		{ .format = V4L2_PIX_FMT_NV61,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
295 		{ .format = V4L2_PIX_FMT_NV20,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 5, 10, 0, 0 }, .bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 1 },
296 		{ .format = V4L2_PIX_FMT_NV24,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
297 		{ .format = V4L2_PIX_FMT_NV42,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
298 		{ .format = V4L2_PIX_FMT_P010,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
299 		{ .format = V4L2_PIX_FMT_P012,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
300 
301 		{ .format = V4L2_PIX_FMT_YUV410,  .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 4, .vdiv = 4 },
302 		{ .format = V4L2_PIX_FMT_YVU410,  .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 4, .vdiv = 4 },
303 		{ .format = V4L2_PIX_FMT_YUV411P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 4, .vdiv = 1 },
304 		{ .format = V4L2_PIX_FMT_YUV420,  .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
305 		{ .format = V4L2_PIX_FMT_YVU420,  .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
306 		{ .format = V4L2_PIX_FMT_YUV422P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
307 		{ .format = V4L2_PIX_FMT_GREY,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
308 
309 		/* Tiled YUV formats */
310 		{ .format = V4L2_PIX_FMT_NV12_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
311 		{ .format = V4L2_PIX_FMT_NV15_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 5, 10, 0, 0 }, .bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 2,
312 		  .block_w = { 4, 2, 0, 0 }, .block_h = { 1, 1, 0, 0 }},
313 		{ .format = V4L2_PIX_FMT_P010_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
314 
315 		/* YUV planar formats, non contiguous variant */
316 		{ .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
317 		{ .format = V4L2_PIX_FMT_YVU420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
318 		{ .format = V4L2_PIX_FMT_YUV422M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
319 		{ .format = V4L2_PIX_FMT_YVU422M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
320 		{ .format = V4L2_PIX_FMT_YUV444M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
321 		{ .format = V4L2_PIX_FMT_YVU444M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
322 
323 		{ .format = V4L2_PIX_FMT_NV12M,   .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
324 		{ .format = V4L2_PIX_FMT_NV21M,   .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
325 		{ .format = V4L2_PIX_FMT_NV16M,   .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
326 		{ .format = V4L2_PIX_FMT_NV61M,   .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
327 		{ .format = V4L2_PIX_FMT_P012M,   .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
328 
329 		/* Tiled YUV formats, non contiguous variant */
330 		{ .format = V4L2_PIX_FMT_NV12MT,        .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2,
331 		  .block_w = { 64, 32, 0, 0 },	.block_h = { 32, 16, 0, 0 }},
332 		{ .format = V4L2_PIX_FMT_NV12MT_16X16,  .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2,
333 		  .block_w = { 16,  8, 0, 0 },	.block_h = { 16,  8, 0, 0 }},
334 
335 		/* Bayer RGB formats */
336 		{ .format = V4L2_PIX_FMT_SBGGR8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
337 		{ .format = V4L2_PIX_FMT_SGBRG8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
338 		{ .format = V4L2_PIX_FMT_SGRBG8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
339 		{ .format = V4L2_PIX_FMT_SRGGB8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
340 		{ .format = V4L2_PIX_FMT_SBGGR10,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
341 		{ .format = V4L2_PIX_FMT_SGBRG10,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
342 		{ .format = V4L2_PIX_FMT_SGRBG10,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
343 		{ .format = V4L2_PIX_FMT_SRGGB10,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
344 		{ .format = V4L2_PIX_FMT_SBGGR10P,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 5, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
345 		{ .format = V4L2_PIX_FMT_SGBRG10P,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 5, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
346 		{ .format = V4L2_PIX_FMT_SGRBG10P,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 5, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
347 		{ .format = V4L2_PIX_FMT_SRGGB10P,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 5, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
348 		{ .format = V4L2_PIX_FMT_SBGGR10ALAW8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
349 		{ .format = V4L2_PIX_FMT_SGBRG10ALAW8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
350 		{ .format = V4L2_PIX_FMT_SGRBG10ALAW8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
351 		{ .format = V4L2_PIX_FMT_SRGGB10ALAW8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
352 		{ .format = V4L2_PIX_FMT_SBGGR10DPCM8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
353 		{ .format = V4L2_PIX_FMT_SGBRG10DPCM8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
354 		{ .format = V4L2_PIX_FMT_SGRBG10DPCM8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
355 		{ .format = V4L2_PIX_FMT_SRGGB10DPCM8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
356 		{ .format = V4L2_PIX_FMT_SBGGR12,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
357 		{ .format = V4L2_PIX_FMT_SGBRG12,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
358 		{ .format = V4L2_PIX_FMT_SGRBG12,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
359 		{ .format = V4L2_PIX_FMT_SRGGB12,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
360 		{ .format = V4L2_PIX_FMT_SBGGR12P,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 2, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
361 		{ .format = V4L2_PIX_FMT_SGBRG12P,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 2, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
362 		{ .format = V4L2_PIX_FMT_SGRBG12P,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 2, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
363 		{ .format = V4L2_PIX_FMT_SRGGB12P,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 2, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
364 		{ .format = V4L2_PIX_FMT_SBGGR14,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
365 		{ .format = V4L2_PIX_FMT_SGBRG14,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
366 		{ .format = V4L2_PIX_FMT_SGRBG14,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
367 		{ .format = V4L2_PIX_FMT_SRGGB14,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
368 		{ .format = V4L2_PIX_FMT_SBGGR14P,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 7, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
369 		{ .format = V4L2_PIX_FMT_SGBRG14P,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 7, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
370 		{ .format = V4L2_PIX_FMT_SGRBG14P,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 7, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
371 		{ .format = V4L2_PIX_FMT_SRGGB14P,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 7, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
372 		{ .format = V4L2_PIX_FMT_SBGGR16,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
373 		{ .format = V4L2_PIX_FMT_SGBRG16,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
374 		{ .format = V4L2_PIX_FMT_SGRBG16,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
375 		{ .format = V4L2_PIX_FMT_SRGGB16,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
376 
377 		/* Renesas Camera Data Receiver Unit formats, bayer order agnostic */
378 		{ .format = V4L2_PIX_FMT_RAW_CRU10,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 8, 0, 0, 0 }, .bpp_div = { 6, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
379 		{ .format = V4L2_PIX_FMT_RAW_CRU12,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 8, 0, 0, 0 }, .bpp_div = { 5, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
380 		{ .format = V4L2_PIX_FMT_RAW_CRU14,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 8, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
381 		{ .format = V4L2_PIX_FMT_RAW_CRU20,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 8, 0, 0, 0 }, .bpp_div = { 3, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
382 	};
383 	unsigned int i;
384 
385 	for (i = 0; i < ARRAY_SIZE(formats); ++i)
386 		if (formats[i].format == format)
387 			return &formats[i];
388 	return NULL;
389 }
390 EXPORT_SYMBOL(v4l2_format_info);
391 
392 static inline unsigned int v4l2_format_block_width(const struct v4l2_format_info *info, int plane)
393 {
394 	if (!info->block_w[plane])
395 		return 1;
396 	return info->block_w[plane];
397 }
398 
399 static inline unsigned int v4l2_format_block_height(const struct v4l2_format_info *info, int plane)
400 {
401 	if (!info->block_h[plane])
402 		return 1;
403 	return info->block_h[plane];
404 }
405 
406 static inline unsigned int v4l2_format_plane_stride(const struct v4l2_format_info *info, int plane,
407 						    unsigned int width)
408 {
409 	unsigned int hdiv = plane ? info->hdiv : 1;
410 	unsigned int aligned_width =
411 		ALIGN(width, v4l2_format_block_width(info, plane));
412 
413 	return DIV_ROUND_UP(aligned_width, hdiv) *
414 	       info->bpp[plane] / info->bpp_div[plane];
415 }
416 
417 static inline unsigned int v4l2_format_plane_height(const struct v4l2_format_info *info, int plane,
418 						    unsigned int height)
419 {
420 	unsigned int vdiv = plane ? info->vdiv : 1;
421 	unsigned int aligned_height =
422 		ALIGN(height, v4l2_format_block_height(info, plane));
423 
424 	return DIV_ROUND_UP(aligned_height, vdiv);
425 }
426 
427 static inline unsigned int v4l2_format_plane_size(const struct v4l2_format_info *info, int plane,
428 						  unsigned int width, unsigned int height)
429 {
430 	return v4l2_format_plane_stride(info, plane, width) *
431 	       v4l2_format_plane_height(info, plane, height);
432 }
433 
434 void v4l2_apply_frmsize_constraints(u32 *width, u32 *height,
435 				    const struct v4l2_frmsize_stepwise *frmsize)
436 {
437 	if (!frmsize)
438 		return;
439 
440 	/*
441 	 * Clamp width/height to meet min/max constraints and round it up to
442 	 * macroblock alignment.
443 	 */
444 	*width = clamp_roundup(*width, frmsize->min_width, frmsize->max_width,
445 			       frmsize->step_width);
446 	*height = clamp_roundup(*height, frmsize->min_height, frmsize->max_height,
447 				frmsize->step_height);
448 }
449 EXPORT_SYMBOL_GPL(v4l2_apply_frmsize_constraints);
450 
451 int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt,
452 			u32 pixelformat, u32 width, u32 height)
453 {
454 	const struct v4l2_format_info *info;
455 	struct v4l2_plane_pix_format *plane;
456 	int i;
457 
458 	info = v4l2_format_info(pixelformat);
459 	if (!info)
460 		return -EINVAL;
461 
462 	pixfmt->width = width;
463 	pixfmt->height = height;
464 	pixfmt->pixelformat = pixelformat;
465 	pixfmt->num_planes = info->mem_planes;
466 
467 	if (info->mem_planes == 1) {
468 		plane = &pixfmt->plane_fmt[0];
469 		plane->bytesperline = v4l2_format_plane_stride(info, 0, width);
470 		plane->sizeimage = 0;
471 
472 		for (i = 0; i < info->comp_planes; i++)
473 			plane->sizeimage +=
474 				v4l2_format_plane_size(info, i, width, height);
475 	} else {
476 		for (i = 0; i < info->comp_planes; i++) {
477 			plane = &pixfmt->plane_fmt[i];
478 			plane->bytesperline =
479 				v4l2_format_plane_stride(info, i, width);
480 			plane->sizeimage = plane->bytesperline *
481 				v4l2_format_plane_height(info, i, height);
482 		}
483 	}
484 	return 0;
485 }
486 EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt_mp);
487 
488 int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat,
489 		     u32 width, u32 height)
490 {
491 	const struct v4l2_format_info *info;
492 	int i;
493 
494 	info = v4l2_format_info(pixelformat);
495 	if (!info)
496 		return -EINVAL;
497 
498 	/* Single planar API cannot be used for multi plane formats. */
499 	if (info->mem_planes > 1)
500 		return -EINVAL;
501 
502 	pixfmt->width = width;
503 	pixfmt->height = height;
504 	pixfmt->pixelformat = pixelformat;
505 	pixfmt->bytesperline = v4l2_format_plane_stride(info, 0, width);
506 	pixfmt->sizeimage = 0;
507 
508 	for (i = 0; i < info->comp_planes; i++)
509 		pixfmt->sizeimage +=
510 			v4l2_format_plane_size(info, i, width, height);
511 	return 0;
512 }
513 EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt);
514 
515 #ifdef CONFIG_MEDIA_CONTROLLER
516 static s64 v4l2_get_link_freq_ctrl(struct v4l2_ctrl_handler *handler,
517 				   unsigned int mul, unsigned int div)
518 {
519 	struct v4l2_ctrl *ctrl;
520 	s64 freq;
521 
522 	ctrl = v4l2_ctrl_find(handler, V4L2_CID_LINK_FREQ);
523 	if (ctrl) {
524 		struct v4l2_querymenu qm = { .id = V4L2_CID_LINK_FREQ };
525 		int ret;
526 
527 		qm.index = v4l2_ctrl_g_ctrl(ctrl);
528 
529 		ret = v4l2_querymenu(handler, &qm);
530 		if (ret)
531 			return -ENOENT;
532 
533 		freq = qm.value;
534 	} else {
535 		if (!mul || !div)
536 			return -ENOENT;
537 
538 		ctrl = v4l2_ctrl_find(handler, V4L2_CID_PIXEL_RATE);
539 		if (!ctrl)
540 			return -ENOENT;
541 
542 		freq = div_u64(v4l2_ctrl_g_ctrl_int64(ctrl) * mul, div);
543 
544 		pr_warn_once("%s: Link frequency estimated using pixel rate: result might be inaccurate\n",
545 			     __func__);
546 		pr_warn_once("%s: Consider implementing support for V4L2_CID_LINK_FREQ in the transmitter driver\n",
547 			     __func__);
548 	}
549 
550 	return freq > 0 ? freq : -EINVAL;
551 }
552 
553 s64 v4l2_get_link_freq(const struct media_pad *pad, unsigned int mul,
554 		       unsigned int div)
555 {
556 	struct v4l2_mbus_config mbus_config = {};
557 	struct v4l2_subdev *sd;
558 	int ret;
559 
560 	sd = media_entity_to_v4l2_subdev(pad->entity);
561 	ret = v4l2_subdev_call(sd, pad, get_mbus_config, pad->index,
562 			       &mbus_config);
563 	if (ret < 0 && ret != -ENOIOCTLCMD)
564 		return ret;
565 
566 	if (mbus_config.link_freq)
567 		return mbus_config.link_freq;
568 
569 	/*
570 	 * Fall back to using the link frequency control if the media bus config
571 	 * doesn't provide a link frequency.
572 	 */
573 	return v4l2_get_link_freq_ctrl(sd->ctrl_handler, mul, div);
574 }
575 EXPORT_SYMBOL_GPL(v4l2_get_link_freq);
576 #endif
577 
578 /*
579  * Simplify a fraction using a simple continued fraction decomposition. The
580  * idea here is to convert fractions such as 333333/10000000 to 1/30 using
581  * 32 bit arithmetic only. The algorithm is not perfect and relies upon two
582  * arbitrary parameters to remove non-significative terms from the simple
583  * continued fraction decomposition. Using 8 and 333 for n_terms and threshold
584  * respectively seems to give nice results.
585  */
586 void v4l2_simplify_fraction(u32 *numerator, u32 *denominator,
587 		unsigned int n_terms, unsigned int threshold)
588 {
589 	u32 *an;
590 	u32 x, y, r;
591 	unsigned int i, n;
592 
593 	an = kmalloc_array(n_terms, sizeof(*an), GFP_KERNEL);
594 	if (an == NULL)
595 		return;
596 
597 	/*
598 	 * Convert the fraction to a simple continued fraction. See
599 	 * https://en.wikipedia.org/wiki/Continued_fraction
600 	 * Stop if the current term is bigger than or equal to the given
601 	 * threshold.
602 	 */
603 	x = *numerator;
604 	y = *denominator;
605 
606 	for (n = 0; n < n_terms && y != 0; ++n) {
607 		an[n] = x / y;
608 		if (an[n] >= threshold) {
609 			if (n < 2)
610 				n++;
611 			break;
612 		}
613 
614 		r = x - an[n] * y;
615 		x = y;
616 		y = r;
617 	}
618 
619 	/* Expand the simple continued fraction back to an integer fraction. */
620 	x = 0;
621 	y = 1;
622 
623 	for (i = n; i > 0; --i) {
624 		r = y;
625 		y = an[i-1] * y + x;
626 		x = r;
627 	}
628 
629 	*numerator = y;
630 	*denominator = x;
631 	kfree(an);
632 }
633 EXPORT_SYMBOL_GPL(v4l2_simplify_fraction);
634 
635 /*
636  * Convert a fraction to a frame interval in 100ns multiples. The idea here is
637  * to compute numerator / denominator * 10000000 using 32 bit fixed point
638  * arithmetic only.
639  */
640 u32 v4l2_fraction_to_interval(u32 numerator, u32 denominator)
641 {
642 	u32 multiplier;
643 
644 	/* Saturate the result if the operation would overflow. */
645 	if (denominator == 0 ||
646 	    numerator/denominator >= ((u32)-1)/10000000)
647 		return (u32)-1;
648 
649 	/*
650 	 * Divide both the denominator and the multiplier by two until
651 	 * numerator * multiplier doesn't overflow. If anyone knows a better
652 	 * algorithm please let me know.
653 	 */
654 	multiplier = 10000000;
655 	while (numerator > ((u32)-1)/multiplier) {
656 		multiplier /= 2;
657 		denominator /= 2;
658 	}
659 
660 	return denominator ? numerator * multiplier / denominator : 0;
661 }
662 EXPORT_SYMBOL_GPL(v4l2_fraction_to_interval);
663 
664 int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs,
665 			     unsigned int num_of_fw_link_freqs,
666 			     const s64 *driver_link_freqs,
667 			     unsigned int num_of_driver_link_freqs,
668 			     unsigned long *bitmap)
669 {
670 	unsigned int i;
671 
672 	*bitmap = 0;
673 
674 	if (!num_of_fw_link_freqs) {
675 		dev_err(dev, "no link frequencies in firmware\n");
676 		return -ENODATA;
677 	}
678 
679 	for (i = 0; i < num_of_fw_link_freqs; i++) {
680 		unsigned int j;
681 
682 		for (j = 0; j < num_of_driver_link_freqs; j++) {
683 			if (fw_link_freqs[i] != driver_link_freqs[j])
684 				continue;
685 
686 			dev_dbg(dev, "enabling link frequency %lld Hz\n",
687 				driver_link_freqs[j]);
688 			*bitmap |= BIT(j);
689 			break;
690 		}
691 	}
692 
693 	if (!*bitmap) {
694 		dev_err(dev, "no matching link frequencies found\n");
695 
696 		dev_dbg(dev, "specified in firmware:\n");
697 		for (i = 0; i < num_of_fw_link_freqs; i++)
698 			dev_dbg(dev, "\t%llu Hz\n", fw_link_freqs[i]);
699 
700 		dev_dbg(dev, "driver supported:\n");
701 		for (i = 0; i < num_of_driver_link_freqs; i++)
702 			dev_dbg(dev, "\t%lld Hz\n", driver_link_freqs[i]);
703 
704 		return -ENOENT;
705 	}
706 
707 	return 0;
708 }
709 EXPORT_SYMBOL_GPL(v4l2_link_freq_to_bitmap);
710 
711 struct clk *__devm_v4l2_sensor_clk_get(struct device *dev, const char *id,
712 				       bool legacy, bool fixed_rate,
713 				       unsigned long clk_rate)
714 {
715 	bool of_node = is_of_node(dev_fwnode(dev));
716 	const char *clk_id __free(kfree) = NULL;
717 	struct clk_hw *clk_hw;
718 	struct clk *clk;
719 	u32 rate = clk_rate;
720 	int ret = 0;
721 
722 	clk = devm_clk_get_optional(dev, id);
723 	if (IS_ERR(clk))
724 		return clk;
725 
726 	/*
727 	 * If the caller didn't request a fixed rate, retrieve it from the
728 	 * clock-frequency property. -EINVAL indicates the property is absent,
729 	 * and is not a failure. Other errors, or success with a clock-frequency
730 	 * value of 0, are hard failures.
731 	 */
732 	if (!fixed_rate || !clk_rate) {
733 		ret = device_property_read_u32(dev, "clock-frequency", &rate);
734 		if ((ret && ret != -EINVAL) || (!ret && !rate))
735 			return ERR_PTR(-EINVAL);
736 	}
737 
738 	if (clk) {
739 		/*
740 		 * On non-OF platforms, or when legacy behaviour is requested,
741 		 * set the clock rate if a rate has been specified by the caller
742 		 * or by the clock-frequency property.
743 		 */
744 		if (rate && (!of_node || legacy)) {
745 			ret = clk_set_rate(clk, rate);
746 			if (ret) {
747 				dev_err(dev, "Failed to set clock rate: %u\n",
748 					rate);
749 				return ERR_PTR(ret);
750 			}
751 		}
752 		return clk;
753 	}
754 
755 	/*
756 	 * Register a dummy fixed clock on non-OF platforms or when legacy
757 	 * behaviour is requested. This required the common clock framework.
758 	 */
759 	if (!IS_ENABLED(CONFIG_COMMON_CLK) || (of_node && !legacy))
760 		return ERR_PTR(-ENOENT);
761 
762 	/* We need a rate to create a clock. */
763 	if (ret)
764 		return ERR_PTR(ret == -EINVAL ? -EPROBE_DEFER : ret);
765 
766 	if (!id) {
767 		clk_id = kasprintf(GFP_KERNEL, "clk-%s", dev_name(dev));
768 		if (!clk_id)
769 			return ERR_PTR(-ENOMEM);
770 		id = clk_id;
771 	}
772 
773 	clk_hw = devm_clk_hw_register_fixed_rate(dev, id, NULL, 0, rate);
774 	if (IS_ERR(clk_hw))
775 		return ERR_CAST(clk_hw);
776 
777 	return clk_hw->clk;
778 }
779 EXPORT_SYMBOL_GPL(__devm_v4l2_sensor_clk_get);
780