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