hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/media/v4l2-core/v4l2-common.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Video for Linux Two
34 *
....@@ -7,14 +8,8 @@
78 * This file replaces the videodev.c file that comes with the
89 * regular kernel distribution.
910 *
10
- * This program is free software; you can redistribute it and/or
11
- * modify it under the terms of the GNU General Public License
12
- * as published by the Free Software Foundation; either version
13
- * 2 of the License, or (at your option) any later version.
14
- *
1511 * Author: Bill Dirks <bill@thedirks.org>
1612 * based on code by Alan Cox, <alan@cymru.net>
17
- *
1813 */
1914
2015 /*
....@@ -22,11 +17,6 @@
2217 *
2318 * A generic video device interface for the LINUX operating system
2419 * using a set of device structures/vectors for low level operations.
25
- *
26
- * This program is free software; you can redistribute it and/or
27
- * modify it under the terms of the GNU General Public License
28
- * as published by the Free Software Foundation; either version
29
- * 2 of the License, or (at your option) any later version.
3020 *
3121 * Author: Alan Cox, <alan@lxorguk.ukuu.org.uk>
3222 *
....@@ -50,12 +40,7 @@
5040 #include <linux/mm.h>
5141 #include <linux/string.h>
5242 #include <linux/errno.h>
53
-#include <linux/i2c.h>
54
-#if defined(CONFIG_SPI)
55
-#include <linux/spi/spi.h>
56
-#endif
5743 #include <linux/uaccess.h>
58
-#include <asm/pgtable.h>
5944 #include <asm/io.h>
6045 #include <asm/div64.h>
6146 #include <media/v4l2-common.h>
....@@ -63,10 +48,6 @@
6348 #include <media/v4l2-ctrls.h>
6449
6550 #include <linux/videodev2.h>
66
-
67
-MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
68
-MODULE_DESCRIPTION("misc helper functions for v4l2 device drivers");
69
-MODULE_LICENSE("GPL");
7051
7152 /*
7253 *
....@@ -100,205 +81,10 @@
10081 qctrl->step = step;
10182 qctrl->default_value = def;
10283 qctrl->reserved[0] = qctrl->reserved[1] = 0;
103
- strlcpy(qctrl->name, name, sizeof(qctrl->name));
84
+ strscpy(qctrl->name, name, sizeof(qctrl->name));
10485 return 0;
10586 }
10687 EXPORT_SYMBOL(v4l2_ctrl_query_fill);
107
-
108
-/* I2C Helper functions */
109
-
110
-#if IS_ENABLED(CONFIG_I2C)
111
-
112
-void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
113
- const struct v4l2_subdev_ops *ops)
114
-{
115
- v4l2_subdev_init(sd, ops);
116
- sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
117
- /* the owner is the same as the i2c_client's driver owner */
118
- sd->owner = client->dev.driver->owner;
119
- sd->dev = &client->dev;
120
- /* i2c_client and v4l2_subdev point to one another */
121
- v4l2_set_subdevdata(sd, client);
122
- i2c_set_clientdata(client, sd);
123
- /* initialize name */
124
- snprintf(sd->name, sizeof(sd->name), "%s %d-%04x",
125
- client->dev.driver->name, i2c_adapter_id(client->adapter),
126
- client->addr);
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
- strlcpy(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
- strlcpy(sd->name, spi->dev.driver->name, sizeof(sd->name));
259
-}
260
-EXPORT_SYMBOL_GPL(v4l2_spi_subdev_init);
261
-
262
-struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev,
263
- struct spi_master *master, struct spi_board_info *info)
264
-{
265
- struct v4l2_subdev *sd = NULL;
266
- struct spi_device *spi = NULL;
267
-
268
- BUG_ON(!v4l2_dev);
269
-
270
- if (info->modalias[0])
271
- request_module(info->modalias);
272
-
273
- spi = spi_new_device(master, info);
274
-
275
- if (spi == NULL || spi->dev.driver == NULL)
276
- goto error;
277
-
278
- if (!try_module_get(spi->dev.driver->owner))
279
- goto error;
280
-
281
- sd = spi_get_drvdata(spi);
282
-
283
- /* Register with the v4l2_device which increases the module's
284
- use count as well. */
285
- if (v4l2_device_register_subdev(v4l2_dev, sd))
286
- sd = NULL;
287
-
288
- /* Decrease the module use count to match the first try_module_get. */
289
- module_put(spi->dev.driver->owner);
290
-
291
-error:
292
- /* If we have a client but no subdev, then something went wrong and
293
- we must unregister the client. */
294
- if (!sd)
295
- spi_unregister_device(spi);
296
-
297
- return sd;
298
-}
299
-EXPORT_SYMBOL_GPL(v4l2_spi_new_subdev);
300
-
301
-#endif /* defined(CONFIG_SPI) */
30288
30389 /* Clamp x to be between min and max, aligned to a multiple of 2^align. min
30490 * and max don't have to be aligned, but there must be at least one valid
....@@ -316,6 +102,16 @@
316102 /* Round to nearest aligned value */
317103 if (align)
318104 x = (x + (1 << (align - 1))) & mask;
105
+
106
+ return x;
107
+}
108
+
109
+static unsigned int clamp_roundup(unsigned int x, unsigned int min,
110
+ unsigned int max, unsigned int alignment)
111
+{
112
+ x = clamp(x, min, max);
113
+ if (alignment)
114
+ x = round_up(x, alignment);
319115
320116 return x;
321117 }
....@@ -387,16 +183,6 @@
387183 }
388184 EXPORT_SYMBOL_GPL(__v4l2_find_nearest_size);
389185
390
-void v4l2_get_timestamp(struct timeval *tv)
391
-{
392
- struct timespec ts;
393
-
394
- ktime_get_ts(&ts);
395
- tv->tv_sec = ts.tv_sec;
396
- tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
397
-}
398
-EXPORT_SYMBOL_GPL(v4l2_get_timestamp);
399
-
400186 int v4l2_g_parm_cap(struct video_device *vdev,
401187 struct v4l2_subdev *sd, struct v4l2_streamparm *a)
402188 {
....@@ -444,3 +230,214 @@
444230 return ret;
445231 }
446232 EXPORT_SYMBOL_GPL(v4l2_s_parm_cap);
233
+
234
+const struct v4l2_format_info *v4l2_format_info(u32 format)
235
+{
236
+ static const struct v4l2_format_info formats[] = {
237
+ /* RGB formats */
238
+ { .format = V4L2_PIX_FMT_BGR24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
239
+ { .format = V4L2_PIX_FMT_RGB24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
240
+ { .format = V4L2_PIX_FMT_HSV24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
241
+ { .format = V4L2_PIX_FMT_BGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
242
+ { .format = V4L2_PIX_FMT_XBGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
243
+ { .format = V4L2_PIX_FMT_BGRX32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
244
+ { .format = V4L2_PIX_FMT_RGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
245
+ { .format = V4L2_PIX_FMT_XRGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
246
+ { .format = V4L2_PIX_FMT_RGBX32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
247
+ { .format = V4L2_PIX_FMT_HSV32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
248
+ { .format = V4L2_PIX_FMT_ARGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
249
+ { .format = V4L2_PIX_FMT_RGBA32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
250
+ { .format = V4L2_PIX_FMT_ABGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
251
+ { .format = V4L2_PIX_FMT_BGRA32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
252
+ { .format = V4L2_PIX_FMT_RGB565, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
253
+ { .format = V4L2_PIX_FMT_RGB555, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
254
+ { .format = V4L2_PIX_FMT_BGR666, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
255
+
256
+ /* YUV packed formats */
257
+ { .format = V4L2_PIX_FMT_YUYV, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
258
+ { .format = V4L2_PIX_FMT_YVYU, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
259
+ { .format = V4L2_PIX_FMT_UYVY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
260
+ { .format = V4L2_PIX_FMT_VYUY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
261
+
262
+ /* YUV planar formats */
263
+ { .format = V4L2_PIX_FMT_NV12, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
264
+ { .format = V4L2_PIX_FMT_NV21, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
265
+ { .format = V4L2_PIX_FMT_NV16, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
266
+ { .format = V4L2_PIX_FMT_NV61, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
267
+ { .format = V4L2_PIX_FMT_NV24, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 },
268
+ { .format = V4L2_PIX_FMT_NV42, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 },
269
+
270
+ { .format = V4L2_PIX_FMT_YUV410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 },
271
+ { .format = V4L2_PIX_FMT_YVU410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 },
272
+ { .format = V4L2_PIX_FMT_YUV411P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 1 },
273
+ { .format = V4L2_PIX_FMT_YUV420, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
274
+ { .format = V4L2_PIX_FMT_YVU420, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
275
+ { .format = V4L2_PIX_FMT_YUV422P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
276
+ { .format = V4L2_PIX_FMT_GREY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
277
+
278
+ /* YUV planar formats, non contiguous variant */
279
+ { .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
280
+ { .format = V4L2_PIX_FMT_YVU420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
281
+ { .format = V4L2_PIX_FMT_YUV422M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
282
+ { .format = V4L2_PIX_FMT_YVU422M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
283
+ { .format = V4L2_PIX_FMT_YUV444M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 },
284
+ { .format = V4L2_PIX_FMT_YVU444M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 },
285
+
286
+ { .format = V4L2_PIX_FMT_NV12M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
287
+ { .format = V4L2_PIX_FMT_NV21M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
288
+ { .format = V4L2_PIX_FMT_NV16M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
289
+ { .format = V4L2_PIX_FMT_NV61M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
290
+
291
+ /* Bayer RGB formats */
292
+ { .format = V4L2_PIX_FMT_SBGGR8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
293
+ { .format = V4L2_PIX_FMT_SGBRG8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
294
+ { .format = V4L2_PIX_FMT_SGRBG8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
295
+ { .format = V4L2_PIX_FMT_SRGGB8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
296
+ { .format = V4L2_PIX_FMT_SBGGR10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
297
+ { .format = V4L2_PIX_FMT_SGBRG10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
298
+ { .format = V4L2_PIX_FMT_SGRBG10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
299
+ { .format = V4L2_PIX_FMT_SRGGB10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
300
+ { .format = V4L2_PIX_FMT_SBGGR10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
301
+ { .format = V4L2_PIX_FMT_SGBRG10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
302
+ { .format = V4L2_PIX_FMT_SGRBG10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
303
+ { .format = V4L2_PIX_FMT_SRGGB10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
304
+ { .format = V4L2_PIX_FMT_SBGGR10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
305
+ { .format = V4L2_PIX_FMT_SGBRG10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
306
+ { .format = V4L2_PIX_FMT_SGRBG10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
307
+ { .format = V4L2_PIX_FMT_SRGGB10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
308
+ { .format = V4L2_PIX_FMT_SBGGR12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
309
+ { .format = V4L2_PIX_FMT_SGBRG12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
310
+ { .format = V4L2_PIX_FMT_SGRBG12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
311
+ { .format = V4L2_PIX_FMT_SRGGB12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
312
+ };
313
+ unsigned int i;
314
+
315
+ for (i = 0; i < ARRAY_SIZE(formats); ++i)
316
+ if (formats[i].format == format)
317
+ return &formats[i];
318
+ return NULL;
319
+}
320
+EXPORT_SYMBOL(v4l2_format_info);
321
+
322
+static inline unsigned int v4l2_format_block_width(const struct v4l2_format_info *info, int plane)
323
+{
324
+ if (!info->block_w[plane])
325
+ return 1;
326
+ return info->block_w[plane];
327
+}
328
+
329
+static inline unsigned int v4l2_format_block_height(const struct v4l2_format_info *info, int plane)
330
+{
331
+ if (!info->block_h[plane])
332
+ return 1;
333
+ return info->block_h[plane];
334
+}
335
+
336
+void v4l2_apply_frmsize_constraints(u32 *width, u32 *height,
337
+ const struct v4l2_frmsize_stepwise *frmsize)
338
+{
339
+ if (!frmsize)
340
+ return;
341
+
342
+ /*
343
+ * Clamp width/height to meet min/max constraints and round it up to
344
+ * macroblock alignment.
345
+ */
346
+ *width = clamp_roundup(*width, frmsize->min_width, frmsize->max_width,
347
+ frmsize->step_width);
348
+ *height = clamp_roundup(*height, frmsize->min_height, frmsize->max_height,
349
+ frmsize->step_height);
350
+}
351
+EXPORT_SYMBOL_GPL(v4l2_apply_frmsize_constraints);
352
+
353
+int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt,
354
+ u32 pixelformat, u32 width, u32 height)
355
+{
356
+ const struct v4l2_format_info *info;
357
+ struct v4l2_plane_pix_format *plane;
358
+ int i;
359
+
360
+ info = v4l2_format_info(pixelformat);
361
+ if (!info)
362
+ return -EINVAL;
363
+
364
+ pixfmt->width = width;
365
+ pixfmt->height = height;
366
+ pixfmt->pixelformat = pixelformat;
367
+ pixfmt->num_planes = info->mem_planes;
368
+
369
+ if (info->mem_planes == 1) {
370
+ plane = &pixfmt->plane_fmt[0];
371
+ plane->bytesperline = ALIGN(width, v4l2_format_block_width(info, 0)) * info->bpp[0];
372
+ plane->sizeimage = 0;
373
+
374
+ for (i = 0; i < info->comp_planes; i++) {
375
+ unsigned int hdiv = (i == 0) ? 1 : info->hdiv;
376
+ unsigned int vdiv = (i == 0) ? 1 : info->vdiv;
377
+ unsigned int aligned_width;
378
+ unsigned int aligned_height;
379
+
380
+ aligned_width = ALIGN(width, v4l2_format_block_width(info, i));
381
+ aligned_height = ALIGN(height, v4l2_format_block_height(info, i));
382
+
383
+ plane->sizeimage += info->bpp[i] *
384
+ DIV_ROUND_UP(aligned_width, hdiv) *
385
+ DIV_ROUND_UP(aligned_height, vdiv);
386
+ }
387
+ } else {
388
+ for (i = 0; i < info->comp_planes; i++) {
389
+ unsigned int hdiv = (i == 0) ? 1 : info->hdiv;
390
+ unsigned int vdiv = (i == 0) ? 1 : info->vdiv;
391
+ unsigned int aligned_width;
392
+ unsigned int aligned_height;
393
+
394
+ aligned_width = ALIGN(width, v4l2_format_block_width(info, i));
395
+ aligned_height = ALIGN(height, v4l2_format_block_height(info, i));
396
+
397
+ plane = &pixfmt->plane_fmt[i];
398
+ plane->bytesperline =
399
+ info->bpp[i] * DIV_ROUND_UP(aligned_width, hdiv);
400
+ plane->sizeimage =
401
+ plane->bytesperline * DIV_ROUND_UP(aligned_height, vdiv);
402
+ }
403
+ }
404
+ return 0;
405
+}
406
+EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt_mp);
407
+
408
+int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat,
409
+ u32 width, u32 height)
410
+{
411
+ const struct v4l2_format_info *info;
412
+ int i;
413
+
414
+ info = v4l2_format_info(pixelformat);
415
+ if (!info)
416
+ return -EINVAL;
417
+
418
+ /* Single planar API cannot be used for multi plane formats. */
419
+ if (info->mem_planes > 1)
420
+ return -EINVAL;
421
+
422
+ pixfmt->width = width;
423
+ pixfmt->height = height;
424
+ pixfmt->pixelformat = pixelformat;
425
+ pixfmt->bytesperline = ALIGN(width, v4l2_format_block_width(info, 0)) * info->bpp[0];
426
+ pixfmt->sizeimage = 0;
427
+
428
+ for (i = 0; i < info->comp_planes; i++) {
429
+ unsigned int hdiv = (i == 0) ? 1 : info->hdiv;
430
+ unsigned int vdiv = (i == 0) ? 1 : info->vdiv;
431
+ unsigned int aligned_width;
432
+ unsigned int aligned_height;
433
+
434
+ aligned_width = ALIGN(width, v4l2_format_block_width(info, i));
435
+ aligned_height = ALIGN(height, v4l2_format_block_height(info, i));
436
+
437
+ pixfmt->sizeimage += info->bpp[i] *
438
+ DIV_ROUND_UP(aligned_width, hdiv) *
439
+ DIV_ROUND_UP(aligned_height, vdiv);
440
+ }
441
+ return 0;
442
+}
443
+EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt);