blob: e7b2733ba86ee65c71558f03c7744fd9d84aaf52 [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
Devin Heitmueller2eaf3962009-03-11 03:01:02 -0300703 if (dev->vdev) {
704 list_del(&dev->au0828list);
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -0300705 video_unregister_device(dev->vdev);
Devin Heitmueller2eaf3962009-03-11 03:01:02 -0300706 }
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -0300707 if (dev->vbi_dev)
708 video_unregister_device(dev->vbi_dev);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300709
710 mutex_unlock(&au0828_sysfs_lock);
711}
712
713
714/* Usage lock check functions */
715static int res_get(struct au0828_fh *fh)
716{
717 struct au0828_dev *dev = fh->dev;
718 int rc = 0;
719
720 /* This instance already has stream_on */
721 if (fh->stream_on)
722 return rc;
723
724 if (dev->stream_on)
725 return -EBUSY;
726
727 dev->stream_on = 1;
728 fh->stream_on = 1;
729 return rc;
730}
731
732static int res_check(struct au0828_fh *fh)
733{
734 return fh->stream_on;
735}
736
737static void res_free(struct au0828_fh *fh)
738{
739 struct au0828_dev *dev = fh->dev;
740
741 fh->stream_on = 0;
742 dev->stream_on = 0;
743}
744
745static int au0828_v4l2_open(struct file *filp)
746{
747 int minor = video_devdata(filp)->minor;
748 int ret = 0;
749 struct au0828_dev *h, *dev = NULL;
750 struct au0828_fh *fh;
751 int type = 0;
752 struct list_head *list;
753
754 list_for_each(list, &au0828_devlist) {
755 h = list_entry(list, struct au0828_dev, au0828list);
756 if(h->vdev->minor == minor) {
757 dev = h;
758 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
759 }
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -0300760#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300761 if(h->vbi_dev->minor == minor) {
762 dev = h;
763 type = V4L2_BUF_TYPE_VBI_CAPTURE;
764 }
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -0300765#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300766 }
767
768 if(NULL == dev)
769 return -ENODEV;
770
771 fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL);
772 if(NULL == fh) {
773 dprintk(1, "Failed allocate au0828_fh struct!\n");
774 return -ENOMEM;
775 }
776
777 fh->type = type;
778 fh->dev = dev;
779 filp->private_data = fh;
780
781 if(fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
782 /* set au0828 interface0 to AS5 here again */
783 ret = usb_set_interface(dev->usbdev, 0, 5);
784 if(ret < 0) {
785 printk("Au0828 can't set alt setting to 5!\n");
786 return -EBUSY;
787 }
788 dev->width = NTSC_STD_W;
789 dev->height = NTSC_STD_H;
790 dev->frame_size = dev->width * dev->height * 2;
791 dev->field_size = dev->width * dev->height;
792 dev->bytesperline = dev->width * 2;
793
794 au0828_analog_stream_enable(dev);
795 au0828_analog_stream_reset(dev);
796
797 /* If we were doing ac97 instead of i2s, it would go here...*/
798 au0828_i2s_init(dev);
799
800 dev->stream_state = STREAM_OFF;
801 dev->dev_state |= DEV_INITIALIZED;
802 }
803
804 dev->users++;
805
806 videobuf_queue_vmalloc_init(&fh->vb_vidq, &au0828_video_qops,
807 NULL, &dev->slock, fh->type,
808 V4L2_FIELD_INTERLACED,
809 sizeof(struct au0828_buffer), fh);
810
811 return ret;
812}
813
814static int au0828_v4l2_close(struct file *filp)
815{
816 int ret;
817 struct au0828_fh *fh = filp->private_data;
818 struct au0828_dev *dev = fh->dev;
819
820 mutex_lock(&dev->lock);
821 if (res_check(fh))
822 res_free(fh);
823
824 if(dev->users == 1) {
825 videobuf_stop(&fh->vb_vidq);
826 videobuf_mmap_free(&fh->vb_vidq);
827
828 if(dev->dev_state & DEV_DISCONNECTED) {
829 au0828_analog_unregister(dev);
830 mutex_unlock(&dev->lock);
831 kfree(dev);
832 return 0;
833 }
834
835 au0828_analog_stream_disable(dev);
836
837 au0828_uninit_isoc(dev);
838
839 /* When close the device, set the usb intf0 into alt0 to free
840 USB bandwidth */
841 ret = usb_set_interface(dev->usbdev, 0, 0);
842 if(ret < 0)
843 printk("Au0828 can't set alt setting to 0!\n");
844 }
845
846 kfree(fh);
847 dev->users--;
848 wake_up_interruptible_nr(&dev->open, 1);
849 mutex_unlock(&dev->lock);
850 return 0;
851}
852
853static ssize_t au0828_v4l2_read(struct file *filp, char __user *buf,
854 size_t count, loff_t *pos)
855{
856 struct au0828_fh *fh = filp->private_data;
857 struct au0828_dev *dev = fh->dev;
858 int rc;
859
860 rc = check_dev(dev);
861 if (rc < 0)
862 return rc;
863
864 if(fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
865 mutex_lock(&dev->lock);
866 rc = res_get(fh);
867 mutex_unlock(&dev->lock);
868
869 if (unlikely(rc < 0))
870 return rc;
871
872 return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
873 filp->f_flags & O_NONBLOCK);
874 }
875 return 0;
876}
877
878static unsigned int au0828_v4l2_poll(struct file *filp, poll_table *wait)
879{
880 struct au0828_fh *fh = filp->private_data;
881 struct au0828_dev *dev = fh->dev;
882 int rc;
883
884 rc = check_dev(dev);
885 if (rc < 0)
886 return rc;
887
888 mutex_lock(&dev->lock);
889 rc = res_get(fh);
890 mutex_unlock(&dev->lock);
891
892 if (unlikely(rc < 0))
893 return POLLERR;
894
895 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
896 return POLLERR;
897
898 return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
899}
900
901static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
902{
903 struct au0828_fh *fh = filp->private_data;
904 struct au0828_dev *dev = fh->dev;
905 int rc;
906
907 rc = check_dev(dev);
908 if (rc < 0)
909 return rc;
910
911 mutex_lock(&dev->lock);
912 rc = res_get(fh);
913 mutex_unlock(&dev->lock);
914
915 if (unlikely(rc < 0))
916 return rc;
917
918 rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
919
920 dprintk(2, "vma start=0x%08lx, size=%ld, ret=%d\n",
921 (unsigned long)vma->vm_start,
922 (unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
923 rc);
924
925 return rc;
926}
927
928static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd,
929 struct v4l2_format *format)
930{
931 int ret;
932 int width = format->fmt.pix.width;
933 int height = format->fmt.pix.height;
934 unsigned int maxwidth, maxheight;
935
936 maxwidth = 720;
937 maxheight = 480;
938
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -0300939#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300940 if(format->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
941 dprintk(1, "VBI format set: to be supported!\n");
942 return 0;
943 }
944 if(format->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
945 return 0;
946 }
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -0300947#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300948 if(format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
949 return -EINVAL;
950 }
951
952 /* If they are demanding a format other than the one we support,
953 bail out (tvtime asks for UYVY and then retries with YUYV) */
954 if (format->fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY) {
955 return -EINVAL;
956 }
957
958 /* format->fmt.pix.width only support 720 and height 480 */
959 if(width != 720)
960 width = 720;
961 if(height != 480)
962 height = 480;
963
964 format->fmt.pix.width = width;
965 format->fmt.pix.height = height;
966 format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
967 format->fmt.pix.bytesperline = width * 2;
968 format->fmt.pix.sizeimage = width * height * 2;
969 format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
970 format->fmt.pix.field = V4L2_FIELD_INTERLACED;
971
972 if(cmd == VIDIOC_TRY_FMT)
973 return 0;
974
975 /* maybe set new image format, driver current only support 720*480 */
976 dev->width = width;
977 dev->height = height;
978 dev->frame_size = width * height * 2;
979 dev->field_size = width * height;
980 dev->bytesperline = width * 2;
981
982 if(dev->stream_state == STREAM_ON) {
983 dprintk(1, "VIDIOC_SET_FMT: interrupting stream!\n");
984 if((ret = au0828_stream_interrupt(dev))) {
985 dprintk(1, "error interrupting video stream!\n");
986 return ret;
987 }
988 }
989
990 /* set au0828 interface0 to AS5 here again */
991 ret = usb_set_interface(dev->usbdev, 0, 5);
992 if(ret < 0) {
993 printk("Au0828 can't set alt setting to 5!\n");
994 return -EBUSY;
995 }
996
997 au0828_analog_stream_enable(dev);
998
999 return 0;
1000}
1001
1002
1003static int vidioc_queryctrl(struct file *file, void *priv,
1004 struct v4l2_queryctrl *qc)
1005{
1006 struct au0828_fh *fh = priv;
1007 struct au0828_dev *dev = fh->dev;
1008 au0828_call_i2c_clients(dev, VIDIOC_QUERYCTRL, qc);
1009 if (qc->type)
1010 return 0;
1011 else
1012 return -EINVAL;
1013}
1014
1015static int vidioc_querycap(struct file *file, void *priv,
1016 struct v4l2_capability *cap)
1017{
1018 struct au0828_fh *fh = priv;
1019 struct au0828_dev *dev = fh->dev;
1020
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001021 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 Heitmuellerb14667f2009-03-11 03:01:04 -03001023 strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001024
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
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001045 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1046 strcpy(f->description, "Packed YUV2");
1047
1048 f->flags = 0;
1049 f->pixelformat = V4L2_PIX_FMT_UYVY;
1050
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001051 return 0;
1052}
1053
1054static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
1055 struct v4l2_format *f)
1056{
1057 struct au0828_fh *fh = priv;
1058 struct au0828_dev *dev = fh->dev;
1059
1060 f->fmt.pix.width = dev->width;
1061 f->fmt.pix.height = dev->height;
1062 f->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
1063 f->fmt.pix.bytesperline = dev->bytesperline;
1064 f->fmt.pix.sizeimage = dev->frame_size;
1065 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* NTSC/PAL */
1066 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
1067 return 0;
1068}
1069
1070static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
1071 struct v4l2_format *f)
1072{
1073 struct au0828_fh *fh = priv;
1074 struct au0828_dev *dev = fh->dev;
1075
1076 return au0828_set_format(dev, VIDIOC_TRY_FMT, f);
1077}
1078
1079static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1080 struct v4l2_format *f)
1081{
1082 struct au0828_fh *fh = priv;
1083 struct au0828_dev *dev = fh->dev;
1084 int rc;
1085
1086 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
1087 printk("%s queue busy\n", __func__);
1088 rc = -EBUSY;
1089 goto out;
1090 }
1091
1092 if (dev->stream_on && !fh->stream_on) {
1093 printk("%s device in use by another fh\n", __func__);
1094 rc = -EBUSY;
1095 goto out;
1096 }
1097
1098 return au0828_set_format(dev, VIDIOC_S_FMT, f);
1099out:
1100 return rc;
1101}
1102
1103static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
1104{
1105 struct au0828_fh *fh = priv;
1106 struct au0828_dev *dev = fh->dev;
1107
1108 /* FIXME: when we support something other than NTSC, we are going to
1109 have to make the au0828 bridge adjust the size of its capture
1110 buffer, which is currently hardcoded at 720x480 */
1111
1112 au0828_call_i2c_clients(dev, VIDIOC_S_STD, norm);
1113 return 0;
1114}
1115
1116static int vidioc_enum_input(struct file *file, void *priv,
1117 struct v4l2_input *input)
1118{
1119 struct au0828_fh *fh = priv;
1120 struct au0828_dev *dev = fh->dev;
1121 unsigned int tmp;
1122
1123 static const char *inames[] = {
1124 [AU0828_VMUX_COMPOSITE] = "Composite",
1125 [AU0828_VMUX_SVIDEO] = "S-Video",
1126 [AU0828_VMUX_CABLE] = "Cable TV",
1127 [AU0828_VMUX_TELEVISION] = "Television",
1128 [AU0828_VMUX_DVB] = "DVB",
1129 [AU0828_VMUX_DEBUG] = "tv debug"
1130 };
1131
1132 tmp = input->index;
1133
1134 if(tmp > AU0828_MAX_INPUT)
1135 return -EINVAL;
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001136 if(AUVI_INPUT(tmp).type == 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001137 return -EINVAL;
1138
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001139 input->index = tmp;
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001140 strcpy(input->name, inames[AUVI_INPUT(tmp).type]);
1141 if((AUVI_INPUT(tmp).type == AU0828_VMUX_TELEVISION) ||
1142 (AUVI_INPUT(tmp).type == AU0828_VMUX_CABLE))
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001143 input->type |= V4L2_INPUT_TYPE_TUNER;
1144 else
1145 input->type |= V4L2_INPUT_TYPE_CAMERA;
1146
1147 input->std = dev->vdev->tvnorms;
1148
1149 return 0;
1150}
1151
1152static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1153{
1154 struct au0828_fh *fh = priv;
1155 struct au0828_dev *dev = fh->dev;
1156 *i = dev->ctrl_input;
1157 return 0;
1158}
1159
1160static int vidioc_s_input(struct file *file, void *priv, unsigned int index)
1161{
1162 struct au0828_fh *fh = priv;
1163 struct au0828_dev *dev = fh->dev;
1164 int i;
1165 struct v4l2_routing route;
1166
1167 dprintk(1, "VIDIOC_S_INPUT in function %s, input=%d\n", __FUNCTION__,
1168 index);
1169 if(index >= AU0828_MAX_INPUT)
1170 return -EINVAL;
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001171 if(AUVI_INPUT(index).type == 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001172 return -EINVAL;
1173 dev->ctrl_input = index;
1174
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001175 switch(AUVI_INPUT(index).type) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001176 case AU0828_VMUX_SVIDEO:
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001177 dev->input_type = AU0828_VMUX_SVIDEO;
1178 break;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001179 case AU0828_VMUX_COMPOSITE:
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001180 dev->input_type = AU0828_VMUX_COMPOSITE;
1181 break;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001182 case AU0828_VMUX_TELEVISION:
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001183 dev->input_type = AU0828_VMUX_TELEVISION;
1184 break;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001185 default:
Devin Heitmuellera1094c42009-03-15 17:43:13 -03001186 dprintk(1, "VIDIOC_S_INPUT unknown input type set [%d]\n",
1187 AUVI_INPUT(index).type);
1188 break;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001189 }
1190
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001191 route.input = AUVI_INPUT(index).vmux;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001192 route.output = 0;
1193 au0828_call_i2c_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
1194
1195 for (i = 0; i < AU0828_MAX_INPUT; i++) {
1196 int enable = 0;
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001197 if (AUVI_INPUT(i).audio_setup == NULL) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001198 continue;
1199 }
1200
1201 if (i == index)
1202 enable = 1;
1203 else
1204 enable = 0;
1205 if (enable) {
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001206 (AUVI_INPUT(i).audio_setup)(dev, enable);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001207 } else {
1208 /* Make sure we leave it turned on if some
1209 other input is routed to this callback */
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001210 if ((AUVI_INPUT(i).audio_setup) !=
1211 ((AUVI_INPUT(index).audio_setup))) {
1212 (AUVI_INPUT(i).audio_setup)(dev, enable);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001213 }
1214 }
1215 }
1216
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001217 route.input = AUVI_INPUT(index).amux;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001218 au0828_call_i2c_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING,
1219 &route);
1220 return 0;
1221}
1222
1223static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
1224{
1225 struct au0828_fh *fh = priv;
1226 struct au0828_dev *dev = fh->dev;
1227 unsigned int index = a->index;
1228
1229 if(a->index > 1)
1230 return -EINVAL;
1231
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001232 index = dev->ctrl_ainput;
1233 if(index == 0)
1234 strcpy(a->name, "Television");
1235 else
1236 strcpy(a->name, "Line in");
1237
1238 a->capability = V4L2_AUDCAP_STEREO;
1239 a->index = index;
1240 return 0;
1241}
1242
1243static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
1244{
1245 struct au0828_fh *fh = priv;
1246 struct au0828_dev *dev = fh->dev;
1247 if(a->index != dev->ctrl_ainput)
1248 return -EINVAL;
1249 return 0;
1250}
1251
1252static int vidioc_g_ctrl(struct file *file, void *priv,
1253 struct v4l2_control *ctrl)
1254{
1255 struct au0828_fh *fh = priv;
1256 struct au0828_dev *dev = fh->dev;
1257
1258 au0828_call_i2c_clients(dev, VIDIOC_G_CTRL, ctrl);
1259 return 0;
1260
1261}
1262
1263static int vidioc_s_ctrl(struct file *file, void *priv,
1264 struct v4l2_control *ctrl)
1265{
1266 struct au0828_fh *fh = priv;
1267 struct au0828_dev *dev = fh->dev;
1268 au0828_call_i2c_clients(dev, VIDIOC_S_CTRL, ctrl);
1269 return 0;
1270}
1271
1272static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1273{
1274 struct au0828_fh *fh = priv;
1275 struct au0828_dev *dev = fh->dev;
1276
1277 if(t->index != 0)
1278 return -EINVAL;
1279
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001280 strcpy(t->name, "Auvitek tuner");
1281
1282 au0828_call_i2c_clients(dev, VIDIOC_G_TUNER, t);
1283 return 0;
1284}
1285
1286static int vidioc_s_tuner(struct file *file, void *priv,
1287 struct v4l2_tuner *t)
1288{
1289 struct au0828_fh *fh = priv;
1290 struct au0828_dev *dev = fh->dev;
1291
1292 if(t->index != 0)
1293 return -EINVAL;
1294
1295 t->type = V4L2_TUNER_ANALOG_TV;
1296 au0828_call_i2c_clients(dev, VIDIOC_S_TUNER, t);
1297 dprintk(1, "VIDIOC_S_TUNER: signal = %x, afc = %x\n", t->signal,
1298 t->afc);
1299 return 0;
1300
1301}
1302
1303static int vidioc_g_frequency(struct file *file, void *priv,
1304 struct v4l2_frequency *freq)
1305{
1306 struct au0828_fh *fh = priv;
1307 struct au0828_dev *dev = fh->dev;
Devin Heitmuellerc8889232009-03-15 17:38:47 -03001308
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001309 freq->type = V4L2_TUNER_ANALOG_TV;
1310 freq->frequency = dev->ctrl_freq;
1311 return 0;
1312}
1313
1314static int vidioc_s_frequency(struct file *file, void *priv,
1315 struct v4l2_frequency *freq)
1316{
1317 struct au0828_fh *fh = priv;
1318 struct au0828_dev *dev = fh->dev;
1319
1320 if(freq->tuner != 0)
1321 return -EINVAL;
1322 if(freq->type != V4L2_TUNER_ANALOG_TV)
1323 return -EINVAL;
1324
1325 dev->ctrl_freq = freq->frequency;
1326
1327 au0828_call_i2c_clients(dev, VIDIOC_S_FREQUENCY, freq);
1328
1329 au0828_analog_stream_reset(dev);
1330
1331 return 0;
1332}
1333
1334static int vidioc_g_chip_ident(struct file *file, void *priv,
1335 struct v4l2_dbg_chip_ident *chip)
1336{
1337 struct au0828_fh *fh = priv;
1338 struct au0828_dev *dev = fh->dev;
1339 chip->ident = V4L2_IDENT_NONE;
1340 chip->revision = 0;
1341
Devin Heitmuellerd9109be2009-03-11 03:00:58 -03001342 if (v4l2_chip_match_host(&chip->match)) {
1343 chip->ident = V4L2_IDENT_AU0828;
1344 return 0;
1345 }
1346
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001347 au0828_call_i2c_clients(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
Devin Heitmuellerd9109be2009-03-11 03:00:58 -03001348 if (chip->ident == V4L2_IDENT_NONE)
1349 return -EINVAL;
1350
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001351 return 0;
1352}
1353
1354static int vidioc_cropcap(struct file *file, void *priv,
1355 struct v4l2_cropcap *cc)
1356{
1357 struct au0828_fh *fh = priv;
1358 struct au0828_dev *dev = fh->dev;
1359
1360 if(cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1361 return -EINVAL;
1362
1363 cc->bounds.left = 0;
1364 cc->bounds.top = 0;
1365 cc->bounds.width = dev->width;
1366 cc->bounds.height = dev->height;
1367
1368 cc->defrect = cc->bounds;
1369
1370 cc->pixelaspect.numerator = 54;
1371 cc->pixelaspect.denominator = 59;
1372
1373 return 0;
1374}
1375
1376static int vidioc_streamon(struct file *file, void *priv,
1377 enum v4l2_buf_type type)
1378{
1379 struct au0828_fh *fh = priv;
1380 struct au0828_dev *dev = fh->dev;
1381 int b = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1382 int rc;
1383
1384 rc = check_dev(dev);
1385 if (rc < 0)
1386 return rc;
1387
1388 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1389 au0828_analog_stream_enable(dev);
1390 au0828_call_i2c_clients(dev, VIDIOC_STREAMON, &b);
1391 }
1392
1393 mutex_lock(&dev->lock);
1394 rc = res_get(fh);
1395
1396 if (likely(rc >= 0))
1397 rc = videobuf_streamon(&fh->vb_vidq);
1398 mutex_unlock(&dev->lock);
1399
1400 return rc;
1401}
1402
1403static int vidioc_streamoff(struct file *file, void *priv,
1404 enum v4l2_buf_type type)
1405{
1406 struct au0828_fh *fh = priv;
1407 struct au0828_dev *dev = fh->dev;
1408 int b = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1409 int i;
1410 int ret;
1411 int rc;
1412
1413 rc = check_dev(dev);
1414 if (rc < 0)
1415 return rc;
1416
1417 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1418 return -EINVAL;
1419 if (type != fh->type)
1420 return -EINVAL;
1421
1422 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1423 au0828_call_i2c_clients(dev, VIDIOC_STREAMOFF, &b);
1424 if((ret = au0828_stream_interrupt(dev)) != 0)
1425 return ret;
1426 }
1427
1428 for (i = 0; i < AU0828_MAX_INPUT; i++) {
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001429 if (AUVI_INPUT(i).audio_setup == NULL) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001430 continue;
1431 }
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001432 (AUVI_INPUT(i).audio_setup)(dev, 0);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001433 }
1434
1435 mutex_lock(&dev->lock);
1436 videobuf_streamoff(&fh->vb_vidq);
1437 res_free(fh);
1438 mutex_unlock(&dev->lock);
1439
1440 return 0;
1441}
1442
1443static int vidioc_g_register(struct file *file, void *priv,
1444 struct v4l2_dbg_register *reg)
1445{
1446 struct au0828_fh *fh = priv;
1447 struct au0828_dev *dev = fh->dev;
1448
1449 switch (reg->match.type) {
1450 case V4L2_CHIP_MATCH_I2C_DRIVER:
1451 au0828_call_i2c_clients(dev, VIDIOC_DBG_G_REGISTER, reg);
1452 return 0;
1453 default:
1454 return -EINVAL;
1455 }
1456}
1457
1458static int vidioc_s_register(struct file *file, void *priv,
1459 struct v4l2_dbg_register *reg)
1460{
1461 struct au0828_fh *fh = priv;
1462 struct au0828_dev *dev = fh->dev;
1463
1464 switch (reg->match.type) {
1465 case V4L2_CHIP_MATCH_I2C_DRIVER:
1466 au0828_call_i2c_clients(dev, VIDIOC_DBG_S_REGISTER, reg);
1467 return 0;
1468 default:
1469 return -EINVAL;
1470 }
1471 return 0;
1472}
1473
1474static int vidioc_reqbufs(struct file *file, void *priv,
1475 struct v4l2_requestbuffers *rb)
1476{
1477 struct au0828_fh *fh = priv;
1478 struct au0828_dev *dev = fh->dev;
1479 int rc;
1480
1481 rc = check_dev(dev);
1482 if (rc < 0)
1483 return rc;
1484
1485 return videobuf_reqbufs(&fh->vb_vidq, rb);
1486}
1487
1488static int vidioc_querybuf(struct file *file, void *priv,
1489 struct v4l2_buffer *b)
1490{
1491 struct au0828_fh *fh = priv;
1492 struct au0828_dev *dev = fh->dev;
1493 int rc;
1494
1495 rc = check_dev(dev);
1496 if (rc < 0)
1497 return rc;
1498
1499 return videobuf_querybuf(&fh->vb_vidq, b);
1500}
1501
1502static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1503{
1504 struct au0828_fh *fh = priv;
1505 struct au0828_dev *dev = fh->dev;
1506 int rc;
1507
1508 rc = check_dev(dev);
1509 if (rc < 0)
1510 return rc;
1511
1512 return videobuf_qbuf(&fh->vb_vidq, b);
1513}
1514
1515static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1516{
1517 struct au0828_fh *fh = priv;
1518 struct au0828_dev *dev = fh->dev;
1519 int rc;
1520
1521 rc = check_dev(dev);
1522 if (rc < 0)
1523 return rc;
1524
1525 /* Workaround for a bug in the au0828 hardware design that sometimes
1526 results in the colorspace being inverted */
1527 if (dev->greenscreen_detected == 1) {
1528 dprintk(1, "Detected green frame. Resetting stream...\n");
1529 au0828_analog_stream_reset(dev);
1530 dev->greenscreen_detected = 0;
1531 }
1532
1533 return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
1534}
1535
1536#ifdef CONFIG_VIDEO_V4L1_COMPAT
1537static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
1538{
1539 struct au0828_fh *fh = priv;
1540
1541 return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
1542}
1543#endif
1544
1545static struct v4l2_file_operations au0828_v4l_fops = {
1546 .owner = THIS_MODULE,
1547 .open = au0828_v4l2_open,
1548 .release = au0828_v4l2_close,
1549 .read = au0828_v4l2_read,
1550 .poll = au0828_v4l2_poll,
1551 .mmap = au0828_v4l2_mmap,
1552 .ioctl = video_ioctl2,
1553};
1554
1555static const struct v4l2_ioctl_ops video_ioctl_ops = {
1556 .vidioc_querycap = vidioc_querycap,
1557 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1558 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1559 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1560 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001561#ifdef VBI_NOT_YET_WORKING
1562 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
1563 .vidioc_try_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
1564 .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
1565#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001566 .vidioc_g_audio = vidioc_g_audio,
1567 .vidioc_s_audio = vidioc_s_audio,
1568 .vidioc_cropcap = vidioc_cropcap,
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001569#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001570 .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap,
1571 .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
1572 .vidioc_s_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
1573#endif
1574 .vidioc_reqbufs = vidioc_reqbufs,
1575 .vidioc_querybuf = vidioc_querybuf,
1576 .vidioc_qbuf = vidioc_qbuf,
1577 .vidioc_dqbuf = vidioc_dqbuf,
1578 .vidioc_s_std = vidioc_s_std,
1579 .vidioc_enum_input = vidioc_enum_input,
1580 .vidioc_g_input = vidioc_g_input,
1581 .vidioc_s_input = vidioc_s_input,
1582 .vidioc_queryctrl = vidioc_queryctrl,
1583 .vidioc_g_ctrl = vidioc_g_ctrl,
1584 .vidioc_s_ctrl = vidioc_s_ctrl,
1585 .vidioc_streamon = vidioc_streamon,
1586 .vidioc_streamoff = vidioc_streamoff,
1587 .vidioc_g_tuner = vidioc_g_tuner,
1588 .vidioc_s_tuner = vidioc_s_tuner,
1589 .vidioc_g_frequency = vidioc_g_frequency,
1590 .vidioc_s_frequency = vidioc_s_frequency,
1591#ifdef CONFIG_VIDEO_ADV_DEBUG
1592 .vidioc_g_register = vidioc_g_register,
1593 .vidioc_s_register = vidioc_s_register,
1594 .vidioc_g_chip_ident = vidioc_g_chip_ident,
1595#endif
1596#ifdef CONFIG_VIDEO_V4L1_COMPAT
1597 .vidiocgmbuf = vidiocgmbuf,
1598#endif
1599};
1600
1601static const struct video_device au0828_video_template = {
1602 .fops = &au0828_v4l_fops,
1603 .release = video_device_release,
1604 .ioctl_ops = &video_ioctl_ops,
1605 .minor = -1,
Devin Heitmueller0ef210712009-03-11 03:00:53 -03001606 .tvnorms = V4L2_STD_NTSC_M,
1607 .current_norm = V4L2_STD_NTSC_M,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001608};
1609
1610/**************************************************************************/
1611
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001612int au0828_analog_register(struct au0828_dev *dev,
1613 struct usb_interface *interface)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001614{
1615 int retval = -ENOMEM;
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001616 struct usb_host_interface *iface_desc;
1617 struct usb_endpoint_descriptor *endpoint;
1618 int i;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001619
1620 dprintk(1, "au0828_analog_register called!\n");
1621
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001622 /* set au0828 usb interface0 to as5 */
1623 retval = usb_set_interface(dev->usbdev,
1624 interface->cur_altsetting->desc.bInterfaceNumber, 5);
1625 if (retval != 0) {
1626 printk("Failure setting usb interface0 to as5\n");
1627 return retval;
1628 }
1629
1630 /* Figure out which endpoint has the isoc interface */
1631 iface_desc = interface->cur_altsetting;
1632 for(i = 0; i < iface_desc->desc.bNumEndpoints; i++){
1633 endpoint = &iface_desc->endpoint[i].desc;
1634 if(((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) &&
1635 ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC)){
1636
1637 /* we find our isoc in endpoint */
1638 u16 tmp = le16_to_cpu(endpoint->wMaxPacketSize);
1639 dev->max_pkt_size = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
1640 dev->isoc_in_endpointaddr = endpoint->bEndpointAddress;
1641 }
1642 }
1643 if(!(dev->isoc_in_endpointaddr)) {
1644 printk("Could not locate isoc endpoint\n");
1645 kfree(dev);
1646 return -ENODEV;
1647 }
1648
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001649 init_waitqueue_head(&dev->open);
1650 spin_lock_init(&dev->slock);
1651 mutex_init(&dev->lock);
1652
1653 INIT_LIST_HEAD(&dev->vidq.active);
1654 INIT_LIST_HEAD(&dev->vidq.queued);
1655
1656 dev->width = NTSC_STD_W;
1657 dev->height = NTSC_STD_H;
1658 dev->field_size = dev->width * dev->height;
1659 dev->frame_size = dev->field_size << 1;
1660 dev->bytesperline = dev->width << 1;
1661 dev->ctrl_ainput = 0;
1662
1663 /* allocate and fill v4l2 video struct */
1664 dev->vdev = video_device_alloc();
1665 if(NULL == dev->vdev) {
1666 dprintk(1, "Can't allocate video_device.\n");
1667 return -ENOMEM;
1668 }
1669
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001670#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001671 dev->vbi_dev = video_device_alloc();
1672 if(NULL == dev->vbi_dev) {
1673 dprintk(1, "Can't allocate vbi_device.\n");
1674 kfree(dev->vdev);
1675 return -ENOMEM;
1676 }
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001677#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001678
1679 /* Fill the video capture device struct */
1680 *dev->vdev = au0828_video_template;
1681 dev->vdev->vfl_type = VID_TYPE_CAPTURE | VID_TYPE_TUNER;
1682 dev->vdev->parent = &dev->usbdev->dev;
1683 strcpy(dev->vdev->name, "au0828a video");
1684
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001685#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001686 /* Setup the VBI device */
1687 *dev->vbi_dev = au0828_video_template;
1688 dev->vbi_dev->vfl_type = VFL_TYPE_VBI;
1689 dev->vbi_dev->parent = &dev->usbdev->dev;
1690 strcpy(dev->vbi_dev->name, "au0828a vbi");
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001691#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001692
1693 list_add_tail(&dev->au0828list, &au0828_devlist);
1694
1695 /* Register the v4l2 device */
1696 if((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1)) != 0) {
1697 dprintk(1, "unable to register video device (error = %d).\n", retval);
1698 list_del(&dev->au0828list);
1699 video_device_release(dev->vdev);
1700 return -ENODEV;
1701 }
1702
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001703#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001704 /* Register the vbi device */
1705 if((retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1)) != 0) {
1706 dprintk(1, "unable to register vbi device (error = %d).\n", retval);
1707 list_del(&dev->au0828list);
1708 video_device_release(dev->vbi_dev);
1709 video_device_release(dev->vdev);
1710 return -ENODEV;
1711 }
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001712#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001713
1714 dprintk(1, "%s completed!\n", __FUNCTION__);
1715
1716 return 0;
1717}
1718