1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47#include <linux/module.h>
48#include <linux/types.h>
49#include <linux/kernel.h>
50#include <linux/mm.h>
51#include <linux/string.h>
52#include <linux/errno.h>
53#include <linux/i2c.h>
54#if defined(CONFIG_SPI)
55#include <linux/spi/spi.h>
56#endif
57#include <asm/uaccess.h>
58#include <asm/pgtable.h>
59#include <asm/io.h>
60#include <asm/div64.h>
61#include <media/v4l2-common.h>
62#include <media/v4l2-device.h>
63#include <media/v4l2-ctrls.h>
64#include <media/v4l2-chip-ident.h>
65
66#include <linux/videodev2.h>
67
68MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
69MODULE_DESCRIPTION("misc helper functions for v4l2 device drivers");
70MODULE_LICENSE("GPL");
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
88 const char * const *menu_items)
89{
90 if (qctrl->flags & V4L2_CTRL_FLAG_DISABLED)
91 return -EINVAL;
92 if (qctrl->flags & V4L2_CTRL_FLAG_GRABBED)
93 return -EBUSY;
94 if (qctrl->type == V4L2_CTRL_TYPE_STRING)
95 return 0;
96 if (qctrl->type == V4L2_CTRL_TYPE_BUTTON ||
97 qctrl->type == V4L2_CTRL_TYPE_INTEGER64 ||
98 qctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
99 return 0;
100 if (ctrl->value < qctrl->minimum || ctrl->value > qctrl->maximum)
101 return -ERANGE;
102 if (qctrl->type == V4L2_CTRL_TYPE_MENU && menu_items != NULL) {
103 if (menu_items[ctrl->value] == NULL ||
104 menu_items[ctrl->value][0] == '\0')
105 return -EINVAL;
106 }
107 if (qctrl->type == V4L2_CTRL_TYPE_BITMASK &&
108 (ctrl->value & ~qctrl->maximum))
109 return -ERANGE;
110 return 0;
111}
112EXPORT_SYMBOL(v4l2_ctrl_check);
113
114
115int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
116{
117 const char *name;
118
119 v4l2_ctrl_fill(qctrl->id, &name, &qctrl->type,
120 &min, &max, &step, &def, &qctrl->flags);
121
122 if (name == NULL)
123 return -EINVAL;
124
125 qctrl->minimum = min;
126 qctrl->maximum = max;
127 qctrl->step = step;
128 qctrl->default_value = def;
129 qctrl->reserved[0] = qctrl->reserved[1] = 0;
130 strlcpy(qctrl->name, name, sizeof(qctrl->name));
131 return 0;
132}
133EXPORT_SYMBOL(v4l2_ctrl_query_fill);
134
135
136
137
138
139int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl,
140 const char * const *menu_items)
141{
142 int i;
143
144 qmenu->reserved = 0;
145 if (menu_items == NULL)
146 menu_items = v4l2_ctrl_get_menu(qmenu->id);
147 if (menu_items == NULL ||
148 (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum)))
149 return -EINVAL;
150 for (i = 0; i < qmenu->index && menu_items[i]; i++) ;
151 if (menu_items[i] == NULL || menu_items[i][0] == '\0')
152 return -EINVAL;
153 strlcpy(qmenu->name, menu_items[qmenu->index], sizeof(qmenu->name));
154 return 0;
155}
156EXPORT_SYMBOL(v4l2_ctrl_query_menu);
157
158
159
160
161int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *ids)
162{
163 const char * const *menu_items = v4l2_ctrl_get_menu(qmenu->id);
164
165 qmenu->reserved = 0;
166 if (menu_items == NULL || ids == NULL)
167 return -EINVAL;
168 while (*ids != V4L2_CTRL_MENU_IDS_END) {
169 if (*ids++ == qmenu->index) {
170 strlcpy(qmenu->name, menu_items[qmenu->index],
171 sizeof(qmenu->name));
172 return 0;
173 }
174 }
175 return -EINVAL;
176}
177EXPORT_SYMBOL(v4l2_ctrl_query_menu_valid_items);
178
179
180
181
182
183
184
185
186
187u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id)
188{
189 u32 ctrl_class = V4L2_CTRL_ID2CLASS(id);
190 const u32 *pctrl;
191
192 if (ctrl_classes == NULL)
193 return 0;
194
195
196 if ((id & V4L2_CTRL_FLAG_NEXT_CTRL) == 0) {
197
198 while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) != ctrl_class)
199 ctrl_classes++;
200 if (*ctrl_classes == NULL)
201 return 0;
202 pctrl = *ctrl_classes;
203
204 while (*pctrl && *pctrl != id) pctrl++;
205 return *pctrl ? id : 0;
206 }
207 id &= V4L2_CTRL_ID_MASK;
208 id++;
209
210
211 while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) < ctrl_class)
212 ctrl_classes++;
213
214 if (*ctrl_classes == NULL)
215 return 0;
216 pctrl = *ctrl_classes;
217
218 while (*pctrl && *pctrl < id) pctrl++;
219 if (*pctrl)
220 return *pctrl;
221
222
223 ctrl_classes++;
224 if (*ctrl_classes == NULL)
225 return 0;
226 return **ctrl_classes;
227}
228EXPORT_SYMBOL(v4l2_ctrl_next);
229
230int v4l2_chip_match_host(const struct v4l2_dbg_match *match)
231{
232 switch (match->type) {
233 case V4L2_CHIP_MATCH_HOST:
234 return match->addr == 0;
235 default:
236 return 0;
237 }
238}
239EXPORT_SYMBOL(v4l2_chip_match_host);
240
241#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
242int v4l2_chip_match_i2c_client(struct i2c_client *c, const struct v4l2_dbg_match *match)
243{
244 int len;
245
246 if (c == NULL || match == NULL)
247 return 0;
248
249 switch (match->type) {
250 case V4L2_CHIP_MATCH_I2C_DRIVER:
251 if (c->driver == NULL || c->driver->driver.name == NULL)
252 return 0;
253 len = strlen(c->driver->driver.name);
254
255 if (len && c->driver->driver.name[len - 1] == '\'')
256 len--;
257 return len && !strncmp(c->driver->driver.name, match->name, len);
258 case V4L2_CHIP_MATCH_I2C_ADDR:
259 return c->addr == match->addr;
260 default:
261 return 0;
262 }
263}
264EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
265
266int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_dbg_chip_ident *chip,
267 u32 ident, u32 revision)
268{
269 if (!v4l2_chip_match_i2c_client(c, &chip->match))
270 return 0;
271 if (chip->ident == V4L2_IDENT_NONE) {
272 chip->ident = ident;
273 chip->revision = revision;
274 }
275 else {
276 chip->ident = V4L2_IDENT_AMBIGUOUS;
277 chip->revision = 0;
278 }
279 return 0;
280}
281EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
282
283
284
285
286
287
288void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
289 const struct v4l2_subdev_ops *ops)
290{
291 v4l2_subdev_init(sd, ops);
292 sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
293
294 sd->owner = client->driver->driver.owner;
295
296 v4l2_set_subdevdata(sd, client);
297 i2c_set_clientdata(client, sd);
298
299 snprintf(sd->name, sizeof(sd->name), "%s %d-%04x",
300 client->driver->driver.name, i2c_adapter_id(client->adapter),
301 client->addr);
302}
303EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
304
305
306
307
308struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
309 struct i2c_adapter *adapter, struct i2c_board_info *info,
310 const unsigned short *probe_addrs)
311{
312 struct v4l2_subdev *sd = NULL;
313 struct i2c_client *client;
314
315 BUG_ON(!v4l2_dev);
316
317 request_module(I2C_MODULE_PREFIX "%s", info->type);
318
319
320 if (info->addr == 0 && probe_addrs)
321 client = i2c_new_probed_device(adapter, info, probe_addrs,
322 NULL);
323 else
324 client = i2c_new_device(adapter, info);
325
326
327
328
329
330
331
332
333 if (client == NULL || client->driver == NULL)
334 goto error;
335
336
337 if (!try_module_get(client->driver->driver.owner))
338 goto error;
339 sd = i2c_get_clientdata(client);
340
341
342
343 if (v4l2_device_register_subdev(v4l2_dev, sd))
344 sd = NULL;
345
346 module_put(client->driver->driver.owner);
347
348error:
349
350
351 if (client && sd == NULL)
352 i2c_unregister_device(client);
353 return sd;
354}
355EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board);
356
357struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
358 struct i2c_adapter *adapter, const char *client_type,
359 u8 addr, const unsigned short *probe_addrs)
360{
361 struct i2c_board_info info;
362
363
364
365 memset(&info, 0, sizeof(info));
366 strlcpy(info.type, client_type, sizeof(info.type));
367 info.addr = addr;
368
369 return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, probe_addrs);
370}
371EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev);
372
373
374unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd)
375{
376 struct i2c_client *client = v4l2_get_subdevdata(sd);
377
378 return client ? client->addr : I2C_CLIENT_END;
379}
380EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_addr);
381
382
383
384const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
385{
386 static const unsigned short radio_addrs[] = {
387#if defined(CONFIG_MEDIA_TUNER_TEA5761) || defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE)
388 0x10,
389#endif
390 0x60,
391 I2C_CLIENT_END
392 };
393 static const unsigned short demod_addrs[] = {
394 0x42, 0x43, 0x4a, 0x4b,
395 I2C_CLIENT_END
396 };
397 static const unsigned short tv_addrs[] = {
398 0x42, 0x43, 0x4a, 0x4b,
399 0x60, 0x61, 0x62, 0x63, 0x64,
400 I2C_CLIENT_END
401 };
402
403 switch (type) {
404 case ADDRS_RADIO:
405 return radio_addrs;
406 case ADDRS_DEMOD:
407 return demod_addrs;
408 case ADDRS_TV:
409 return tv_addrs;
410 case ADDRS_TV_WITH_DEMOD:
411 return tv_addrs + 4;
412 }
413 return NULL;
414}
415EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
416
417#endif
418
419#if defined(CONFIG_SPI)
420
421
422
423void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
424 const struct v4l2_subdev_ops *ops)
425{
426 v4l2_subdev_init(sd, ops);
427 sd->flags |= V4L2_SUBDEV_FL_IS_SPI;
428
429 sd->owner = spi->dev.driver->owner;
430
431 v4l2_set_subdevdata(sd, spi);
432 spi_set_drvdata(spi, sd);
433
434 strlcpy(sd->name, spi->dev.driver->name, sizeof(sd->name));
435}
436EXPORT_SYMBOL_GPL(v4l2_spi_subdev_init);
437
438struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev,
439 struct spi_master *master, struct spi_board_info *info)
440{
441 struct v4l2_subdev *sd = NULL;
442 struct spi_device *spi = NULL;
443
444 BUG_ON(!v4l2_dev);
445
446 if (info->modalias)
447 request_module(info->modalias);
448
449 spi = spi_new_device(master, info);
450
451 if (spi == NULL || spi->dev.driver == NULL)
452 goto error;
453
454 if (!try_module_get(spi->dev.driver->owner))
455 goto error;
456
457 sd = spi_get_drvdata(spi);
458
459
460
461 if (v4l2_device_register_subdev(v4l2_dev, sd))
462 sd = NULL;
463
464
465 module_put(spi->dev.driver->owner);
466
467error:
468
469
470 if (spi && sd == NULL)
471 spi_unregister_device(spi);
472
473 return sd;
474}
475EXPORT_SYMBOL_GPL(v4l2_spi_new_subdev);
476
477#endif
478
479
480
481
482
483static unsigned int clamp_align(unsigned int x, unsigned int min,
484 unsigned int max, unsigned int align)
485{
486
487 unsigned int mask = ~((1 << align) - 1);
488
489
490 if (align)
491 x = (x + (1 << (align - 1))) & mask;
492
493
494 if (x < min)
495 x = (min + ~mask) & mask;
496 else if (x > max)
497 x = max & mask;
498
499 return x;
500}
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
517 unsigned int walign,
518 u32 *h, unsigned int hmin, unsigned int hmax,
519 unsigned int halign, unsigned int salign)
520{
521 *w = clamp_align(*w, wmin, wmax, walign);
522 *h = clamp_align(*h, hmin, hmax, halign);
523
524
525 if (!salign)
526 return;
527
528
529 walign = __ffs(*w);
530 halign = __ffs(*h);
531
532 if (walign + halign < salign) {
533
534 unsigned int wmaxa = __fls(wmax ^ (wmin - 1));
535
536 unsigned int hmaxa = __fls(hmax ^ (hmin - 1));
537
538
539 do {
540 if (halign >= hmaxa ||
541 (walign <= halign && walign < wmaxa)) {
542 *w = clamp_align(*w, wmin, wmax, walign + 1);
543 walign = __ffs(*w);
544 } else {
545 *h = clamp_align(*h, hmin, hmax, halign + 1);
546 halign = __ffs(*h);
547 }
548 } while (halign + walign < salign);
549 }
550}
551EXPORT_SYMBOL_GPL(v4l_bound_align_image);
552
553
554
555
556
557
558
559
560
561int v4l_fill_dv_preset_info(u32 preset, struct v4l2_dv_enum_preset *info)
562{
563 static const struct v4l2_dv_preset_info {
564 u16 width;
565 u16 height;
566 const char *name;
567 } dv_presets[] = {
568 { 0, 0, "Invalid" },
569 { 720, 480, "480p@59.94" },
570 { 720, 576, "576p@50" },
571 { 1280, 720, "720p@24" },
572 { 1280, 720, "720p@25" },
573 { 1280, 720, "720p@30" },
574 { 1280, 720, "720p@50" },
575 { 1280, 720, "720p@59.94" },
576 { 1280, 720, "720p@60" },
577 { 1920, 1080, "1080i@29.97" },
578 { 1920, 1080, "1080i@30" },
579 { 1920, 1080, "1080i@25" },
580 { 1920, 1080, "1080i@50" },
581 { 1920, 1080, "1080i@60" },
582 { 1920, 1080, "1080p@24" },
583 { 1920, 1080, "1080p@25" },
584 { 1920, 1080, "1080p@30" },
585 { 1920, 1080, "1080p@50" },
586 { 1920, 1080, "1080p@60" },
587 };
588
589 if (info == NULL || preset >= ARRAY_SIZE(dv_presets))
590 return -EINVAL;
591
592 info->preset = preset;
593 info->width = dv_presets[preset].width;
594 info->height = dv_presets[preset].height;
595 strlcpy(info->name, dv_presets[preset].name, sizeof(info->name));
596 return 0;
597}
598EXPORT_SYMBOL_GPL(v4l_fill_dv_preset_info);
599
600const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
601 const struct v4l2_discrete_probe *probe,
602 s32 width, s32 height)
603{
604 int i;
605 u32 error, min_error = UINT_MAX;
606 const struct v4l2_frmsize_discrete *size, *best = NULL;
607
608 if (!probe)
609 return best;
610
611 for (i = 0, size = probe->sizes; i < probe->num_sizes; i++, size++) {
612 error = abs(size->width - width) + abs(size->height - height);
613 if (error < min_error) {
614 min_error = error;
615 best = size;
616 }
617 if (!error)
618 break;
619 }
620
621 return best;
622}
623EXPORT_SYMBOL_GPL(v4l2_find_nearest_format);
624