• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/staging/tm6000/
1/*
2   tm6000-video.c - driver for TM5600/TM6000/TM6010 USB video capture devices
3
4   Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
5
6   Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
7	- Fixed module load/unload
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation version 2
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22#include <linux/module.h>
23#include <linux/delay.h>
24#include <linux/errno.h>
25#include <linux/fs.h>
26#include <linux/kernel.h>
27#include <linux/slab.h>
28#include <linux/mm.h>
29#include <linux/ioport.h>
30#include <linux/init.h>
31#include <linux/sched.h>
32#include <linux/random.h>
33#include <linux/version.h>
34#include <linux/usb.h>
35#include <linux/videodev2.h>
36#include <media/v4l2-ioctl.h>
37#include <linux/interrupt.h>
38#include <linux/kthread.h>
39#include <linux/highmem.h>
40#include <linux/freezer.h>
41
42#include "tm6000-regs.h"
43#include "tm6000.h"
44
45#define BUFFER_TIMEOUT     msecs_to_jiffies(2000)  /* 2 seconds */
46
47/* Limits minimum and default number of buffers */
48#define TM6000_MIN_BUF 4
49#define TM6000_DEF_BUF 8
50
51#define TM6000_MAX_ISO_PACKETS	46	/* Max number of ISO packets */
52
53/* Declare static vars that will be used as parameters */
54static unsigned int vid_limit = 16;	/* Video memory limit, in Mb */
55static int video_nr = -1;		/* /dev/videoN, -1 for autodetect */
56
57/* Debug level */
58int tm6000_debug;
59EXPORT_SYMBOL_GPL(tm6000_debug);
60
61/* supported controls */
62static struct v4l2_queryctrl tm6000_qctrl[] = {
63	{
64		.id            = V4L2_CID_BRIGHTNESS,
65		.type          = V4L2_CTRL_TYPE_INTEGER,
66		.name          = "Brightness",
67		.minimum       = 0,
68		.maximum       = 255,
69		.step          = 1,
70		.default_value = 54,
71		.flags         = 0,
72	}, {
73		.id            = V4L2_CID_CONTRAST,
74		.type          = V4L2_CTRL_TYPE_INTEGER,
75		.name          = "Contrast",
76		.minimum       = 0,
77		.maximum       = 255,
78		.step          = 0x1,
79		.default_value = 119,
80		.flags         = 0,
81	}, {
82		.id            = V4L2_CID_SATURATION,
83		.type          = V4L2_CTRL_TYPE_INTEGER,
84		.name          = "Saturation",
85		.minimum       = 0,
86		.maximum       = 255,
87		.step          = 0x1,
88		.default_value = 112,
89		.flags         = 0,
90	}, {
91		.id            = V4L2_CID_HUE,
92		.type          = V4L2_CTRL_TYPE_INTEGER,
93		.name          = "Hue",
94		.minimum       = -128,
95		.maximum       = 127,
96		.step          = 0x1,
97		.default_value = 0,
98		.flags         = 0,
99	}
100};
101
102static int qctl_regs[ARRAY_SIZE(tm6000_qctrl)];
103
104static struct tm6000_fmt format[] = {
105	{
106		.name     = "4:2:2, packed, YVY2",
107		.fourcc   = V4L2_PIX_FMT_YUYV,
108		.depth    = 16,
109	}, {
110		.name     = "4:2:2, packed, UYVY",
111		.fourcc   = V4L2_PIX_FMT_UYVY,
112		.depth    = 16,
113	}, {
114		.name     = "A/V + VBI mux packet",
115		.fourcc   = V4L2_PIX_FMT_TM6000,
116		.depth    = 16,
117	}
118};
119
120/* ------------------------------------------------------------------
121	DMA and thread functions
122   ------------------------------------------------------------------*/
123
124#define norm_maxw(a) 720
125#define norm_maxh(a) 576
126
127#define norm_minw(a) norm_maxw(a)
128#define norm_minh(a) norm_maxh(a)
129
130/*
131 * video-buf generic routine to get the next available buffer
132 */
133static inline void get_next_buf(struct tm6000_dmaqueue *dma_q,
134			       struct tm6000_buffer   **buf)
135{
136	struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
137	char *outp;
138
139	if (list_empty(&dma_q->active)) {
140		dprintk(dev, V4L2_DEBUG_QUEUE, "No active queue to serve\n");
141		*buf = NULL;
142		return;
143	}
144
145	*buf = list_entry(dma_q->active.next,
146			struct tm6000_buffer, vb.queue);
147
148	if (!buf)
149		return;
150
151	/* Cleans up buffer - Usefull for testing for frame/URB loss */
152	outp = videobuf_to_vmalloc(&(*buf)->vb);
153
154	return;
155}
156
157/*
158 * Announces that a buffer were filled and request the next
159 */
160static inline void buffer_filled(struct tm6000_core *dev,
161				 struct tm6000_dmaqueue *dma_q,
162				 struct tm6000_buffer *buf)
163{
164	/* Advice that buffer was filled */
165	dprintk(dev, V4L2_DEBUG_ISOC, "[%p/%d] wakeup\n", buf, buf->vb.i);
166	buf->vb.state = VIDEOBUF_DONE;
167	buf->vb.field_count++;
168	do_gettimeofday(&buf->vb.ts);
169
170	list_del(&buf->vb.queue);
171	wake_up(&buf->vb.done);
172}
173
174const char *tm6000_msg_type[] = {
175	"unknown(0)",   /* 0 */
176	"video",        /* 1 */
177	"audio",        /* 2 */
178	"vbi",          /* 3 */
179	"pts",          /* 4 */
180	"err",          /* 5 */
181	"unknown(6)",   /* 6 */
182	"unknown(7)",   /* 7 */
183};
184
185/*
186 * Identify the tm5600/6000 buffer header type and properly handles
187 */
188static int copy_streams(u8 *data, unsigned long len,
189			struct urb *urb)
190{
191	struct tm6000_dmaqueue  *dma_q = urb->context;
192	struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
193	u8 *ptr=data, *endp=data+len, c;
194	unsigned long header=0;
195	int rc=0;
196	unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0;
197	struct tm6000_buffer *vbuf;
198	char *voutp = NULL;
199	unsigned int linewidth;
200
201	/* get video buffer */
202	get_next_buf (dma_q, &vbuf);
203	if (!vbuf)
204		return rc;
205	voutp = videobuf_to_vmalloc(&vbuf->vb);
206	if (!voutp)
207		return 0;
208
209	for (ptr = data; ptr < endp;) {
210		if (!dev->isoc_ctl.cmd) {
211			/* Header */
212			if (dev->isoc_ctl.tmp_buf_len > 0) {
213				/* from last urb or packet */
214				header = dev->isoc_ctl.tmp_buf;
215				if (4 - dev->isoc_ctl.tmp_buf_len > 0) {
216					memcpy ((u8 *)&header +
217						dev->isoc_ctl.tmp_buf_len,
218						ptr,
219						4 - dev->isoc_ctl.tmp_buf_len);
220					ptr += 4 - dev->isoc_ctl.tmp_buf_len;
221				}
222				dev->isoc_ctl.tmp_buf_len = 0;
223			} else {
224				if (ptr + 3 >= endp) {
225					/* have incomplete header */
226					dev->isoc_ctl.tmp_buf_len = endp - ptr;
227					memcpy (&dev->isoc_ctl.tmp_buf, ptr,
228						dev->isoc_ctl.tmp_buf_len);
229					return rc;
230				}
231				/* Seek for sync */
232				for (; ptr < endp - 3; ptr++) {
233					if (*(ptr + 3) == 0x47)
234						break;
235				}
236				/* Get message header */
237				header = *(unsigned long *)ptr;
238				ptr += 4;
239			}
240
241			/* split the header fields */
242			c = (header >> 24) & 0xff;
243			size = ((header & 0x7e) << 1);
244			if (size > 0)
245				size -= 4;
246			block = (header >> 7) & 0xf;
247			field = (header >> 11) & 0x1;
248			line  = (header >> 12) & 0x1ff;
249			cmd   = (header >> 21) & 0x7;
250			/* Validates haeder fields */
251			if (size > TM6000_URB_MSG_LEN)
252				size = TM6000_URB_MSG_LEN;
253			pktsize = TM6000_URB_MSG_LEN;
254			/* calculate position in buffer
255			 * and change the buffer
256			 */
257			switch (cmd) {
258			case TM6000_URB_MSG_VIDEO:
259				if ((dev->isoc_ctl.vfield != field) &&
260					(field == 1)) {
261					/* Announces that a new buffer
262					 * were filled
263					 */
264					buffer_filled (dev, dma_q, vbuf);
265					dprintk (dev, V4L2_DEBUG_ISOC,
266							"new buffer filled\n");
267					get_next_buf (dma_q, &vbuf);
268					if (!vbuf)
269						return rc;
270					voutp = videobuf_to_vmalloc (&vbuf->vb);
271					if (!voutp)
272						return rc;
273					memset(voutp, 0, vbuf->vb.size);
274				}
275				linewidth = vbuf->vb.width << 1;
276				pos = ((line << 1) - field - 1) * linewidth +
277					block * TM6000_URB_MSG_LEN;
278				/* Don't allow to write out of the buffer */
279				if (pos + size > vbuf->vb.size)
280					cmd = TM6000_URB_MSG_ERR;
281				dev->isoc_ctl.vfield = field;
282				break;
283			case TM6000_URB_MSG_VBI:
284				break;
285			case TM6000_URB_MSG_AUDIO:
286			case TM6000_URB_MSG_PTS:
287				size = pktsize;		/* Size is always 180 bytes */
288				break;
289			}
290		} else {
291			/* Continue the last copy */
292			cmd = dev->isoc_ctl.cmd;
293			size = dev->isoc_ctl.size;
294			pos = dev->isoc_ctl.pos;
295			pktsize = dev->isoc_ctl.pktsize;
296		}
297		cpysize = (endp - ptr > size) ? size : endp - ptr;
298		if (cpysize) {
299			/* copy data in different buffers */
300			switch (cmd) {
301			case TM6000_URB_MSG_VIDEO:
302				/* Fills video buffer */
303				if (vbuf)
304					memcpy (&voutp[pos], ptr, cpysize);
305				break;
306			case TM6000_URB_MSG_AUDIO:
307				tm6000_call_fillbuf(dev, TM6000_AUDIO, ptr, cpysize);
308				break;
309			case TM6000_URB_MSG_VBI:
310				/* Need some code to copy vbi buffer */
311				break;
312			case TM6000_URB_MSG_PTS:
313				/* Need some code to copy pts */
314				break;
315			}
316		}
317		if (ptr + pktsize > endp) {
318			/* End of URB packet, but cmd processing is not
319			 * complete. Preserve the state for a next packet
320			 */
321			dev->isoc_ctl.pos = pos + cpysize;
322			dev->isoc_ctl.size = size - cpysize;
323			dev->isoc_ctl.cmd = cmd;
324			dev->isoc_ctl.pktsize = pktsize - (endp - ptr);
325			ptr += endp - ptr;
326		} else {
327			dev->isoc_ctl.cmd = 0;
328			ptr += pktsize;
329		}
330	}
331	return 0;
332}
333
334/*
335 * Identify the tm5600/6000 buffer header type and properly handles
336 */
337static int copy_multiplexed(u8 *ptr, unsigned long len,
338			struct urb *urb)
339{
340	struct tm6000_dmaqueue  *dma_q = urb->context;
341	struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
342	unsigned int pos=dev->isoc_ctl.pos,cpysize;
343	int rc=1;
344	struct tm6000_buffer *buf;
345	char *outp = NULL;
346
347	get_next_buf(dma_q, &buf);
348	if (buf)
349		outp = videobuf_to_vmalloc(&buf->vb);
350
351	if (!outp)
352		return 0;
353
354	while (len>0) {
355		cpysize=min(len,buf->vb.size-pos);
356		//printk("Copying %d bytes (max=%lu) from %p to %p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos);
357		memcpy(&outp[pos], ptr, cpysize);
358		pos+=cpysize;
359		ptr+=cpysize;
360		len-=cpysize;
361		if (pos >= buf->vb.size) {
362			pos=0;
363			/* Announces that a new buffer were filled */
364			buffer_filled (dev, dma_q, buf);
365			dprintk(dev, V4L2_DEBUG_ISOC, "new buffer filled\n");
366			get_next_buf (dma_q, &buf);
367			if (!buf)
368				break;
369			outp = videobuf_to_vmalloc(&(buf->vb));
370			if (!outp)
371				return rc;
372			pos = 0;
373		}
374	}
375
376	dev->isoc_ctl.pos=pos;
377	return rc;
378}
379
380static void inline print_err_status (struct tm6000_core *dev,
381				     int packet, int status)
382{
383	char *errmsg = "Unknown";
384
385	switch(status) {
386	case -ENOENT:
387		errmsg = "unlinked synchronuously";
388		break;
389	case -ECONNRESET:
390		errmsg = "unlinked asynchronuously";
391		break;
392	case -ENOSR:
393		errmsg = "Buffer error (overrun)";
394		break;
395	case -EPIPE:
396		errmsg = "Stalled (device not responding)";
397		break;
398	case -EOVERFLOW:
399		errmsg = "Babble (bad cable?)";
400		break;
401	case -EPROTO:
402		errmsg = "Bit-stuff error (bad cable?)";
403		break;
404	case -EILSEQ:
405		errmsg = "CRC/Timeout (could be anything)";
406		break;
407	case -ETIME:
408		errmsg = "Device does not respond";
409		break;
410	}
411	if (packet<0) {
412		dprintk(dev, V4L2_DEBUG_QUEUE, "URB status %d [%s].\n",
413			status, errmsg);
414	} else {
415		dprintk(dev, V4L2_DEBUG_QUEUE, "URB packet %d, status %d [%s].\n",
416			packet, status, errmsg);
417	}
418}
419
420
421/*
422 * Controls the isoc copy of each urb packet
423 */
424static inline int tm6000_isoc_copy(struct urb *urb)
425{
426	struct tm6000_dmaqueue  *dma_q = urb->context;
427	struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
428	int i, len=0, rc=1, status;
429	char *p;
430
431	if (urb->status < 0) {
432		print_err_status (dev, -1, urb->status);
433		return 0;
434	}
435
436	for (i = 0; i < urb->number_of_packets; i++) {
437		status = urb->iso_frame_desc[i].status;
438
439		if (status<0) {
440			print_err_status (dev,i,status);
441			continue;
442		}
443
444		len = urb->iso_frame_desc[i].actual_length;
445
446		if (len > 0) {
447			p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
448			if (!urb->iso_frame_desc[i].status) {
449				if ((dev->fourcc)==V4L2_PIX_FMT_TM6000) {
450					rc=copy_multiplexed(p, len, urb);
451					if (rc<=0)
452						return rc;
453				} else {
454					copy_streams(p, len, urb);
455				}
456			}
457		}
458	}
459	return rc;
460}
461
462/* ------------------------------------------------------------------
463	URB control
464   ------------------------------------------------------------------*/
465
466/*
467 * IRQ callback, called by URB callback
468 */
469static void tm6000_irq_callback(struct urb *urb)
470{
471	struct tm6000_dmaqueue  *dma_q = urb->context;
472	struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
473	int i;
474
475	if (!dev)
476		return;
477
478	spin_lock(&dev->slock);
479	tm6000_isoc_copy(urb);
480	spin_unlock(&dev->slock);
481
482	/* Reset urb buffers */
483	for (i = 0; i < urb->number_of_packets; i++) {
484		urb->iso_frame_desc[i].status = 0;
485		urb->iso_frame_desc[i].actual_length = 0;
486	}
487
488	urb->status = usb_submit_urb(urb, GFP_ATOMIC);
489	if (urb->status)
490		tm6000_err("urb resubmit failed (error=%i)\n",
491			urb->status);
492}
493
494/*
495 * Stop and Deallocate URBs
496 */
497static void tm6000_uninit_isoc(struct tm6000_core *dev)
498{
499	struct urb *urb;
500	int i;
501
502	dev->isoc_ctl.buf = NULL;
503	for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
504		urb=dev->isoc_ctl.urb[i];
505		if (urb) {
506			usb_kill_urb(urb);
507			usb_unlink_urb(urb);
508			if (dev->isoc_ctl.transfer_buffer[i]) {
509				usb_free_coherent(dev->udev,
510						urb->transfer_buffer_length,
511						dev->isoc_ctl.transfer_buffer[i],
512						urb->transfer_dma);
513			}
514			usb_free_urb(urb);
515			dev->isoc_ctl.urb[i] = NULL;
516		}
517		dev->isoc_ctl.transfer_buffer[i] = NULL;
518	}
519
520	kfree (dev->isoc_ctl.urb);
521	kfree (dev->isoc_ctl.transfer_buffer);
522
523	dev->isoc_ctl.urb=NULL;
524	dev->isoc_ctl.transfer_buffer=NULL;
525	dev->isoc_ctl.num_bufs = 0;
526}
527
528/*
529 * Allocate URBs and start IRQ
530 */
531static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize)
532{
533	struct tm6000_dmaqueue *dma_q = &dev->vidq;
534	int i, j, sb_size, pipe, size, max_packets, num_bufs = 8;
535	struct urb *urb;
536
537	/* De-allocates all pending stuff */
538	tm6000_uninit_isoc(dev);
539
540	usb_set_interface(dev->udev,
541			  dev->isoc_in.bInterfaceNumber,
542			  dev->isoc_in.bAlternateSetting);
543
544	pipe = usb_rcvisocpipe(dev->udev,
545			       dev->isoc_in.endp->desc.bEndpointAddress &
546			       USB_ENDPOINT_NUMBER_MASK);
547
548	size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
549
550	if (size > dev->isoc_in.maxsize)
551		size = dev->isoc_in.maxsize;
552
553	dev->isoc_ctl.max_pkt_size = size;
554
555	max_packets = ( framesize + size - 1) / size;
556
557	if (max_packets > TM6000_MAX_ISO_PACKETS)
558		max_packets = TM6000_MAX_ISO_PACKETS;
559
560	sb_size = max_packets * size;
561
562	dev->isoc_ctl.num_bufs = num_bufs;
563
564	dev->isoc_ctl.urb = kmalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
565	if (!dev->isoc_ctl.urb) {
566		tm6000_err("cannot alloc memory for usb buffers\n");
567		return -ENOMEM;
568	}
569
570	dev->isoc_ctl.transfer_buffer = kmalloc(sizeof(void *)*num_bufs,
571				   GFP_KERNEL);
572	if (!dev->isoc_ctl.transfer_buffer) {
573		tm6000_err("cannot allocate memory for usbtransfer\n");
574		kfree(dev->isoc_ctl.urb);
575		return -ENOMEM;
576	}
577
578	dprintk(dev, V4L2_DEBUG_QUEUE, "Allocating %d x %d packets"
579		    " (%d bytes) of %d bytes each to handle %u size\n",
580		    max_packets, num_bufs, sb_size,
581		    dev->isoc_in.maxsize, size);
582
583	/* allocate urbs and transfer buffers */
584	for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
585		urb = usb_alloc_urb(max_packets, GFP_KERNEL);
586		if (!urb) {
587			tm6000_err("cannot alloc isoc_ctl.urb %i\n", i);
588			tm6000_uninit_isoc(dev);
589			usb_free_urb(urb);
590			return -ENOMEM;
591		}
592		dev->isoc_ctl.urb[i] = urb;
593
594		dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->udev,
595			sb_size, GFP_KERNEL, &urb->transfer_dma);
596		if (!dev->isoc_ctl.transfer_buffer[i]) {
597			tm6000_err ("unable to allocate %i bytes for transfer"
598					" buffer %i%s\n",
599					sb_size, i,
600					in_interrupt()?" while in int":"");
601			tm6000_uninit_isoc(dev);
602			return -ENOMEM;
603		}
604		memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
605
606		usb_fill_bulk_urb(urb, dev->udev, pipe,
607				  dev->isoc_ctl.transfer_buffer[i], sb_size,
608				  tm6000_irq_callback, dma_q);
609		urb->interval = dev->isoc_in.endp->desc.bInterval;
610		urb->number_of_packets = max_packets;
611		urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
612
613		for (j = 0; j < max_packets; j++) {
614			urb->iso_frame_desc[j].offset = size * j;
615			urb->iso_frame_desc[j].length = size;
616		}
617	}
618
619	return 0;
620}
621
622static int tm6000_start_thread( struct tm6000_core *dev)
623{
624	struct tm6000_dmaqueue *dma_q = &dev->vidq;
625	int i;
626
627	dma_q->frame=0;
628	dma_q->ini_jiffies=jiffies;
629
630	init_waitqueue_head(&dma_q->wq);
631
632	/* submit urbs and enables IRQ */
633	for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
634		int rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC);
635		if (rc) {
636			tm6000_err("submit of urb %i failed (error=%i)\n", i,
637				   rc);
638			tm6000_uninit_isoc(dev);
639			return rc;
640		}
641	}
642
643	return 0;
644}
645
646/* ------------------------------------------------------------------
647	Videobuf operations
648   ------------------------------------------------------------------*/
649
650static int
651buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
652{
653	struct tm6000_fh *fh = vq->priv_data;
654
655	*size = fh->fmt->depth * fh->width * fh->height >> 3;
656	if (0 == *count)
657		*count = TM6000_DEF_BUF;
658
659	if (*count < TM6000_MIN_BUF) {
660		*count=TM6000_MIN_BUF;
661	}
662
663	while (*size * *count > vid_limit * 1024 * 1024)
664		(*count)--;
665
666	return 0;
667}
668
669static void free_buffer(struct videobuf_queue *vq, struct tm6000_buffer *buf)
670{
671	struct tm6000_fh *fh = vq->priv_data;
672	struct tm6000_core   *dev = fh->dev;
673	unsigned long flags;
674
675	if (in_interrupt())
676		BUG();
677
678	/* We used to wait for the buffer to finish here, but this didn't work
679	   because, as we were keeping the state as VIDEOBUF_QUEUED,
680	   videobuf_queue_cancel marked it as finished for us.
681	   (Also, it could wedge forever if the hardware was misconfigured.)
682
683	   This should be safe; by the time we get here, the buffer isn't
684	   queued anymore. If we ever start marking the buffers as
685	   VIDEOBUF_ACTIVE, it won't be, though.
686	*/
687	spin_lock_irqsave(&dev->slock, flags);
688	if (dev->isoc_ctl.buf == buf)
689		dev->isoc_ctl.buf = NULL;
690	spin_unlock_irqrestore(&dev->slock, flags);
691
692	videobuf_vmalloc_free(&buf->vb);
693	buf->vb.state = VIDEOBUF_NEEDS_INIT;
694}
695
696static int
697buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
698						enum v4l2_field field)
699{
700	struct tm6000_fh     *fh  = vq->priv_data;
701	struct tm6000_buffer *buf = container_of(vb,struct tm6000_buffer,vb);
702	struct tm6000_core   *dev = fh->dev;
703	int rc = 0, urb_init = 0;
704
705	BUG_ON(NULL == fh->fmt);
706
707
708	/* The only currently supported format is 16 bits/pixel */
709	buf->vb.size = fh->fmt->depth*fh->width*fh->height >> 3;
710	if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
711		return -EINVAL;
712
713	if (buf->fmt       != fh->fmt    ||
714	    buf->vb.width  != fh->width  ||
715	    buf->vb.height != fh->height ||
716	    buf->vb.field  != field) {
717		buf->fmt       = fh->fmt;
718		buf->vb.width  = fh->width;
719		buf->vb.height = fh->height;
720		buf->vb.field  = field;
721		buf->vb.state = VIDEOBUF_NEEDS_INIT;
722	}
723
724	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
725		if (0 != (rc = videobuf_iolock(vq, &buf->vb, NULL)))
726			goto fail;
727		urb_init = 1;
728	}
729
730	if (!dev->isoc_ctl.num_bufs)
731		urb_init = 1;
732
733	if (urb_init) {
734		rc = tm6000_prepare_isoc(dev, buf->vb.size);
735		if (rc < 0)
736			goto fail;
737
738		rc = tm6000_start_thread(dev);
739		if (rc < 0)
740			goto fail;
741
742	}
743
744	buf->vb.state = VIDEOBUF_PREPARED;
745	return 0;
746
747fail:
748	free_buffer(vq, buf);
749	return rc;
750}
751
752static void
753buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
754{
755	struct tm6000_buffer    *buf     = container_of(vb,struct tm6000_buffer,vb);
756	struct tm6000_fh        *fh      = vq->priv_data;
757	struct tm6000_core      *dev     = fh->dev;
758	struct tm6000_dmaqueue  *vidq    = &dev->vidq;
759
760	buf->vb.state = VIDEOBUF_QUEUED;
761	list_add_tail(&buf->vb.queue, &vidq->active);
762}
763
764static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb)
765{
766	struct tm6000_buffer   *buf  = container_of(vb,struct tm6000_buffer,vb);
767
768	free_buffer(vq,buf);
769}
770
771static struct videobuf_queue_ops tm6000_video_qops = {
772	.buf_setup      = buffer_setup,
773	.buf_prepare    = buffer_prepare,
774	.buf_queue      = buffer_queue,
775	.buf_release    = buffer_release,
776};
777
778/* ------------------------------------------------------------------
779	IOCTL handling
780   ------------------------------------------------------------------*/
781
782static int res_get(struct tm6000_core *dev, struct tm6000_fh *fh)
783{
784	/* is it free? */
785	mutex_lock(&dev->lock);
786	if (dev->resources) {
787		/* no, someone else uses it */
788		mutex_unlock(&dev->lock);
789		return 0;
790	}
791	/* it's free, grab it */
792	dev->resources =1;
793	dprintk(dev, V4L2_DEBUG_RES_LOCK, "res: get\n");
794	mutex_unlock(&dev->lock);
795	return 1;
796}
797
798static int res_locked(struct tm6000_core *dev)
799{
800	return (dev->resources);
801}
802
803static void res_free(struct tm6000_core *dev, struct tm6000_fh *fh)
804{
805	mutex_lock(&dev->lock);
806	dev->resources = 0;
807	dprintk(dev, V4L2_DEBUG_RES_LOCK, "res: put\n");
808	mutex_unlock(&dev->lock);
809}
810
811/* ------------------------------------------------------------------
812	IOCTL vidioc handling
813   ------------------------------------------------------------------*/
814static int vidioc_querycap (struct file *file, void  *priv,
815					struct v4l2_capability *cap)
816{
817	//	struct tm6000_core *dev = ((struct tm6000_fh *)priv)->dev;
818
819	strlcpy(cap->driver, "tm6000", sizeof(cap->driver));
820	strlcpy(cap->card,"Trident TVMaster TM5600/6000/6010", sizeof(cap->card));
821	//	strlcpy(cap->bus_info, dev->udev->dev.bus_id, sizeof(cap->bus_info));
822	cap->version = TM6000_VERSION;
823	cap->capabilities =	V4L2_CAP_VIDEO_CAPTURE |
824				V4L2_CAP_STREAMING     |
825				V4L2_CAP_TUNER	       |
826				V4L2_CAP_READWRITE;
827	return 0;
828}
829
830static int vidioc_enum_fmt_vid_cap (struct file *file, void  *priv,
831					struct v4l2_fmtdesc *f)
832{
833	if (unlikely(f->index >= ARRAY_SIZE(format)))
834		return -EINVAL;
835
836	strlcpy(f->description,format[f->index].name,sizeof(f->description));
837	f->pixelformat = format[f->index].fourcc;
838	return 0;
839}
840
841static int vidioc_g_fmt_vid_cap (struct file *file, void *priv,
842					struct v4l2_format *f)
843{
844	struct tm6000_fh  *fh=priv;
845
846	f->fmt.pix.width        = fh->width;
847	f->fmt.pix.height       = fh->height;
848	f->fmt.pix.field        = fh->vb_vidq.field;
849	f->fmt.pix.pixelformat  = fh->fmt->fourcc;
850	f->fmt.pix.bytesperline =
851		(f->fmt.pix.width * fh->fmt->depth) >> 3;
852	f->fmt.pix.sizeimage =
853		f->fmt.pix.height * f->fmt.pix.bytesperline;
854
855	return (0);
856}
857
858static struct tm6000_fmt* format_by_fourcc(unsigned int fourcc)
859{
860	unsigned int i;
861
862	for (i = 0; i < ARRAY_SIZE(format); i++)
863		if (format[i].fourcc == fourcc)
864			return format+i;
865	return NULL;
866}
867
868static int vidioc_try_fmt_vid_cap (struct file *file, void *priv,
869			struct v4l2_format *f)
870{
871	struct tm6000_core *dev = ((struct tm6000_fh *)priv)->dev;
872	struct tm6000_fmt *fmt;
873	enum v4l2_field field;
874
875	fmt = format_by_fourcc(f->fmt.pix.pixelformat);
876	if (NULL == fmt) {
877		dprintk(dev, V4L2_DEBUG_IOCTL_ARG, "Fourcc format (0x%08x)"
878				" invalid.\n", f->fmt.pix.pixelformat);
879		return -EINVAL;
880	}
881
882	field = f->fmt.pix.field;
883
884	if (field == V4L2_FIELD_ANY) {
885//		field=V4L2_FIELD_INTERLACED;
886		field=V4L2_FIELD_SEQ_TB;
887	} else if (V4L2_FIELD_INTERLACED != field) {
888		dprintk(dev, V4L2_DEBUG_IOCTL_ARG, "Field type invalid.\n");
889		return -EINVAL;
890	}
891
892	tm6000_get_std_res (dev);
893
894	f->fmt.pix.width  = dev->width;
895	f->fmt.pix.height = dev->height;
896
897	f->fmt.pix.width &= ~0x01;
898
899	f->fmt.pix.field = field;
900
901	f->fmt.pix.bytesperline =
902		(f->fmt.pix.width * fmt->depth) >> 3;
903	f->fmt.pix.sizeimage =
904		f->fmt.pix.height * f->fmt.pix.bytesperline;
905
906	return 0;
907}
908
909static int vidioc_s_fmt_vid_cap (struct file *file, void *priv,
910					struct v4l2_format *f)
911{
912	struct tm6000_fh  *fh=priv;
913	struct tm6000_core *dev = fh->dev;
914	int ret = vidioc_try_fmt_vid_cap(file,fh,f);
915	if (ret < 0)
916		return (ret);
917
918	fh->fmt           = format_by_fourcc(f->fmt.pix.pixelformat);
919	fh->width         = f->fmt.pix.width;
920	fh->height        = f->fmt.pix.height;
921	fh->vb_vidq.field = f->fmt.pix.field;
922	fh->type          = f->type;
923
924	dev->fourcc       = f->fmt.pix.pixelformat;
925
926	tm6000_set_fourcc_format(dev);
927
928	return (0);
929}
930
931static int vidioc_reqbufs (struct file *file, void *priv,
932			   struct v4l2_requestbuffers *p)
933{
934	struct tm6000_fh  *fh=priv;
935
936	return (videobuf_reqbufs(&fh->vb_vidq, p));
937}
938
939static int vidioc_querybuf (struct file *file, void *priv,
940			    struct v4l2_buffer *p)
941{
942	struct tm6000_fh  *fh=priv;
943
944	return (videobuf_querybuf(&fh->vb_vidq, p));
945}
946
947static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *p)
948{
949	struct tm6000_fh  *fh=priv;
950
951	return (videobuf_qbuf(&fh->vb_vidq, p));
952}
953
954static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p)
955{
956	struct tm6000_fh  *fh=priv;
957
958	return (videobuf_dqbuf(&fh->vb_vidq, p,
959				file->f_flags & O_NONBLOCK));
960}
961
962#ifdef CONFIG_VIDEO_V4L1_COMPAT
963static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf)
964{
965	struct tm6000_fh  *fh=priv;
966
967	return videobuf_cgmbuf (&fh->vb_vidq, mbuf, 8);
968}
969#endif
970
971static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
972{
973	struct tm6000_fh  *fh=priv;
974	struct tm6000_core *dev    = fh->dev;
975
976	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
977		return -EINVAL;
978	if (i != fh->type)
979		return -EINVAL;
980
981	if (!res_get(dev,fh))
982		return -EBUSY;
983	return (videobuf_streamon(&fh->vb_vidq));
984}
985
986static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
987{
988	struct tm6000_fh  *fh=priv;
989	struct tm6000_core *dev    = fh->dev;
990
991	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
992		return -EINVAL;
993	if (i != fh->type)
994		return -EINVAL;
995
996	videobuf_streamoff(&fh->vb_vidq);
997	res_free(dev,fh);
998
999	return (0);
1000}
1001
1002static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *norm)
1003{
1004	int rc=0;
1005	struct tm6000_fh   *fh=priv;
1006	struct tm6000_core *dev = fh->dev;
1007
1008	rc=tm6000_set_standard (dev, norm);
1009
1010	fh->width  = dev->width;
1011	fh->height = dev->height;
1012
1013	if (rc<0)
1014		return rc;
1015
1016	v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
1017
1018	return 0;
1019}
1020
1021static int vidioc_enum_input (struct file *file, void *priv,
1022				struct v4l2_input *inp)
1023{
1024	switch (inp->index) {
1025	case TM6000_INPUT_TV:
1026		inp->type = V4L2_INPUT_TYPE_TUNER;
1027		strcpy(inp->name,"Television");
1028		break;
1029	case TM6000_INPUT_COMPOSITE:
1030		inp->type = V4L2_INPUT_TYPE_CAMERA;
1031		strcpy(inp->name,"Composite");
1032		break;
1033	case TM6000_INPUT_SVIDEO:
1034		inp->type = V4L2_INPUT_TYPE_CAMERA;
1035		strcpy(inp->name,"S-Video");
1036		break;
1037	default:
1038		return -EINVAL;
1039	}
1040	inp->std = TM6000_STD;
1041
1042	return 0;
1043}
1044
1045static int vidioc_g_input (struct file *file, void *priv, unsigned int *i)
1046{
1047	struct tm6000_fh   *fh=priv;
1048	struct tm6000_core *dev = fh->dev;
1049
1050	*i=dev->input;
1051
1052	return 0;
1053}
1054static int vidioc_s_input (struct file *file, void *priv, unsigned int i)
1055{
1056	struct tm6000_fh   *fh=priv;
1057	struct tm6000_core *dev = fh->dev;
1058	int rc=0;
1059	char buf[1];
1060
1061	switch (i) {
1062	case TM6000_INPUT_TV:
1063		dev->input=i;
1064		*buf=0;
1065		break;
1066	case TM6000_INPUT_COMPOSITE:
1067	case TM6000_INPUT_SVIDEO:
1068		dev->input=i;
1069		*buf=1;
1070		break;
1071	default:
1072		return -EINVAL;
1073	}
1074	rc=tm6000_read_write_usb (dev, USB_DIR_OUT | USB_TYPE_VENDOR,
1075			       REQ_03_SET_GET_MCU_PIN, 0x03, 1, buf, 1);
1076
1077	if (!rc) {
1078		dev->input=i;
1079		rc=vidioc_s_std (file, priv, &dev->vfd->current_norm);
1080	}
1081
1082	return (rc);
1083}
1084
1085	/* --- controls ---------------------------------------------- */
1086static int vidioc_queryctrl (struct file *file, void *priv,
1087				struct v4l2_queryctrl *qc)
1088{
1089	int i;
1090
1091	for (i = 0; i < ARRAY_SIZE(tm6000_qctrl); i++)
1092		if (qc->id && qc->id == tm6000_qctrl[i].id) {
1093			memcpy(qc, &(tm6000_qctrl[i]),
1094				sizeof(*qc));
1095			return (0);
1096		}
1097
1098	return -EINVAL;
1099}
1100
1101static int vidioc_g_ctrl (struct file *file, void *priv,
1102				struct v4l2_control *ctrl)
1103{
1104	struct tm6000_fh  *fh=priv;
1105	struct tm6000_core *dev    = fh->dev;
1106	int  val;
1107
1108	switch (ctrl->id) {
1109	case V4L2_CID_CONTRAST:
1110		val = tm6000_get_reg(dev, TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, 0);
1111		break;
1112	case V4L2_CID_BRIGHTNESS:
1113		val = tm6000_get_reg(dev, TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, 0);
1114		return 0;
1115	case V4L2_CID_SATURATION:
1116		val = tm6000_get_reg(dev, TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, 0);
1117		return 0;
1118	case V4L2_CID_HUE:
1119		val = tm6000_get_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, 0);
1120		return 0;
1121	default:
1122		return -EINVAL;
1123	}
1124
1125	if (val<0)
1126		return val;
1127
1128	ctrl->value=val;
1129
1130	return 0;
1131}
1132static int vidioc_s_ctrl (struct file *file, void *priv,
1133				struct v4l2_control *ctrl)
1134{
1135	struct tm6000_fh   *fh  =priv;
1136	struct tm6000_core *dev = fh->dev;
1137	u8  val=ctrl->value;
1138
1139	switch (ctrl->id) {
1140	case V4L2_CID_CONTRAST:
1141  tm6000_set_reg(dev, TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, val);
1142		return 0;
1143	case V4L2_CID_BRIGHTNESS:
1144  tm6000_set_reg(dev, TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, val);
1145		return 0;
1146	case V4L2_CID_SATURATION:
1147  tm6000_set_reg(dev, TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, val);
1148		return 0;
1149	case V4L2_CID_HUE:
1150  tm6000_set_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, val);
1151		return 0;
1152	}
1153	return -EINVAL;
1154}
1155
1156static int vidioc_g_tuner (struct file *file, void *priv,
1157				struct v4l2_tuner *t)
1158{
1159	struct tm6000_fh   *fh  =priv;
1160	struct tm6000_core *dev = fh->dev;
1161
1162	if (unlikely(UNSET == dev->tuner_type))
1163		return -EINVAL;
1164	if (0 != t->index)
1165		return -EINVAL;
1166
1167	strcpy(t->name, "Television");
1168	t->type       = V4L2_TUNER_ANALOG_TV;
1169	t->capability = V4L2_TUNER_CAP_NORM;
1170	t->rangehigh  = 0xffffffffUL;
1171	t->rxsubchans = V4L2_TUNER_SUB_MONO;
1172
1173	return 0;
1174}
1175
1176static int vidioc_s_tuner (struct file *file, void *priv,
1177				struct v4l2_tuner *t)
1178{
1179	struct tm6000_fh   *fh  =priv;
1180	struct tm6000_core *dev = fh->dev;
1181
1182	if (UNSET == dev->tuner_type)
1183		return -EINVAL;
1184	if (0 != t->index)
1185		return -EINVAL;
1186
1187	return 0;
1188}
1189
1190static int vidioc_g_frequency (struct file *file, void *priv,
1191				struct v4l2_frequency *f)
1192{
1193	struct tm6000_fh   *fh  =priv;
1194	struct tm6000_core *dev = fh->dev;
1195
1196	if (unlikely(UNSET == dev->tuner_type))
1197		return -EINVAL;
1198
1199	f->type = V4L2_TUNER_ANALOG_TV;
1200	f->frequency = dev->freq;
1201
1202	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, f);
1203
1204	return 0;
1205}
1206
1207static int vidioc_s_frequency (struct file *file, void *priv,
1208				struct v4l2_frequency *f)
1209{
1210	struct tm6000_fh   *fh  =priv;
1211	struct tm6000_core *dev = fh->dev;
1212
1213	if (unlikely(f->type != V4L2_TUNER_ANALOG_TV))
1214		return -EINVAL;
1215
1216	if (unlikely(UNSET == dev->tuner_type))
1217		return -EINVAL;
1218	if (unlikely(f->tuner != 0))
1219		return -EINVAL;
1220
1221//	mutex_lock(&dev->lock);
1222	dev->freq = f->frequency;
1223	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f);
1224//	mutex_unlock(&dev->lock);
1225
1226	return 0;
1227}
1228
1229/* ------------------------------------------------------------------
1230	File operations for the device
1231   ------------------------------------------------------------------*/
1232
1233static int tm6000_open(struct file *file)
1234{
1235	struct video_device *vdev = video_devdata(file);
1236	struct tm6000_core *dev = video_drvdata(file);
1237	struct tm6000_fh *fh;
1238	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1239	int i,rc;
1240
1241	printk(KERN_INFO "tm6000: open called (dev=%s)\n",
1242		video_device_node_name(vdev));
1243
1244	dprintk(dev, V4L2_DEBUG_OPEN, "tm6000: open called (dev=%s)\n",
1245		video_device_node_name(vdev));
1246
1247
1248	/* If more than one user, mutex should be added */
1249	dev->users++;
1250
1251	dprintk(dev, V4L2_DEBUG_OPEN, "open dev=%s type=%s users=%d\n",
1252		video_device_node_name(vdev), v4l2_type_names[type],
1253		dev->users);
1254
1255	/* allocate + initialize per filehandle data */
1256	fh = kzalloc(sizeof(*fh),GFP_KERNEL);
1257	if (NULL == fh) {
1258		dev->users--;
1259		return -ENOMEM;
1260	}
1261
1262	file->private_data = fh;
1263	fh->dev      = dev;
1264
1265	fh->type     = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1266	dev->fourcc  = format[0].fourcc;
1267
1268	fh->fmt      = format_by_fourcc(dev->fourcc);
1269
1270	tm6000_get_std_res (dev);
1271
1272	fh->width    = dev->width;
1273	fh->height   = dev->height;
1274
1275	dprintk(dev, V4L2_DEBUG_OPEN, "Open: fh=0x%08lx, dev=0x%08lx, "
1276						"dev->vidq=0x%08lx\n",
1277		(unsigned long)fh,(unsigned long)dev,(unsigned long)&dev->vidq);
1278	dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty "
1279				"queued=%d\n",list_empty(&dev->vidq.queued));
1280	dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty "
1281				"active=%d\n",list_empty(&dev->vidq.active));
1282
1283	/* initialize hardware on analog mode */
1284	if (dev->mode!=TM6000_MODE_ANALOG) {
1285		rc=tm6000_init_analog_mode (dev);
1286		if (rc<0)
1287			return rc;
1288
1289		/* Put all controls at a sane state */
1290		for (i = 0; i < ARRAY_SIZE(tm6000_qctrl); i++)
1291			qctl_regs[i] =tm6000_qctrl[i].default_value;
1292
1293		dev->mode=TM6000_MODE_ANALOG;
1294	}
1295
1296	videobuf_queue_vmalloc_init(&fh->vb_vidq, &tm6000_video_qops,
1297			NULL, &dev->slock,
1298			fh->type,
1299			V4L2_FIELD_INTERLACED,
1300			sizeof(struct tm6000_buffer),fh);
1301
1302	return 0;
1303}
1304
1305static ssize_t
1306tm6000_read(struct file *file, char __user *data, size_t count, loff_t *pos)
1307{
1308	struct tm6000_fh        *fh = file->private_data;
1309
1310	if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1311		if (res_locked(fh->dev))
1312			return -EBUSY;
1313
1314		return videobuf_read_stream(&fh->vb_vidq, data, count, pos, 0,
1315					file->f_flags & O_NONBLOCK);
1316	}
1317	return 0;
1318}
1319
1320static unsigned int
1321tm6000_poll(struct file *file, struct poll_table_struct *wait)
1322{
1323	struct tm6000_fh        *fh = file->private_data;
1324	struct tm6000_buffer    *buf;
1325
1326	if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1327		return POLLERR;
1328
1329	if (res_get(fh->dev,fh)) {
1330		/* streaming capture */
1331		if (list_empty(&fh->vb_vidq.stream))
1332			return POLLERR;
1333		buf = list_entry(fh->vb_vidq.stream.next,struct tm6000_buffer,vb.stream);
1334	} else {
1335		/* read() capture */
1336		return videobuf_poll_stream(file, &fh->vb_vidq,
1337					    wait);
1338	}
1339	poll_wait(file, &buf->vb.done, wait);
1340	if (buf->vb.state == VIDEOBUF_DONE ||
1341	    buf->vb.state == VIDEOBUF_ERROR)
1342		return POLLIN|POLLRDNORM;
1343	return 0;
1344}
1345
1346static int tm6000_release(struct file *file)
1347{
1348	struct tm6000_fh         *fh = file->private_data;
1349	struct tm6000_core      *dev = fh->dev;
1350	struct video_device    *vdev = video_devdata(file);
1351
1352	dprintk(dev, V4L2_DEBUG_OPEN, "tm6000: close called (dev=%s, users=%d)\n",
1353		video_device_node_name(vdev), dev->users);
1354
1355	dev->users--;
1356
1357	if (!dev->users) {
1358		tm6000_uninit_isoc(dev);
1359		videobuf_mmap_free(&fh->vb_vidq);
1360	}
1361
1362	kfree (fh);
1363
1364	return 0;
1365}
1366
1367static int tm6000_mmap(struct file *file, struct vm_area_struct * vma)
1368{
1369	struct tm6000_fh        *fh = file->private_data;
1370	int ret;
1371
1372	ret=videobuf_mmap_mapper(&fh->vb_vidq, vma);
1373
1374	return ret;
1375}
1376
1377static struct v4l2_file_operations tm6000_fops = {
1378	.owner		= THIS_MODULE,
1379	.open           = tm6000_open,
1380	.release        = tm6000_release,
1381	.ioctl          = video_ioctl2, /* V4L2 ioctl handler */
1382	.read           = tm6000_read,
1383	.poll		= tm6000_poll,
1384	.mmap		= tm6000_mmap,
1385};
1386
1387static const struct v4l2_ioctl_ops video_ioctl_ops = {
1388	.vidioc_querycap          = vidioc_querycap,
1389	.vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
1390	.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
1391	.vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,
1392	.vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,
1393	.vidioc_s_std             = vidioc_s_std,
1394	.vidioc_enum_input        = vidioc_enum_input,
1395	.vidioc_g_input           = vidioc_g_input,
1396	.vidioc_s_input           = vidioc_s_input,
1397	.vidioc_queryctrl         = vidioc_queryctrl,
1398	.vidioc_g_ctrl            = vidioc_g_ctrl,
1399	.vidioc_s_ctrl            = vidioc_s_ctrl,
1400	.vidioc_g_tuner           = vidioc_g_tuner,
1401	.vidioc_s_tuner           = vidioc_s_tuner,
1402	.vidioc_g_frequency       = vidioc_g_frequency,
1403	.vidioc_s_frequency       = vidioc_s_frequency,
1404	.vidioc_streamon          = vidioc_streamon,
1405	.vidioc_streamoff         = vidioc_streamoff,
1406	.vidioc_reqbufs           = vidioc_reqbufs,
1407	.vidioc_querybuf          = vidioc_querybuf,
1408	.vidioc_qbuf              = vidioc_qbuf,
1409	.vidioc_dqbuf             = vidioc_dqbuf,
1410#ifdef CONFIG_VIDEO_V4L1_COMPAT
1411	.vidiocgmbuf              = vidiocgmbuf,
1412#endif
1413};
1414
1415static struct video_device tm6000_template = {
1416	.name		= "tm6000",
1417	.fops           = &tm6000_fops,
1418	.ioctl_ops      = &video_ioctl_ops,
1419	.release	= video_device_release,
1420	.tvnorms        = TM6000_STD,
1421	.current_norm   = V4L2_STD_NTSC_M,
1422};
1423
1424/* -----------------------------------------------------------------
1425	Initialization and module stuff
1426   ------------------------------------------------------------------*/
1427
1428int tm6000_v4l2_register(struct tm6000_core *dev)
1429{
1430	int ret = -1;
1431	struct video_device *vfd;
1432
1433	vfd = video_device_alloc();
1434	if(!vfd) {
1435		return -ENOMEM;
1436	}
1437	dev->vfd = vfd;
1438
1439	/* init video dma queues */
1440	INIT_LIST_HEAD(&dev->vidq.active);
1441	INIT_LIST_HEAD(&dev->vidq.queued);
1442
1443	memcpy (dev->vfd, &tm6000_template, sizeof(*(dev->vfd)));
1444	dev->vfd->debug=tm6000_debug;
1445	vfd->v4l2_dev = &dev->v4l2_dev;
1446	video_set_drvdata(vfd, dev);
1447
1448	ret = video_register_device(dev->vfd, VFL_TYPE_GRABBER, video_nr);
1449	printk(KERN_INFO "Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: %d)\n", ret);
1450	return ret;
1451}
1452
1453int tm6000_v4l2_unregister(struct tm6000_core *dev)
1454{
1455	video_unregister_device(dev->vfd);
1456
1457	return 0;
1458}
1459
1460int tm6000_v4l2_exit(void)
1461{
1462	return 0;
1463}
1464
1465module_param(video_nr, int, 0);
1466MODULE_PARM_DESC(video_nr,"Allow changing video device number");
1467
1468module_param_named (debug, tm6000_debug, int, 0444);
1469MODULE_PARM_DESC(debug,"activates debug info");
1470
1471module_param(vid_limit,int,0644);
1472MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes");
1473