e9bb5dad84d55f6ebc9c2df7610cbbf633140beb
[linux-2.6.git] / drivers / media / video / vivi.c
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>
28 #include <linux/videodev2.h>
29 #include <media/video-buf.h>
30 #include <media/v4l2-common.h>
31 #include <linux/kthread.h>
32 #include <linux/highmem.h>
33
34 /* Wake up at about 30 fps */
35 #define WAKE_NUMERATOR 30
36 #define WAKE_DENOMINATOR 1001
37 #define BUFFER_TIMEOUT     msecs_to_jiffies(500)  /* 0.5 seconds */
38
39 /* These timers are for 1 fps - used only for testing */
40 //#define WAKE_DENOMINATOR 30 /* hack for testing purposes */
41 //#define BUFFER_TIMEOUT     msecs_to_jiffies(5000)  /* 5 seconds */
42
43 #include "font.h"
44
45 #ifndef kzalloc
46 #define kzalloc(size, flags)                            \
47 ({                                                      \
48         void *__ret = kmalloc(size, flags);             \
49         if (__ret)                                      \
50                 memset(__ret, 0, size);                 \
51         __ret;                                          \
52 })
53 #endif
54
55 MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
56 MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
57 MODULE_LICENSE("Dual BSD/GPL");
58
59 #define VIVI_MAJOR_VERSION 0
60 #define VIVI_MINOR_VERSION 4
61 #define VIVI_RELEASE 0
62 #define VIVI_VERSION KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE)
63
64 static int video_nr = -1;        /* /dev/videoN, -1 for autodetect */
65 module_param(video_nr, int, 0);
66
67 static int debug = 0;
68 module_param(debug, int, 0);
69
70 static unsigned int vid_limit = 16;
71 module_param(vid_limit,int,0644);
72 MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes");
73
74 /* supported controls */
75 static struct v4l2_queryctrl vivi_qctrl[] = {
76         {
77                 .id            = V4L2_CID_AUDIO_VOLUME,
78                 .name          = "Volume",
79                 .minimum       = 0,
80                 .maximum       = 65535,
81                 .step          = 65535/100,
82                 .default_value = 65535,
83                 .flags         = 0,
84                 .type          = V4L2_CTRL_TYPE_INTEGER,
85         },{
86                 .id            = V4L2_CID_BRIGHTNESS,
87                 .type          = V4L2_CTRL_TYPE_INTEGER,
88                 .name          = "Brightness",
89                 .minimum       = 0,
90                 .maximum       = 255,
91                 .step          = 1,
92                 .default_value = 127,
93                 .flags         = 0,
94         }, {
95                 .id            = V4L2_CID_CONTRAST,
96                 .type          = V4L2_CTRL_TYPE_INTEGER,
97                 .name          = "Contrast",
98                 .minimum       = 0,
99                 .maximum       = 255,
100                 .step          = 0x1,
101                 .default_value = 0x10,
102                 .flags         = 0,
103         }, {
104                 .id            = V4L2_CID_SATURATION,
105                 .type          = V4L2_CTRL_TYPE_INTEGER,
106                 .name          = "Saturation",
107                 .minimum       = 0,
108                 .maximum       = 255,
109                 .step          = 0x1,
110                 .default_value = 127,
111                 .flags         = 0,
112         }, {
113                 .id            = V4L2_CID_HUE,
114                 .type          = V4L2_CTRL_TYPE_INTEGER,
115                 .name          = "Hue",
116                 .minimum       = -128,
117                 .maximum       = 127,
118                 .step          = 0x1,
119                 .default_value = 0,
120                 .flags         = 0,
121         }
122 };
123
124 static int qctl_regs[ARRAY_SIZE(vivi_qctrl)];
125
126 #define dprintk(level,fmt, arg...)                           \
127         do {                                                 \
128                 if (debug >= (level))                        \
129                         printk(KERN_DEBUG "vivi: " fmt , ## arg);    \
130         } while (0)
131
132 /* ------------------------------------------------------------------
133         Basic structures
134    ------------------------------------------------------------------*/
135
136 struct vivi_fmt {
137         char  *name;
138         u32   fourcc;          /* v4l2 format id */
139         int   depth;
140 };
141
142 static struct vivi_fmt format = {
143         .name     = "4:2:2, packed, YUYV",
144         .fourcc   = V4L2_PIX_FMT_YUYV,
145         .depth    = 16,
146 };
147
148 struct sg_to_addr {
149         int pos;
150         struct scatterlist *sg;
151 };
152
153 /* buffer for one video frame */
154 struct vivi_buffer {
155         /* common v4l buffer stuff -- must be first */
156         struct videobuf_buffer vb;
157
158         struct vivi_fmt        *fmt;
159
160         struct sg_to_addr      *to_addr;
161 };
162
163 struct vivi_dmaqueue {
164         struct list_head       active;
165         struct list_head       queued;
166         struct timer_list      timeout;
167
168         /* thread for generating video stream*/
169         struct task_struct         *kthread;
170         wait_queue_head_t          wq;
171         /* Counters to control fps rate */
172         int                        frame;
173         int                        ini_jiffies;
174 };
175
176 static LIST_HEAD(vivi_devlist);
177
178 struct vivi_dev {
179         struct list_head           vivi_devlist;
180
181         struct semaphore           lock;
182
183         int                        users;
184
185         /* various device info */
186         unsigned int               resources;
187         struct video_device        video_dev;
188
189         struct vivi_dmaqueue       vidq;
190
191         /* Several counters */
192         int                        h,m,s,us,jiffies;
193         char                       timestr[13];
194 };
195
196 struct vivi_fh {
197         struct vivi_dev            *dev;
198
199         /* video capture */
200         struct vivi_fmt            *fmt;
201         unsigned int               width,height;
202         struct videobuf_queue      vb_vidq;
203
204         enum v4l2_buf_type         type;
205 };
206
207 /* ------------------------------------------------------------------
208         DMA and thread functions
209    ------------------------------------------------------------------*/
210
211 /* Bars and Colors should match positions */
212
213 enum colors {
214         WHITE,
215         AMBAR,
216         CYAN,
217         GREEN,
218         MAGENTA,
219         RED,
220         BLUE
221 };
222
223 static u8 bars[8][3] = {
224         /* R   G   B */
225         {204,204,204},  /* white */
226         {208,208,  0},  /* ambar */
227         {  0,206,206},  /* cyan */
228         {  0,239,  0},  /* green */
229         {239,  0,239},  /* magenta */
230         {205,  0,  0},  /* red */
231         {  0,  0,255},  /* blue */
232         {  0,  0,  0}
233 };
234
235 #define TO_Y(r,g,b) (((16829*r +33039*g +6416*b  + 32768)>>16)+16)
236 /* RGB to  V(Cr) Color transform */
237 #define TO_V(r,g,b) (((28784*r -24103*g -4681*b  + 32768)>>16)+128)
238 /* RGB to  U(Cb) Color transform */
239 #define TO_U(r,g,b) (((-9714*r -19070*g +28784*b + 32768)>>16)+128)
240
241 #define TSTAMP_MIN_Y 24
242 #define TSTAMP_MAX_Y TSTAMP_MIN_Y+15
243 #define TSTAMP_MIN_X 64
244
245 void prep_to_addr(struct sg_to_addr to_addr[],struct videobuf_buffer *vb)
246 {
247         int i, pos=0;
248
249         for (i=0;i<vb->dma.nr_pages;i++) {
250                 to_addr[i].sg=&vb->dma.sglist[i];
251                 to_addr[i].pos=pos;
252                 pos += vb->dma.sglist[i].length;
253         }
254 }
255
256 inline int get_addr_pos(int pos, int pages, struct sg_to_addr to_addr[])
257 {
258         int p1=0,p2=pages-1,p3=pages/2;
259
260         /* Sanity test */
261         BUG_ON (pos>=to_addr[p2].pos+to_addr[p2].sg->length);
262
263         while (p1+1<p2) {
264                 if (pos < to_addr[p3].pos) {
265                         p2=p3;
266                 } else {
267                         p1=p3;
268                 }
269                 p3=(p1+p2)/2;
270         }
271         if (pos >= to_addr[p2].pos)
272                 p1=p2;
273
274         return (p1);
275 }
276
277 void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax,
278                                         int hmax, int line, char *timestr)
279 {
280         int  w,i,j,pos=inipos,pgpos,oldpg,y;
281         char *p,*s,*basep;
282         struct page *pg;
283         u8   chr,r,g,b,color;
284
285         /* Get first addr pointed to pixel position */
286         oldpg=get_addr_pos(pos,pages,to_addr);
287         pg=pfn_to_page(to_addr[oldpg].sg->dma_address >> PAGE_SHIFT);
288         basep = kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[oldpg].sg->offset;
289
290         /* We will just duplicate the second pixel at the packet */
291         wmax/=2;
292
293         /* Generate a standard color bar pattern */
294         for (w=0;w<wmax;w++) {
295                 r=bars[w*7/wmax][0];
296                 g=bars[w*7/wmax][1];
297                 b=bars[w*7/wmax][2];
298
299                 for (color=0;color<4;color++) {
300                         pgpos=get_addr_pos(pos,pages,to_addr);
301                         if (pgpos!=oldpg) {
302                                 pg=pfn_to_page(to_addr[pgpos].sg->dma_address >> PAGE_SHIFT);
303                                 kunmap_atomic(basep, KM_BOUNCE_READ);
304                                 basep= kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[pgpos].sg->offset;
305                                 oldpg=pgpos;
306                         }
307                         p=basep+pos-to_addr[pgpos].pos;
308
309                         switch (color) {
310                                 case 0:
311                                 case 2:
312                                         *p=TO_Y(r,g,b);         /* Luminance */
313                                         break;
314                                 case 1:
315                                         *p=TO_U(r,g,b);         /* Cb */
316                                         break;
317                                 case 3:
318                                         *p=TO_V(r,g,b);         /* Cr */
319                                         break;
320                         }
321                         pos++;
322                 }
323         }
324
325         /* Checks if it is possible to show timestamp */
326         if (TSTAMP_MAX_Y>=hmax)
327                 goto end;
328         if (TSTAMP_MIN_X+strlen(timestr)>=wmax)
329                 goto end;
330
331         /* Print stream time */
332         if (line>=TSTAMP_MIN_Y && line<=TSTAMP_MAX_Y) {
333                 j=TSTAMP_MIN_X;
334                 for (s=timestr;*s;s++) {
335                         chr=rom8x16_bits[(*s-0x30)*16+line-TSTAMP_MIN_Y];
336                         for (i=0;i<7;i++) {
337                                 if (chr&1<<(7-i)) { /* Font color*/
338                                         r=bars[BLUE][0];
339                                         g=bars[BLUE][1];
340                                         b=bars[BLUE][2];
341                                         r=g=b=0;
342                                         g=198;
343                                 } else { /* Background color */
344                                         r=bars[WHITE][0];
345                                         g=bars[WHITE][1];
346                                         b=bars[WHITE][2];
347                                         r=g=b=0;
348                                 }
349
350                                 pos=inipos+j*2;
351                                 for (color=0;color<4;color++) {
352                                         pgpos=get_addr_pos(pos,pages,to_addr);
353                                         if (pgpos!=oldpg) {
354                                                 pg=pfn_to_page(to_addr[pgpos].
355                                                                 sg->dma_address
356                                                                 >> PAGE_SHIFT);
357                                                 kunmap_atomic(basep,
358                                                                 KM_BOUNCE_READ);
359                                                 basep= kmap_atomic(pg,
360                                                         KM_BOUNCE_READ)+
361                                                         to_addr[pgpos].sg->offset;
362                                                 oldpg=pgpos;
363                                         }
364                                         p=basep+pos-to_addr[pgpos].pos;
365
366                                         y=TO_Y(r,g,b);
367
368                                         switch (color) {
369                                                 case 0:
370                                                 case 2:
371                                                         *p=TO_Y(r,g,b);         /* Luminance */
372                                                         break;
373                                                 case 1:
374                                                         *p=TO_U(r,g,b);         /* Cb */
375                                                         break;
376                                                 case 3:
377                                                         *p=TO_V(r,g,b);         /* Cr */
378                                                         break;
379                                         }
380                                         pos++;
381                                 }
382                                 j++;
383                         }
384                 }
385         }
386
387
388 end:
389         kunmap_atomic(basep, KM_BOUNCE_READ);
390 }
391 static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf)
392 {
393         int h,pos=0;
394         int hmax  = buf->vb.height;
395         int wmax  = buf->vb.width;
396         struct videobuf_buffer *vb=&buf->vb;
397         struct sg_to_addr *to_addr=buf->to_addr;
398         struct timeval ts;
399
400         /* Test if DMA mapping is ready */
401         if (!vb->dma.sglist[0].dma_address)
402                 return;
403
404         prep_to_addr(to_addr,vb);
405
406         /* Check if there is enough memory */
407         BUG_ON(buf->vb.dma.nr_pages << PAGE_SHIFT < (buf->vb.width*buf->vb.height)*2);
408
409         for (h=0;h<hmax;h++) {
410                 gen_line(to_addr,pos,vb->dma.nr_pages,wmax,hmax,h,dev->timestr);
411                 pos += wmax*2;
412         }
413
414         /* Updates stream time */
415
416         dev->us+=jiffies_to_usecs(jiffies-dev->jiffies);
417         dev->jiffies=jiffies;
418         if (dev->us>=1000000) {
419                 dev->us-=1000000;
420                 dev->s++;
421                 if (dev->s>=60) {
422                         dev->s-=60;
423                         dev->m++;
424                         if (dev->m>60) {
425                                 dev->m-=60;
426                                 dev->h++;
427                                 if (dev->h>24)
428                                         dev->h-=24;
429                         }
430                 }
431         }
432         sprintf(dev->timestr,"%02d:%02d:%02d:%03d",
433                         dev->h,dev->m,dev->s,(dev->us+500)/1000);
434
435         dprintk(2,"vivifill at %s: Buffer 0x%08lx size= %d\n",dev->timestr,
436                         (unsigned long)buf->vb.dma.vmalloc,pos);
437
438         /* Advice that buffer was filled */
439         buf->vb.state = STATE_DONE;
440         buf->vb.field_count++;
441         do_gettimeofday(&ts);
442         buf->vb.ts = ts;
443
444         list_del(&buf->vb.queue);
445         wake_up(&buf->vb.done);
446 }
447
448 static int restart_video_queue(struct vivi_dmaqueue *dma_q);
449
450 static void vivi_thread_tick(struct vivi_dmaqueue  *dma_q)
451 {
452         struct vivi_buffer    *buf;
453         struct vivi_dev *dev= container_of(dma_q,struct vivi_dev,vidq);
454
455         int bc;
456
457         /* Announces videobuf that all went ok */
458         for (bc = 0;; bc++) {
459                 if (list_empty(&dma_q->active)) {
460                         dprintk(1,"No active queue to serve\n");
461                         break;
462                 }
463
464                 buf = list_entry(dma_q->active.next,
465                                  struct vivi_buffer, vb.queue);
466
467                 /* Nobody is waiting something to be done, just return */
468                 if (!waitqueue_active(&buf->vb.done)) {
469                         mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT);
470                         return;
471                 }
472
473                 do_gettimeofday(&buf->vb.ts);
474                 dprintk(2,"[%p/%d] wakeup\n",buf,buf->vb.i);
475
476                 /* Fill buffer */
477                 vivi_fillbuff(dev,buf);
478         }
479         if (list_empty(&dma_q->active)) {
480                 del_timer(&dma_q->timeout);
481         } else {
482                 mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT);
483         }
484         if (bc != 1)
485                 dprintk(1,"%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc);
486 }
487
488 void vivi_sleep(struct vivi_dmaqueue  *dma_q)
489 {
490         int timeout;
491         DECLARE_WAITQUEUE(wait, current);
492
493         dprintk(1,"%s dma_q=0x%08lx\n",__FUNCTION__,(unsigned long)dma_q);
494
495         add_wait_queue(&dma_q->wq, &wait);
496         if (!kthread_should_stop()) {
497                 dma_q->frame++;
498
499                 /* Calculate time to wake up */
500                 timeout=dma_q->ini_jiffies+msecs_to_jiffies((dma_q->frame*WAKE_NUMERATOR*1000)/WAKE_DENOMINATOR)-jiffies;
501
502                 if (timeout <= 0) {
503                         int old=dma_q->frame;
504                         dma_q->frame=(jiffies_to_msecs(jiffies-dma_q->ini_jiffies)*WAKE_DENOMINATOR)/(WAKE_NUMERATOR*1000)+1;
505
506                         timeout=dma_q->ini_jiffies+msecs_to_jiffies((dma_q->frame*WAKE_NUMERATOR*1000)/WAKE_DENOMINATOR)-jiffies;
507
508                         dprintk(1,"underrun, losed %d frames. "
509                                   "Now, frame is %d. Waking on %d jiffies\n",
510                                         dma_q->frame-old,dma_q->frame,timeout);
511                 } else
512                         dprintk(1,"will sleep for %i jiffies\n",timeout);
513
514                 vivi_thread_tick(dma_q);
515
516                 schedule_timeout_interruptible (timeout);
517         }
518
519         remove_wait_queue(&dma_q->wq, &wait);
520         try_to_freeze();
521 }
522
523 int vivi_thread(void *data)
524 {
525         struct vivi_dmaqueue  *dma_q=data;
526
527         dprintk(1,"thread started\n");
528
529         for (;;) {
530                 vivi_sleep(dma_q);
531
532                 if (kthread_should_stop())
533                         break;
534         }
535         dprintk(1, "thread: exit\n");
536         return 0;
537 }
538
539 int vivi_start_thread(struct vivi_dmaqueue  *dma_q)
540 {
541         dma_q->frame=0;
542         dma_q->ini_jiffies=jiffies;
543
544         dprintk(1,"%s\n",__FUNCTION__);
545         init_waitqueue_head(&dma_q->wq);
546
547         dma_q->kthread = kthread_run(vivi_thread, dma_q, "vivi");
548
549         if (dma_q->kthread == NULL) {
550                 printk(KERN_ERR "vivi: kernel_thread() failed\n");
551                 return -EINVAL;
552         }
553         dprintk(1,"returning from %s\n",__FUNCTION__);
554         return 0;
555 }
556
557 void vivi_stop_thread(struct vivi_dmaqueue  *dma_q)
558 {
559         dprintk(1,"%s\n",__FUNCTION__);
560         /* shutdown control thread */
561         if (dma_q->kthread) {
562                 kthread_stop(dma_q->kthread);
563                 dma_q->kthread=NULL;
564         }
565 }
566
567 static int restart_video_queue(struct vivi_dmaqueue *dma_q)
568 {
569         struct vivi_buffer *buf, *prev;
570         struct list_head *item;
571
572         dprintk(1,"%s dma_q=0x%08lx\n",__FUNCTION__,(unsigned long)dma_q);
573
574         if (!list_empty(&dma_q->active)) {
575                 buf = list_entry(dma_q->active.next, struct vivi_buffer, vb.queue);
576                 dprintk(2,"restart_queue [%p/%d]: restart dma\n",
577                         buf, buf->vb.i);
578
579                 dprintk(1,"Restarting video dma\n");
580                 vivi_stop_thread(dma_q);
581 //              vivi_start_thread(dma_q);
582
583                 /* cancel all outstanding capture / vbi requests */
584                 list_for_each(item,&dma_q->active) {
585                         buf = list_entry(item, struct vivi_buffer, vb.queue);
586
587                         list_del(&buf->vb.queue);
588                         buf->vb.state = STATE_ERROR;
589                         wake_up(&buf->vb.done);
590                 }
591                 mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT);
592
593                 return 0;
594         }
595
596         prev = NULL;
597         for (;;) {
598                 if (list_empty(&dma_q->queued))
599                         return 0;
600                 buf = list_entry(dma_q->queued.next, struct vivi_buffer, vb.queue);
601                 if (NULL == prev) {
602                         list_del(&buf->vb.queue);
603                         list_add_tail(&buf->vb.queue,&dma_q->active);
604
605                         dprintk(1,"Restarting video dma\n");
606                         vivi_stop_thread(dma_q);
607                         vivi_start_thread(dma_q);
608
609                         buf->vb.state = STATE_ACTIVE;
610                         mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT);
611                         dprintk(2,"[%p/%d] restart_queue - first active\n",
612                                 buf,buf->vb.i);
613
614                 } else if (prev->vb.width  == buf->vb.width  &&
615                            prev->vb.height == buf->vb.height &&
616                            prev->fmt       == buf->fmt) {
617                         list_del(&buf->vb.queue);
618                         list_add_tail(&buf->vb.queue,&dma_q->active);
619                         buf->vb.state = STATE_ACTIVE;
620                         dprintk(2,"[%p/%d] restart_queue - move to active\n",
621                                 buf,buf->vb.i);
622                 } else {
623                         return 0;
624                 }
625                 prev = buf;
626         }
627 }
628
629 static void vivi_vid_timeout(unsigned long data)
630 {
631         struct vivi_dev      *dev  = (struct vivi_dev*)data;
632         struct vivi_dmaqueue *vidq = &dev->vidq;
633         struct vivi_buffer   *buf;
634
635         while (!list_empty(&vidq->active)) {
636                 buf = list_entry(vidq->active.next, struct vivi_buffer, vb.queue);
637                 list_del(&buf->vb.queue);
638                 buf->vb.state = STATE_ERROR;
639                 wake_up(&buf->vb.done);
640                 printk("vivi/0: [%p/%d] timeout\n", buf, buf->vb.i);
641         }
642
643         restart_video_queue(vidq);
644 }
645
646 /* ------------------------------------------------------------------
647         Videobuf operations
648    ------------------------------------------------------------------*/
649 static int
650 buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
651 {
652         struct vivi_fh *fh = vq->priv_data;
653
654         *size = fh->width*fh->height*2;
655
656         if (0 == *count)
657                 *count = 32;
658         while (*size * *count > vid_limit * 1024 * 1024)
659                 (*count)--;
660         return 0;
661 }
662
663 void
664 free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf)
665 {
666         dprintk(1,"%s\n",__FUNCTION__);
667
668         if (in_interrupt())
669                 BUG();
670
671         /*FIXME: Maybe a spinlock is required here */
672         kfree(buf->to_addr);
673         buf->to_addr=NULL;
674
675         videobuf_waiton(&buf->vb,0,0);
676         videobuf_dma_unmap(vq, &buf->vb.dma);
677         videobuf_dma_free(&buf->vb.dma);
678         buf->vb.state = STATE_NEEDS_INIT;
679 }
680
681 #define norm_maxw() 1024
682 #define norm_maxh() 768
683 static int
684 buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
685                                                 enum v4l2_field field)
686 {
687         struct vivi_fh     *fh  = vq->priv_data;
688         struct vivi_buffer *buf = container_of(vb,struct vivi_buffer,vb);
689         int rc, init_buffer = 0;
690
691 //      dprintk(1,"%s, field=%d\n",__FUNCTION__,field);
692
693         BUG_ON(NULL == fh->fmt);
694         if (fh->width  < 48 || fh->width  > norm_maxw() ||
695             fh->height < 32 || fh->height > norm_maxh())
696                 return -EINVAL;
697         buf->vb.size = fh->width*fh->height*2;
698         if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
699                 return -EINVAL;
700
701         if (buf->fmt       != fh->fmt    ||
702             buf->vb.width  != fh->width  ||
703             buf->vb.height != fh->height ||
704         buf->vb.field  != field) {
705                 buf->fmt       = fh->fmt;
706                 buf->vb.width  = fh->width;
707                 buf->vb.height = fh->height;
708                 buf->vb.field  = field;
709                 init_buffer = 1;
710         }
711
712         if (STATE_NEEDS_INIT == buf->vb.state) {
713                 if (0 != (rc = videobuf_iolock(vq,&buf->vb,NULL)))
714                         goto fail;
715         }
716
717         buf->vb.state = STATE_PREPARED;
718
719         if (NULL == (buf->to_addr = kmalloc(sizeof(*buf->to_addr) * vb->dma.nr_pages,GFP_KERNEL))) {
720                 rc=-ENOMEM;
721                 goto fail;
722         }
723
724         return 0;
725
726 fail:
727         free_buffer(vq,buf);
728         return rc;
729 }
730
731 static void
732 buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
733 {
734         struct vivi_buffer    *buf     = container_of(vb,struct vivi_buffer,vb);
735         struct vivi_fh        *fh      = vq->priv_data;
736         struct vivi_dev       *dev     = fh->dev;
737         struct vivi_dmaqueue  *vidq    = &dev->vidq;
738         struct vivi_buffer    *prev;
739
740         if (!list_empty(&vidq->queued)) {
741                 dprintk(1,"adding vb queue=0x%08lx\n",(unsigned long)&buf->vb.queue);
742                 list_add_tail(&buf->vb.queue,&vidq->queued);
743                 buf->vb.state = STATE_QUEUED;
744                 dprintk(2,"[%p/%d] buffer_queue - append to queued\n",
745                         buf, buf->vb.i);
746         } else if (list_empty(&vidq->active)) {
747                 list_add_tail(&buf->vb.queue,&vidq->active);
748
749                 buf->vb.state = STATE_ACTIVE;
750                 mod_timer(&vidq->timeout, jiffies+BUFFER_TIMEOUT);
751                 dprintk(2,"[%p/%d] buffer_queue - first active\n",
752                         buf, buf->vb.i);
753
754                 vivi_start_thread(vidq);
755         } else {
756                 prev = list_entry(vidq->active.prev, struct vivi_buffer, vb.queue);
757                 if (prev->vb.width  == buf->vb.width  &&
758                     prev->vb.height == buf->vb.height &&
759                     prev->fmt       == buf->fmt) {
760                         list_add_tail(&buf->vb.queue,&vidq->active);
761                         buf->vb.state = STATE_ACTIVE;
762                         dprintk(2,"[%p/%d] buffer_queue - append to active\n",
763                                 buf, buf->vb.i);
764
765                 } else {
766                         list_add_tail(&buf->vb.queue,&vidq->queued);
767                         buf->vb.state = STATE_QUEUED;
768                         dprintk(2,"[%p/%d] buffer_queue - first queued\n",
769                                 buf, buf->vb.i);
770                 }
771         }
772 }
773
774 static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb)
775 {
776         struct vivi_buffer   *buf  = container_of(vb,struct vivi_buffer,vb);
777         struct vivi_fh       *fh   = vq->priv_data;
778         struct vivi_dev      *dev  = (struct vivi_dev*)fh->dev;
779         struct vivi_dmaqueue *vidq = &dev->vidq;
780
781         dprintk(1,"%s\n",__FUNCTION__);
782
783         vivi_stop_thread(vidq);
784
785         free_buffer(vq,buf);
786 }
787
788 int vivi_map_sg (void *dev, struct scatterlist *sg, int nents,
789            int direction)
790 {
791         int i;
792
793         dprintk(1,"%s, number of pages=%d\n",__FUNCTION__,nents);
794         BUG_ON(direction == DMA_NONE);
795
796         for (i = 0; i < nents; i++ ) {
797                 BUG_ON(!sg[i].page);
798
799                 sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset;
800         }
801
802         return nents;
803 }
804
805 int vivi_unmap_sg(void *dev,struct scatterlist *sglist,int nr_pages,
806                                         int direction)
807 {
808         dprintk(1,"%s\n",__FUNCTION__);
809         return 0;
810 }
811
812 int vivi_dma_sync_sg(void *dev,struct scatterlist *sglist,int nr_pages,
813                                         int direction)
814 {
815 //      dprintk(1,"%s\n",__FUNCTION__);
816
817 //      flush_write_buffers();
818         return 0;
819 }
820
821 static struct videobuf_queue_ops vivi_video_qops = {
822         .buf_setup      = buffer_setup,
823         .buf_prepare    = buffer_prepare,
824         .buf_queue      = buffer_queue,
825         .buf_release    = buffer_release,
826
827         /* Non-pci handling routines */
828         .vb_map_sg      = vivi_map_sg,
829         .vb_dma_sync_sg = vivi_dma_sync_sg,
830         .vb_unmap_sg    = vivi_unmap_sg,
831 };
832
833 /* ------------------------------------------------------------------
834         IOCTL handling
835    ------------------------------------------------------------------*/
836
837 static int vivi_try_fmt(struct vivi_dev *dev, struct vivi_fh *fh,
838                         struct v4l2_format *f)
839 {
840         struct vivi_fmt *fmt;
841         enum v4l2_field field;
842         unsigned int maxw, maxh;
843
844         if (format.fourcc != f->fmt.pix.pixelformat) {
845                 dprintk(1,"Fourcc format invalid.\n");
846                 return -EINVAL;
847         }
848         fmt=&format;
849
850         field = f->fmt.pix.field;
851
852         if (field == V4L2_FIELD_ANY) {
853 //              field=V4L2_FIELD_INTERLACED;
854                 field=V4L2_FIELD_SEQ_TB;
855         } else if (V4L2_FIELD_INTERLACED != field) {
856                 dprintk(1,"Field type invalid.\n");
857                 return -EINVAL;
858         }
859
860         maxw  = norm_maxw();
861         maxh  = norm_maxh();
862
863         f->fmt.pix.field = field;
864         if (f->fmt.pix.height < 32)
865                 f->fmt.pix.height = 32;
866         if (f->fmt.pix.height > maxh)
867                 f->fmt.pix.height = maxh;
868         if (f->fmt.pix.width < 48)
869                 f->fmt.pix.width = 48;
870         if (f->fmt.pix.width > maxw)
871                 f->fmt.pix.width = maxw;
872         f->fmt.pix.width &= ~0x03;
873         f->fmt.pix.bytesperline =
874                 (f->fmt.pix.width * fmt->depth) >> 3;
875         f->fmt.pix.sizeimage =
876                 f->fmt.pix.height * f->fmt.pix.bytesperline;
877
878         return 0;
879 }
880
881 static int res_get(struct vivi_dev *dev, struct vivi_fh *fh)
882 {
883         /* is it free? */
884         down(&dev->lock);
885         if (dev->resources) {
886                 /* no, someone else uses it */
887                 up(&dev->lock);
888                 return 0;
889         }
890         /* it's free, grab it */
891         dev->resources =1;
892         dprintk(1,"res: get\n");
893         up(&dev->lock);
894         return 1;
895 }
896
897 static inline int res_locked(struct vivi_dev *dev)
898 {
899         return (dev->resources);
900 }
901
902 static void res_free(struct vivi_dev *dev, struct vivi_fh *fh)
903 {
904         down(&dev->lock);
905         dev->resources = 0;
906         dprintk(1,"res: put\n");
907         up(&dev->lock);
908 }
909
910 static int vivi_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg)
911 {
912         struct vivi_fh  *fh     = file->private_data;
913         struct vivi_dev *dev    = fh->dev;
914         int ret=0;
915
916         if (debug) {
917                 if (_IOC_DIR(cmd) & _IOC_WRITE)
918                         v4l_printk_ioctl_arg("vivi(w)",cmd, arg);
919                 else if (!_IOC_DIR(cmd) & _IOC_READ) {
920                         v4l_print_ioctl("vivi", cmd);
921                 }
922         }
923
924         switch(cmd) {
925         /* --- capabilities ------------------------------------------ */
926         case VIDIOC_QUERYCAP:
927         {
928                 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
929
930                 memset(cap, 0, sizeof(*cap));
931
932                 strcpy(cap->driver, "vivi");
933                 strcpy(cap->card, "vivi");
934                 cap->version = VIVI_VERSION;
935                 cap->capabilities =
936                                         V4L2_CAP_VIDEO_CAPTURE |
937                                         V4L2_CAP_STREAMING     |
938                                         V4L2_CAP_READWRITE;
939                 break;
940         }
941         /* --- capture ioctls ---------------------------------------- */
942         case VIDIOC_ENUM_FMT:
943         {
944                 struct v4l2_fmtdesc *f = arg;
945                 enum v4l2_buf_type type;
946                 unsigned int index;
947
948                 index = f->index;
949                 type  = f->type;
950
951                 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
952                         ret=-EINVAL;
953                         break;
954                 }
955
956                 switch (type) {
957                 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
958                         if (index > 0){
959                                 ret=-EINVAL;
960                                 break;
961                         }
962                         memset(f,0,sizeof(*f));
963
964                         f->index = index;
965                         f->type  = type;
966                         strlcpy(f->description,format.name,sizeof(f->description));
967                         f->pixelformat = format.fourcc;
968                         break;
969                 default:
970                         ret=-EINVAL;
971                 }
972                 break;
973         }
974         case VIDIOC_G_FMT:
975         {
976                 struct v4l2_format *f = (struct v4l2_format *)arg;
977
978                 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
979                         ret=-EINVAL;
980                         break;
981                 }
982
983                 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
984                 f->fmt.pix.width        = fh->width;
985                 f->fmt.pix.height       = fh->height;
986                 f->fmt.pix.field        = fh->vb_vidq.field;
987                 f->fmt.pix.pixelformat  = fh->fmt->fourcc;
988                 f->fmt.pix.bytesperline =
989                         (f->fmt.pix.width * fh->fmt->depth) >> 3;
990                 f->fmt.pix.sizeimage =
991                         f->fmt.pix.height * f->fmt.pix.bytesperline;
992                 break;
993         }
994         case VIDIOC_S_FMT:
995         {
996                 struct v4l2_format *f = arg;
997
998                 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
999                         dprintk(1,"Only capture supported.\n");
1000                         ret=-EINVAL;
1001                         break;
1002                 }
1003
1004                 ret = vivi_try_fmt(dev,fh,f);
1005                 if (ret < 0)
1006                         break;
1007
1008                 fh->fmt           = &format;
1009                 fh->width         = f->fmt.pix.width;
1010                 fh->height        = f->fmt.pix.height;
1011                 fh->vb_vidq.field = f->fmt.pix.field;
1012                 fh->type          = f->type;
1013
1014                 break;
1015         }
1016         case VIDIOC_TRY_FMT:
1017         {
1018                 struct v4l2_format *f = arg;
1019                 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1020                         ret=-EINVAL;
1021                         break;
1022                 }
1023
1024                 ret=vivi_try_fmt(dev,fh,f);
1025                 break;
1026         }
1027         case VIDIOC_REQBUFS:
1028                 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1029                         ret=-EINVAL;
1030                         break;
1031                 }
1032                 ret=videobuf_reqbufs(&fh->vb_vidq, arg);
1033                 break;
1034         case VIDIOC_QUERYBUF:
1035                 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1036                         ret=-EINVAL;
1037                         break;
1038                 }
1039                 ret=videobuf_querybuf(&fh->vb_vidq, arg);
1040                 break;
1041         case VIDIOC_QBUF:
1042                 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1043                         ret=-EINVAL;
1044                         break;
1045                 }
1046                 ret=videobuf_qbuf(&fh->vb_vidq, arg);
1047                 break;
1048         case VIDIOC_DQBUF:
1049                 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1050                         ret=-EINVAL;
1051                         break;
1052                 }
1053                 ret=videobuf_dqbuf(&fh->vb_vidq, arg,
1054                                         file->f_flags & O_NONBLOCK);
1055                 break;
1056 #ifdef HAVE_V4L1
1057         /* --- streaming capture ------------------------------------- */
1058         case VIDIOCGMBUF:
1059         {
1060                 struct video_mbuf *mbuf = arg;
1061                 struct videobuf_queue *q=&fh->vb_vidq;
1062                 struct v4l2_requestbuffers req;
1063                 unsigned int i;
1064
1065                 memset(&req,0,sizeof(req));
1066                 req.type   = q->type;
1067                 req.count  = 8;
1068                 req.memory = V4L2_MEMORY_MMAP;
1069                 ret = videobuf_reqbufs(q,&req);
1070                 if (ret < 0)
1071                         break;
1072                 memset(mbuf,0,sizeof(*mbuf));
1073                 mbuf->frames = req.count;
1074                 mbuf->size   = 0;
1075                 for (i = 0; i < mbuf->frames; i++) {
1076                         mbuf->offsets[i]  = q->bufs[i]->boff;
1077                         mbuf->size       += q->bufs[i]->bsize;
1078                 }
1079                 break;
1080         }
1081 #endif
1082         case VIDIOC_STREAMON:
1083         {
1084                 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1085                         return -EINVAL;
1086                 if (!res_get(dev,fh))
1087                         return -EBUSY;
1088                 ret=videobuf_streamon(&fh->vb_vidq);
1089                 break;
1090         }
1091         case VIDIOC_STREAMOFF:
1092         {
1093                 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1094                         ret=-EINVAL;
1095                         break;
1096                 }
1097                 ret = videobuf_streamoff(&fh->vb_vidq);
1098                 if (ret < 0)
1099                         break;
1100                 res_free(dev,fh);
1101                 break;
1102         }
1103         /* ---------- tv norms ---------- */
1104         case VIDIOC_ENUMSTD:
1105         {
1106                 struct v4l2_standard *e = arg;
1107
1108                 if (e->index>0) {
1109                         ret=-EINVAL;
1110                         break;
1111                 }
1112                 ret = v4l2_video_std_construct(e, V4L2_STD_NTSC_M, "NTSC-M");
1113
1114                 /* Allows vivi to use different fps from video std */
1115                 e->frameperiod.numerator = WAKE_NUMERATOR;
1116                 e->frameperiod.denominator = WAKE_DENOMINATOR;
1117
1118                 break;
1119         }
1120         case VIDIOC_G_STD:
1121         {
1122                 v4l2_std_id *id = arg;
1123
1124                 *id = V4L2_STD_NTSC_M;
1125                 break;
1126         }
1127         case VIDIOC_S_STD:
1128         {
1129                 break;
1130         }
1131         /* ------ input switching ---------- */
1132         case VIDIOC_ENUMINPUT:
1133         { /* only one input in this sample driver */
1134                 struct v4l2_input *inp = arg;
1135
1136                 if (inp->index != 0) {
1137                         ret=-EINVAL;
1138                         break;
1139                 }
1140                 memset(inp, 0, sizeof(*inp));
1141
1142                 inp->index = 0;
1143                 inp->type = V4L2_INPUT_TYPE_CAMERA;
1144                 inp->std = V4L2_STD_NTSC_M;
1145                 strcpy(inp->name,"Camera");
1146                 break;
1147         }
1148         case VIDIOC_G_INPUT:
1149         {
1150                 unsigned int *i = arg;
1151
1152                 *i = 0;
1153                 break;
1154         }
1155         case VIDIOC_S_INPUT:
1156         {
1157                 unsigned int *i = arg;
1158
1159                 if (*i > 0)
1160                         ret=-EINVAL;
1161                 break;
1162         }
1163
1164         /* --- controls ---------------------------------------------- */
1165         case VIDIOC_QUERYCTRL:
1166         {
1167                 struct v4l2_queryctrl *qc = arg;
1168                 int i;
1169
1170                 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1171                         if (qc->id && qc->id == vivi_qctrl[i].id) {
1172                                 memcpy(qc, &(vivi_qctrl[i]),
1173                                         sizeof(*qc));
1174                                 break;
1175                         }
1176
1177                 ret=-EINVAL;
1178                 break;
1179         }
1180         case VIDIOC_G_CTRL:
1181         {
1182                 struct v4l2_control *ctrl = arg;
1183                 int i;
1184
1185                 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1186                         if (ctrl->id == vivi_qctrl[i].id) {
1187                                 ctrl->value=qctl_regs[i];
1188                                 break;
1189                         }
1190
1191                 ret=-EINVAL;
1192                 break;
1193         }
1194         case VIDIOC_S_CTRL:
1195         {
1196                 struct v4l2_control *ctrl = arg;
1197                 int i;
1198                 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1199                         if (ctrl->id == vivi_qctrl[i].id) {
1200                                 if (ctrl->value <
1201                                         vivi_qctrl[i].minimum
1202                                         || ctrl->value >
1203                                         vivi_qctrl[i].maximum) {
1204                                                 ret=-ERANGE;
1205                                                 break;
1206                                         }
1207                                 qctl_regs[i]=ctrl->value;
1208                                 break;
1209                         }
1210                 ret=-EINVAL;
1211                 break;
1212         }
1213         default:
1214                 ret=v4l_compat_translate_ioctl(inode,file,cmd,arg,vivi_do_ioctl);
1215         }
1216
1217         if (debug) {
1218                 if (ret<0) {
1219                         v4l_print_ioctl("vivi(err)", cmd);
1220                         dprintk(1,"errcode=%d\n",ret);
1221                 } else if (_IOC_DIR(cmd) & _IOC_READ)
1222                         v4l_printk_ioctl_arg("vivi(r)",cmd, arg);
1223         }
1224
1225         return ret;
1226 }
1227
1228 static int vivi_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
1229 {
1230         return video_usercopy(inode, file, cmd, arg, vivi_do_ioctl);
1231 }
1232
1233 /* ------------------------------------------------------------------
1234         File operations for the device
1235    ------------------------------------------------------------------*/
1236
1237 #define line_buf_size(norm) (norm_maxw(norm)*(format.depth+7)/8)
1238
1239 static int vivi_open(struct inode *inode, struct file *file)
1240 {
1241         int minor = iminor(inode);
1242         struct vivi_dev *h,*dev = NULL;
1243         struct vivi_fh *fh;
1244         struct list_head *list;
1245         enum v4l2_buf_type type = 0;
1246         int i;
1247
1248         printk(KERN_DEBUG "vivi: open called (minor=%d)\n",minor);
1249
1250         list_for_each(list,&vivi_devlist) {
1251                 h = list_entry(list, struct vivi_dev, vivi_devlist);
1252                 if (h->video_dev.minor == minor) {
1253                         dev  = h;
1254                         type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1255                 }
1256         }
1257         if (NULL == dev)
1258                 return -ENODEV;
1259
1260
1261         /* If more than one user, mutex should be added */
1262         dev->users++;
1263
1264         dprintk(1,"open minor=%d type=%s users=%d\n",
1265                                 minor,v4l2_type_names[type],dev->users);
1266
1267         /* allocate + initialize per filehandle data */
1268         fh = kzalloc(sizeof(*fh),GFP_KERNEL);
1269         if (NULL == fh) {
1270                 dev->users--;
1271                 return -ENOMEM;
1272         }
1273
1274         file->private_data = fh;
1275         fh->dev      = dev;
1276         fh->type     = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1277         fh->fmt      = &format;
1278         fh->width    = 640;
1279         fh->height   = 480;
1280
1281         /* Put all controls at a sane state */
1282         for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1283                 qctl_regs[i] =vivi_qctrl[i].default_value;
1284
1285         dprintk(1,"Open: fh=0x%08lx, dev=0x%08lx, dev->vidq=0x%08lx\n",
1286                 (unsigned long)fh,(unsigned long)dev,(unsigned long)&dev->vidq);
1287         dprintk(1,"Open: list_empty queued=%d\n",list_empty(&dev->vidq.queued));
1288         dprintk(1,"Open: list_empty active=%d\n",list_empty(&dev->vidq.active));
1289
1290         /* Resets frame counters */
1291         dev->h=0;
1292         dev->m=0;
1293         dev->s=0;
1294         dev->us=0;
1295         dev->jiffies=jiffies;
1296         sprintf(dev->timestr,"%02d:%02d:%02d:%03d",
1297                         dev->h,dev->m,dev->s,(dev->us+500)/1000);
1298
1299         videobuf_queue_init(&fh->vb_vidq, &vivi_video_qops,
1300                         NULL, NULL,
1301                         fh->type,
1302                         V4L2_FIELD_INTERLACED,
1303                         sizeof(struct vivi_buffer),fh);
1304
1305         return 0;
1306 }
1307
1308 static ssize_t
1309 vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1310 {
1311         struct vivi_fh *fh = file->private_data;
1312
1313         if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1314                 if (res_locked(fh->dev))
1315                         return -EBUSY;
1316                 return videobuf_read_one(&fh->vb_vidq, data, count, ppos,
1317                                         file->f_flags & O_NONBLOCK);
1318         }
1319         return 0;
1320 }
1321
1322 static unsigned int
1323 vivi_poll(struct file *file, struct poll_table_struct *wait)
1324 {
1325         struct vivi_fh *fh = file->private_data;
1326         struct vivi_buffer *buf;
1327
1328         dprintk(1,"%s\n",__FUNCTION__);
1329
1330         if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1331                 return POLLERR;
1332
1333         if (res_get(fh->dev,fh)) {
1334                 dprintk(1,"poll: mmap interface\n");
1335                 /* streaming capture */
1336                 if (list_empty(&fh->vb_vidq.stream))
1337                         return POLLERR;
1338                 buf = list_entry(fh->vb_vidq.stream.next,struct vivi_buffer,vb.stream);
1339         } else {
1340                 dprintk(1,"poll: read() interface\n");
1341                 /* read() capture */
1342                 buf = (struct vivi_buffer*)fh->vb_vidq.read_buf;
1343                 if (NULL == buf)
1344                         return POLLERR;
1345         }
1346         poll_wait(file, &buf->vb.done, wait);
1347         if (buf->vb.state == STATE_DONE ||
1348             buf->vb.state == STATE_ERROR)
1349                 return POLLIN|POLLRDNORM;
1350         return 0;
1351 }
1352
1353 static int vivi_release(struct inode *inode, struct file *file)
1354 {
1355         struct vivi_fh  *fh     = file->private_data;
1356         struct vivi_dev *dev    = fh->dev;
1357         struct vivi_dmaqueue *vidq = &dev->vidq;
1358
1359         int minor = iminor(inode);
1360
1361         vivi_stop_thread(vidq);
1362         videobuf_mmap_free(&fh->vb_vidq);
1363
1364         kfree (fh);
1365
1366         dev->users--;
1367
1368         printk(KERN_DEBUG "vivi: close called (minor=%d, users=%d)\n",minor,dev->users);
1369
1370         return 0;
1371 }
1372
1373 static int
1374 vivi_mmap(struct file *file, struct vm_area_struct * vma)
1375 {
1376         struct vivi_fh *fh = file->private_data;
1377         int ret;
1378
1379         dprintk (1,"mmap called, vma=0x%08lx\n",(unsigned long)vma);
1380
1381         ret=videobuf_mmap_mapper(&fh->vb_vidq, vma);
1382
1383         dprintk (1,"vma start=0x%08lx, size=%ld, ret=%d\n",
1384                 (unsigned long)vma->vm_start,
1385                 (unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
1386                 ret);
1387
1388         return ret;
1389 }
1390
1391 static struct file_operations vivi_fops = {
1392         .owner          = THIS_MODULE,
1393         .open           = vivi_open,
1394         .release        = vivi_release,
1395         .read           = vivi_read,
1396         .poll           = vivi_poll,
1397         .ioctl          = vivi_ioctl,
1398         .mmap           = vivi_mmap,
1399         .llseek         = no_llseek,
1400 };
1401
1402 static struct video_device vivi = {
1403         .name           = "VTM Virtual Video Capture Board",
1404         .type           = VID_TYPE_CAPTURE,
1405         .hardware       = 0,
1406         .fops           = &vivi_fops,
1407         .minor          = -1,
1408 //      .release        = video_device_release,
1409 };
1410 /* ------------------------------------------------------------------
1411         Initialization and module stuff
1412    ------------------------------------------------------------------*/
1413
1414 static int __init vivi_init(void)
1415 {
1416         int ret;
1417         struct vivi_dev *dev;
1418
1419         dev = kzalloc(sizeof(*dev),GFP_KERNEL);
1420         if (NULL == dev)
1421                 return -ENOMEM;
1422         list_add_tail(&dev->vivi_devlist,&vivi_devlist);
1423
1424         /* init video dma queues */
1425         INIT_LIST_HEAD(&dev->vidq.active);
1426         INIT_LIST_HEAD(&dev->vidq.queued);
1427
1428         /* initialize locks */
1429         init_MUTEX(&dev->lock);
1430
1431         dev->vidq.timeout.function = vivi_vid_timeout;
1432         dev->vidq.timeout.data     = (unsigned long)dev;
1433         init_timer(&dev->vidq.timeout);
1434
1435         ret = video_register_device(&vivi, VFL_TYPE_GRABBER, video_nr);
1436         printk(KERN_INFO "Video Technology Magazine Virtual Video Capture Board (Load status: %d)\n", ret);
1437         return ret;
1438 }
1439
1440 static void __exit vivi_exit(void)
1441 {
1442         struct vivi_dev *h;
1443         struct list_head *list;
1444
1445         list_for_each(list,&vivi_devlist) {
1446                 h = list_entry(list, struct vivi_dev, vivi_devlist);
1447                 kfree (h);
1448         }
1449         video_unregister_device(&vivi);
1450 }
1451
1452 module_init(vivi_init);
1453 module_exit(vivi_exit);