blob: 96895117a0ce2a705d5e8315192dd6e3035130c0 [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:
1177 {
1178 dev->input_type = AU0828_VMUX_SVIDEO;
1179 break;
1180 }
1181 case AU0828_VMUX_COMPOSITE:
1182 {
1183 dev->input_type = AU0828_VMUX_COMPOSITE;
1184 break;
1185 }
1186 case AU0828_VMUX_TELEVISION:
1187 {
1188 dev->input_type = AU0828_VMUX_TELEVISION;
1189 break;
1190 }
1191 default:
1192 ;
1193 }
1194
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001195 route.input = AUVI_INPUT(index).vmux;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001196 route.output = 0;
1197 au0828_call_i2c_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
1198
1199 for (i = 0; i < AU0828_MAX_INPUT; i++) {
1200 int enable = 0;
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001201 if (AUVI_INPUT(i).audio_setup == NULL) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001202 continue;
1203 }
1204
1205 if (i == index)
1206 enable = 1;
1207 else
1208 enable = 0;
1209 if (enable) {
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001210 (AUVI_INPUT(i).audio_setup)(dev, enable);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001211 } else {
1212 /* Make sure we leave it turned on if some
1213 other input is routed to this callback */
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001214 if ((AUVI_INPUT(i).audio_setup) !=
1215 ((AUVI_INPUT(index).audio_setup))) {
1216 (AUVI_INPUT(i).audio_setup)(dev, enable);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001217 }
1218 }
1219 }
1220
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001221 route.input = AUVI_INPUT(index).amux;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001222 au0828_call_i2c_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING,
1223 &route);
1224 return 0;
1225}
1226
1227static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
1228{
1229 struct au0828_fh *fh = priv;
1230 struct au0828_dev *dev = fh->dev;
1231 unsigned int index = a->index;
1232
1233 if(a->index > 1)
1234 return -EINVAL;
1235
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001236 index = dev->ctrl_ainput;
1237 if(index == 0)
1238 strcpy(a->name, "Television");
1239 else
1240 strcpy(a->name, "Line in");
1241
1242 a->capability = V4L2_AUDCAP_STEREO;
1243 a->index = index;
1244 return 0;
1245}
1246
1247static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
1248{
1249 struct au0828_fh *fh = priv;
1250 struct au0828_dev *dev = fh->dev;
1251 if(a->index != dev->ctrl_ainput)
1252 return -EINVAL;
1253 return 0;
1254}
1255
1256static int vidioc_g_ctrl(struct file *file, void *priv,
1257 struct v4l2_control *ctrl)
1258{
1259 struct au0828_fh *fh = priv;
1260 struct au0828_dev *dev = fh->dev;
1261
1262 au0828_call_i2c_clients(dev, VIDIOC_G_CTRL, ctrl);
1263 return 0;
1264
1265}
1266
1267static int vidioc_s_ctrl(struct file *file, void *priv,
1268 struct v4l2_control *ctrl)
1269{
1270 struct au0828_fh *fh = priv;
1271 struct au0828_dev *dev = fh->dev;
1272 au0828_call_i2c_clients(dev, VIDIOC_S_CTRL, ctrl);
1273 return 0;
1274}
1275
1276static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1277{
1278 struct au0828_fh *fh = priv;
1279 struct au0828_dev *dev = fh->dev;
1280
1281 if(t->index != 0)
1282 return -EINVAL;
1283
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001284 strcpy(t->name, "Auvitek tuner");
1285
1286 au0828_call_i2c_clients(dev, VIDIOC_G_TUNER, t);
1287 return 0;
1288}
1289
1290static int vidioc_s_tuner(struct file *file, void *priv,
1291 struct v4l2_tuner *t)
1292{
1293 struct au0828_fh *fh = priv;
1294 struct au0828_dev *dev = fh->dev;
1295
1296 if(t->index != 0)
1297 return -EINVAL;
1298
1299 t->type = V4L2_TUNER_ANALOG_TV;
1300 au0828_call_i2c_clients(dev, VIDIOC_S_TUNER, t);
1301 dprintk(1, "VIDIOC_S_TUNER: signal = %x, afc = %x\n", t->signal,
1302 t->afc);
1303 return 0;
1304
1305}
1306
1307static int vidioc_g_frequency(struct file *file, void *priv,
1308 struct v4l2_frequency *freq)
1309{
1310 struct au0828_fh *fh = priv;
1311 struct au0828_dev *dev = fh->dev;
Devin Heitmuellerc8889232009-03-15 17:38:47 -03001312
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001313 freq->type = V4L2_TUNER_ANALOG_TV;
1314 freq->frequency = dev->ctrl_freq;
1315 return 0;
1316}
1317
1318static int vidioc_s_frequency(struct file *file, void *priv,
1319 struct v4l2_frequency *freq)
1320{
1321 struct au0828_fh *fh = priv;
1322 struct au0828_dev *dev = fh->dev;
1323
1324 if(freq->tuner != 0)
1325 return -EINVAL;
1326 if(freq->type != V4L2_TUNER_ANALOG_TV)
1327 return -EINVAL;
1328
1329 dev->ctrl_freq = freq->frequency;
1330
1331 au0828_call_i2c_clients(dev, VIDIOC_S_FREQUENCY, freq);
1332
1333 au0828_analog_stream_reset(dev);
1334
1335 return 0;
1336}
1337
1338static int vidioc_g_chip_ident(struct file *file, void *priv,
1339 struct v4l2_dbg_chip_ident *chip)
1340{
1341 struct au0828_fh *fh = priv;
1342 struct au0828_dev *dev = fh->dev;
1343 chip->ident = V4L2_IDENT_NONE;
1344 chip->revision = 0;
1345
Devin Heitmuellerd9109be2009-03-11 03:00:58 -03001346 if (v4l2_chip_match_host(&chip->match)) {
1347 chip->ident = V4L2_IDENT_AU0828;
1348 return 0;
1349 }
1350
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001351 au0828_call_i2c_clients(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
Devin Heitmuellerd9109be2009-03-11 03:00:58 -03001352 if (chip->ident == V4L2_IDENT_NONE)
1353 return -EINVAL;
1354
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001355 return 0;
1356}
1357
1358static int vidioc_cropcap(struct file *file, void *priv,
1359 struct v4l2_cropcap *cc)
1360{
1361 struct au0828_fh *fh = priv;
1362 struct au0828_dev *dev = fh->dev;
1363
1364 if(cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1365 return -EINVAL;
1366
1367 cc->bounds.left = 0;
1368 cc->bounds.top = 0;
1369 cc->bounds.width = dev->width;
1370 cc->bounds.height = dev->height;
1371
1372 cc->defrect = cc->bounds;
1373
1374 cc->pixelaspect.numerator = 54;
1375 cc->pixelaspect.denominator = 59;
1376
1377 return 0;
1378}
1379
1380static int vidioc_streamon(struct file *file, void *priv,
1381 enum v4l2_buf_type type)
1382{
1383 struct au0828_fh *fh = priv;
1384 struct au0828_dev *dev = fh->dev;
1385 int b = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1386 int rc;
1387
1388 rc = check_dev(dev);
1389 if (rc < 0)
1390 return rc;
1391
1392 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1393 au0828_analog_stream_enable(dev);
1394 au0828_call_i2c_clients(dev, VIDIOC_STREAMON, &b);
1395 }
1396
1397 mutex_lock(&dev->lock);
1398 rc = res_get(fh);
1399
1400 if (likely(rc >= 0))
1401 rc = videobuf_streamon(&fh->vb_vidq);
1402 mutex_unlock(&dev->lock);
1403
1404 return rc;
1405}
1406
1407static int vidioc_streamoff(struct file *file, void *priv,
1408 enum v4l2_buf_type type)
1409{
1410 struct au0828_fh *fh = priv;
1411 struct au0828_dev *dev = fh->dev;
1412 int b = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1413 int i;
1414 int ret;
1415 int rc;
1416
1417 rc = check_dev(dev);
1418 if (rc < 0)
1419 return rc;
1420
1421 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1422 return -EINVAL;
1423 if (type != fh->type)
1424 return -EINVAL;
1425
1426 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1427 au0828_call_i2c_clients(dev, VIDIOC_STREAMOFF, &b);
1428 if((ret = au0828_stream_interrupt(dev)) != 0)
1429 return ret;
1430 }
1431
1432 for (i = 0; i < AU0828_MAX_INPUT; i++) {
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001433 if (AUVI_INPUT(i).audio_setup == NULL) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001434 continue;
1435 }
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001436 (AUVI_INPUT(i).audio_setup)(dev, 0);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001437 }
1438
1439 mutex_lock(&dev->lock);
1440 videobuf_streamoff(&fh->vb_vidq);
1441 res_free(fh);
1442 mutex_unlock(&dev->lock);
1443
1444 return 0;
1445}
1446
1447static int vidioc_g_register(struct file *file, void *priv,
1448 struct v4l2_dbg_register *reg)
1449{
1450 struct au0828_fh *fh = priv;
1451 struct au0828_dev *dev = fh->dev;
1452
1453 switch (reg->match.type) {
1454 case V4L2_CHIP_MATCH_I2C_DRIVER:
1455 au0828_call_i2c_clients(dev, VIDIOC_DBG_G_REGISTER, reg);
1456 return 0;
1457 default:
1458 return -EINVAL;
1459 }
1460}
1461
1462static int vidioc_s_register(struct file *file, void *priv,
1463 struct v4l2_dbg_register *reg)
1464{
1465 struct au0828_fh *fh = priv;
1466 struct au0828_dev *dev = fh->dev;
1467
1468 switch (reg->match.type) {
1469 case V4L2_CHIP_MATCH_I2C_DRIVER:
1470 au0828_call_i2c_clients(dev, VIDIOC_DBG_S_REGISTER, reg);
1471 return 0;
1472 default:
1473 return -EINVAL;
1474 }
1475 return 0;
1476}
1477
1478static int vidioc_reqbufs(struct file *file, void *priv,
1479 struct v4l2_requestbuffers *rb)
1480{
1481 struct au0828_fh *fh = priv;
1482 struct au0828_dev *dev = fh->dev;
1483 int rc;
1484
1485 rc = check_dev(dev);
1486 if (rc < 0)
1487 return rc;
1488
1489 return videobuf_reqbufs(&fh->vb_vidq, rb);
1490}
1491
1492static int vidioc_querybuf(struct file *file, void *priv,
1493 struct v4l2_buffer *b)
1494{
1495 struct au0828_fh *fh = priv;
1496 struct au0828_dev *dev = fh->dev;
1497 int rc;
1498
1499 rc = check_dev(dev);
1500 if (rc < 0)
1501 return rc;
1502
1503 return videobuf_querybuf(&fh->vb_vidq, b);
1504}
1505
1506static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1507{
1508 struct au0828_fh *fh = priv;
1509 struct au0828_dev *dev = fh->dev;
1510 int rc;
1511
1512 rc = check_dev(dev);
1513 if (rc < 0)
1514 return rc;
1515
1516 return videobuf_qbuf(&fh->vb_vidq, b);
1517}
1518
1519static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1520{
1521 struct au0828_fh *fh = priv;
1522 struct au0828_dev *dev = fh->dev;
1523 int rc;
1524
1525 rc = check_dev(dev);
1526 if (rc < 0)
1527 return rc;
1528
1529 /* Workaround for a bug in the au0828 hardware design that sometimes
1530 results in the colorspace being inverted */
1531 if (dev->greenscreen_detected == 1) {
1532 dprintk(1, "Detected green frame. Resetting stream...\n");
1533 au0828_analog_stream_reset(dev);
1534 dev->greenscreen_detected = 0;
1535 }
1536
1537 return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
1538}
1539
1540#ifdef CONFIG_VIDEO_V4L1_COMPAT
1541static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
1542{
1543 struct au0828_fh *fh = priv;
1544
1545 return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
1546}
1547#endif
1548
1549static struct v4l2_file_operations au0828_v4l_fops = {
1550 .owner = THIS_MODULE,
1551 .open = au0828_v4l2_open,
1552 .release = au0828_v4l2_close,
1553 .read = au0828_v4l2_read,
1554 .poll = au0828_v4l2_poll,
1555 .mmap = au0828_v4l2_mmap,
1556 .ioctl = video_ioctl2,
1557};
1558
1559static const struct v4l2_ioctl_ops video_ioctl_ops = {
1560 .vidioc_querycap = vidioc_querycap,
1561 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1562 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1563 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1564 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001565#ifdef VBI_NOT_YET_WORKING
1566 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
1567 .vidioc_try_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
1568 .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
1569#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001570 .vidioc_g_audio = vidioc_g_audio,
1571 .vidioc_s_audio = vidioc_s_audio,
1572 .vidioc_cropcap = vidioc_cropcap,
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001573#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001574 .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap,
1575 .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
1576 .vidioc_s_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
1577#endif
1578 .vidioc_reqbufs = vidioc_reqbufs,
1579 .vidioc_querybuf = vidioc_querybuf,
1580 .vidioc_qbuf = vidioc_qbuf,
1581 .vidioc_dqbuf = vidioc_dqbuf,
1582 .vidioc_s_std = vidioc_s_std,
1583 .vidioc_enum_input = vidioc_enum_input,
1584 .vidioc_g_input = vidioc_g_input,
1585 .vidioc_s_input = vidioc_s_input,
1586 .vidioc_queryctrl = vidioc_queryctrl,
1587 .vidioc_g_ctrl = vidioc_g_ctrl,
1588 .vidioc_s_ctrl = vidioc_s_ctrl,
1589 .vidioc_streamon = vidioc_streamon,
1590 .vidioc_streamoff = vidioc_streamoff,
1591 .vidioc_g_tuner = vidioc_g_tuner,
1592 .vidioc_s_tuner = vidioc_s_tuner,
1593 .vidioc_g_frequency = vidioc_g_frequency,
1594 .vidioc_s_frequency = vidioc_s_frequency,
1595#ifdef CONFIG_VIDEO_ADV_DEBUG
1596 .vidioc_g_register = vidioc_g_register,
1597 .vidioc_s_register = vidioc_s_register,
1598 .vidioc_g_chip_ident = vidioc_g_chip_ident,
1599#endif
1600#ifdef CONFIG_VIDEO_V4L1_COMPAT
1601 .vidiocgmbuf = vidiocgmbuf,
1602#endif
1603};
1604
1605static const struct video_device au0828_video_template = {
1606 .fops = &au0828_v4l_fops,
1607 .release = video_device_release,
1608 .ioctl_ops = &video_ioctl_ops,
1609 .minor = -1,
Devin Heitmueller0ef210712009-03-11 03:00:53 -03001610 .tvnorms = V4L2_STD_NTSC_M,
1611 .current_norm = V4L2_STD_NTSC_M,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001612};
1613
1614/**************************************************************************/
1615
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001616int au0828_analog_register(struct au0828_dev *dev,
1617 struct usb_interface *interface)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001618{
1619 int retval = -ENOMEM;
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001620 struct usb_host_interface *iface_desc;
1621 struct usb_endpoint_descriptor *endpoint;
1622 int i;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001623
1624 dprintk(1, "au0828_analog_register called!\n");
1625
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001626 /* set au0828 usb interface0 to as5 */
1627 retval = usb_set_interface(dev->usbdev,
1628 interface->cur_altsetting->desc.bInterfaceNumber, 5);
1629 if (retval != 0) {
1630 printk("Failure setting usb interface0 to as5\n");
1631 return retval;
1632 }
1633
1634 /* Figure out which endpoint has the isoc interface */
1635 iface_desc = interface->cur_altsetting;
1636 for(i = 0; i < iface_desc->desc.bNumEndpoints; i++){
1637 endpoint = &iface_desc->endpoint[i].desc;
1638 if(((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) &&
1639 ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC)){
1640
1641 /* we find our isoc in endpoint */
1642 u16 tmp = le16_to_cpu(endpoint->wMaxPacketSize);
1643 dev->max_pkt_size = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
1644 dev->isoc_in_endpointaddr = endpoint->bEndpointAddress;
1645 }
1646 }
1647 if(!(dev->isoc_in_endpointaddr)) {
1648 printk("Could not locate isoc endpoint\n");
1649 kfree(dev);
1650 return -ENODEV;
1651 }
1652
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001653 init_waitqueue_head(&dev->open);
1654 spin_lock_init(&dev->slock);
1655 mutex_init(&dev->lock);
1656
1657 INIT_LIST_HEAD(&dev->vidq.active);
1658 INIT_LIST_HEAD(&dev->vidq.queued);
1659
1660 dev->width = NTSC_STD_W;
1661 dev->height = NTSC_STD_H;
1662 dev->field_size = dev->width * dev->height;
1663 dev->frame_size = dev->field_size << 1;
1664 dev->bytesperline = dev->width << 1;
1665 dev->ctrl_ainput = 0;
1666
1667 /* allocate and fill v4l2 video struct */
1668 dev->vdev = video_device_alloc();
1669 if(NULL == dev->vdev) {
1670 dprintk(1, "Can't allocate video_device.\n");
1671 return -ENOMEM;
1672 }
1673
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001674#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001675 dev->vbi_dev = video_device_alloc();
1676 if(NULL == dev->vbi_dev) {
1677 dprintk(1, "Can't allocate vbi_device.\n");
1678 kfree(dev->vdev);
1679 return -ENOMEM;
1680 }
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001681#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001682
1683 /* Fill the video capture device struct */
1684 *dev->vdev = au0828_video_template;
1685 dev->vdev->vfl_type = VID_TYPE_CAPTURE | VID_TYPE_TUNER;
1686 dev->vdev->parent = &dev->usbdev->dev;
1687 strcpy(dev->vdev->name, "au0828a video");
1688
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001689#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001690 /* Setup the VBI device */
1691 *dev->vbi_dev = au0828_video_template;
1692 dev->vbi_dev->vfl_type = VFL_TYPE_VBI;
1693 dev->vbi_dev->parent = &dev->usbdev->dev;
1694 strcpy(dev->vbi_dev->name, "au0828a vbi");
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001695#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001696
1697 list_add_tail(&dev->au0828list, &au0828_devlist);
1698
1699 /* Register the v4l2 device */
1700 if((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1)) != 0) {
1701 dprintk(1, "unable to register video device (error = %d).\n", retval);
1702 list_del(&dev->au0828list);
1703 video_device_release(dev->vdev);
1704 return -ENODEV;
1705 }
1706
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001707#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001708 /* Register the vbi device */
1709 if((retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1)) != 0) {
1710 dprintk(1, "unable to register vbi device (error = %d).\n", retval);
1711 list_del(&dev->au0828list);
1712 video_device_release(dev->vbi_dev);
1713 video_device_release(dev->vdev);
1714 return -ENODEV;
1715 }
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001716#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001717
1718 dprintk(1, "%s completed!\n", __FUNCTION__);
1719
1720 return 0;
1721}
1722