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