Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[linux-2.6-block.git] / drivers / media / video / vivi.c
CommitLineData
1e6dd65e
MCC
1/*
2 * Virtual Video driver - This code emulates a real video device with v4l2 api
3 *
4 * Copyright (c) 2006 by:
5 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
6 * Ted Walther <ted--a.t--enumera.com>
7 * John Sokol <sokol--a.t--videotechnology.com>
8 * http://v4l.videotechnology.com/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the BSD Licence, GNU General Public License
12 * as published by the Free Software Foundation; either version 2 of the
13 * License, or (at your option) any later version
14 */
15#include <linux/module.h>
16#include <linux/delay.h>
17#include <linux/errno.h>
18#include <linux/fs.h>
19#include <linux/kernel.h>
20#include <linux/slab.h>
21#include <linux/mm.h>
22#include <linux/ioport.h>
23#include <linux/init.h>
24#include <linux/sched.h>
25#include <linux/pci.h>
26#include <linux/random.h>
27#include <linux/version.h>
51b54029 28#include <linux/mutex.h>
1e6dd65e 29#include <linux/videodev2.h>
1095136d 30#include <linux/dma-mapping.h>
cd41e28e
MCC
31#ifdef CONFIG_VIDEO_V4L1_COMPAT
32/* Include V4L1 specific functions. Should be removed soon */
33#include <linux/videodev.h>
34#endif
f13df919 35#include <linux/interrupt.h>
5a037706 36#include <media/videobuf-vmalloc.h>
1e6dd65e 37#include <media/v4l2-common.h>
35ea11ff 38#include <media/v4l2-ioctl.h>
1e6dd65e
MCC
39#include <linux/kthread.h>
40#include <linux/highmem.h>
7dfb7103 41#include <linux/freezer.h>
1e6dd65e 42
584ce48d 43#define VIVI_MODULE_NAME "vivi"
745271ae 44
1e6dd65e
MCC
45/* Wake up at about 30 fps */
46#define WAKE_NUMERATOR 30
47#define WAKE_DENOMINATOR 1001
48#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */
49
1e6dd65e
MCC
50#include "font.h"
51
1e6dd65e 52#define VIVI_MAJOR_VERSION 0
745271ae 53#define VIVI_MINOR_VERSION 5
1e6dd65e 54#define VIVI_RELEASE 0
543323bc
MCC
55#define VIVI_VERSION \
56 KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE)
1e6dd65e 57
c820cc45
MCC
58/* Declare static vars that will be used as parameters */
59static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
c820cc45 60static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
55712ff7 61static int n_devs = 1; /* Number of virtual devices */
1e6dd65e
MCC
62
63/* supported controls */
64static struct v4l2_queryctrl vivi_qctrl[] = {
65 {
66 .id = V4L2_CID_AUDIO_VOLUME,
67 .name = "Volume",
68 .minimum = 0,
69 .maximum = 65535,
70 .step = 65535/100,
71 .default_value = 65535,
72 .flags = 0,
73 .type = V4L2_CTRL_TYPE_INTEGER,
543323bc 74 }, {
1e6dd65e
MCC
75 .id = V4L2_CID_BRIGHTNESS,
76 .type = V4L2_CTRL_TYPE_INTEGER,
77 .name = "Brightness",
78 .minimum = 0,
79 .maximum = 255,
80 .step = 1,
81 .default_value = 127,
82 .flags = 0,
83 }, {
84 .id = V4L2_CID_CONTRAST,
85 .type = V4L2_CTRL_TYPE_INTEGER,
86 .name = "Contrast",
87 .minimum = 0,
88 .maximum = 255,
89 .step = 0x1,
90 .default_value = 0x10,
91 .flags = 0,
92 }, {
93 .id = V4L2_CID_SATURATION,
94 .type = V4L2_CTRL_TYPE_INTEGER,
95 .name = "Saturation",
96 .minimum = 0,
97 .maximum = 255,
98 .step = 0x1,
99 .default_value = 127,
100 .flags = 0,
101 }, {
102 .id = V4L2_CID_HUE,
103 .type = V4L2_CTRL_TYPE_INTEGER,
104 .name = "Hue",
105 .minimum = -128,
106 .maximum = 127,
107 .step = 0x1,
108 .default_value = 0,
109 .flags = 0,
110 }
111};
112
113static int qctl_regs[ARRAY_SIZE(vivi_qctrl)];
114
6c2f9901 115#define dprintk(dev, level, fmt, arg...) \
c820cc45 116 do { \
6c2f9901 117 if (dev->vfd->debug >= (level)) \
c820cc45 118 printk(KERN_DEBUG "vivi: " fmt , ## arg); \
1e6dd65e
MCC
119 } while (0)
120
121/* ------------------------------------------------------------------
122 Basic structures
123 ------------------------------------------------------------------*/
124
125struct vivi_fmt {
126 char *name;
127 u32 fourcc; /* v4l2 format id */
128 int depth;
129};
130
131static struct vivi_fmt format = {
132 .name = "4:2:2, packed, YUYV",
133 .fourcc = V4L2_PIX_FMT_YUYV,
134 .depth = 16,
135};
136
137struct sg_to_addr {
138 int pos;
139 struct scatterlist *sg;
140};
141
142/* buffer for one video frame */
143struct vivi_buffer {
144 /* common v4l buffer stuff -- must be first */
145 struct videobuf_buffer vb;
146
147 struct vivi_fmt *fmt;
1e6dd65e
MCC
148};
149
150struct vivi_dmaqueue {
151 struct list_head active;
1e6dd65e
MCC
152
153 /* thread for generating video stream*/
154 struct task_struct *kthread;
155 wait_queue_head_t wq;
156 /* Counters to control fps rate */
157 int frame;
158 int ini_jiffies;
159};
160
161static LIST_HEAD(vivi_devlist);
162
163struct vivi_dev {
164 struct list_head vivi_devlist;
165
55862ac9 166 spinlock_t slock;
aa9dbac4 167 struct mutex mutex;
1e6dd65e
MCC
168
169 int users;
170
171 /* various device info */
f905c442 172 struct video_device *vfd;
1e6dd65e
MCC
173
174 struct vivi_dmaqueue vidq;
175
176 /* Several counters */
dfd8c04e
MCC
177 int h, m, s, ms;
178 unsigned long jiffies;
1e6dd65e 179 char timestr[13];
025341d4
MCC
180
181 int mv_count; /* Controls bars movement */
1e6dd65e
MCC
182};
183
184struct vivi_fh {
185 struct vivi_dev *dev;
186
187 /* video capture */
188 struct vivi_fmt *fmt;
543323bc 189 unsigned int width, height;
1e6dd65e
MCC
190 struct videobuf_queue vb_vidq;
191
192 enum v4l2_buf_type type;
193};
194
195/* ------------------------------------------------------------------
196 DMA and thread functions
197 ------------------------------------------------------------------*/
198
199/* Bars and Colors should match positions */
200
201enum colors {
202 WHITE,
203 AMBAR,
204 CYAN,
205 GREEN,
206 MAGENTA,
207 RED,
543323bc
MCC
208 BLUE,
209 BLACK,
1e6dd65e
MCC
210};
211
212static u8 bars[8][3] = {
213 /* R G B */
543323bc
MCC
214 {204, 204, 204}, /* white */
215 {208, 208, 0}, /* ambar */
216 { 0, 206, 206}, /* cyan */
217 { 0, 239, 0}, /* green */
218 {239, 0, 239}, /* magenta */
219 {205, 0, 0}, /* red */
220 { 0, 0, 255}, /* blue */
221 { 0, 0, 0}, /* black */
1e6dd65e
MCC
222};
223
543323bc
MCC
224#define TO_Y(r, g, b) \
225 (((16829 * r + 33039 * g + 6416 * b + 32768) >> 16) + 16)
1e6dd65e 226/* RGB to V(Cr) Color transform */
543323bc
MCC
227#define TO_V(r, g, b) \
228 (((28784 * r - 24103 * g - 4681 * b + 32768) >> 16) + 128)
1e6dd65e 229/* RGB to U(Cb) Color transform */
543323bc
MCC
230#define TO_U(r, g, b) \
231 (((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128)
1e6dd65e
MCC
232
233#define TSTAMP_MIN_Y 24
234#define TSTAMP_MAX_Y TSTAMP_MIN_Y+15
235#define TSTAMP_MIN_X 64
236
543323bc
MCC
237static void gen_line(char *basep, int inipos, int wmax,
238 int hmax, int line, int count, char *timestr)
1e6dd65e 239{
543323bc
MCC
240 int w, i, j, y;
241 int pos = inipos;
242 char *p, *s;
243 u8 chr, r, g, b, color;
1e6dd65e
MCC
244
245 /* We will just duplicate the second pixel at the packet */
543323bc 246 wmax /= 2;
1e6dd65e
MCC
247
248 /* Generate a standard color bar pattern */
543323bc
MCC
249 for (w = 0; w < wmax; w++) {
250 int colorpos = ((w + count) * 8/(wmax + 1)) % 8;
251 r = bars[colorpos][0];
252 g = bars[colorpos][1];
253 b = bars[colorpos][2];
1e6dd65e 254
543323bc
MCC
255 for (color = 0; color < 4; color++) {
256 p = basep + pos;
1e6dd65e
MCC
257
258 switch (color) {
543323bc
MCC
259 case 0:
260 case 2:
261 *p = TO_Y(r, g, b); /* Luma */
262 break;
263 case 1:
264 *p = TO_U(r, g, b); /* Cb */
265 break;
266 case 3:
267 *p = TO_V(r, g, b); /* Cr */
268 break;
1e6dd65e
MCC
269 }
270 pos++;
271 }
272 }
273
274 /* Checks if it is possible to show timestamp */
543323bc 275 if (TSTAMP_MAX_Y >= hmax)
1e6dd65e 276 goto end;
543323bc 277 if (TSTAMP_MIN_X + strlen(timestr) >= wmax)
1e6dd65e
MCC
278 goto end;
279
280 /* Print stream time */
543323bc
MCC
281 if (line >= TSTAMP_MIN_Y && line <= TSTAMP_MAX_Y) {
282 j = TSTAMP_MIN_X;
283 for (s = timestr; *s; s++) {
284 chr = rom8x16_bits[(*s-0x30)*16+line-TSTAMP_MIN_Y];
285 for (i = 0; i < 7; i++) {
286 if (chr & 1 << (7 - i)) {
287 /* Font color*/
288 r = 0;
289 g = 198;
290 b = 0;
291 } else {
292 /* Background color */
293 r = bars[BLACK][0];
294 g = bars[BLACK][1];
295 b = bars[BLACK][2];
1e6dd65e
MCC
296 }
297
543323bc
MCC
298 pos = inipos + j * 2;
299 for (color = 0; color < 4; color++) {
300 p = basep + pos;
1e6dd65e 301
543323bc 302 y = TO_Y(r, g, b);
1e6dd65e
MCC
303
304 switch (color) {
543323bc
MCC
305 case 0:
306 case 2:
307 *p = TO_Y(r, g, b); /* Luma */
308 break;
309 case 1:
310 *p = TO_U(r, g, b); /* Cb */
311 break;
312 case 3:
313 *p = TO_V(r, g, b); /* Cr */
314 break;
1e6dd65e
MCC
315 }
316 pos++;
317 }
318 j++;
319 }
320 }
321 }
322
1e6dd65e 323end:
b50e7fe9 324 return;
1e6dd65e 325}
78718e5d 326
543323bc 327static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
1e6dd65e 328{
543323bc 329 int h , pos = 0;
1e6dd65e
MCC
330 int hmax = buf->vb.height;
331 int wmax = buf->vb.width;
1e6dd65e 332 struct timeval ts;
5c554e6b 333 char *tmpbuf;
543323bc 334 void *vbuf = videobuf_to_vmalloc(&buf->vb);
b50e7fe9 335
5c554e6b 336 if (!vbuf)
5a037706 337 return;
1e6dd65e 338
5c554e6b
MS
339 tmpbuf = kmalloc(wmax * 2, GFP_ATOMIC);
340 if (!tmpbuf)
78718e5d
BP
341 return;
342
543323bc 343 for (h = 0; h < hmax; h++) {
025341d4 344 gen_line(tmpbuf, 0, wmax, hmax, h, dev->mv_count,
3bef5e4a 345 dev->timestr);
78718e5d 346 memcpy(vbuf + pos, tmpbuf, wmax * 2);
1e6dd65e
MCC
347 pos += wmax*2;
348 }
349
025341d4 350 dev->mv_count++;
3bef5e4a 351
5a037706
MCC
352 kfree(tmpbuf);
353
1e6dd65e
MCC
354 /* Updates stream time */
355
dfd8c04e 356 dev->ms += jiffies_to_msecs(jiffies-dev->jiffies);
543323bc 357 dev->jiffies = jiffies;
dfd8c04e
MCC
358 if (dev->ms >= 1000) {
359 dev->ms -= 1000;
1e6dd65e 360 dev->s++;
543323bc
MCC
361 if (dev->s >= 60) {
362 dev->s -= 60;
1e6dd65e 363 dev->m++;
543323bc
MCC
364 if (dev->m > 60) {
365 dev->m -= 60;
1e6dd65e 366 dev->h++;
543323bc
MCC
367 if (dev->h > 24)
368 dev->h -= 24;
1e6dd65e
MCC
369 }
370 }
371 }
543323bc 372 sprintf(dev->timestr, "%02d:%02d:%02d:%03d",
dfd8c04e 373 dev->h, dev->m, dev->s, dev->ms);
1e6dd65e 374
6c2f9901
MCC
375 dprintk(dev, 2, "vivifill at %s: Buffer 0x%08lx size= %d\n",
376 dev->timestr, (unsigned long)tmpbuf, pos);
1e6dd65e
MCC
377
378 /* Advice that buffer was filled */
1e6dd65e
MCC
379 buf->vb.field_count++;
380 do_gettimeofday(&ts);
381 buf->vb.ts = ts;
78718e5d 382 buf->vb.state = VIDEOBUF_DONE;
1e6dd65e
MCC
383}
384
78718e5d 385static void vivi_thread_tick(struct vivi_fh *fh)
1e6dd65e 386{
78718e5d
BP
387 struct vivi_buffer *buf;
388 struct vivi_dev *dev = fh->dev;
389 struct vivi_dmaqueue *dma_q = &dev->vidq;
1e6dd65e 390
78718e5d 391 unsigned long flags = 0;
1e6dd65e 392
78718e5d 393 dprintk(dev, 1, "Thread tick\n");
1e6dd65e 394
78718e5d
BP
395 spin_lock_irqsave(&dev->slock, flags);
396 if (list_empty(&dma_q->active)) {
397 dprintk(dev, 1, "No active queue to serve\n");
398 goto unlock;
399 }
1e6dd65e 400
78718e5d
BP
401 buf = list_entry(dma_q->active.next,
402 struct vivi_buffer, vb.queue);
1e6dd65e 403
78718e5d
BP
404 /* Nobody is waiting on this buffer, return */
405 if (!waitqueue_active(&buf->vb.done))
406 goto unlock;
1e6dd65e 407
78718e5d 408 list_del(&buf->vb.queue);
0b600512 409
78718e5d
BP
410 do_gettimeofday(&buf->vb.ts);
411
412 /* Fill buffer */
413 vivi_fillbuff(dev, buf);
414 dprintk(dev, 1, "filled buffer %p\n", buf);
415
416 wake_up(&buf->vb.done);
417 dprintk(dev, 2, "[%p/%d] wakeup\n", buf, buf->vb. i);
418unlock:
419 spin_unlock_irqrestore(&dev->slock, flags);
420 return;
1e6dd65e
MCC
421}
422
6594ad82
MCC
423#define frames_to_ms(frames) \
424 ((frames * WAKE_NUMERATOR * 1000) / WAKE_DENOMINATOR)
425
78718e5d 426static void vivi_sleep(struct vivi_fh *fh)
1e6dd65e 427{
78718e5d
BP
428 struct vivi_dev *dev = fh->dev;
429 struct vivi_dmaqueue *dma_q = &dev->vidq;
430 int timeout;
1e6dd65e
MCC
431 DECLARE_WAITQUEUE(wait, current);
432
7e28adb2 433 dprintk(dev, 1, "%s dma_q=0x%08lx\n", __func__,
6c2f9901 434 (unsigned long)dma_q);
1e6dd65e
MCC
435
436 add_wait_queue(&dma_q->wq, &wait);
6594ad82
MCC
437 if (kthread_should_stop())
438 goto stop_task;
439
6594ad82 440 /* Calculate time to wake up */
78718e5d 441 timeout = msecs_to_jiffies(frames_to_ms(1));
6594ad82 442
78718e5d 443 vivi_thread_tick(fh);
6594ad82
MCC
444
445 schedule_timeout_interruptible(timeout);
1e6dd65e 446
6594ad82 447stop_task:
1e6dd65e
MCC
448 remove_wait_queue(&dma_q->wq, &wait);
449 try_to_freeze();
450}
451
972c3517 452static int vivi_thread(void *data)
1e6dd65e 453{
78718e5d
BP
454 struct vivi_fh *fh = data;
455 struct vivi_dev *dev = fh->dev;
1e6dd65e 456
6c2f9901 457 dprintk(dev, 1, "thread started\n");
1e6dd65e 458
83144186 459 set_freezable();
0b600512 460
1e6dd65e 461 for (;;) {
78718e5d 462 vivi_sleep(fh);
1e6dd65e
MCC
463
464 if (kthread_should_stop())
465 break;
466 }
6c2f9901 467 dprintk(dev, 1, "thread: exit\n");
1e6dd65e
MCC
468 return 0;
469}
470
78718e5d 471static int vivi_start_thread(struct vivi_fh *fh)
1e6dd65e 472{
78718e5d
BP
473 struct vivi_dev *dev = fh->dev;
474 struct vivi_dmaqueue *dma_q = &dev->vidq;
6c2f9901 475
543323bc
MCC
476 dma_q->frame = 0;
477 dma_q->ini_jiffies = jiffies;
1e6dd65e 478
7e28adb2 479 dprintk(dev, 1, "%s\n", __func__);
1e6dd65e 480
78718e5d 481 dma_q->kthread = kthread_run(vivi_thread, fh, "vivi");
1e6dd65e 482
054afee4 483 if (IS_ERR(dma_q->kthread)) {
1e6dd65e 484 printk(KERN_ERR "vivi: kernel_thread() failed\n");
054afee4 485 return PTR_ERR(dma_q->kthread);
1e6dd65e 486 }
0b600512
MCC
487 /* Wakes thread */
488 wake_up_interruptible(&dma_q->wq);
489
7e28adb2 490 dprintk(dev, 1, "returning from %s\n", __func__);
1e6dd65e
MCC
491 return 0;
492}
493
972c3517 494static void vivi_stop_thread(struct vivi_dmaqueue *dma_q)
1e6dd65e 495{
6c2f9901
MCC
496 struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq);
497
7e28adb2 498 dprintk(dev, 1, "%s\n", __func__);
1e6dd65e
MCC
499 /* shutdown control thread */
500 if (dma_q->kthread) {
501 kthread_stop(dma_q->kthread);
543323bc 502 dma_q->kthread = NULL;
1e6dd65e
MCC
503 }
504}
505
1e6dd65e
MCC
506/* ------------------------------------------------------------------
507 Videobuf operations
508 ------------------------------------------------------------------*/
509static int
510buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
511{
6c2f9901
MCC
512 struct vivi_fh *fh = vq->priv_data;
513 struct vivi_dev *dev = fh->dev;
1e6dd65e
MCC
514
515 *size = fh->width*fh->height*2;
516
517 if (0 == *count)
518 *count = 32;
6bb2790f 519
1e6dd65e
MCC
520 while (*size * *count > vid_limit * 1024 * 1024)
521 (*count)--;
6bb2790f 522
7e28adb2 523 dprintk(dev, 1, "%s, count=%d, size=%d\n", __func__,
6c2f9901 524 *count, *size);
6bb2790f 525
1e6dd65e
MCC
526 return 0;
527}
528
972c3517 529static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf)
1e6dd65e 530{
6c2f9901
MCC
531 struct vivi_fh *fh = vq->priv_data;
532 struct vivi_dev *dev = fh->dev;
533
7e28adb2 534 dprintk(dev, 1, "%s, state: %i\n", __func__, buf->vb.state);
1e6dd65e
MCC
535
536 if (in_interrupt())
537 BUG();
538
5a037706 539 videobuf_vmalloc_free(&buf->vb);
fbde31d5 540 dprintk(dev, 1, "free_buffer: freed\n");
0fc0686e 541 buf->vb.state = VIDEOBUF_NEEDS_INIT;
1e6dd65e
MCC
542}
543
544#define norm_maxw() 1024
545#define norm_maxh() 768
546static int
547buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
548 enum v4l2_field field)
549{
550 struct vivi_fh *fh = vq->priv_data;
6c2f9901 551 struct vivi_dev *dev = fh->dev;
543323bc 552 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb);
78718e5d 553 int rc;
1e6dd65e 554
7e28adb2 555 dprintk(dev, 1, "%s, field=%d\n", __func__, field);
1e6dd65e
MCC
556
557 BUG_ON(NULL == fh->fmt);
78718e5d 558
1e6dd65e
MCC
559 if (fh->width < 48 || fh->width > norm_maxw() ||
560 fh->height < 32 || fh->height > norm_maxh())
561 return -EINVAL;
78718e5d 562
1e6dd65e
MCC
563 buf->vb.size = fh->width*fh->height*2;
564 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
565 return -EINVAL;
566
78718e5d
BP
567 /* These properties only change when queue is idle, see s_fmt */
568 buf->fmt = fh->fmt;
569 buf->vb.width = fh->width;
570 buf->vb.height = fh->height;
571 buf->vb.field = field;
1e6dd65e 572
0fc0686e 573 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
543323bc
MCC
574 rc = videobuf_iolock(vq, &buf->vb, NULL);
575 if (rc < 0)
1e6dd65e
MCC
576 goto fail;
577 }
578
0fc0686e 579 buf->vb.state = VIDEOBUF_PREPARED;
1e6dd65e 580
1e6dd65e
MCC
581 return 0;
582
583fail:
543323bc 584 free_buffer(vq, buf);
1e6dd65e
MCC
585 return rc;
586}
587
588static void
589buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
590{
543323bc
MCC
591 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb);
592 struct vivi_fh *fh = vq->priv_data;
593 struct vivi_dev *dev = fh->dev;
78718e5d
BP
594 struct vivi_dmaqueue *vidq = &dev->vidq;
595
7e28adb2 596 dprintk(dev, 1, "%s\n", __func__);
78718e5d
BP
597
598 buf->vb.state = VIDEOBUF_QUEUED;
599 list_add_tail(&buf->vb.queue, &vidq->active);
1e6dd65e
MCC
600}
601
543323bc
MCC
602static void buffer_release(struct videobuf_queue *vq,
603 struct videobuf_buffer *vb)
1e6dd65e 604{
543323bc 605 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb);
1e6dd65e 606 struct vivi_fh *fh = vq->priv_data;
543323bc 607 struct vivi_dev *dev = (struct vivi_dev *)fh->dev;
1e6dd65e 608
7e28adb2 609 dprintk(dev, 1, "%s\n", __func__);
1e6dd65e 610
543323bc 611 free_buffer(vq, buf);
1e6dd65e
MCC
612}
613
1e6dd65e
MCC
614static struct videobuf_queue_ops vivi_video_qops = {
615 .buf_setup = buffer_setup,
616 .buf_prepare = buffer_prepare,
617 .buf_queue = buffer_queue,
618 .buf_release = buffer_release,
1e6dd65e
MCC
619};
620
c820cc45
MCC
621/* ------------------------------------------------------------------
622 IOCTL vidioc handling
623 ------------------------------------------------------------------*/
543323bc 624static int vidioc_querycap(struct file *file, void *priv,
c820cc45
MCC
625 struct v4l2_capability *cap)
626{
627 strcpy(cap->driver, "vivi");
628 strcpy(cap->card, "vivi");
629 cap->version = VIVI_VERSION;
630 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
631 V4L2_CAP_STREAMING |
632 V4L2_CAP_READWRITE;
633 return 0;
634}
635
78b526a4 636static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
c820cc45
MCC
637 struct v4l2_fmtdesc *f)
638{
639 if (f->index > 0)
640 return -EINVAL;
641
543323bc 642 strlcpy(f->description, format.name, sizeof(f->description));
c820cc45
MCC
643 f->pixelformat = format.fourcc;
644 return 0;
645}
646
78b526a4 647static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
c820cc45
MCC
648 struct v4l2_format *f)
649{
543323bc 650 struct vivi_fh *fh = priv;
c820cc45
MCC
651
652 f->fmt.pix.width = fh->width;
653 f->fmt.pix.height = fh->height;
654 f->fmt.pix.field = fh->vb_vidq.field;
655 f->fmt.pix.pixelformat = fh->fmt->fourcc;
656 f->fmt.pix.bytesperline =
657 (f->fmt.pix.width * fh->fmt->depth) >> 3;
658 f->fmt.pix.sizeimage =
659 f->fmt.pix.height * f->fmt.pix.bytesperline;
660
661 return (0);
662}
663
78b526a4 664static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
1e6dd65e
MCC
665 struct v4l2_format *f)
666{
6c2f9901
MCC
667 struct vivi_fh *fh = priv;
668 struct vivi_dev *dev = fh->dev;
1e6dd65e
MCC
669 struct vivi_fmt *fmt;
670 enum v4l2_field field;
671 unsigned int maxw, maxh;
672
673 if (format.fourcc != f->fmt.pix.pixelformat) {
6c2f9901
MCC
674 dprintk(dev, 1, "Fourcc format (0x%08x) invalid. "
675 "Driver accepts only 0x%08x\n",
676 f->fmt.pix.pixelformat, format.fourcc);
1e6dd65e
MCC
677 return -EINVAL;
678 }
543323bc 679 fmt = &format;
1e6dd65e
MCC
680
681 field = f->fmt.pix.field;
682
683 if (field == V4L2_FIELD_ANY) {
543323bc 684 field = V4L2_FIELD_INTERLACED;
1e6dd65e 685 } else if (V4L2_FIELD_INTERLACED != field) {
6c2f9901 686 dprintk(dev, 1, "Field type invalid.\n");
1e6dd65e
MCC
687 return -EINVAL;
688 }
689
690 maxw = norm_maxw();
691 maxh = norm_maxh();
692
693 f->fmt.pix.field = field;
694 if (f->fmt.pix.height < 32)
695 f->fmt.pix.height = 32;
696 if (f->fmt.pix.height > maxh)
697 f->fmt.pix.height = maxh;
698 if (f->fmt.pix.width < 48)
699 f->fmt.pix.width = 48;
700 if (f->fmt.pix.width > maxw)
701 f->fmt.pix.width = maxw;
702 f->fmt.pix.width &= ~0x03;
703 f->fmt.pix.bytesperline =
704 (f->fmt.pix.width * fmt->depth) >> 3;
705 f->fmt.pix.sizeimage =
706 f->fmt.pix.height * f->fmt.pix.bytesperline;
707
708 return 0;
709}
710
c820cc45 711/*FIXME: This seems to be generic enough to be at videodev2 */
78b526a4 712static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
c820cc45 713 struct v4l2_format *f)
1e6dd65e 714{
543323bc 715 struct vivi_fh *fh = priv;
78718e5d
BP
716 struct videobuf_queue *q = &fh->vb_vidq;
717
78b526a4 718 int ret = vidioc_try_fmt_vid_cap(file, fh, f);
c820cc45
MCC
719 if (ret < 0)
720 return (ret);
721
78718e5d
BP
722 mutex_lock(&q->vb_lock);
723
724 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
7e28adb2 725 dprintk(fh->dev, 1, "%s queue busy\n", __func__);
78718e5d
BP
726 ret = -EBUSY;
727 goto out;
728 }
729
c820cc45
MCC
730 fh->fmt = &format;
731 fh->width = f->fmt.pix.width;
732 fh->height = f->fmt.pix.height;
733 fh->vb_vidq.field = f->fmt.pix.field;
734 fh->type = f->type;
735
78718e5d
BP
736 ret = 0;
737out:
738 mutex_unlock(&q->vb_lock);
739
740 return (ret);
1e6dd65e
MCC
741}
742
543323bc
MCC
743static int vidioc_reqbufs(struct file *file, void *priv,
744 struct v4l2_requestbuffers *p)
1e6dd65e 745{
543323bc 746 struct vivi_fh *fh = priv;
1e6dd65e 747
c820cc45 748 return (videobuf_reqbufs(&fh->vb_vidq, p));
1e6dd65e
MCC
749}
750
543323bc 751static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1e6dd65e 752{
543323bc 753 struct vivi_fh *fh = priv;
1e6dd65e 754
c820cc45
MCC
755 return (videobuf_querybuf(&fh->vb_vidq, p));
756}
1e6dd65e 757
543323bc 758static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
c820cc45 759{
543323bc 760 struct vivi_fh *fh = priv;
1e6dd65e 761
c820cc45
MCC
762 return (videobuf_qbuf(&fh->vb_vidq, p));
763}
1e6dd65e 764
543323bc 765static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
c820cc45 766{
543323bc 767 struct vivi_fh *fh = priv;
1e6dd65e 768
c820cc45
MCC
769 return (videobuf_dqbuf(&fh->vb_vidq, p,
770 file->f_flags & O_NONBLOCK));
771}
1e6dd65e 772
0dfa9abd 773#ifdef CONFIG_VIDEO_V4L1_COMPAT
543323bc 774static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
c820cc45 775{
543323bc 776 struct vivi_fh *fh = priv;
4ceb04e1 777
543323bc 778 return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
c820cc45
MCC
779}
780#endif
1e6dd65e 781
dc46ace1 782static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
c820cc45 783{
543323bc 784 struct vivi_fh *fh = priv;
1e6dd65e 785
c820cc45
MCC
786 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
787 return -EINVAL;
788 if (i != fh->type)
789 return -EINVAL;
1e6dd65e 790
ba32bd95 791 return videobuf_streamon(&fh->vb_vidq);
c820cc45 792}
1e6dd65e 793
dc46ace1 794static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
c820cc45 795{
543323bc 796 struct vivi_fh *fh = priv;
1e6dd65e 797
c820cc45
MCC
798 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
799 return -EINVAL;
800 if (i != fh->type)
801 return -EINVAL;
1e6dd65e 802
ba32bd95 803 return videobuf_streamoff(&fh->vb_vidq);
c820cc45
MCC
804}
805
543323bc 806static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
c820cc45 807{
c820cc45
MCC
808 return 0;
809}
1e6dd65e 810
c820cc45 811/* only one input in this sample driver */
543323bc 812static int vidioc_enum_input(struct file *file, void *priv,
c820cc45
MCC
813 struct v4l2_input *inp)
814{
815 if (inp->index != 0)
816 return -EINVAL;
1e6dd65e 817
c820cc45 818 inp->type = V4L2_INPUT_TYPE_CAMERA;
784c668b 819 inp->std = V4L2_STD_525_60;
543323bc 820 strcpy(inp->name, "Camera");
1e6dd65e 821
c820cc45
MCC
822 return (0);
823}
1e6dd65e 824
543323bc 825static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
c820cc45
MCC
826{
827 *i = 0;
1e6dd65e 828
c820cc45
MCC
829 return (0);
830}
543323bc 831static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
c820cc45
MCC
832{
833 if (i > 0)
834 return -EINVAL;
1e6dd65e 835
c820cc45
MCC
836 return (0);
837}
1e6dd65e
MCC
838
839 /* --- controls ---------------------------------------------- */
543323bc
MCC
840static int vidioc_queryctrl(struct file *file, void *priv,
841 struct v4l2_queryctrl *qc)
c820cc45
MCC
842{
843 int i;
1e6dd65e 844
c820cc45
MCC
845 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
846 if (qc->id && qc->id == vivi_qctrl[i].id) {
847 memcpy(qc, &(vivi_qctrl[i]),
848 sizeof(*qc));
849 return (0);
850 }
1e6dd65e 851
c820cc45
MCC
852 return -EINVAL;
853}
1e6dd65e 854
543323bc
MCC
855static int vidioc_g_ctrl(struct file *file, void *priv,
856 struct v4l2_control *ctrl)
c820cc45
MCC
857{
858 int i;
1e6dd65e 859
c820cc45
MCC
860 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
861 if (ctrl->id == vivi_qctrl[i].id) {
543323bc 862 ctrl->value = qctl_regs[i];
c820cc45
MCC
863 return (0);
864 }
1e6dd65e 865
c820cc45 866 return -EINVAL;
1e6dd65e 867}
543323bc 868static int vidioc_s_ctrl(struct file *file, void *priv,
c820cc45 869 struct v4l2_control *ctrl)
1e6dd65e 870{
c820cc45
MCC
871 int i;
872
873 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
874 if (ctrl->id == vivi_qctrl[i].id) {
543323bc
MCC
875 if (ctrl->value < vivi_qctrl[i].minimum
876 || ctrl->value > vivi_qctrl[i].maximum) {
c820cc45
MCC
877 return (-ERANGE);
878 }
543323bc 879 qctl_regs[i] = ctrl->value;
c820cc45
MCC
880 return (0);
881 }
882 return -EINVAL;
1e6dd65e
MCC
883}
884
885/* ------------------------------------------------------------------
886 File operations for the device
887 ------------------------------------------------------------------*/
888
889#define line_buf_size(norm) (norm_maxw(norm)*(format.depth+7)/8)
890
891static int vivi_open(struct inode *inode, struct file *file)
892{
893 int minor = iminor(inode);
a991f44b 894 struct vivi_dev *dev;
63b79cfa 895 struct vivi_fh *fh = NULL;
1e6dd65e 896 int i;
aa9dbac4 897 int retval = 0;
1e6dd65e 898
543323bc 899 printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor);
1e6dd65e 900
d56dc612 901 lock_kernel();
a991f44b 902 list_for_each_entry(dev, &vivi_devlist, vivi_devlist)
f905c442 903 if (dev->vfd->minor == minor)
a991f44b 904 goto found;
d56dc612 905 unlock_kernel();
a991f44b 906 return -ENODEV;
c820cc45 907
543323bc 908found:
aa9dbac4 909 mutex_lock(&dev->mutex);
1e6dd65e
MCC
910 dev->users++;
911
aa9dbac4
BP
912 if (dev->users > 1) {
913 dev->users--;
914 retval = -EBUSY;
915 goto unlock;
916 }
917
6c2f9901 918 dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor,
a991f44b 919 v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users);
1e6dd65e
MCC
920
921 /* allocate + initialize per filehandle data */
543323bc 922 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
1e6dd65e
MCC
923 if (NULL == fh) {
924 dev->users--;
aa9dbac4
BP
925 retval = -ENOMEM;
926 goto unlock;
1e6dd65e 927 }
aa9dbac4
BP
928unlock:
929 mutex_unlock(&dev->mutex);
d56dc612
HV
930 if (retval) {
931 unlock_kernel();
aa9dbac4 932 return retval;
d56dc612 933 }
1e6dd65e
MCC
934
935 file->private_data = fh;
936 fh->dev = dev;
c820cc45 937
1e6dd65e
MCC
938 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
939 fh->fmt = &format;
940 fh->width = 640;
941 fh->height = 480;
942
943 /* Put all controls at a sane state */
944 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
543323bc 945 qctl_regs[i] = vivi_qctrl[i].default_value;
1e6dd65e
MCC
946
947 /* Resets frame counters */
543323bc
MCC
948 dev->h = 0;
949 dev->m = 0;
950 dev->s = 0;
dfd8c04e 951 dev->ms = 0;
543323bc
MCC
952 dev->mv_count = 0;
953 dev->jiffies = jiffies;
954 sprintf(dev->timestr, "%02d:%02d:%02d:%03d",
dfd8c04e 955 dev->h, dev->m, dev->s, dev->ms);
1e6dd65e 956
5a037706 957 videobuf_queue_vmalloc_init(&fh->vb_vidq, &vivi_video_qops,
55862ac9 958 NULL, &dev->slock, fh->type, V4L2_FIELD_INTERLACED,
543323bc 959 sizeof(struct vivi_buffer), fh);
1e6dd65e 960
78718e5d 961 vivi_start_thread(fh);
d56dc612 962 unlock_kernel();
78718e5d 963
1e6dd65e
MCC
964 return 0;
965}
966
967static ssize_t
968vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
969{
543323bc 970 struct vivi_fh *fh = file->private_data;
1e6dd65e 971
543323bc 972 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
acb09af4 973 return videobuf_read_stream(&fh->vb_vidq, data, count, ppos, 0,
1e6dd65e
MCC
974 file->f_flags & O_NONBLOCK);
975 }
976 return 0;
977}
978
979static unsigned int
980vivi_poll(struct file *file, struct poll_table_struct *wait)
981{
c820cc45 982 struct vivi_fh *fh = file->private_data;
6c2f9901 983 struct vivi_dev *dev = fh->dev;
85c7c70b 984 struct videobuf_queue *q = &fh->vb_vidq;
1e6dd65e 985
7e28adb2 986 dprintk(dev, 1, "%s\n", __func__);
1e6dd65e
MCC
987
988 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
989 return POLLERR;
990
85c7c70b 991 return videobuf_poll_stream(file, q, wait);
1e6dd65e
MCC
992}
993
f905c442 994static int vivi_close(struct inode *inode, struct file *file)
1e6dd65e 995{
c820cc45
MCC
996 struct vivi_fh *fh = file->private_data;
997 struct vivi_dev *dev = fh->dev;
1e6dd65e
MCC
998 struct vivi_dmaqueue *vidq = &dev->vidq;
999
1000 int minor = iminor(inode);
1001
1002 vivi_stop_thread(vidq);
053fcb60 1003 videobuf_stop(&fh->vb_vidq);
1e6dd65e
MCC
1004 videobuf_mmap_free(&fh->vb_vidq);
1005
55712ff7 1006 kfree(fh);
1e6dd65e 1007
aa9dbac4 1008 mutex_lock(&dev->mutex);
1e6dd65e 1009 dev->users--;
aa9dbac4 1010 mutex_unlock(&dev->mutex);
1e6dd65e 1011
6c2f9901
MCC
1012 dprintk(dev, 1, "close called (minor=%d, users=%d)\n",
1013 minor, dev->users);
1e6dd65e
MCC
1014
1015 return 0;
1016}
1017
55712ff7 1018static int vivi_release(void)
f905c442 1019{
55712ff7
MCC
1020 struct vivi_dev *dev;
1021 struct list_head *list;
1022
1023 while (!list_empty(&vivi_devlist)) {
1024 list = vivi_devlist.next;
1025 list_del(list);
1026 dev = list_entry(list, struct vivi_dev, vivi_devlist);
f905c442 1027
745271ae 1028 if (-1 != dev->vfd->minor) {
8da9bae3 1029 printk(KERN_INFO "%s: unregistering /dev/video%d\n",
584ce48d 1030 VIVI_MODULE_NAME, dev->vfd->minor);
8da9bae3 1031 video_unregister_device(dev->vfd);
745271ae 1032 } else {
8da9bae3 1033 printk(KERN_INFO "%s: releasing /dev/video%d\n",
584ce48d 1034 VIVI_MODULE_NAME, dev->vfd->minor);
8da9bae3 1035 video_device_release(dev->vfd);
745271ae 1036 }
55712ff7
MCC
1037
1038 kfree(dev);
1039 }
f905c442
MCC
1040
1041 return 0;
1042}
1043
543323bc 1044static int vivi_mmap(struct file *file, struct vm_area_struct *vma)
1e6dd65e 1045{
6c2f9901
MCC
1046 struct vivi_fh *fh = file->private_data;
1047 struct vivi_dev *dev = fh->dev;
1e6dd65e
MCC
1048 int ret;
1049
6c2f9901 1050 dprintk(dev, 1, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
1e6dd65e 1051
543323bc 1052 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
1e6dd65e 1053
6c2f9901 1054 dprintk(dev, 1, "vma start=0x%08lx, size=%ld, ret=%d\n",
1e6dd65e
MCC
1055 (unsigned long)vma->vm_start,
1056 (unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
1057 ret);
1058
1059 return ret;
1060}
1061
fa027c2a 1062static const struct file_operations vivi_fops = {
1e6dd65e
MCC
1063 .owner = THIS_MODULE,
1064 .open = vivi_open,
f905c442 1065 .release = vivi_close,
1e6dd65e
MCC
1066 .read = vivi_read,
1067 .poll = vivi_poll,
c820cc45 1068 .ioctl = video_ioctl2, /* V4L2 ioctl handler */
fbde31d5 1069 .compat_ioctl = v4l_compat_ioctl32,
5a037706 1070 .mmap = vivi_mmap,
1e6dd65e
MCC
1071 .llseek = no_llseek,
1072};
1073
a399810c 1074static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
c820cc45 1075 .vidioc_querycap = vidioc_querycap,
78b526a4
HV
1076 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1077 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1078 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1079 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
c820cc45
MCC
1080 .vidioc_reqbufs = vidioc_reqbufs,
1081 .vidioc_querybuf = vidioc_querybuf,
1082 .vidioc_qbuf = vidioc_qbuf,
1083 .vidioc_dqbuf = vidioc_dqbuf,
1084 .vidioc_s_std = vidioc_s_std,
1085 .vidioc_enum_input = vidioc_enum_input,
1086 .vidioc_g_input = vidioc_g_input,
1087 .vidioc_s_input = vidioc_s_input,
1088 .vidioc_queryctrl = vidioc_queryctrl,
1089 .vidioc_g_ctrl = vidioc_g_ctrl,
1090 .vidioc_s_ctrl = vidioc_s_ctrl,
1091 .vidioc_streamon = vidioc_streamon,
1092 .vidioc_streamoff = vidioc_streamoff,
0dfa9abd 1093#ifdef CONFIG_VIDEO_V4L1_COMPAT
c820cc45
MCC
1094 .vidiocgmbuf = vidiocgmbuf,
1095#endif
a399810c
HV
1096};
1097
1098static struct video_device vivi_template = {
1099 .name = "vivi",
a399810c
HV
1100 .fops = &vivi_fops,
1101 .ioctl_ops = &vivi_ioctl_ops,
1102 .minor = -1,
1103 .release = video_device_release,
1104
784c668b 1105 .tvnorms = V4L2_STD_525_60,
e75f9cee 1106 .current_norm = V4L2_STD_NTSC_M,
1e6dd65e 1107};
c820cc45 1108/* -----------------------------------------------------------------
1e6dd65e
MCC
1109 Initialization and module stuff
1110 ------------------------------------------------------------------*/
1111
980d4f17
MCC
1112/* This routine allocates from 1 to n_devs virtual drivers.
1113
1114 The real maximum number of virtual drivers will depend on how many drivers
1115 will succeed. This is limited to the maximum number of devices that
1116 videodev supports. Since there are 64 minors for video grabbers, this is
1117 currently the theoretical maximum limit. However, a further limit does
1118 exist at videodev that forbids any driver to register more than 32 video
1119 grabbers.
1120 */
1e6dd65e
MCC
1121static int __init vivi_init(void)
1122{
55712ff7 1123 int ret = -ENOMEM, i;
1e6dd65e 1124 struct vivi_dev *dev;
f905c442 1125 struct video_device *vfd;
1e6dd65e 1126
980d4f17
MCC
1127 if (n_devs <= 0)
1128 n_devs = 1;
1129
55712ff7
MCC
1130 for (i = 0; i < n_devs; i++) {
1131 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
980d4f17 1132 if (!dev)
55712ff7 1133 break;
1e6dd65e 1134
55712ff7
MCC
1135 /* init video dma queues */
1136 INIT_LIST_HEAD(&dev->vidq.active);
55712ff7 1137 init_waitqueue_head(&dev->vidq.wq);
1e6dd65e 1138
55712ff7 1139 /* initialize locks */
55862ac9 1140 spin_lock_init(&dev->slock);
aa9dbac4 1141 mutex_init(&dev->mutex);
1e6dd65e 1142
55712ff7 1143 vfd = video_device_alloc();
980d4f17
MCC
1144 if (!vfd) {
1145 kfree(dev);
55712ff7 1146 break;
980d4f17 1147 }
55712ff7
MCC
1148
1149 *vfd = vivi_template;
1150
1151 ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
980d4f17
MCC
1152 if (ret < 0) {
1153 video_device_release(vfd);
1154 kfree(dev);
1155
1156 /* If some registers succeeded, keep driver */
1157 if (i)
1158 ret = 0;
1159
55712ff7 1160 break;
980d4f17
MCC
1161 }
1162
1163 /* Now that everything is fine, let's add it to device list */
1164 list_add_tail(&dev->vivi_devlist, &vivi_devlist);
55712ff7
MCC
1165
1166 snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
1167 vivi_template.name, vfd->minor);
f905c442 1168
55712ff7
MCC
1169 if (video_nr >= 0)
1170 video_nr++;
f905c442 1171
55712ff7 1172 dev->vfd = vfd;
745271ae 1173 printk(KERN_INFO "%s: V4L2 device registered as /dev/video%d\n",
584ce48d 1174 VIVI_MODULE_NAME, vfd->minor);
55712ff7 1175 }
f905c442 1176
55712ff7
MCC
1177 if (ret < 0) {
1178 vivi_release();
1179 printk(KERN_INFO "Error %d while loading vivi driver\n", ret);
980d4f17 1180 } else {
55712ff7 1181 printk(KERN_INFO "Video Technology Magazine Virtual Video "
745271ae
CK
1182 "Capture Board ver %u.%u.%u successfully loaded.\n",
1183 (VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF,
1184 VIVI_VERSION & 0xFF);
980d4f17
MCC
1185
1186 /* n_devs will reflect the actual number of allocated devices */
1187 n_devs = i;
1188 }
1189
1e6dd65e
MCC
1190 return ret;
1191}
1192
1193static void __exit vivi_exit(void)
1194{
55712ff7 1195 vivi_release();
1e6dd65e
MCC
1196}
1197
1198module_init(vivi_init);
1199module_exit(vivi_exit);
c820cc45
MCC
1200
1201MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
1202MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
1203MODULE_LICENSE("Dual BSD/GPL");
1204
980d4f17 1205module_param(video_nr, uint, 0444);
55712ff7 1206MODULE_PARM_DESC(video_nr, "video iminor start number");
c820cc45 1207
980d4f17 1208module_param(n_devs, uint, 0444);
55712ff7 1209MODULE_PARM_DESC(n_devs, "number of video devices to create");
c820cc45 1210
8996b3f3 1211module_param_named(debug, vivi_template.debug, int, 0444);
55712ff7 1212MODULE_PARM_DESC(debug, "activates debug info");
c820cc45 1213
55712ff7
MCC
1214module_param(vid_limit, int, 0644);
1215MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");