blob: ce80882d45e2d7fd8ae2c0baa8976b6e97974c54 [file] [log] [blame]
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001/*
2 * Auvitek AU0828 USB Bridge (Analog video support)
3 *
4 * Copyright (C) 2009 Devin Heitmueller <dheitmueller@linuxtv.org>
5 * Copyright (C) 2005-2008 Auvitek International, Ltd.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * As published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 */
22
23/* Developer Notes:
24 *
25 * VBI support is not yet working
26 * The hardware scaler supported is unimplemented
27 * AC97 audio support is unimplemented (only i2s audio mode)
28 *
29 */
30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/device.h>
34#include <linux/suspend.h>
35#include <linux/version.h>
36#include <linux/videodev.h>
37#include <media/v4l2-common.h>
38#include <media/v4l2-ioctl.h>
39#include <media/v4l2-chip-ident.h>
40#include <media/tuner.h>
41#include "au0828.h"
42#include "au0828-reg.h"
43
44static LIST_HEAD(au0828_devlist);
45static DEFINE_MUTEX(au0828_sysfs_lock);
46
47#define AU0828_VERSION_CODE KERNEL_VERSION(0, 0, 1)
48
49/* Forward declarations */
50void au0828_analog_stream_reset(struct au0828_dev *dev);
51
52/* ------------------------------------------------------------------
53 Videobuf operations
54 ------------------------------------------------------------------*/
55
56static unsigned int isoc_debug;
57module_param(isoc_debug, int, 0644);
58MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
59
60#define au0828_isocdbg(fmt, arg...) \
61do {\
62 if (isoc_debug) { \
63 printk(KERN_INFO "au0828 %s :"fmt, \
64 __func__ , ##arg); \
65 } \
66 } while (0)
67
68static inline void print_err_status(struct au0828_dev *dev,
69 int packet, int status)
70{
71 char *errmsg = "Unknown";
72
73 switch (status) {
74 case -ENOENT:
75 errmsg = "unlinked synchronuously";
76 break;
77 case -ECONNRESET:
78 errmsg = "unlinked asynchronuously";
79 break;
80 case -ENOSR:
81 errmsg = "Buffer error (overrun)";
82 break;
83 case -EPIPE:
84 errmsg = "Stalled (device not responding)";
85 break;
86 case -EOVERFLOW:
87 errmsg = "Babble (bad cable?)";
88 break;
89 case -EPROTO:
90 errmsg = "Bit-stuff error (bad cable?)";
91 break;
92 case -EILSEQ:
93 errmsg = "CRC/Timeout (could be anything)";
94 break;
95 case -ETIME:
96 errmsg = "Device does not respond";
97 break;
98 }
99 if (packet < 0) {
100 au0828_isocdbg("URB status %d [%s].\n", status, errmsg);
101 } else {
102 au0828_isocdbg("URB packet %d, status %d [%s].\n",
103 packet, status, errmsg);
104 }
105}
106
107static int check_dev(struct au0828_dev *dev)
108{
109 if (dev->dev_state & DEV_DISCONNECTED) {
110 printk("v4l2 ioctl: device not present\n");
111 return -ENODEV;
112 }
113
114 if (dev->dev_state & DEV_MISCONFIGURED) {
115 printk("v4l2 ioctl: device is misconfigured; "
116 "close and open it again\n");
117 return -EIO;
118 }
119 return 0;
120}
121
122/*
123 * IRQ callback, called by URB callback
124 */
125static void au0828_irq_callback(struct urb *urb)
126{
127 struct au0828_dmaqueue *dma_q = urb->context;
128 struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
129 int rc, i;
130
131 switch (urb->status) {
132 case 0: /* success */
133 case -ETIMEDOUT: /* NAK */
134 break;
135 case -ECONNRESET: /* kill */
136 case -ENOENT:
137 case -ESHUTDOWN:
138 au0828_isocdbg("au0828_irq_callback called: status kill\n");
139 return;
140 default: /* unknown error */
141 au0828_isocdbg("urb completition error %d.\n", urb->status);
142 break;
143 }
144
145 /* Copy data from URB */
146 spin_lock(&dev->slock);
147 rc = dev->isoc_ctl.isoc_copy(dev, urb);
148 spin_unlock(&dev->slock);
149
150 /* Reset urb buffers */
151 for (i = 0; i < urb->number_of_packets; i++) {
152 urb->iso_frame_desc[i].status = 0;
153 urb->iso_frame_desc[i].actual_length = 0;
154 }
155 urb->status = 0;
156
157 urb->status = usb_submit_urb(urb, GFP_ATOMIC);
158 if (urb->status) {
159 au0828_isocdbg("urb resubmit failed (error=%i)\n",
160 urb->status);
161 }
162}
163
164/*
165 * Stop and Deallocate URBs
166 */
167void au0828_uninit_isoc(struct au0828_dev *dev)
168{
169 struct urb *urb;
170 int i;
171
172 au0828_isocdbg("au0828: called au0828_uninit_isoc\n");
173
174 dev->isoc_ctl.nfields = -1;
175 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
176 urb = dev->isoc_ctl.urb[i];
177 if (urb) {
178 if (!irqs_disabled())
179 usb_kill_urb(urb);
180 else
181 usb_unlink_urb(urb);
182
183 if (dev->isoc_ctl.transfer_buffer[i]) {
184 usb_buffer_free(dev->usbdev,
185 urb->transfer_buffer_length,
186 dev->isoc_ctl.transfer_buffer[i],
187 urb->transfer_dma);
188 }
189 usb_free_urb(urb);
190 dev->isoc_ctl.urb[i] = NULL;
191 }
192 dev->isoc_ctl.transfer_buffer[i] = NULL;
193 }
194
195 kfree(dev->isoc_ctl.urb);
196 kfree(dev->isoc_ctl.transfer_buffer);
197
198 dev->isoc_ctl.urb = NULL;
199 dev->isoc_ctl.transfer_buffer = NULL;
200 dev->isoc_ctl.num_bufs = 0;
201}
202
203/*
204 * Allocate URBs and start IRQ
205 */
206int au0828_init_isoc(struct au0828_dev *dev, int max_packets,
207 int num_bufs, int max_pkt_size,
208 int (*isoc_copy) (struct au0828_dev *dev, struct urb *urb))
209{
210 struct au0828_dmaqueue *dma_q = &dev->vidq;
211 int i;
212 int sb_size, pipe;
213 struct urb *urb;
214 int j, k;
215 int rc;
216
217 au0828_isocdbg("au0828: called au0828_prepare_isoc\n");
218
219 /* De-allocates all pending stuff */
220 au0828_uninit_isoc(dev);
221
222 dev->isoc_ctl.isoc_copy = isoc_copy;
223 dev->isoc_ctl.num_bufs = num_bufs;
224
225 dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
226 if (!dev->isoc_ctl.urb) {
227 au0828_isocdbg("cannot alloc memory for usb buffers\n");
228 return -ENOMEM;
229 }
230
231 dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs,
232 GFP_KERNEL);
233 if (!dev->isoc_ctl.transfer_buffer) {
234 au0828_isocdbg("cannot allocate memory for usb transfer\n");
235 kfree(dev->isoc_ctl.urb);
236 return -ENOMEM;
237 }
238
239 dev->isoc_ctl.max_pkt_size = max_pkt_size;
240 dev->isoc_ctl.buf = NULL;
241
242 sb_size = max_packets * dev->isoc_ctl.max_pkt_size;
243
244 /* allocate urbs and transfer buffers */
245 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
246 urb = usb_alloc_urb(max_packets, GFP_KERNEL);
247 if (!urb) {
248 au0828_isocdbg("cannot alloc isoc_ctl.urb %i\n", i);
249 au0828_uninit_isoc(dev);
250 return -ENOMEM;
251 }
252 dev->isoc_ctl.urb[i] = urb;
253
254 dev->isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->usbdev,
255 sb_size, GFP_KERNEL, &urb->transfer_dma);
256 if (!dev->isoc_ctl.transfer_buffer[i]) {
257 printk("unable to allocate %i bytes for transfer"
258 " buffer %i%s\n",
259 sb_size, i,
260 in_interrupt() ? " while in int" : "");
261 au0828_uninit_isoc(dev);
262 return -ENOMEM;
263 }
264 memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
265
266 pipe = usb_rcvisocpipe(dev->usbdev,
267 dev->isoc_in_endpointaddr),
268
269 usb_fill_int_urb(urb, dev->usbdev, pipe,
270 dev->isoc_ctl.transfer_buffer[i], sb_size,
271 au0828_irq_callback, dma_q, 1);
272
273 urb->number_of_packets = max_packets;
274 urb->transfer_flags = URB_ISO_ASAP;
275
276 k = 0;
277 for (j = 0; j < max_packets; j++) {
278 urb->iso_frame_desc[j].offset = k;
279 urb->iso_frame_desc[j].length =
280 dev->isoc_ctl.max_pkt_size;
281 k += dev->isoc_ctl.max_pkt_size;
282 }
283 }
284
285 init_waitqueue_head(&dma_q->wq);
286
287 /* submit urbs and enables IRQ */
288 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
289 rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC);
290 if (rc) {
291 au0828_isocdbg("submit of urb %i failed (error=%i)\n",
292 i, rc);
293 au0828_uninit_isoc(dev);
294 return rc;
295 }
296 }
297
298 return 0;
299}
300
301/*
302 * Announces that a buffer were filled and request the next
303 */
304static inline void buffer_filled(struct au0828_dev *dev,
305 struct au0828_dmaqueue *dma_q,
306 struct au0828_buffer *buf)
307{
308 /* Advice that buffer was filled */
309 au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
310
311 buf->vb.state = VIDEOBUF_DONE;
312 buf->vb.field_count++;
313 do_gettimeofday(&buf->vb.ts);
314
315 dev->isoc_ctl.buf = NULL;
316
317 list_del(&buf->vb.queue);
318 wake_up(&buf->vb.done);
319}
320
321/*
322 * Identify the buffer header type and properly handles
323 */
324static void au0828_copy_video(struct au0828_dev *dev,
325 struct au0828_dmaqueue *dma_q,
326 struct au0828_buffer *buf,
327 unsigned char *p,
328 unsigned char *outp, unsigned long len)
329{
330 void *fieldstart, *startwrite, *startread;
331 int linesdone, currlinedone, offset, lencopy, remain;
332 int bytesperline = dev->width << 1; /* Assumes 16-bit depth @@@@ */
333
334 if (dma_q->pos + len > buf->vb.size)
335 len = buf->vb.size - dma_q->pos;
336
337 startread = p;
338 remain = len;
339
340 /* Interlaces frame */
341 if (buf->top_field)
342 fieldstart = outp;
343 else
344 fieldstart = outp + bytesperline;
345
346 linesdone = dma_q->pos / bytesperline;
347 currlinedone = dma_q->pos % bytesperline;
348 offset = linesdone * bytesperline * 2 + currlinedone;
349 startwrite = fieldstart + offset;
350 lencopy = bytesperline - currlinedone;
351 lencopy = lencopy > remain ? remain : lencopy;
352
353 if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) {
354 au0828_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
355 ((char *)startwrite + lencopy) -
356 ((char *)outp + buf->vb.size));
357 remain = (char *)outp + buf->vb.size - (char *)startwrite;
358 lencopy = remain;
359 }
360 if (lencopy <= 0)
361 return;
362 memcpy(startwrite, startread, lencopy);
363
364 remain -= lencopy;
365
366 while (remain > 0) {
367 startwrite += lencopy + bytesperline;
368 startread += lencopy;
369 if (bytesperline > remain)
370 lencopy = remain;
371 else
372 lencopy = bytesperline;
373
374 if ((char *)startwrite + lencopy > (char *)outp +
375 buf->vb.size) {
376 au0828_isocdbg("Overflow of %zi bytes past buffer end (2)\n",
377 ((char *)startwrite + lencopy) -
378 ((char *)outp + buf->vb.size));
379 lencopy = remain = (char *)outp + buf->vb.size -
380 (char *)startwrite;
381 }
382 if (lencopy <= 0)
383 break;
384
385 memcpy(startwrite, startread, lencopy);
386
387 remain -= lencopy;
388 }
389
390 if (offset > 1440) {
391 /* We have enough data to check for greenscreen */
392 if (outp[0] < 0x60 && outp[1440] < 0x60) {
393 dev->greenscreen_detected = 1;
394 }
395 }
396
397 dma_q->pos += len;
398}
399
400/*
401 * video-buf generic routine to get the next available buffer
402 */
403static inline void get_next_buf(struct au0828_dmaqueue *dma_q,
404 struct au0828_buffer **buf)
405{
406 struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
407
408 if (list_empty(&dma_q->active)) {
409 au0828_isocdbg("No active queue to serve\n");
410 dev->isoc_ctl.buf = NULL;
411 *buf = NULL;
412 return;
413 }
414
415 /* Get the next buffer */
416 *buf = list_entry(dma_q->active.next, struct au0828_buffer, vb.queue);
417 dev->isoc_ctl.buf = *buf;
418
419 return;
420}
421
422/*
423 * Controls the isoc copy of each urb packet
424 */
425static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
426{
427 struct au0828_buffer *buf;
428 struct au0828_dmaqueue *dma_q = urb->context;
429 unsigned char *outp = NULL;
430 int i, len = 0, rc = 1;
431 unsigned char *p;
432 unsigned char fbyte;
433
434 if (!dev)
435 return 0;
436
437 if ((dev->dev_state & DEV_DISCONNECTED) ||
438 (dev->dev_state & DEV_MISCONFIGURED))
439 return 0;
440
441 if (urb->status < 0) {
442 print_err_status(dev, -1, urb->status);
443 if (urb->status == -ENOENT)
444 return 0;
445 }
446
447 buf = dev->isoc_ctl.buf;
448 if (buf != NULL)
449 outp = videobuf_to_vmalloc(&buf->vb);
450
451 for (i = 0; i < urb->number_of_packets; i++) {
452 int status = urb->iso_frame_desc[i].status;
453
454 if (status < 0) {
455 print_err_status(dev, i, status);
456 if (urb->iso_frame_desc[i].status != -EPROTO)
457 continue;
458 }
459
460 if (urb->iso_frame_desc[i].actual_length <= 0) {
461 continue;
462 }
463 if (urb->iso_frame_desc[i].actual_length >
464 dev->max_pkt_size) {
465 au0828_isocdbg("packet bigger than packet size");
466 continue;
467 }
468
469 p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
470 fbyte = p[0];
471 len = urb->iso_frame_desc[i].actual_length - 4;
472 p += 4;
473
474 if (fbyte & 0x80) {
475 len -= 4;
476 p += 4;
477 au0828_isocdbg("Video frame %s\n",
478 (fbyte & 0x40) ? "odd" : "even");
479 if (!(fbyte & 0x40)) {
480 if (buf != NULL)
481 buffer_filled(dev, dma_q, buf);
482 get_next_buf(dma_q, &buf);
483 if (buf == NULL) {
484 outp = NULL;
485 } else
486 outp = videobuf_to_vmalloc(&buf->vb);
487 }
488
489 if (buf != NULL) {
490 if (fbyte & 0x40) {
491 buf->top_field = 1;
492 } else {
493 buf->top_field = 0;
494 }
495 }
496
497 dma_q->pos = 0;
498 }
499 if (buf != NULL) {
500 au0828_copy_video(dev, dma_q, buf, p, outp, len);
501 }
502 }
503 return rc;
504}
505
506static int
507buffer_setup(struct videobuf_queue *vq, unsigned int *count,
508 unsigned int *size)
509{
510 struct au0828_fh *fh = vq->priv_data;
511 *size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3;
512
513 if (0 == *count)
514 *count = AU0828_DEF_BUF;
515
516 if (*count < AU0828_MIN_BUF)
517 *count = AU0828_MIN_BUF;
518 return 0;
519}
520
521/* This is called *without* dev->slock held; please keep it that way */
522static void free_buffer(struct videobuf_queue *vq, struct au0828_buffer *buf)
523{
524 struct au0828_fh *fh = vq->priv_data;
525 struct au0828_dev *dev = fh->dev;
526 unsigned long flags = 0;
527 if (in_interrupt())
528 BUG();
529
530 /* We used to wait for the buffer to finish here, but this didn't work
531 because, as we were keeping the state as VIDEOBUF_QUEUED,
532 videobuf_queue_cancel marked it as finished for us.
533 (Also, it could wedge forever if the hardware was misconfigured.)
534
535 This should be safe; by the time we get here, the buffer isn't
536 queued anymore. If we ever start marking the buffers as
537 VIDEOBUF_ACTIVE, it won't be, though.
538 */
539 spin_lock_irqsave(&dev->slock, flags);
540 if (dev->isoc_ctl.buf == buf)
541 dev->isoc_ctl.buf = NULL;
542 spin_unlock_irqrestore(&dev->slock, flags);
543
544 videobuf_vmalloc_free(&buf->vb);
545 buf->vb.state = VIDEOBUF_NEEDS_INIT;
546}
547
548static int
549buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
550 enum v4l2_field field)
551{
552 struct au0828_fh *fh = vq->priv_data;
553 struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
554 struct au0828_dev *dev = fh->dev;
555 int rc = 0, urb_init = 0;
556
557 buf->vb.size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3;
558
559 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
560 return -EINVAL;
561
562 buf->vb.width = dev->width;
563 buf->vb.height = dev->height;
564 buf->vb.field = field;
565
566 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
567 rc = videobuf_iolock(vq, &buf->vb, NULL);
568 if (rc < 0) {
569 printk("videobuf_iolock failed\n");
570 goto fail;
571 }
572 }
573
574 if (!dev->isoc_ctl.num_bufs)
575 urb_init = 1;
576
577 if (urb_init) {
578 rc = au0828_init_isoc(dev, AU0828_ISO_PACKETS_PER_URB,
579 AU0828_MAX_ISO_BUFS, dev->max_pkt_size,
580 au0828_isoc_copy);
581 if (rc < 0) {
582 printk("au0828_init_isoc failed\n");
583 goto fail;
584 }
585 }
586
587 buf->vb.state = VIDEOBUF_PREPARED;
588 return 0;
589
590fail:
591 free_buffer(vq, buf);
592 return rc;
593}
594
595static void
596buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
597{
598 struct au0828_buffer *buf = container_of(vb,
599 struct au0828_buffer,
600 vb);
601 struct au0828_fh *fh = vq->priv_data;
602 struct au0828_dev *dev = fh->dev;
603 struct au0828_dmaqueue *vidq = &dev->vidq;
604
605 buf->vb.state = VIDEOBUF_QUEUED;
606 list_add_tail(&buf->vb.queue, &vidq->active);
607}
608
609static void buffer_release(struct videobuf_queue *vq,
610 struct videobuf_buffer *vb)
611{
612 struct au0828_buffer *buf = container_of(vb,
613 struct au0828_buffer,
614 vb);
615
616 free_buffer(vq, buf);
617}
618
619static struct videobuf_queue_ops au0828_video_qops = {
620 .buf_setup = buffer_setup,
621 .buf_prepare = buffer_prepare,
622 .buf_queue = buffer_queue,
623 .buf_release = buffer_release,
624};
625
626/* ------------------------------------------------------------------
627 V4L2 interface
628 ------------------------------------------------------------------*/
629
630static int au0828_i2s_init(struct au0828_dev *dev)
631{
632 /* Enable i2s mode */
633 au0828_writereg(dev, AU0828_AUDIOCTRL_50C, 0x01);
634 return 0;
635}
636
637/*
638 * Auvitek au0828 analog stream enable
639 * Please set interface0 to AS5 before enable the stream
640 */
641int au0828_analog_stream_enable(struct au0828_dev *d)
642{
643 dprintk(1, "au0828_analog_stream_enable called\n");
644 au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00);
645 au0828_writereg(d, 0x106, 0x00);
646 /* set x position */
647 au0828_writereg(d, 0x110, 0x00);
648 au0828_writereg(d, 0x111, 0x00);
649 au0828_writereg(d, 0x114, 0xa0);
650 au0828_writereg(d, 0x115, 0x05);
651 /* set y position */
652 au0828_writereg(d, 0x112, 0x02);
653 au0828_writereg(d, 0x113, 0x00);
654 au0828_writereg(d, 0x116, 0xf2);
655 au0828_writereg(d, 0x117, 0x00);
656 au0828_writereg(d, AU0828_SENSORCTRL_100, 0xb3);
657
658 return 0;
659}
660
661int au0828_analog_stream_disable(struct au0828_dev *d)
662{
663 dprintk(1, "au0828_analog_stream_disable called\n");
664 au0828_writereg(d, AU0828_SENSORCTRL_100, 0x0);
665 return 0;
666}
667
668void au0828_analog_stream_reset(struct au0828_dev *dev)
669{
670 dprintk(1, "au0828_analog_stream_reset called\n");
671 au0828_writereg(dev, AU0828_SENSORCTRL_100, 0x0);
672 mdelay(30);
673 au0828_writereg(dev, AU0828_SENSORCTRL_100, 0xb3);
674}
675
676/*
677 * Some operations needs to stop current streaming
678 */
679static int au0828_stream_interrupt(struct au0828_dev *dev)
680{
681 int ret = 0;
682
683 dev->stream_state = STREAM_INTERRUPT;
684 if(dev->dev_state == DEV_DISCONNECTED)
685 return -ENODEV;
686 else if(ret) {
687 dev->dev_state = DEV_MISCONFIGURED;
688 dprintk(1, "%s device is misconfigured!\n", __FUNCTION__);
689 return ret;
690 }
691 return 0;
692}
693
694/*
695 * au0828_release_resources
696 * unregister v4l2 devices
697 */
698void au0828_analog_unregister(struct au0828_dev *dev)
699{
700 dprintk(1, "au0828_release_resources called\n");
701 mutex_lock(&au0828_sysfs_lock);
702
703 list_del(&dev->au0828list);
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -0300704 if (dev->vdev)
705 video_unregister_device(dev->vdev);
706 if (dev->vbi_dev)
707 video_unregister_device(dev->vbi_dev);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300708
709 mutex_unlock(&au0828_sysfs_lock);
710}
711
712
713/* Usage lock check functions */
714static int res_get(struct au0828_fh *fh)
715{
716 struct au0828_dev *dev = fh->dev;
717 int rc = 0;
718
719 /* This instance already has stream_on */
720 if (fh->stream_on)
721 return rc;
722
723 if (dev->stream_on)
724 return -EBUSY;
725
726 dev->stream_on = 1;
727 fh->stream_on = 1;
728 return rc;
729}
730
731static int res_check(struct au0828_fh *fh)
732{
733 return fh->stream_on;
734}
735
736static void res_free(struct au0828_fh *fh)
737{
738 struct au0828_dev *dev = fh->dev;
739
740 fh->stream_on = 0;
741 dev->stream_on = 0;
742}
743
744static int au0828_v4l2_open(struct file *filp)
745{
746 int minor = video_devdata(filp)->minor;
747 int ret = 0;
748 struct au0828_dev *h, *dev = NULL;
749 struct au0828_fh *fh;
750 int type = 0;
751 struct list_head *list;
752
753 list_for_each(list, &au0828_devlist) {
754 h = list_entry(list, struct au0828_dev, au0828list);
755 if(h->vdev->minor == minor) {
756 dev = h;
757 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
758 }
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -0300759#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300760 if(h->vbi_dev->minor == minor) {
761 dev = h;
762 type = V4L2_BUF_TYPE_VBI_CAPTURE;
763 }
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -0300764#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300765 }
766
767 if(NULL == dev)
768 return -ENODEV;
769
770 fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL);
771 if(NULL == fh) {
772 dprintk(1, "Failed allocate au0828_fh struct!\n");
773 return -ENOMEM;
774 }
775
776 fh->type = type;
777 fh->dev = dev;
778 filp->private_data = fh;
779
780 if(fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
781 /* set au0828 interface0 to AS5 here again */
782 ret = usb_set_interface(dev->usbdev, 0, 5);
783 if(ret < 0) {
784 printk("Au0828 can't set alt setting to 5!\n");
785 return -EBUSY;
786 }
787 dev->width = NTSC_STD_W;
788 dev->height = NTSC_STD_H;
789 dev->frame_size = dev->width * dev->height * 2;
790 dev->field_size = dev->width * dev->height;
791 dev->bytesperline = dev->width * 2;
792
793 au0828_analog_stream_enable(dev);
794 au0828_analog_stream_reset(dev);
795
796 /* If we were doing ac97 instead of i2s, it would go here...*/
797 au0828_i2s_init(dev);
798
799 dev->stream_state = STREAM_OFF;
800 dev->dev_state |= DEV_INITIALIZED;
801 }
802
803 dev->users++;
804
805 videobuf_queue_vmalloc_init(&fh->vb_vidq, &au0828_video_qops,
806 NULL, &dev->slock, fh->type,
807 V4L2_FIELD_INTERLACED,
808 sizeof(struct au0828_buffer), fh);
809
810 return ret;
811}
812
813static int au0828_v4l2_close(struct file *filp)
814{
815 int ret;
816 struct au0828_fh *fh = filp->private_data;
817 struct au0828_dev *dev = fh->dev;
818
819 mutex_lock(&dev->lock);
820 if (res_check(fh))
821 res_free(fh);
822
823 if(dev->users == 1) {
824 videobuf_stop(&fh->vb_vidq);
825 videobuf_mmap_free(&fh->vb_vidq);
826
827 if(dev->dev_state & DEV_DISCONNECTED) {
828 au0828_analog_unregister(dev);
829 mutex_unlock(&dev->lock);
830 kfree(dev);
831 return 0;
832 }
833
834 au0828_analog_stream_disable(dev);
835
836 au0828_uninit_isoc(dev);
837
838 /* When close the device, set the usb intf0 into alt0 to free
839 USB bandwidth */
840 ret = usb_set_interface(dev->usbdev, 0, 0);
841 if(ret < 0)
842 printk("Au0828 can't set alt setting to 0!\n");
843 }
844
845 kfree(fh);
846 dev->users--;
847 wake_up_interruptible_nr(&dev->open, 1);
848 mutex_unlock(&dev->lock);
849 return 0;
850}
851
852static ssize_t au0828_v4l2_read(struct file *filp, char __user *buf,
853 size_t count, loff_t *pos)
854{
855 struct au0828_fh *fh = filp->private_data;
856 struct au0828_dev *dev = fh->dev;
857 int rc;
858
859 rc = check_dev(dev);
860 if (rc < 0)
861 return rc;
862
863 if(fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
864 mutex_lock(&dev->lock);
865 rc = res_get(fh);
866 mutex_unlock(&dev->lock);
867
868 if (unlikely(rc < 0))
869 return rc;
870
871 return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
872 filp->f_flags & O_NONBLOCK);
873 }
874 return 0;
875}
876
877static unsigned int au0828_v4l2_poll(struct file *filp, poll_table *wait)
878{
879 struct au0828_fh *fh = filp->private_data;
880 struct au0828_dev *dev = fh->dev;
881 int rc;
882
883 rc = check_dev(dev);
884 if (rc < 0)
885 return rc;
886
887 mutex_lock(&dev->lock);
888 rc = res_get(fh);
889 mutex_unlock(&dev->lock);
890
891 if (unlikely(rc < 0))
892 return POLLERR;
893
894 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
895 return POLLERR;
896
897 return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
898}
899
900static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
901{
902 struct au0828_fh *fh = filp->private_data;
903 struct au0828_dev *dev = fh->dev;
904 int rc;
905
906 rc = check_dev(dev);
907 if (rc < 0)
908 return rc;
909
910 mutex_lock(&dev->lock);
911 rc = res_get(fh);
912 mutex_unlock(&dev->lock);
913
914 if (unlikely(rc < 0))
915 return rc;
916
917 rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
918
919 dprintk(2, "vma start=0x%08lx, size=%ld, ret=%d\n",
920 (unsigned long)vma->vm_start,
921 (unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
922 rc);
923
924 return rc;
925}
926
927static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd,
928 struct v4l2_format *format)
929{
930 int ret;
931 int width = format->fmt.pix.width;
932 int height = format->fmt.pix.height;
933 unsigned int maxwidth, maxheight;
934
935 maxwidth = 720;
936 maxheight = 480;
937
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -0300938#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300939 if(format->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
940 dprintk(1, "VBI format set: to be supported!\n");
941 return 0;
942 }
943 if(format->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
944 return 0;
945 }
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -0300946#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300947 if(format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
948 return -EINVAL;
949 }
950
951 /* If they are demanding a format other than the one we support,
952 bail out (tvtime asks for UYVY and then retries with YUYV) */
953 if (format->fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY) {
954 return -EINVAL;
955 }
956
957 /* format->fmt.pix.width only support 720 and height 480 */
958 if(width != 720)
959 width = 720;
960 if(height != 480)
961 height = 480;
962
963 format->fmt.pix.width = width;
964 format->fmt.pix.height = height;
965 format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
966 format->fmt.pix.bytesperline = width * 2;
967 format->fmt.pix.sizeimage = width * height * 2;
968 format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
969 format->fmt.pix.field = V4L2_FIELD_INTERLACED;
970
971 if(cmd == VIDIOC_TRY_FMT)
972 return 0;
973
974 /* maybe set new image format, driver current only support 720*480 */
975 dev->width = width;
976 dev->height = height;
977 dev->frame_size = width * height * 2;
978 dev->field_size = width * height;
979 dev->bytesperline = width * 2;
980
981 if(dev->stream_state == STREAM_ON) {
982 dprintk(1, "VIDIOC_SET_FMT: interrupting stream!\n");
983 if((ret = au0828_stream_interrupt(dev))) {
984 dprintk(1, "error interrupting video stream!\n");
985 return ret;
986 }
987 }
988
989 /* set au0828 interface0 to AS5 here again */
990 ret = usb_set_interface(dev->usbdev, 0, 5);
991 if(ret < 0) {
992 printk("Au0828 can't set alt setting to 5!\n");
993 return -EBUSY;
994 }
995
996 au0828_analog_stream_enable(dev);
997
998 return 0;
999}
1000
1001
1002static int vidioc_queryctrl(struct file *file, void *priv,
1003 struct v4l2_queryctrl *qc)
1004{
1005 struct au0828_fh *fh = priv;
1006 struct au0828_dev *dev = fh->dev;
1007 au0828_call_i2c_clients(dev, VIDIOC_QUERYCTRL, qc);
1008 if (qc->type)
1009 return 0;
1010 else
1011 return -EINVAL;
1012}
1013
1014static int vidioc_querycap(struct file *file, void *priv,
1015 struct v4l2_capability *cap)
1016{
1017 struct au0828_fh *fh = priv;
1018 struct au0828_dev *dev = fh->dev;
1019
1020 memset(cap, 0, sizeof(*cap));
1021 strlcpy(cap->driver, "au0828", sizeof(cap->driver));
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001022 strlcpy(cap->card, dev->board.name, sizeof(cap->card));
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001023 strlcpy(cap->bus_info, dev->usbdev->dev.bus_id, sizeof(cap->bus_info));
1024
1025 cap->version = AU0828_VERSION_CODE;
1026
1027 /*set the device capabilities */
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001028 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
1029#ifdef VBI_NOT_YET_WORKING
1030 V4L2_CAP_VBI_CAPTURE |
1031#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001032 V4L2_CAP_AUDIO |
1033 V4L2_CAP_READWRITE |
1034 V4L2_CAP_STREAMING |
1035 V4L2_CAP_TUNER;
1036 return 0;
1037}
1038
1039static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
1040 struct v4l2_fmtdesc *f)
1041{
1042 if(f->index)
1043 return -EINVAL;
1044
1045 memset(f, 0, sizeof(*f));
1046 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1047 strcpy(f->description, "Packed YUV2");
1048
1049 f->flags = 0;
1050 f->pixelformat = V4L2_PIX_FMT_UYVY;
1051
1052 memset(f->reserved, 0, sizeof(f->reserved));
1053 return 0;
1054}
1055
1056static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
1057 struct v4l2_format *f)
1058{
1059 struct au0828_fh *fh = priv;
1060 struct au0828_dev *dev = fh->dev;
1061
1062 f->fmt.pix.width = dev->width;
1063 f->fmt.pix.height = dev->height;
1064 f->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
1065 f->fmt.pix.bytesperline = dev->bytesperline;
1066 f->fmt.pix.sizeimage = dev->frame_size;
1067 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* NTSC/PAL */
1068 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
1069 return 0;
1070}
1071
1072static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
1073 struct v4l2_format *f)
1074{
1075 struct au0828_fh *fh = priv;
1076 struct au0828_dev *dev = fh->dev;
1077
1078 return au0828_set_format(dev, VIDIOC_TRY_FMT, f);
1079}
1080
1081static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1082 struct v4l2_format *f)
1083{
1084 struct au0828_fh *fh = priv;
1085 struct au0828_dev *dev = fh->dev;
1086 int rc;
1087
1088 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
1089 printk("%s queue busy\n", __func__);
1090 rc = -EBUSY;
1091 goto out;
1092 }
1093
1094 if (dev->stream_on && !fh->stream_on) {
1095 printk("%s device in use by another fh\n", __func__);
1096 rc = -EBUSY;
1097 goto out;
1098 }
1099
1100 return au0828_set_format(dev, VIDIOC_S_FMT, f);
1101out:
1102 return rc;
1103}
1104
1105static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
1106{
1107 struct au0828_fh *fh = priv;
1108 struct au0828_dev *dev = fh->dev;
1109
1110 /* FIXME: when we support something other than NTSC, we are going to
1111 have to make the au0828 bridge adjust the size of its capture
1112 buffer, which is currently hardcoded at 720x480 */
1113
1114 au0828_call_i2c_clients(dev, VIDIOC_S_STD, norm);
1115 return 0;
1116}
1117
1118static int vidioc_enum_input(struct file *file, void *priv,
1119 struct v4l2_input *input)
1120{
1121 struct au0828_fh *fh = priv;
1122 struct au0828_dev *dev = fh->dev;
1123 unsigned int tmp;
1124
1125 static const char *inames[] = {
1126 [AU0828_VMUX_COMPOSITE] = "Composite",
1127 [AU0828_VMUX_SVIDEO] = "S-Video",
1128 [AU0828_VMUX_CABLE] = "Cable TV",
1129 [AU0828_VMUX_TELEVISION] = "Television",
1130 [AU0828_VMUX_DVB] = "DVB",
1131 [AU0828_VMUX_DEBUG] = "tv debug"
1132 };
1133
1134 tmp = input->index;
1135
1136 if(tmp > AU0828_MAX_INPUT)
1137 return -EINVAL;
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001138 if(AUVI_INPUT(tmp).type == 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001139 return -EINVAL;
1140
1141 memset(input, 0, sizeof(*input));
1142 input->index = tmp;
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001143 strcpy(input->name, inames[AUVI_INPUT(tmp).type]);
1144 if((AUVI_INPUT(tmp).type == AU0828_VMUX_TELEVISION) ||
1145 (AUVI_INPUT(tmp).type == AU0828_VMUX_CABLE))
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001146 input->type |= V4L2_INPUT_TYPE_TUNER;
1147 else
1148 input->type |= V4L2_INPUT_TYPE_CAMERA;
1149
1150 input->std = dev->vdev->tvnorms;
1151
1152 return 0;
1153}
1154
1155static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1156{
1157 struct au0828_fh *fh = priv;
1158 struct au0828_dev *dev = fh->dev;
1159 *i = dev->ctrl_input;
1160 return 0;
1161}
1162
1163static int vidioc_s_input(struct file *file, void *priv, unsigned int index)
1164{
1165 struct au0828_fh *fh = priv;
1166 struct au0828_dev *dev = fh->dev;
1167 int i;
1168 struct v4l2_routing route;
1169
1170 dprintk(1, "VIDIOC_S_INPUT in function %s, input=%d\n", __FUNCTION__,
1171 index);
1172 if(index >= AU0828_MAX_INPUT)
1173 return -EINVAL;
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001174 if(AUVI_INPUT(index).type == 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001175 return -EINVAL;
1176 dev->ctrl_input = index;
1177
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001178 switch(AUVI_INPUT(index).type) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001179 case AU0828_VMUX_SVIDEO:
1180 {
1181 dev->input_type = AU0828_VMUX_SVIDEO;
1182 break;
1183 }
1184 case AU0828_VMUX_COMPOSITE:
1185 {
1186 dev->input_type = AU0828_VMUX_COMPOSITE;
1187 break;
1188 }
1189 case AU0828_VMUX_TELEVISION:
1190 {
1191 dev->input_type = AU0828_VMUX_TELEVISION;
1192 break;
1193 }
1194 default:
1195 ;
1196 }
1197
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001198 route.input = AUVI_INPUT(index).vmux;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001199 route.output = 0;
1200 au0828_call_i2c_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
1201
1202 for (i = 0; i < AU0828_MAX_INPUT; i++) {
1203 int enable = 0;
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001204 if (AUVI_INPUT(i).audio_setup == NULL) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001205 continue;
1206 }
1207
1208 if (i == index)
1209 enable = 1;
1210 else
1211 enable = 0;
1212 if (enable) {
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001213 (AUVI_INPUT(i).audio_setup)(dev, enable);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001214 } else {
1215 /* Make sure we leave it turned on if some
1216 other input is routed to this callback */
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001217 if ((AUVI_INPUT(i).audio_setup) !=
1218 ((AUVI_INPUT(index).audio_setup))) {
1219 (AUVI_INPUT(i).audio_setup)(dev, enable);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001220 }
1221 }
1222 }
1223
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001224 route.input = AUVI_INPUT(index).amux;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001225 au0828_call_i2c_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING,
1226 &route);
1227 return 0;
1228}
1229
1230static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
1231{
1232 struct au0828_fh *fh = priv;
1233 struct au0828_dev *dev = fh->dev;
1234 unsigned int index = a->index;
1235
1236 if(a->index > 1)
1237 return -EINVAL;
1238
1239 memset(a, 0, sizeof(*a));
1240 index = dev->ctrl_ainput;
1241 if(index == 0)
1242 strcpy(a->name, "Television");
1243 else
1244 strcpy(a->name, "Line in");
1245
1246 a->capability = V4L2_AUDCAP_STEREO;
1247 a->index = index;
1248 return 0;
1249}
1250
1251static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
1252{
1253 struct au0828_fh *fh = priv;
1254 struct au0828_dev *dev = fh->dev;
1255 if(a->index != dev->ctrl_ainput)
1256 return -EINVAL;
1257 return 0;
1258}
1259
1260static int vidioc_g_ctrl(struct file *file, void *priv,
1261 struct v4l2_control *ctrl)
1262{
1263 struct au0828_fh *fh = priv;
1264 struct au0828_dev *dev = fh->dev;
1265
1266 au0828_call_i2c_clients(dev, VIDIOC_G_CTRL, ctrl);
1267 return 0;
1268
1269}
1270
1271static int vidioc_s_ctrl(struct file *file, void *priv,
1272 struct v4l2_control *ctrl)
1273{
1274 struct au0828_fh *fh = priv;
1275 struct au0828_dev *dev = fh->dev;
1276 au0828_call_i2c_clients(dev, VIDIOC_S_CTRL, ctrl);
1277 return 0;
1278}
1279
1280static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1281{
1282 struct au0828_fh *fh = priv;
1283 struct au0828_dev *dev = fh->dev;
1284
1285 if(t->index != 0)
1286 return -EINVAL;
1287
1288 memset(t, 0, sizeof(*t));
1289 strcpy(t->name, "Auvitek tuner");
1290
1291 au0828_call_i2c_clients(dev, VIDIOC_G_TUNER, t);
1292 return 0;
1293}
1294
1295static int vidioc_s_tuner(struct file *file, void *priv,
1296 struct v4l2_tuner *t)
1297{
1298 struct au0828_fh *fh = priv;
1299 struct au0828_dev *dev = fh->dev;
1300
1301 if(t->index != 0)
1302 return -EINVAL;
1303
1304 t->type = V4L2_TUNER_ANALOG_TV;
1305 au0828_call_i2c_clients(dev, VIDIOC_S_TUNER, t);
1306 dprintk(1, "VIDIOC_S_TUNER: signal = %x, afc = %x\n", t->signal,
1307 t->afc);
1308 return 0;
1309
1310}
1311
1312static int vidioc_g_frequency(struct file *file, void *priv,
1313 struct v4l2_frequency *freq)
1314{
1315 struct au0828_fh *fh = priv;
1316 struct au0828_dev *dev = fh->dev;
1317 memset(freq, 0, sizeof(*freq));
1318 freq->type = V4L2_TUNER_ANALOG_TV;
1319 freq->frequency = dev->ctrl_freq;
1320 return 0;
1321}
1322
1323static int vidioc_s_frequency(struct file *file, void *priv,
1324 struct v4l2_frequency *freq)
1325{
1326 struct au0828_fh *fh = priv;
1327 struct au0828_dev *dev = fh->dev;
1328
1329 if(freq->tuner != 0)
1330 return -EINVAL;
1331 if(freq->type != V4L2_TUNER_ANALOG_TV)
1332 return -EINVAL;
1333
1334 dev->ctrl_freq = freq->frequency;
1335
1336 au0828_call_i2c_clients(dev, VIDIOC_S_FREQUENCY, freq);
1337
1338 au0828_analog_stream_reset(dev);
1339
1340 return 0;
1341}
1342
1343static int vidioc_g_chip_ident(struct file *file, void *priv,
1344 struct v4l2_dbg_chip_ident *chip)
1345{
1346 struct au0828_fh *fh = priv;
1347 struct au0828_dev *dev = fh->dev;
1348 chip->ident = V4L2_IDENT_NONE;
1349 chip->revision = 0;
1350
Devin Heitmuellerd9109be2009-03-11 03:00:58 -03001351 if (v4l2_chip_match_host(&chip->match)) {
1352 chip->ident = V4L2_IDENT_AU0828;
1353 return 0;
1354 }
1355
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001356 au0828_call_i2c_clients(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
Devin Heitmuellerd9109be2009-03-11 03:00:58 -03001357 if (chip->ident == V4L2_IDENT_NONE)
1358 return -EINVAL;
1359
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001360 return 0;
1361}
1362
1363static int vidioc_cropcap(struct file *file, void *priv,
1364 struct v4l2_cropcap *cc)
1365{
1366 struct au0828_fh *fh = priv;
1367 struct au0828_dev *dev = fh->dev;
1368
1369 if(cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1370 return -EINVAL;
1371
1372 cc->bounds.left = 0;
1373 cc->bounds.top = 0;
1374 cc->bounds.width = dev->width;
1375 cc->bounds.height = dev->height;
1376
1377 cc->defrect = cc->bounds;
1378
1379 cc->pixelaspect.numerator = 54;
1380 cc->pixelaspect.denominator = 59;
1381
1382 return 0;
1383}
1384
1385static int vidioc_streamon(struct file *file, void *priv,
1386 enum v4l2_buf_type type)
1387{
1388 struct au0828_fh *fh = priv;
1389 struct au0828_dev *dev = fh->dev;
1390 int b = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1391 int rc;
1392
1393 rc = check_dev(dev);
1394 if (rc < 0)
1395 return rc;
1396
1397 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1398 au0828_analog_stream_enable(dev);
1399 au0828_call_i2c_clients(dev, VIDIOC_STREAMON, &b);
1400 }
1401
1402 mutex_lock(&dev->lock);
1403 rc = res_get(fh);
1404
1405 if (likely(rc >= 0))
1406 rc = videobuf_streamon(&fh->vb_vidq);
1407 mutex_unlock(&dev->lock);
1408
1409 return rc;
1410}
1411
1412static int vidioc_streamoff(struct file *file, void *priv,
1413 enum v4l2_buf_type type)
1414{
1415 struct au0828_fh *fh = priv;
1416 struct au0828_dev *dev = fh->dev;
1417 int b = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1418 int i;
1419 int ret;
1420 int rc;
1421
1422 rc = check_dev(dev);
1423 if (rc < 0)
1424 return rc;
1425
1426 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1427 return -EINVAL;
1428 if (type != fh->type)
1429 return -EINVAL;
1430
1431 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1432 au0828_call_i2c_clients(dev, VIDIOC_STREAMOFF, &b);
1433 if((ret = au0828_stream_interrupt(dev)) != 0)
1434 return ret;
1435 }
1436
1437 for (i = 0; i < AU0828_MAX_INPUT; i++) {
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001438 if (AUVI_INPUT(i).audio_setup == NULL) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001439 continue;
1440 }
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001441 (AUVI_INPUT(i).audio_setup)(dev, 0);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001442 }
1443
1444 mutex_lock(&dev->lock);
1445 videobuf_streamoff(&fh->vb_vidq);
1446 res_free(fh);
1447 mutex_unlock(&dev->lock);
1448
1449 return 0;
1450}
1451
1452static int vidioc_g_register(struct file *file, void *priv,
1453 struct v4l2_dbg_register *reg)
1454{
1455 struct au0828_fh *fh = priv;
1456 struct au0828_dev *dev = fh->dev;
1457
1458 switch (reg->match.type) {
1459 case V4L2_CHIP_MATCH_I2C_DRIVER:
1460 au0828_call_i2c_clients(dev, VIDIOC_DBG_G_REGISTER, reg);
1461 return 0;
1462 default:
1463 return -EINVAL;
1464 }
1465}
1466
1467static int vidioc_s_register(struct file *file, void *priv,
1468 struct v4l2_dbg_register *reg)
1469{
1470 struct au0828_fh *fh = priv;
1471 struct au0828_dev *dev = fh->dev;
1472
1473 switch (reg->match.type) {
1474 case V4L2_CHIP_MATCH_I2C_DRIVER:
1475 au0828_call_i2c_clients(dev, VIDIOC_DBG_S_REGISTER, reg);
1476 return 0;
1477 default:
1478 return -EINVAL;
1479 }
1480 return 0;
1481}
1482
1483static int vidioc_reqbufs(struct file *file, void *priv,
1484 struct v4l2_requestbuffers *rb)
1485{
1486 struct au0828_fh *fh = priv;
1487 struct au0828_dev *dev = fh->dev;
1488 int rc;
1489
1490 rc = check_dev(dev);
1491 if (rc < 0)
1492 return rc;
1493
1494 return videobuf_reqbufs(&fh->vb_vidq, rb);
1495}
1496
1497static int vidioc_querybuf(struct file *file, void *priv,
1498 struct v4l2_buffer *b)
1499{
1500 struct au0828_fh *fh = priv;
1501 struct au0828_dev *dev = fh->dev;
1502 int rc;
1503
1504 rc = check_dev(dev);
1505 if (rc < 0)
1506 return rc;
1507
1508 return videobuf_querybuf(&fh->vb_vidq, b);
1509}
1510
1511static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1512{
1513 struct au0828_fh *fh = priv;
1514 struct au0828_dev *dev = fh->dev;
1515 int rc;
1516
1517 rc = check_dev(dev);
1518 if (rc < 0)
1519 return rc;
1520
1521 return videobuf_qbuf(&fh->vb_vidq, b);
1522}
1523
1524static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1525{
1526 struct au0828_fh *fh = priv;
1527 struct au0828_dev *dev = fh->dev;
1528 int rc;
1529
1530 rc = check_dev(dev);
1531 if (rc < 0)
1532 return rc;
1533
1534 /* Workaround for a bug in the au0828 hardware design that sometimes
1535 results in the colorspace being inverted */
1536 if (dev->greenscreen_detected == 1) {
1537 dprintk(1, "Detected green frame. Resetting stream...\n");
1538 au0828_analog_stream_reset(dev);
1539 dev->greenscreen_detected = 0;
1540 }
1541
1542 return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
1543}
1544
1545#ifdef CONFIG_VIDEO_V4L1_COMPAT
1546static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
1547{
1548 struct au0828_fh *fh = priv;
1549
1550 return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
1551}
1552#endif
1553
1554static struct v4l2_file_operations au0828_v4l_fops = {
1555 .owner = THIS_MODULE,
1556 .open = au0828_v4l2_open,
1557 .release = au0828_v4l2_close,
1558 .read = au0828_v4l2_read,
1559 .poll = au0828_v4l2_poll,
1560 .mmap = au0828_v4l2_mmap,
1561 .ioctl = video_ioctl2,
1562};
1563
1564static const struct v4l2_ioctl_ops video_ioctl_ops = {
1565 .vidioc_querycap = vidioc_querycap,
1566 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1567 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1568 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1569 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001570#ifdef VBI_NOT_YET_WORKING
1571 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
1572 .vidioc_try_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
1573 .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
1574#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001575 .vidioc_g_audio = vidioc_g_audio,
1576 .vidioc_s_audio = vidioc_s_audio,
1577 .vidioc_cropcap = vidioc_cropcap,
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001578#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001579 .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap,
1580 .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
1581 .vidioc_s_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
1582#endif
1583 .vidioc_reqbufs = vidioc_reqbufs,
1584 .vidioc_querybuf = vidioc_querybuf,
1585 .vidioc_qbuf = vidioc_qbuf,
1586 .vidioc_dqbuf = vidioc_dqbuf,
1587 .vidioc_s_std = vidioc_s_std,
1588 .vidioc_enum_input = vidioc_enum_input,
1589 .vidioc_g_input = vidioc_g_input,
1590 .vidioc_s_input = vidioc_s_input,
1591 .vidioc_queryctrl = vidioc_queryctrl,
1592 .vidioc_g_ctrl = vidioc_g_ctrl,
1593 .vidioc_s_ctrl = vidioc_s_ctrl,
1594 .vidioc_streamon = vidioc_streamon,
1595 .vidioc_streamoff = vidioc_streamoff,
1596 .vidioc_g_tuner = vidioc_g_tuner,
1597 .vidioc_s_tuner = vidioc_s_tuner,
1598 .vidioc_g_frequency = vidioc_g_frequency,
1599 .vidioc_s_frequency = vidioc_s_frequency,
1600#ifdef CONFIG_VIDEO_ADV_DEBUG
1601 .vidioc_g_register = vidioc_g_register,
1602 .vidioc_s_register = vidioc_s_register,
1603 .vidioc_g_chip_ident = vidioc_g_chip_ident,
1604#endif
1605#ifdef CONFIG_VIDEO_V4L1_COMPAT
1606 .vidiocgmbuf = vidiocgmbuf,
1607#endif
1608};
1609
1610static const struct video_device au0828_video_template = {
1611 .fops = &au0828_v4l_fops,
1612 .release = video_device_release,
1613 .ioctl_ops = &video_ioctl_ops,
1614 .minor = -1,
Devin Heitmueller0ef210712009-03-11 03:00:53 -03001615 .tvnorms = V4L2_STD_NTSC_M,
1616 .current_norm = V4L2_STD_NTSC_M,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001617};
1618
1619/**************************************************************************/
1620
1621int au0828_analog_register(struct au0828_dev *dev)
1622{
1623 int retval = -ENOMEM;
1624
1625 dprintk(1, "au0828_analog_register called!\n");
1626
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001627 init_waitqueue_head(&dev->open);
1628 spin_lock_init(&dev->slock);
1629 mutex_init(&dev->lock);
1630
1631 INIT_LIST_HEAD(&dev->vidq.active);
1632 INIT_LIST_HEAD(&dev->vidq.queued);
1633
1634 dev->width = NTSC_STD_W;
1635 dev->height = NTSC_STD_H;
1636 dev->field_size = dev->width * dev->height;
1637 dev->frame_size = dev->field_size << 1;
1638 dev->bytesperline = dev->width << 1;
1639 dev->ctrl_ainput = 0;
1640
1641 /* allocate and fill v4l2 video struct */
1642 dev->vdev = video_device_alloc();
1643 if(NULL == dev->vdev) {
1644 dprintk(1, "Can't allocate video_device.\n");
1645 return -ENOMEM;
1646 }
1647
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001648#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001649 dev->vbi_dev = video_device_alloc();
1650 if(NULL == dev->vbi_dev) {
1651 dprintk(1, "Can't allocate vbi_device.\n");
1652 kfree(dev->vdev);
1653 return -ENOMEM;
1654 }
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001655#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001656
1657 /* Fill the video capture device struct */
1658 *dev->vdev = au0828_video_template;
1659 dev->vdev->vfl_type = VID_TYPE_CAPTURE | VID_TYPE_TUNER;
1660 dev->vdev->parent = &dev->usbdev->dev;
1661 strcpy(dev->vdev->name, "au0828a video");
1662
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001663#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001664 /* Setup the VBI device */
1665 *dev->vbi_dev = au0828_video_template;
1666 dev->vbi_dev->vfl_type = VFL_TYPE_VBI;
1667 dev->vbi_dev->parent = &dev->usbdev->dev;
1668 strcpy(dev->vbi_dev->name, "au0828a vbi");
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001669#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001670
1671 list_add_tail(&dev->au0828list, &au0828_devlist);
1672
1673 /* Register the v4l2 device */
1674 if((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1)) != 0) {
1675 dprintk(1, "unable to register video device (error = %d).\n", retval);
1676 list_del(&dev->au0828list);
1677 video_device_release(dev->vdev);
1678 return -ENODEV;
1679 }
1680
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001681#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001682 /* Register the vbi device */
1683 if((retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1)) != 0) {
1684 dprintk(1, "unable to register vbi device (error = %d).\n", retval);
1685 list_del(&dev->au0828list);
1686 video_device_release(dev->vbi_dev);
1687 video_device_release(dev->vdev);
1688 return -ENODEV;
1689 }
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001690#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001691
1692 dprintk(1, "%s completed!\n", __FUNCTION__);
1693
1694 return 0;
1695}
1696