1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/module.h>
19#include <linux/errno.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/sched.h>
23#include <linux/slab.h>
24#include <linux/font.h>
25#include <linux/mutex.h>
26#include <linux/videodev2.h>
27#include <linux/kthread.h>
28#include <linux/freezer.h>
29#include <media/videobuf2-vmalloc.h>
30#include <media/v4l2-device.h>
31#include <media/v4l2-ioctl.h>
32#include <media/v4l2-ctrls.h>
33#include <media/v4l2-fh.h>
34#include <media/v4l2-event.h>
35#include <media/v4l2-common.h>
36
37#define VIVI_MODULE_NAME "vivi"
38
39
40
41
42
43
44
45
46
47
48
49#define FPS_MAX 1000
50
51#define MAX_WIDTH 1920
52#define MAX_HEIGHT 1200
53
54#define VIVI_VERSION "0.8.1"
55
56MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
57MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
58MODULE_LICENSE("Dual BSD/GPL");
59MODULE_VERSION(VIVI_VERSION);
60
61static unsigned video_nr = -1;
62module_param(video_nr, uint, 0644);
63MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect");
64
65static unsigned n_devs = 1;
66module_param(n_devs, uint, 0644);
67MODULE_PARM_DESC(n_devs, "number of video devices to create");
68
69static unsigned debug;
70module_param(debug, uint, 0644);
71MODULE_PARM_DESC(debug, "activates debug info");
72
73
74static const u8 *font8x16;
75
76
77static const struct v4l2_fract
78 tpf_min = {.numerator = 1, .denominator = FPS_MAX},
79 tpf_max = {.numerator = FPS_MAX, .denominator = 1},
80 tpf_default = {.numerator = 1001, .denominator = 30000};
81
82#define dprintk(dev, level, fmt, arg...) \
83 v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
84
85
86
87
88
89struct vivi_fmt {
90 const char *name;
91 u32 fourcc;
92 u8 depth;
93 bool is_yuv;
94};
95
96static const struct vivi_fmt formats[] = {
97 {
98 .name = "4:2:2, packed, YUYV",
99 .fourcc = V4L2_PIX_FMT_YUYV,
100 .depth = 16,
101 .is_yuv = true,
102 },
103 {
104 .name = "4:2:2, packed, UYVY",
105 .fourcc = V4L2_PIX_FMT_UYVY,
106 .depth = 16,
107 .is_yuv = true,
108 },
109 {
110 .name = "4:2:2, packed, YVYU",
111 .fourcc = V4L2_PIX_FMT_YVYU,
112 .depth = 16,
113 .is_yuv = true,
114 },
115 {
116 .name = "4:2:2, packed, VYUY",
117 .fourcc = V4L2_PIX_FMT_VYUY,
118 .depth = 16,
119 .is_yuv = true,
120 },
121 {
122 .name = "RGB565 (LE)",
123 .fourcc = V4L2_PIX_FMT_RGB565,
124 .depth = 16,
125 },
126 {
127 .name = "RGB565 (BE)",
128 .fourcc = V4L2_PIX_FMT_RGB565X,
129 .depth = 16,
130 },
131 {
132 .name = "RGB555 (LE)",
133 .fourcc = V4L2_PIX_FMT_RGB555,
134 .depth = 16,
135 },
136 {
137 .name = "RGB555 (BE)",
138 .fourcc = V4L2_PIX_FMT_RGB555X,
139 .depth = 16,
140 },
141 {
142 .name = "RGB24 (LE)",
143 .fourcc = V4L2_PIX_FMT_RGB24,
144 .depth = 24,
145 },
146 {
147 .name = "RGB24 (BE)",
148 .fourcc = V4L2_PIX_FMT_BGR24,
149 .depth = 24,
150 },
151 {
152 .name = "RGB32 (LE)",
153 .fourcc = V4L2_PIX_FMT_RGB32,
154 .depth = 32,
155 },
156 {
157 .name = "RGB32 (BE)",
158 .fourcc = V4L2_PIX_FMT_BGR32,
159 .depth = 32,
160 },
161};
162
163static const struct vivi_fmt *__get_format(u32 pixelformat)
164{
165 const struct vivi_fmt *fmt;
166 unsigned int k;
167
168 for (k = 0; k < ARRAY_SIZE(formats); k++) {
169 fmt = &formats[k];
170 if (fmt->fourcc == pixelformat)
171 break;
172 }
173
174 if (k == ARRAY_SIZE(formats))
175 return NULL;
176
177 return &formats[k];
178}
179
180static const struct vivi_fmt *get_format(struct v4l2_format *f)
181{
182 return __get_format(f->fmt.pix.pixelformat);
183}
184
185
186struct vivi_buffer {
187
188 struct vb2_buffer vb;
189 struct list_head list;
190};
191
192struct vivi_dmaqueue {
193 struct list_head active;
194
195
196 struct task_struct *kthread;
197 wait_queue_head_t wq;
198
199 int frame;
200 int ini_jiffies;
201};
202
203static LIST_HEAD(vivi_devlist);
204
205struct vivi_dev {
206 struct list_head vivi_devlist;
207 struct v4l2_device v4l2_dev;
208 struct v4l2_ctrl_handler ctrl_handler;
209 struct video_device vdev;
210
211
212 struct v4l2_ctrl *brightness;
213 struct v4l2_ctrl *contrast;
214 struct v4l2_ctrl *saturation;
215 struct v4l2_ctrl *hue;
216 struct {
217
218 struct v4l2_ctrl *autogain;
219 struct v4l2_ctrl *gain;
220 };
221 struct v4l2_ctrl *volume;
222 struct v4l2_ctrl *alpha;
223 struct v4l2_ctrl *button;
224 struct v4l2_ctrl *boolean;
225 struct v4l2_ctrl *int32;
226 struct v4l2_ctrl *int64;
227 struct v4l2_ctrl *menu;
228 struct v4l2_ctrl *string;
229 struct v4l2_ctrl *bitmask;
230 struct v4l2_ctrl *int_menu;
231
232 spinlock_t slock;
233 struct mutex mutex;
234
235 struct vivi_dmaqueue vidq;
236
237
238 unsigned ms;
239 unsigned long jiffies;
240 unsigned button_pressed;
241
242 int mv_count;
243
244
245 int input;
246
247
248 const struct vivi_fmt *fmt;
249 struct v4l2_fract timeperframe;
250 unsigned int width, height;
251 struct vb2_queue vb_vidq;
252 unsigned int seq_count;
253
254 u8 bars[9][3];
255 u8 line[MAX_WIDTH * 8] __attribute__((__aligned__(4)));
256 unsigned int pixelsize;
257 u8 alpha_component;
258 u32 textfg, textbg;
259};
260
261
262
263
264
265
266
267enum colors {
268 WHITE,
269 AMBER,
270 CYAN,
271 GREEN,
272 MAGENTA,
273 RED,
274 BLUE,
275 BLACK,
276 TEXT_BLACK,
277};
278
279
280#define COLOR_WHITE {204, 204, 204}
281#define COLOR_AMBER {208, 208, 0}
282#define COLOR_CYAN { 0, 206, 206}
283#define COLOR_GREEN { 0, 239, 0}
284#define COLOR_MAGENTA {239, 0, 239}
285#define COLOR_RED {205, 0, 0}
286#define COLOR_BLUE { 0, 0, 255}
287#define COLOR_BLACK { 0, 0, 0}
288
289struct bar_std {
290 u8 bar[9][3];
291};
292
293
294
295static const struct bar_std bars[] = {
296 {
297 { COLOR_WHITE, COLOR_AMBER, COLOR_CYAN, COLOR_GREEN,
298 COLOR_MAGENTA, COLOR_RED, COLOR_BLUE, COLOR_BLACK, COLOR_BLACK }
299 }, {
300 { COLOR_WHITE, COLOR_AMBER, COLOR_BLACK, COLOR_WHITE,
301 COLOR_AMBER, COLOR_BLACK, COLOR_WHITE, COLOR_AMBER, COLOR_BLACK }
302 }, {
303 { COLOR_WHITE, COLOR_CYAN, COLOR_BLACK, COLOR_WHITE,
304 COLOR_CYAN, COLOR_BLACK, COLOR_WHITE, COLOR_CYAN, COLOR_BLACK }
305 }, {
306 { COLOR_WHITE, COLOR_GREEN, COLOR_BLACK, COLOR_WHITE,
307 COLOR_GREEN, COLOR_BLACK, COLOR_WHITE, COLOR_GREEN, COLOR_BLACK }
308 },
309};
310
311#define NUM_INPUTS ARRAY_SIZE(bars)
312
313#define TO_Y(r, g, b) \
314 (((16829 * r + 33039 * g + 6416 * b + 32768) >> 16) + 16)
315
316#define TO_V(r, g, b) \
317 (((28784 * r - 24103 * g - 4681 * b + 32768) >> 16) + 128)
318
319#define TO_U(r, g, b) \
320 (((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128)
321
322
323static void precalculate_bars(struct vivi_dev *dev)
324{
325 u8 r, g, b;
326 int k, is_yuv;
327
328 for (k = 0; k < 9; k++) {
329 r = bars[dev->input].bar[k][0];
330 g = bars[dev->input].bar[k][1];
331 b = bars[dev->input].bar[k][2];
332 is_yuv = dev->fmt->is_yuv;
333
334 switch (dev->fmt->fourcc) {
335 case V4L2_PIX_FMT_RGB565:
336 case V4L2_PIX_FMT_RGB565X:
337 r >>= 3;
338 g >>= 2;
339 b >>= 3;
340 break;
341 case V4L2_PIX_FMT_RGB555:
342 case V4L2_PIX_FMT_RGB555X:
343 r >>= 3;
344 g >>= 3;
345 b >>= 3;
346 break;
347 case V4L2_PIX_FMT_YUYV:
348 case V4L2_PIX_FMT_UYVY:
349 case V4L2_PIX_FMT_YVYU:
350 case V4L2_PIX_FMT_VYUY:
351 case V4L2_PIX_FMT_RGB24:
352 case V4L2_PIX_FMT_BGR24:
353 case V4L2_PIX_FMT_RGB32:
354 case V4L2_PIX_FMT_BGR32:
355 break;
356 }
357
358 if (is_yuv) {
359 dev->bars[k][0] = TO_Y(r, g, b);
360 dev->bars[k][1] = TO_U(r, g, b);
361 dev->bars[k][2] = TO_V(r, g, b);
362 } else {
363 dev->bars[k][0] = r;
364 dev->bars[k][1] = g;
365 dev->bars[k][2] = b;
366 }
367 }
368}
369
370
371static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos, bool odd)
372{
373 u8 r_y, g_u, b_v;
374 u8 alpha = dev->alpha_component;
375 int color;
376 u8 *p;
377
378 r_y = dev->bars[colorpos][0];
379 g_u = dev->bars[colorpos][1];
380 b_v = dev->bars[colorpos][2];
381
382 for (color = 0; color < dev->pixelsize; color++) {
383 p = buf + color;
384
385 switch (dev->fmt->fourcc) {
386 case V4L2_PIX_FMT_YUYV:
387 switch (color) {
388 case 0:
389 *p = r_y;
390 break;
391 case 1:
392 *p = odd ? b_v : g_u;
393 break;
394 }
395 break;
396 case V4L2_PIX_FMT_UYVY:
397 switch (color) {
398 case 0:
399 *p = odd ? b_v : g_u;
400 break;
401 case 1:
402 *p = r_y;
403 break;
404 }
405 break;
406 case V4L2_PIX_FMT_YVYU:
407 switch (color) {
408 case 0:
409 *p = r_y;
410 break;
411 case 1:
412 *p = odd ? g_u : b_v;
413 break;
414 }
415 break;
416 case V4L2_PIX_FMT_VYUY:
417 switch (color) {
418 case 0:
419 *p = odd ? g_u : b_v;
420 break;
421 case 1:
422 *p = r_y;
423 break;
424 }
425 break;
426 case V4L2_PIX_FMT_RGB565:
427 switch (color) {
428 case 0:
429 *p = (g_u << 5) | b_v;
430 break;
431 case 1:
432 *p = (r_y << 3) | (g_u >> 3);
433 break;
434 }
435 break;
436 case V4L2_PIX_FMT_RGB565X:
437 switch (color) {
438 case 0:
439 *p = (r_y << 3) | (g_u >> 3);
440 break;
441 case 1:
442 *p = (g_u << 5) | b_v;
443 break;
444 }
445 break;
446 case V4L2_PIX_FMT_RGB555:
447 switch (color) {
448 case 0:
449 *p = (g_u << 5) | b_v;
450 break;
451 case 1:
452 *p = (alpha & 0x80) | (r_y << 2) | (g_u >> 3);
453 break;
454 }
455 break;
456 case V4L2_PIX_FMT_RGB555X:
457 switch (color) {
458 case 0:
459 *p = (alpha & 0x80) | (r_y << 2) | (g_u >> 3);
460 break;
461 case 1:
462 *p = (g_u << 5) | b_v;
463 break;
464 }
465 break;
466 case V4L2_PIX_FMT_RGB24:
467 switch (color) {
468 case 0:
469 *p = r_y;
470 break;
471 case 1:
472 *p = g_u;
473 break;
474 case 2:
475 *p = b_v;
476 break;
477 }
478 break;
479 case V4L2_PIX_FMT_BGR24:
480 switch (color) {
481 case 0:
482 *p = b_v;
483 break;
484 case 1:
485 *p = g_u;
486 break;
487 case 2:
488 *p = r_y;
489 break;
490 }
491 break;
492 case V4L2_PIX_FMT_RGB32:
493 switch (color) {
494 case 0:
495 *p = alpha;
496 break;
497 case 1:
498 *p = r_y;
499 break;
500 case 2:
501 *p = g_u;
502 break;
503 case 3:
504 *p = b_v;
505 break;
506 }
507 break;
508 case V4L2_PIX_FMT_BGR32:
509 switch (color) {
510 case 0:
511 *p = b_v;
512 break;
513 case 1:
514 *p = g_u;
515 break;
516 case 2:
517 *p = r_y;
518 break;
519 case 3:
520 *p = alpha;
521 break;
522 }
523 break;
524 }
525 }
526}
527
528static void precalculate_line(struct vivi_dev *dev)
529{
530 unsigned pixsize = dev->pixelsize;
531 unsigned pixsize2 = 2*pixsize;
532 int colorpos;
533 u8 *pos;
534
535 for (colorpos = 0; colorpos < 16; ++colorpos) {
536 u8 pix[8];
537 int wstart = colorpos * dev->width / 8;
538 int wend = (colorpos+1) * dev->width / 8;
539 int w;
540
541 gen_twopix(dev, &pix[0], colorpos % 8, 0);
542 gen_twopix(dev, &pix[pixsize], colorpos % 8, 1);
543
544 for (w = wstart/2*2, pos = dev->line + w*pixsize; w < wend; w += 2, pos += pixsize2)
545 memcpy(pos, pix, pixsize2);
546 }
547}
548
549
550typedef struct { u16 __; u8 _; } __attribute__((packed)) x24;
551
552static void gen_text(struct vivi_dev *dev, char *basep,
553 int y, int x, char *text)
554{
555 int line;
556 unsigned int width = dev->width;
557
558
559 if (y + 16 >= dev->height || x + strlen(text) * 8 >= width)
560 return;
561
562
563#define PRINTSTR(PIXTYPE) do { \
564 PIXTYPE fg; \
565 PIXTYPE bg; \
566 memcpy(&fg, &dev->textfg, sizeof(PIXTYPE)); \
567 memcpy(&bg, &dev->textbg, sizeof(PIXTYPE)); \
568 \
569 for (line = 0; line < 16; line++) { \
570 PIXTYPE *pos = (PIXTYPE *)( basep + ((y + line) * width + x) * sizeof(PIXTYPE) ); \
571 u8 *s; \
572 \
573 for (s = text; *s; s++) { \
574 u8 chr = font8x16[*s * 16 + line]; \
575 \
576 pos[0] = (chr & (0x01 << 7) ? fg : bg); \
577 pos[1] = (chr & (0x01 << 6) ? fg : bg); \
578 pos[2] = (chr & (0x01 << 5) ? fg : bg); \
579 pos[3] = (chr & (0x01 << 4) ? fg : bg); \
580 pos[4] = (chr & (0x01 << 3) ? fg : bg); \
581 pos[5] = (chr & (0x01 << 2) ? fg : bg); \
582 pos[6] = (chr & (0x01 << 1) ? fg : bg); \
583 pos[7] = (chr & (0x01 << 0) ? fg : bg); \
584 \
585 pos += 8; \
586 } \
587 } \
588} while (0)
589
590 switch (dev->pixelsize) {
591 case 2:
592 PRINTSTR(u16); break;
593 case 4:
594 PRINTSTR(u32); break;
595 case 3:
596 PRINTSTR(x24); break;
597 }
598}
599
600static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
601{
602 int stride = dev->width * dev->pixelsize;
603 int hmax = dev->height;
604 void *vbuf = vb2_plane_vaddr(&buf->vb, 0);
605 unsigned ms;
606 char str[100];
607 int h, line = 1;
608 u8 *linestart;
609 s32 gain;
610
611 if (!vbuf)
612 return;
613
614 linestart = dev->line + (dev->mv_count % dev->width) * dev->pixelsize;
615
616 for (h = 0; h < hmax; h++)
617 memcpy(vbuf + h * stride, linestart, stride);
618
619
620
621 gen_twopix(dev, (u8 *)&dev->textbg, TEXT_BLACK, 0);
622 gen_twopix(dev, (u8 *)&dev->textfg, WHITE, 0);
623
624 dev->ms += jiffies_to_msecs(jiffies - dev->jiffies);
625 dev->jiffies = jiffies;
626 ms = dev->ms;
627 snprintf(str, sizeof(str), " %02d:%02d:%02d:%03d ",
628 (ms / (60 * 60 * 1000)) % 24,
629 (ms / (60 * 1000)) % 60,
630 (ms / 1000) % 60,
631 ms % 1000);
632 gen_text(dev, vbuf, line++ * 16, 16, str);
633 snprintf(str, sizeof(str), " %dx%d, input %d ",
634 dev->width, dev->height, dev->input);
635 gen_text(dev, vbuf, line++ * 16, 16, str);
636
637 gain = v4l2_ctrl_g_ctrl(dev->gain);
638 mutex_lock(dev->ctrl_handler.lock);
639 snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ",
640 dev->brightness->cur.val,
641 dev->contrast->cur.val,
642 dev->saturation->cur.val,
643 dev->hue->cur.val);
644 gen_text(dev, vbuf, line++ * 16, 16, str);
645 snprintf(str, sizeof(str), " autogain %d, gain %3d, volume %3d, alpha 0x%02x ",
646 dev->autogain->cur.val, gain, dev->volume->cur.val,
647 dev->alpha->cur.val);
648 gen_text(dev, vbuf, line++ * 16, 16, str);
649 snprintf(str, sizeof(str), " int32 %d, int64 %lld, bitmask %08x ",
650 dev->int32->cur.val,
651 dev->int64->cur.val64,
652 dev->bitmask->cur.val);
653 gen_text(dev, vbuf, line++ * 16, 16, str);
654 snprintf(str, sizeof(str), " boolean %d, menu %s, string \"%s\" ",
655 dev->boolean->cur.val,
656 dev->menu->qmenu[dev->menu->cur.val],
657 dev->string->cur.string);
658 gen_text(dev, vbuf, line++ * 16, 16, str);
659 snprintf(str, sizeof(str), " integer_menu %lld, value %d ",
660 dev->int_menu->qmenu_int[dev->int_menu->cur.val],
661 dev->int_menu->cur.val);
662 gen_text(dev, vbuf, line++ * 16, 16, str);
663 mutex_unlock(dev->ctrl_handler.lock);
664 if (dev->button_pressed) {
665 dev->button_pressed--;
666 snprintf(str, sizeof(str), " button pressed!");
667 gen_text(dev, vbuf, line++ * 16, 16, str);
668 }
669
670 dev->mv_count += 2;
671
672 buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
673 buf->vb.v4l2_buf.sequence = dev->seq_count++;
674 v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
675}
676
677static void vivi_thread_tick(struct vivi_dev *dev)
678{
679 struct vivi_dmaqueue *dma_q = &dev->vidq;
680 struct vivi_buffer *buf;
681 unsigned long flags = 0;
682
683 dprintk(dev, 1, "Thread tick\n");
684
685 spin_lock_irqsave(&dev->slock, flags);
686 if (list_empty(&dma_q->active)) {
687 dprintk(dev, 1, "No active queue to serve\n");
688 spin_unlock_irqrestore(&dev->slock, flags);
689 return;
690 }
691
692 buf = list_entry(dma_q->active.next, struct vivi_buffer, list);
693 list_del(&buf->list);
694 spin_unlock_irqrestore(&dev->slock, flags);
695
696 v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
697
698
699 vivi_fillbuff(dev, buf);
700 dprintk(dev, 1, "filled buffer %p\n", buf);
701
702 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
703 dprintk(dev, 2, "[%p/%d] done\n", buf, buf->vb.v4l2_buf.index);
704}
705
706#define frames_to_ms(dev, frames) \
707 ((frames * dev->timeperframe.numerator * 1000) / dev->timeperframe.denominator)
708
709static void vivi_sleep(struct vivi_dev *dev)
710{
711 struct vivi_dmaqueue *dma_q = &dev->vidq;
712 int timeout;
713 DECLARE_WAITQUEUE(wait, current);
714
715 dprintk(dev, 1, "%s dma_q=0x%08lx\n", __func__,
716 (unsigned long)dma_q);
717
718 add_wait_queue(&dma_q->wq, &wait);
719 if (kthread_should_stop())
720 goto stop_task;
721
722
723 timeout = msecs_to_jiffies(frames_to_ms(dev, 1));
724
725 vivi_thread_tick(dev);
726
727 schedule_timeout_interruptible(timeout);
728
729stop_task:
730 remove_wait_queue(&dma_q->wq, &wait);
731 try_to_freeze();
732}
733
734static int vivi_thread(void *data)
735{
736 struct vivi_dev *dev = data;
737
738 dprintk(dev, 1, "thread started\n");
739
740 set_freezable();
741
742 for (;;) {
743 vivi_sleep(dev);
744
745 if (kthread_should_stop())
746 break;
747 }
748 dprintk(dev, 1, "thread: exit\n");
749 return 0;
750}
751
752static int vivi_start_generating(struct vivi_dev *dev)
753{
754 struct vivi_dmaqueue *dma_q = &dev->vidq;
755
756 dprintk(dev, 1, "%s\n", __func__);
757
758
759 dev->ms = 0;
760 dev->mv_count = 0;
761 dev->jiffies = jiffies;
762
763 dma_q->frame = 0;
764 dma_q->ini_jiffies = jiffies;
765 dma_q->kthread = kthread_run(vivi_thread, dev, "%s",
766 dev->v4l2_dev.name);
767
768 if (IS_ERR(dma_q->kthread)) {
769 v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
770 return PTR_ERR(dma_q->kthread);
771 }
772
773 wake_up_interruptible(&dma_q->wq);
774
775 dprintk(dev, 1, "returning from %s\n", __func__);
776 return 0;
777}
778
779static void vivi_stop_generating(struct vivi_dev *dev)
780{
781 struct vivi_dmaqueue *dma_q = &dev->vidq;
782
783 dprintk(dev, 1, "%s\n", __func__);
784
785
786 if (dma_q->kthread) {
787 kthread_stop(dma_q->kthread);
788 dma_q->kthread = NULL;
789 }
790
791
792
793
794
795
796
797 while (!list_empty(&dma_q->active)) {
798 struct vivi_buffer *buf;
799 buf = list_entry(dma_q->active.next, struct vivi_buffer, list);
800 list_del(&buf->list);
801 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
802 dprintk(dev, 2, "[%p/%d] done\n", buf, buf->vb.v4l2_buf.index);
803 }
804}
805
806
807
808static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
809 unsigned int *nbuffers, unsigned int *nplanes,
810 unsigned int sizes[], void *alloc_ctxs[])
811{
812 struct vivi_dev *dev = vb2_get_drv_priv(vq);
813 unsigned long size;
814
815 size = dev->width * dev->height * dev->pixelsize;
816 if (fmt) {
817 if (fmt->fmt.pix.sizeimage < size)
818 return -EINVAL;
819 size = fmt->fmt.pix.sizeimage;
820
821 if (size > 7680 * 4320 * dev->pixelsize)
822 return -EINVAL;
823 }
824
825 *nplanes = 1;
826
827 sizes[0] = size;
828
829
830
831
832
833
834 dprintk(dev, 1, "%s, count=%d, size=%ld\n", __func__,
835 *nbuffers, size);
836
837 return 0;
838}
839
840static int buffer_prepare(struct vb2_buffer *vb)
841{
842 struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
843 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb);
844 unsigned long size;
845
846 dprintk(dev, 1, "%s, field=%d\n", __func__, vb->v4l2_buf.field);
847
848 BUG_ON(NULL == dev->fmt);
849
850
851
852
853
854
855
856 if (dev->width < 48 || dev->width > MAX_WIDTH ||
857 dev->height < 32 || dev->height > MAX_HEIGHT)
858 return -EINVAL;
859
860 size = dev->width * dev->height * dev->pixelsize;
861 if (vb2_plane_size(vb, 0) < size) {
862 dprintk(dev, 1, "%s data will not fit into plane (%lu < %lu)\n",
863 __func__, vb2_plane_size(vb, 0), size);
864 return -EINVAL;
865 }
866
867 vb2_set_plane_payload(&buf->vb, 0, size);
868
869 precalculate_bars(dev);
870 precalculate_line(dev);
871
872 return 0;
873}
874
875static void buffer_queue(struct vb2_buffer *vb)
876{
877 struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
878 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb);
879 struct vivi_dmaqueue *vidq = &dev->vidq;
880 unsigned long flags = 0;
881
882 dprintk(dev, 1, "%s\n", __func__);
883
884 spin_lock_irqsave(&dev->slock, flags);
885 list_add_tail(&buf->list, &vidq->active);
886 spin_unlock_irqrestore(&dev->slock, flags);
887}
888
889static int start_streaming(struct vb2_queue *vq, unsigned int count)
890{
891 struct vivi_dev *dev = vb2_get_drv_priv(vq);
892 int err;
893
894 dprintk(dev, 1, "%s\n", __func__);
895 dev->seq_count = 0;
896 err = vivi_start_generating(dev);
897 if (err) {
898 struct vivi_buffer *buf, *tmp;
899
900 list_for_each_entry_safe(buf, tmp, &dev->vidq.active, list) {
901 list_del(&buf->list);
902 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
903 }
904 }
905 return err;
906}
907
908
909static int stop_streaming(struct vb2_queue *vq)
910{
911 struct vivi_dev *dev = vb2_get_drv_priv(vq);
912 dprintk(dev, 1, "%s\n", __func__);
913 vivi_stop_generating(dev);
914 return 0;
915}
916
917static void vivi_lock(struct vb2_queue *vq)
918{
919 struct vivi_dev *dev = vb2_get_drv_priv(vq);
920 mutex_lock(&dev->mutex);
921}
922
923static void vivi_unlock(struct vb2_queue *vq)
924{
925 struct vivi_dev *dev = vb2_get_drv_priv(vq);
926 mutex_unlock(&dev->mutex);
927}
928
929
930static const struct vb2_ops vivi_video_qops = {
931 .queue_setup = queue_setup,
932 .buf_prepare = buffer_prepare,
933 .buf_queue = buffer_queue,
934 .start_streaming = start_streaming,
935 .stop_streaming = stop_streaming,
936 .wait_prepare = vivi_unlock,
937 .wait_finish = vivi_lock,
938};
939
940
941
942
943static int vidioc_querycap(struct file *file, void *priv,
944 struct v4l2_capability *cap)
945{
946 struct vivi_dev *dev = video_drvdata(file);
947
948 strcpy(cap->driver, "vivi");
949 strcpy(cap->card, "vivi");
950 snprintf(cap->bus_info, sizeof(cap->bus_info),
951 "platform:%s", dev->v4l2_dev.name);
952 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
953 V4L2_CAP_READWRITE;
954 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
955 return 0;
956}
957
958static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
959 struct v4l2_fmtdesc *f)
960{
961 const struct vivi_fmt *fmt;
962
963 if (f->index >= ARRAY_SIZE(formats))
964 return -EINVAL;
965
966 fmt = &formats[f->index];
967
968 strlcpy(f->description, fmt->name, sizeof(f->description));
969 f->pixelformat = fmt->fourcc;
970 return 0;
971}
972
973static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
974 struct v4l2_format *f)
975{
976 struct vivi_dev *dev = video_drvdata(file);
977
978 f->fmt.pix.width = dev->width;
979 f->fmt.pix.height = dev->height;
980 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
981 f->fmt.pix.pixelformat = dev->fmt->fourcc;
982 f->fmt.pix.bytesperline =
983 (f->fmt.pix.width * dev->fmt->depth) >> 3;
984 f->fmt.pix.sizeimage =
985 f->fmt.pix.height * f->fmt.pix.bytesperline;
986 if (dev->fmt->is_yuv)
987 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
988 else
989 f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
990 return 0;
991}
992
993static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
994 struct v4l2_format *f)
995{
996 struct vivi_dev *dev = video_drvdata(file);
997 const struct vivi_fmt *fmt;
998
999 fmt = get_format(f);
1000 if (!fmt) {
1001 dprintk(dev, 1, "Fourcc format (0x%08x) unknown.\n",
1002 f->fmt.pix.pixelformat);
1003 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1004 fmt = get_format(f);
1005 }
1006
1007 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
1008 v4l_bound_align_image(&f->fmt.pix.width, 48, MAX_WIDTH, 2,
1009 &f->fmt.pix.height, 32, MAX_HEIGHT, 0, 0);
1010 f->fmt.pix.bytesperline =
1011 (f->fmt.pix.width * fmt->depth) >> 3;
1012 f->fmt.pix.sizeimage =
1013 f->fmt.pix.height * f->fmt.pix.bytesperline;
1014 if (fmt->is_yuv)
1015 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1016 else
1017 f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
1018 f->fmt.pix.priv = 0;
1019 return 0;
1020}
1021
1022static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1023 struct v4l2_format *f)
1024{
1025 struct vivi_dev *dev = video_drvdata(file);
1026 struct vb2_queue *q = &dev->vb_vidq;
1027
1028 int ret = vidioc_try_fmt_vid_cap(file, priv, f);
1029 if (ret < 0)
1030 return ret;
1031
1032 if (vb2_is_busy(q)) {
1033 dprintk(dev, 1, "%s device busy\n", __func__);
1034 return -EBUSY;
1035 }
1036
1037 dev->fmt = get_format(f);
1038 dev->pixelsize = dev->fmt->depth / 8;
1039 dev->width = f->fmt.pix.width;
1040 dev->height = f->fmt.pix.height;
1041
1042 return 0;
1043}
1044
1045static int vidioc_enum_framesizes(struct file *file, void *fh,
1046 struct v4l2_frmsizeenum *fsize)
1047{
1048 static const struct v4l2_frmsize_stepwise sizes = {
1049 48, MAX_WIDTH, 4,
1050 32, MAX_HEIGHT, 1
1051 };
1052 int i;
1053
1054 if (fsize->index)
1055 return -EINVAL;
1056 for (i = 0; i < ARRAY_SIZE(formats); i++)
1057 if (formats[i].fourcc == fsize->pixel_format)
1058 break;
1059 if (i == ARRAY_SIZE(formats))
1060 return -EINVAL;
1061 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
1062 fsize->stepwise = sizes;
1063 return 0;
1064}
1065
1066
1067static int vidioc_enum_input(struct file *file, void *priv,
1068 struct v4l2_input *inp)
1069{
1070 if (inp->index >= NUM_INPUTS)
1071 return -EINVAL;
1072
1073 inp->type = V4L2_INPUT_TYPE_CAMERA;
1074 sprintf(inp->name, "Camera %u", inp->index);
1075 return 0;
1076}
1077
1078static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1079{
1080 struct vivi_dev *dev = video_drvdata(file);
1081
1082 *i = dev->input;
1083 return 0;
1084}
1085
1086static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1087{
1088 struct vivi_dev *dev = video_drvdata(file);
1089
1090 if (i >= NUM_INPUTS)
1091 return -EINVAL;
1092
1093 if (i == dev->input)
1094 return 0;
1095
1096 dev->input = i;
1097
1098
1099
1100
1101
1102
1103
1104 v4l2_ctrl_modify_range(dev->brightness,
1105 128 * i, 255 + 128 * i, 1, 127 + 128 * i);
1106 precalculate_bars(dev);
1107 precalculate_line(dev);
1108 return 0;
1109}
1110
1111
1112static int vidioc_enum_frameintervals(struct file *file, void *priv,
1113 struct v4l2_frmivalenum *fival)
1114{
1115 const struct vivi_fmt *fmt;
1116
1117 if (fival->index)
1118 return -EINVAL;
1119
1120 fmt = __get_format(fival->pixel_format);
1121 if (!fmt)
1122 return -EINVAL;
1123
1124
1125 if (fival->width < 48 || fival->width > MAX_WIDTH || (fival->width & 3))
1126 return -EINVAL;
1127 if (fival->height < 32 || fival->height > MAX_HEIGHT)
1128 return -EINVAL;
1129
1130 fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
1131
1132
1133 fival->stepwise.min = tpf_min;
1134 fival->stepwise.max = tpf_max;
1135 fival->stepwise.step = (struct v4l2_fract) {1, 1};
1136
1137 return 0;
1138}
1139
1140static int vidioc_g_parm(struct file *file, void *priv,
1141 struct v4l2_streamparm *parm)
1142{
1143 struct vivi_dev *dev = video_drvdata(file);
1144
1145 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1146 return -EINVAL;
1147
1148 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
1149 parm->parm.capture.timeperframe = dev->timeperframe;
1150 parm->parm.capture.readbuffers = 1;
1151 return 0;
1152}
1153
1154#define FRACT_CMP(a, OP, b) \
1155 ((u64)(a).numerator * (b).denominator OP (u64)(b).numerator * (a).denominator)
1156
1157static int vidioc_s_parm(struct file *file, void *priv,
1158 struct v4l2_streamparm *parm)
1159{
1160 struct vivi_dev *dev = video_drvdata(file);
1161 struct v4l2_fract tpf;
1162
1163 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1164 return -EINVAL;
1165
1166 tpf = parm->parm.capture.timeperframe;
1167
1168
1169 tpf = tpf.denominator ? tpf : tpf_default;
1170 tpf = FRACT_CMP(tpf, <, tpf_min) ? tpf_min : tpf;
1171 tpf = FRACT_CMP(tpf, >, tpf_max) ? tpf_max : tpf;
1172
1173 dev->timeperframe = tpf;
1174 parm->parm.capture.timeperframe = tpf;
1175 parm->parm.capture.readbuffers = 1;
1176 return 0;
1177}
1178
1179
1180
1181static int vivi_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1182{
1183 struct vivi_dev *dev = container_of(ctrl->handler, struct vivi_dev, ctrl_handler);
1184
1185 if (ctrl == dev->autogain)
1186 dev->gain->val = jiffies & 0xff;
1187 return 0;
1188}
1189
1190static int vivi_s_ctrl(struct v4l2_ctrl *ctrl)
1191{
1192 struct vivi_dev *dev = container_of(ctrl->handler, struct vivi_dev, ctrl_handler);
1193
1194 switch (ctrl->id) {
1195 case V4L2_CID_ALPHA_COMPONENT:
1196 dev->alpha_component = ctrl->val;
1197 break;
1198 default:
1199 if (ctrl == dev->button)
1200 dev->button_pressed = 30;
1201 break;
1202 }
1203 return 0;
1204}
1205
1206
1207
1208
1209
1210static const struct v4l2_ctrl_ops vivi_ctrl_ops = {
1211 .g_volatile_ctrl = vivi_g_volatile_ctrl,
1212 .s_ctrl = vivi_s_ctrl,
1213};
1214
1215#define VIVI_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000)
1216
1217static const struct v4l2_ctrl_config vivi_ctrl_button = {
1218 .ops = &vivi_ctrl_ops,
1219 .id = VIVI_CID_CUSTOM_BASE + 0,
1220 .name = "Button",
1221 .type = V4L2_CTRL_TYPE_BUTTON,
1222};
1223
1224static const struct v4l2_ctrl_config vivi_ctrl_boolean = {
1225 .ops = &vivi_ctrl_ops,
1226 .id = VIVI_CID_CUSTOM_BASE + 1,
1227 .name = "Boolean",
1228 .type = V4L2_CTRL_TYPE_BOOLEAN,
1229 .min = 0,
1230 .max = 1,
1231 .step = 1,
1232 .def = 1,
1233};
1234
1235static const struct v4l2_ctrl_config vivi_ctrl_int32 = {
1236 .ops = &vivi_ctrl_ops,
1237 .id = VIVI_CID_CUSTOM_BASE + 2,
1238 .name = "Integer 32 Bits",
1239 .type = V4L2_CTRL_TYPE_INTEGER,
1240 .min = 0x80000000,
1241 .max = 0x7fffffff,
1242 .step = 1,
1243};
1244
1245static const struct v4l2_ctrl_config vivi_ctrl_int64 = {
1246 .ops = &vivi_ctrl_ops,
1247 .id = VIVI_CID_CUSTOM_BASE + 3,
1248 .name = "Integer 64 Bits",
1249 .type = V4L2_CTRL_TYPE_INTEGER64,
1250};
1251
1252static const char * const vivi_ctrl_menu_strings[] = {
1253 "Menu Item 0 (Skipped)",
1254 "Menu Item 1",
1255 "Menu Item 2 (Skipped)",
1256 "Menu Item 3",
1257 "Menu Item 4",
1258 "Menu Item 5 (Skipped)",
1259 NULL,
1260};
1261
1262static const struct v4l2_ctrl_config vivi_ctrl_menu = {
1263 .ops = &vivi_ctrl_ops,
1264 .id = VIVI_CID_CUSTOM_BASE + 4,
1265 .name = "Menu",
1266 .type = V4L2_CTRL_TYPE_MENU,
1267 .min = 1,
1268 .max = 4,
1269 .def = 3,
1270 .menu_skip_mask = 0x04,
1271 .qmenu = vivi_ctrl_menu_strings,
1272};
1273
1274static const struct v4l2_ctrl_config vivi_ctrl_string = {
1275 .ops = &vivi_ctrl_ops,
1276 .id = VIVI_CID_CUSTOM_BASE + 5,
1277 .name = "String",
1278 .type = V4L2_CTRL_TYPE_STRING,
1279 .min = 2,
1280 .max = 4,
1281 .step = 1,
1282};
1283
1284static const struct v4l2_ctrl_config vivi_ctrl_bitmask = {
1285 .ops = &vivi_ctrl_ops,
1286 .id = VIVI_CID_CUSTOM_BASE + 6,
1287 .name = "Bitmask",
1288 .type = V4L2_CTRL_TYPE_BITMASK,
1289 .def = 0x80002000,
1290 .min = 0,
1291 .max = 0x80402010,
1292 .step = 0,
1293};
1294
1295static const s64 vivi_ctrl_int_menu_values[] = {
1296 1, 1, 2, 3, 5, 8, 13, 21, 42,
1297};
1298
1299static const struct v4l2_ctrl_config vivi_ctrl_int_menu = {
1300 .ops = &vivi_ctrl_ops,
1301 .id = VIVI_CID_CUSTOM_BASE + 7,
1302 .name = "Integer menu",
1303 .type = V4L2_CTRL_TYPE_INTEGER_MENU,
1304 .min = 1,
1305 .max = 8,
1306 .def = 4,
1307 .menu_skip_mask = 0x02,
1308 .qmenu_int = vivi_ctrl_int_menu_values,
1309};
1310
1311static const struct v4l2_file_operations vivi_fops = {
1312 .owner = THIS_MODULE,
1313 .open = v4l2_fh_open,
1314 .release = vb2_fop_release,
1315 .read = vb2_fop_read,
1316 .poll = vb2_fop_poll,
1317 .unlocked_ioctl = video_ioctl2,
1318 .mmap = vb2_fop_mmap,
1319};
1320
1321static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
1322 .vidioc_querycap = vidioc_querycap,
1323 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1324 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1325 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1326 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1327 .vidioc_enum_framesizes = vidioc_enum_framesizes,
1328 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1329 .vidioc_create_bufs = vb2_ioctl_create_bufs,
1330 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1331 .vidioc_querybuf = vb2_ioctl_querybuf,
1332 .vidioc_qbuf = vb2_ioctl_qbuf,
1333 .vidioc_dqbuf = vb2_ioctl_dqbuf,
1334 .vidioc_enum_input = vidioc_enum_input,
1335 .vidioc_g_input = vidioc_g_input,
1336 .vidioc_s_input = vidioc_s_input,
1337 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
1338 .vidioc_g_parm = vidioc_g_parm,
1339 .vidioc_s_parm = vidioc_s_parm,
1340 .vidioc_streamon = vb2_ioctl_streamon,
1341 .vidioc_streamoff = vb2_ioctl_streamoff,
1342 .vidioc_log_status = v4l2_ctrl_log_status,
1343 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1344 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1345};
1346
1347static const struct video_device vivi_template = {
1348 .name = "vivi",
1349 .fops = &vivi_fops,
1350 .ioctl_ops = &vivi_ioctl_ops,
1351 .release = video_device_release_empty,
1352};
1353
1354
1355
1356
1357
1358static int vivi_release(void)
1359{
1360 struct vivi_dev *dev;
1361 struct list_head *list;
1362
1363 while (!list_empty(&vivi_devlist)) {
1364 list = vivi_devlist.next;
1365 list_del(list);
1366 dev = list_entry(list, struct vivi_dev, vivi_devlist);
1367
1368 v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
1369 video_device_node_name(&dev->vdev));
1370 video_unregister_device(&dev->vdev);
1371 v4l2_device_unregister(&dev->v4l2_dev);
1372 v4l2_ctrl_handler_free(&dev->ctrl_handler);
1373 kfree(dev);
1374 }
1375
1376 return 0;
1377}
1378
1379static int __init vivi_create_instance(int inst)
1380{
1381 struct vivi_dev *dev;
1382 struct video_device *vfd;
1383 struct v4l2_ctrl_handler *hdl;
1384 struct vb2_queue *q;
1385 int ret;
1386
1387 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1388 if (!dev)
1389 return -ENOMEM;
1390
1391 snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
1392 "%s-%03d", VIVI_MODULE_NAME, inst);
1393 ret = v4l2_device_register(NULL, &dev->v4l2_dev);
1394 if (ret)
1395 goto free_dev;
1396
1397 dev->fmt = &formats[0];
1398 dev->timeperframe = tpf_default;
1399 dev->width = 640;
1400 dev->height = 480;
1401 dev->pixelsize = dev->fmt->depth / 8;
1402 hdl = &dev->ctrl_handler;
1403 v4l2_ctrl_handler_init(hdl, 11);
1404 dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1405 V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200);
1406 dev->brightness = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1407 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
1408 dev->contrast = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1409 V4L2_CID_CONTRAST, 0, 255, 1, 16);
1410 dev->saturation = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1411 V4L2_CID_SATURATION, 0, 255, 1, 127);
1412 dev->hue = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1413 V4L2_CID_HUE, -128, 127, 1, 0);
1414 dev->autogain = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1415 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1416 dev->gain = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1417 V4L2_CID_GAIN, 0, 255, 1, 100);
1418 dev->alpha = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1419 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0);
1420 dev->button = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_button, NULL);
1421 dev->int32 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int32, NULL);
1422 dev->int64 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int64, NULL);
1423 dev->boolean = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_boolean, NULL);
1424 dev->menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_menu, NULL);
1425 dev->string = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_string, NULL);
1426 dev->bitmask = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_bitmask, NULL);
1427 dev->int_menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int_menu, NULL);
1428 if (hdl->error) {
1429 ret = hdl->error;
1430 goto unreg_dev;
1431 }
1432 v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true);
1433 dev->v4l2_dev.ctrl_handler = hdl;
1434
1435
1436 spin_lock_init(&dev->slock);
1437
1438
1439 q = &dev->vb_vidq;
1440 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1441 q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
1442 q->drv_priv = dev;
1443 q->buf_struct_size = sizeof(struct vivi_buffer);
1444 q->ops = &vivi_video_qops;
1445 q->mem_ops = &vb2_vmalloc_memops;
1446 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1447
1448 ret = vb2_queue_init(q);
1449 if (ret)
1450 goto unreg_dev;
1451
1452 mutex_init(&dev->mutex);
1453
1454
1455 INIT_LIST_HEAD(&dev->vidq.active);
1456 init_waitqueue_head(&dev->vidq.wq);
1457
1458 vfd = &dev->vdev;
1459 *vfd = vivi_template;
1460 vfd->debug = debug;
1461 vfd->v4l2_dev = &dev->v4l2_dev;
1462 vfd->queue = q;
1463 set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
1464
1465
1466
1467
1468
1469 vfd->lock = &dev->mutex;
1470 video_set_drvdata(vfd, dev);
1471
1472 ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
1473 if (ret < 0)
1474 goto unreg_dev;
1475
1476
1477 list_add_tail(&dev->vivi_devlist, &vivi_devlist);
1478
1479 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
1480 video_device_node_name(vfd));
1481 return 0;
1482
1483unreg_dev:
1484 v4l2_ctrl_handler_free(hdl);
1485 v4l2_device_unregister(&dev->v4l2_dev);
1486free_dev:
1487 kfree(dev);
1488 return ret;
1489}
1490
1491
1492
1493
1494
1495
1496
1497static int __init vivi_init(void)
1498{
1499 const struct font_desc *font = find_font("VGA8x16");
1500 int ret = 0, i;
1501
1502 if (font == NULL) {
1503 printk(KERN_ERR "vivi: could not find font\n");
1504 return -ENODEV;
1505 }
1506 font8x16 = font->data;
1507
1508 if (n_devs <= 0)
1509 n_devs = 1;
1510
1511 for (i = 0; i < n_devs; i++) {
1512 ret = vivi_create_instance(i);
1513 if (ret) {
1514
1515 if (i)
1516 ret = 0;
1517 break;
1518 }
1519 }
1520
1521 if (ret < 0) {
1522 printk(KERN_ERR "vivi: error %d while loading driver\n", ret);
1523 return ret;
1524 }
1525
1526 printk(KERN_INFO "Video Technology Magazine Virtual Video "
1527 "Capture Board ver %s successfully loaded.\n",
1528 VIVI_VERSION);
1529
1530
1531 n_devs = i;
1532
1533 return ret;
1534}
1535
1536static void __exit vivi_exit(void)
1537{
1538 vivi_release();
1539}
1540
1541module_init(vivi_init);
1542module_exit(vivi_exit);
1543