blob: 6abdd8bf44948689df61a9ca1faf31d6f88e8253 [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
1021 memset(cap, 0, sizeof(*cap));
1022 strlcpy(cap->driver, "au0828", sizeof(cap->driver));
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001023 strlcpy(cap->card, dev->board.name, sizeof(cap->card));
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001024 strlcpy(cap->bus_info, dev->usbdev->dev.bus_id, sizeof(cap->bus_info));
1025
1026 cap->version = AU0828_VERSION_CODE;
1027
1028 /*set the device capabilities */
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001029 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
1030#ifdef VBI_NOT_YET_WORKING
1031 V4L2_CAP_VBI_CAPTURE |
1032#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001033 V4L2_CAP_AUDIO |
1034 V4L2_CAP_READWRITE |
1035 V4L2_CAP_STREAMING |
1036 V4L2_CAP_TUNER;
1037 return 0;
1038}
1039
1040static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
1041 struct v4l2_fmtdesc *f)
1042{
1043 if(f->index)
1044 return -EINVAL;
1045
1046 memset(f, 0, sizeof(*f));
1047 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1048 strcpy(f->description, "Packed YUV2");
1049
1050 f->flags = 0;
1051 f->pixelformat = V4L2_PIX_FMT_UYVY;
1052
1053 memset(f->reserved, 0, sizeof(f->reserved));
1054 return 0;
1055}
1056
1057static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
1058 struct v4l2_format *f)
1059{
1060 struct au0828_fh *fh = priv;
1061 struct au0828_dev *dev = fh->dev;
1062
1063 f->fmt.pix.width = dev->width;
1064 f->fmt.pix.height = dev->height;
1065 f->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
1066 f->fmt.pix.bytesperline = dev->bytesperline;
1067 f->fmt.pix.sizeimage = dev->frame_size;
1068 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* NTSC/PAL */
1069 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
1070 return 0;
1071}
1072
1073static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
1074 struct v4l2_format *f)
1075{
1076 struct au0828_fh *fh = priv;
1077 struct au0828_dev *dev = fh->dev;
1078
1079 return au0828_set_format(dev, VIDIOC_TRY_FMT, f);
1080}
1081
1082static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1083 struct v4l2_format *f)
1084{
1085 struct au0828_fh *fh = priv;
1086 struct au0828_dev *dev = fh->dev;
1087 int rc;
1088
1089 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
1090 printk("%s queue busy\n", __func__);
1091 rc = -EBUSY;
1092 goto out;
1093 }
1094
1095 if (dev->stream_on && !fh->stream_on) {
1096 printk("%s device in use by another fh\n", __func__);
1097 rc = -EBUSY;
1098 goto out;
1099 }
1100
1101 return au0828_set_format(dev, VIDIOC_S_FMT, f);
1102out:
1103 return rc;
1104}
1105
1106static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
1107{
1108 struct au0828_fh *fh = priv;
1109 struct au0828_dev *dev = fh->dev;
1110
1111 /* FIXME: when we support something other than NTSC, we are going to
1112 have to make the au0828 bridge adjust the size of its capture
1113 buffer, which is currently hardcoded at 720x480 */
1114
1115 au0828_call_i2c_clients(dev, VIDIOC_S_STD, norm);
1116 return 0;
1117}
1118
1119static int vidioc_enum_input(struct file *file, void *priv,
1120 struct v4l2_input *input)
1121{
1122 struct au0828_fh *fh = priv;
1123 struct au0828_dev *dev = fh->dev;
1124 unsigned int tmp;
1125
1126 static const char *inames[] = {
1127 [AU0828_VMUX_COMPOSITE] = "Composite",
1128 [AU0828_VMUX_SVIDEO] = "S-Video",
1129 [AU0828_VMUX_CABLE] = "Cable TV",
1130 [AU0828_VMUX_TELEVISION] = "Television",
1131 [AU0828_VMUX_DVB] = "DVB",
1132 [AU0828_VMUX_DEBUG] = "tv debug"
1133 };
1134
1135 tmp = input->index;
1136
1137 if(tmp > AU0828_MAX_INPUT)
1138 return -EINVAL;
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001139 if(AUVI_INPUT(tmp).type == 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001140 return -EINVAL;
1141
1142 memset(input, 0, sizeof(*input));
1143 input->index = tmp;
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001144 strcpy(input->name, inames[AUVI_INPUT(tmp).type]);
1145 if((AUVI_INPUT(tmp).type == AU0828_VMUX_TELEVISION) ||
1146 (AUVI_INPUT(tmp).type == AU0828_VMUX_CABLE))
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001147 input->type |= V4L2_INPUT_TYPE_TUNER;
1148 else
1149 input->type |= V4L2_INPUT_TYPE_CAMERA;
1150
1151 input->std = dev->vdev->tvnorms;
1152
1153 return 0;
1154}
1155
1156static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1157{
1158 struct au0828_fh *fh = priv;
1159 struct au0828_dev *dev = fh->dev;
1160 *i = dev->ctrl_input;
1161 return 0;
1162}
1163
1164static int vidioc_s_input(struct file *file, void *priv, unsigned int index)
1165{
1166 struct au0828_fh *fh = priv;
1167 struct au0828_dev *dev = fh->dev;
1168 int i;
1169 struct v4l2_routing route;
1170
1171 dprintk(1, "VIDIOC_S_INPUT in function %s, input=%d\n", __FUNCTION__,
1172 index);
1173 if(index >= AU0828_MAX_INPUT)
1174 return -EINVAL;
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001175 if(AUVI_INPUT(index).type == 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001176 return -EINVAL;
1177 dev->ctrl_input = index;
1178
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001179 switch(AUVI_INPUT(index).type) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001180 case AU0828_VMUX_SVIDEO:
1181 {
1182 dev->input_type = AU0828_VMUX_SVIDEO;
1183 break;
1184 }
1185 case AU0828_VMUX_COMPOSITE:
1186 {
1187 dev->input_type = AU0828_VMUX_COMPOSITE;
1188 break;
1189 }
1190 case AU0828_VMUX_TELEVISION:
1191 {
1192 dev->input_type = AU0828_VMUX_TELEVISION;
1193 break;
1194 }
1195 default:
1196 ;
1197 }
1198
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001199 route.input = AUVI_INPUT(index).vmux;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001200 route.output = 0;
1201 au0828_call_i2c_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
1202
1203 for (i = 0; i < AU0828_MAX_INPUT; i++) {
1204 int enable = 0;
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001205 if (AUVI_INPUT(i).audio_setup == NULL) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001206 continue;
1207 }
1208
1209 if (i == index)
1210 enable = 1;
1211 else
1212 enable = 0;
1213 if (enable) {
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001214 (AUVI_INPUT(i).audio_setup)(dev, enable);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001215 } else {
1216 /* Make sure we leave it turned on if some
1217 other input is routed to this callback */
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001218 if ((AUVI_INPUT(i).audio_setup) !=
1219 ((AUVI_INPUT(index).audio_setup))) {
1220 (AUVI_INPUT(i).audio_setup)(dev, enable);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001221 }
1222 }
1223 }
1224
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001225 route.input = AUVI_INPUT(index).amux;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001226 au0828_call_i2c_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING,
1227 &route);
1228 return 0;
1229}
1230
1231static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
1232{
1233 struct au0828_fh *fh = priv;
1234 struct au0828_dev *dev = fh->dev;
1235 unsigned int index = a->index;
1236
1237 if(a->index > 1)
1238 return -EINVAL;
1239
1240 memset(a, 0, sizeof(*a));
1241 index = dev->ctrl_ainput;
1242 if(index == 0)
1243 strcpy(a->name, "Television");
1244 else
1245 strcpy(a->name, "Line in");
1246
1247 a->capability = V4L2_AUDCAP_STEREO;
1248 a->index = index;
1249 return 0;
1250}
1251
1252static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
1253{
1254 struct au0828_fh *fh = priv;
1255 struct au0828_dev *dev = fh->dev;
1256 if(a->index != dev->ctrl_ainput)
1257 return -EINVAL;
1258 return 0;
1259}
1260
1261static int vidioc_g_ctrl(struct file *file, void *priv,
1262 struct v4l2_control *ctrl)
1263{
1264 struct au0828_fh *fh = priv;
1265 struct au0828_dev *dev = fh->dev;
1266
1267 au0828_call_i2c_clients(dev, VIDIOC_G_CTRL, ctrl);
1268 return 0;
1269
1270}
1271
1272static int vidioc_s_ctrl(struct file *file, void *priv,
1273 struct v4l2_control *ctrl)
1274{
1275 struct au0828_fh *fh = priv;
1276 struct au0828_dev *dev = fh->dev;
1277 au0828_call_i2c_clients(dev, VIDIOC_S_CTRL, ctrl);
1278 return 0;
1279}
1280
1281static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1282{
1283 struct au0828_fh *fh = priv;
1284 struct au0828_dev *dev = fh->dev;
1285
1286 if(t->index != 0)
1287 return -EINVAL;
1288
1289 memset(t, 0, sizeof(*t));
1290 strcpy(t->name, "Auvitek tuner");
1291
1292 au0828_call_i2c_clients(dev, VIDIOC_G_TUNER, t);
1293 return 0;
1294}
1295
1296static int vidioc_s_tuner(struct file *file, void *priv,
1297 struct v4l2_tuner *t)
1298{
1299 struct au0828_fh *fh = priv;
1300 struct au0828_dev *dev = fh->dev;
1301
1302 if(t->index != 0)
1303 return -EINVAL;
1304
1305 t->type = V4L2_TUNER_ANALOG_TV;
1306 au0828_call_i2c_clients(dev, VIDIOC_S_TUNER, t);
1307 dprintk(1, "VIDIOC_S_TUNER: signal = %x, afc = %x\n", t->signal,
1308 t->afc);
1309 return 0;
1310
1311}
1312
1313static int vidioc_g_frequency(struct file *file, void *priv,
1314 struct v4l2_frequency *freq)
1315{
1316 struct au0828_fh *fh = priv;
1317 struct au0828_dev *dev = fh->dev;
1318 memset(freq, 0, sizeof(*freq));
1319 freq->type = V4L2_TUNER_ANALOG_TV;
1320 freq->frequency = dev->ctrl_freq;
1321 return 0;
1322}
1323
1324static int vidioc_s_frequency(struct file *file, void *priv,
1325 struct v4l2_frequency *freq)
1326{
1327 struct au0828_fh *fh = priv;
1328 struct au0828_dev *dev = fh->dev;
1329
1330 if(freq->tuner != 0)
1331 return -EINVAL;
1332 if(freq->type != V4L2_TUNER_ANALOG_TV)
1333 return -EINVAL;
1334
1335 dev->ctrl_freq = freq->frequency;
1336
1337 au0828_call_i2c_clients(dev, VIDIOC_S_FREQUENCY, freq);
1338
1339 au0828_analog_stream_reset(dev);
1340
1341 return 0;
1342}
1343
1344static int vidioc_g_chip_ident(struct file *file, void *priv,
1345 struct v4l2_dbg_chip_ident *chip)
1346{
1347 struct au0828_fh *fh = priv;
1348 struct au0828_dev *dev = fh->dev;
1349 chip->ident = V4L2_IDENT_NONE;
1350 chip->revision = 0;
1351
Devin Heitmuellerd9109be2009-03-11 03:00:58 -03001352 if (v4l2_chip_match_host(&chip->match)) {
1353 chip->ident = V4L2_IDENT_AU0828;
1354 return 0;
1355 }
1356
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001357 au0828_call_i2c_clients(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
Devin Heitmuellerd9109be2009-03-11 03:00:58 -03001358 if (chip->ident == V4L2_IDENT_NONE)
1359 return -EINVAL;
1360
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001361 return 0;
1362}
1363
1364static int vidioc_cropcap(struct file *file, void *priv,
1365 struct v4l2_cropcap *cc)
1366{
1367 struct au0828_fh *fh = priv;
1368 struct au0828_dev *dev = fh->dev;
1369
1370 if(cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1371 return -EINVAL;
1372
1373 cc->bounds.left = 0;
1374 cc->bounds.top = 0;
1375 cc->bounds.width = dev->width;
1376 cc->bounds.height = dev->height;
1377
1378 cc->defrect = cc->bounds;
1379
1380 cc->pixelaspect.numerator = 54;
1381 cc->pixelaspect.denominator = 59;
1382
1383 return 0;
1384}
1385
1386static int vidioc_streamon(struct file *file, void *priv,
1387 enum v4l2_buf_type type)
1388{
1389 struct au0828_fh *fh = priv;
1390 struct au0828_dev *dev = fh->dev;
1391 int b = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1392 int rc;
1393
1394 rc = check_dev(dev);
1395 if (rc < 0)
1396 return rc;
1397
1398 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1399 au0828_analog_stream_enable(dev);
1400 au0828_call_i2c_clients(dev, VIDIOC_STREAMON, &b);
1401 }
1402
1403 mutex_lock(&dev->lock);
1404 rc = res_get(fh);
1405
1406 if (likely(rc >= 0))
1407 rc = videobuf_streamon(&fh->vb_vidq);
1408 mutex_unlock(&dev->lock);
1409
1410 return rc;
1411}
1412
1413static int vidioc_streamoff(struct file *file, void *priv,
1414 enum v4l2_buf_type type)
1415{
1416 struct au0828_fh *fh = priv;
1417 struct au0828_dev *dev = fh->dev;
1418 int b = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1419 int i;
1420 int ret;
1421 int rc;
1422
1423 rc = check_dev(dev);
1424 if (rc < 0)
1425 return rc;
1426
1427 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1428 return -EINVAL;
1429 if (type != fh->type)
1430 return -EINVAL;
1431
1432 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1433 au0828_call_i2c_clients(dev, VIDIOC_STREAMOFF, &b);
1434 if((ret = au0828_stream_interrupt(dev)) != 0)
1435 return ret;
1436 }
1437
1438 for (i = 0; i < AU0828_MAX_INPUT; i++) {
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001439 if (AUVI_INPUT(i).audio_setup == NULL) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001440 continue;
1441 }
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001442 (AUVI_INPUT(i).audio_setup)(dev, 0);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001443 }
1444
1445 mutex_lock(&dev->lock);
1446 videobuf_streamoff(&fh->vb_vidq);
1447 res_free(fh);
1448 mutex_unlock(&dev->lock);
1449
1450 return 0;
1451}
1452
1453static int vidioc_g_register(struct file *file, void *priv,
1454 struct v4l2_dbg_register *reg)
1455{
1456 struct au0828_fh *fh = priv;
1457 struct au0828_dev *dev = fh->dev;
1458
1459 switch (reg->match.type) {
1460 case V4L2_CHIP_MATCH_I2C_DRIVER:
1461 au0828_call_i2c_clients(dev, VIDIOC_DBG_G_REGISTER, reg);
1462 return 0;
1463 default:
1464 return -EINVAL;
1465 }
1466}
1467
1468static int vidioc_s_register(struct file *file, void *priv,
1469 struct v4l2_dbg_register *reg)
1470{
1471 struct au0828_fh *fh = priv;
1472 struct au0828_dev *dev = fh->dev;
1473
1474 switch (reg->match.type) {
1475 case V4L2_CHIP_MATCH_I2C_DRIVER:
1476 au0828_call_i2c_clients(dev, VIDIOC_DBG_S_REGISTER, reg);
1477 return 0;
1478 default:
1479 return -EINVAL;
1480 }
1481 return 0;
1482}
1483
1484static int vidioc_reqbufs(struct file *file, void *priv,
1485 struct v4l2_requestbuffers *rb)
1486{
1487 struct au0828_fh *fh = priv;
1488 struct au0828_dev *dev = fh->dev;
1489 int rc;
1490
1491 rc = check_dev(dev);
1492 if (rc < 0)
1493 return rc;
1494
1495 return videobuf_reqbufs(&fh->vb_vidq, rb);
1496}
1497
1498static int vidioc_querybuf(struct file *file, void *priv,
1499 struct v4l2_buffer *b)
1500{
1501 struct au0828_fh *fh = priv;
1502 struct au0828_dev *dev = fh->dev;
1503 int rc;
1504
1505 rc = check_dev(dev);
1506 if (rc < 0)
1507 return rc;
1508
1509 return videobuf_querybuf(&fh->vb_vidq, b);
1510}
1511
1512static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1513{
1514 struct au0828_fh *fh = priv;
1515 struct au0828_dev *dev = fh->dev;
1516 int rc;
1517
1518 rc = check_dev(dev);
1519 if (rc < 0)
1520 return rc;
1521
1522 return videobuf_qbuf(&fh->vb_vidq, b);
1523}
1524
1525static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1526{
1527 struct au0828_fh *fh = priv;
1528 struct au0828_dev *dev = fh->dev;
1529 int rc;
1530
1531 rc = check_dev(dev);
1532 if (rc < 0)
1533 return rc;
1534
1535 /* Workaround for a bug in the au0828 hardware design that sometimes
1536 results in the colorspace being inverted */
1537 if (dev->greenscreen_detected == 1) {
1538 dprintk(1, "Detected green frame. Resetting stream...\n");
1539 au0828_analog_stream_reset(dev);
1540 dev->greenscreen_detected = 0;
1541 }
1542
1543 return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
1544}
1545
1546#ifdef CONFIG_VIDEO_V4L1_COMPAT
1547static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
1548{
1549 struct au0828_fh *fh = priv;
1550
1551 return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
1552}
1553#endif
1554
1555static struct v4l2_file_operations au0828_v4l_fops = {
1556 .owner = THIS_MODULE,
1557 .open = au0828_v4l2_open,
1558 .release = au0828_v4l2_close,
1559 .read = au0828_v4l2_read,
1560 .poll = au0828_v4l2_poll,
1561 .mmap = au0828_v4l2_mmap,
1562 .ioctl = video_ioctl2,
1563};
1564
1565static const struct v4l2_ioctl_ops video_ioctl_ops = {
1566 .vidioc_querycap = vidioc_querycap,
1567 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1568 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1569 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1570 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001571#ifdef VBI_NOT_YET_WORKING
1572 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
1573 .vidioc_try_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
1574 .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
1575#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001576 .vidioc_g_audio = vidioc_g_audio,
1577 .vidioc_s_audio = vidioc_s_audio,
1578 .vidioc_cropcap = vidioc_cropcap,
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001579#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001580 .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap,
1581 .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
1582 .vidioc_s_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
1583#endif
1584 .vidioc_reqbufs = vidioc_reqbufs,
1585 .vidioc_querybuf = vidioc_querybuf,
1586 .vidioc_qbuf = vidioc_qbuf,
1587 .vidioc_dqbuf = vidioc_dqbuf,
1588 .vidioc_s_std = vidioc_s_std,
1589 .vidioc_enum_input = vidioc_enum_input,
1590 .vidioc_g_input = vidioc_g_input,
1591 .vidioc_s_input = vidioc_s_input,
1592 .vidioc_queryctrl = vidioc_queryctrl,
1593 .vidioc_g_ctrl = vidioc_g_ctrl,
1594 .vidioc_s_ctrl = vidioc_s_ctrl,
1595 .vidioc_streamon = vidioc_streamon,
1596 .vidioc_streamoff = vidioc_streamoff,
1597 .vidioc_g_tuner = vidioc_g_tuner,
1598 .vidioc_s_tuner = vidioc_s_tuner,
1599 .vidioc_g_frequency = vidioc_g_frequency,
1600 .vidioc_s_frequency = vidioc_s_frequency,
1601#ifdef CONFIG_VIDEO_ADV_DEBUG
1602 .vidioc_g_register = vidioc_g_register,
1603 .vidioc_s_register = vidioc_s_register,
1604 .vidioc_g_chip_ident = vidioc_g_chip_ident,
1605#endif
1606#ifdef CONFIG_VIDEO_V4L1_COMPAT
1607 .vidiocgmbuf = vidiocgmbuf,
1608#endif
1609};
1610
1611static const struct video_device au0828_video_template = {
1612 .fops = &au0828_v4l_fops,
1613 .release = video_device_release,
1614 .ioctl_ops = &video_ioctl_ops,
1615 .minor = -1,
Devin Heitmueller0ef210712009-03-11 03:00:53 -03001616 .tvnorms = V4L2_STD_NTSC_M,
1617 .current_norm = V4L2_STD_NTSC_M,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001618};
1619
1620/**************************************************************************/
1621
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001622int au0828_analog_register(struct au0828_dev *dev,
1623 struct usb_interface *interface)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001624{
1625 int retval = -ENOMEM;
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001626 struct usb_host_interface *iface_desc;
1627 struct usb_endpoint_descriptor *endpoint;
1628 int i;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001629
1630 dprintk(1, "au0828_analog_register called!\n");
1631
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001632 /* set au0828 usb interface0 to as5 */
1633 retval = usb_set_interface(dev->usbdev,
1634 interface->cur_altsetting->desc.bInterfaceNumber, 5);
1635 if (retval != 0) {
1636 printk("Failure setting usb interface0 to as5\n");
1637 return retval;
1638 }
1639
1640 /* Figure out which endpoint has the isoc interface */
1641 iface_desc = interface->cur_altsetting;
1642 for(i = 0; i < iface_desc->desc.bNumEndpoints; i++){
1643 endpoint = &iface_desc->endpoint[i].desc;
1644 if(((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) &&
1645 ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC)){
1646
1647 /* we find our isoc in endpoint */
1648 u16 tmp = le16_to_cpu(endpoint->wMaxPacketSize);
1649 dev->max_pkt_size = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
1650 dev->isoc_in_endpointaddr = endpoint->bEndpointAddress;
1651 }
1652 }
1653 if(!(dev->isoc_in_endpointaddr)) {
1654 printk("Could not locate isoc endpoint\n");
1655 kfree(dev);
1656 return -ENODEV;
1657 }
1658
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001659 init_waitqueue_head(&dev->open);
1660 spin_lock_init(&dev->slock);
1661 mutex_init(&dev->lock);
1662
1663 INIT_LIST_HEAD(&dev->vidq.active);
1664 INIT_LIST_HEAD(&dev->vidq.queued);
1665
1666 dev->width = NTSC_STD_W;
1667 dev->height = NTSC_STD_H;
1668 dev->field_size = dev->width * dev->height;
1669 dev->frame_size = dev->field_size << 1;
1670 dev->bytesperline = dev->width << 1;
1671 dev->ctrl_ainput = 0;
1672
1673 /* allocate and fill v4l2 video struct */
1674 dev->vdev = video_device_alloc();
1675 if(NULL == dev->vdev) {
1676 dprintk(1, "Can't allocate video_device.\n");
1677 return -ENOMEM;
1678 }
1679
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001680#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001681 dev->vbi_dev = video_device_alloc();
1682 if(NULL == dev->vbi_dev) {
1683 dprintk(1, "Can't allocate vbi_device.\n");
1684 kfree(dev->vdev);
1685 return -ENOMEM;
1686 }
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001687#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001688
1689 /* Fill the video capture device struct */
1690 *dev->vdev = au0828_video_template;
1691 dev->vdev->vfl_type = VID_TYPE_CAPTURE | VID_TYPE_TUNER;
1692 dev->vdev->parent = &dev->usbdev->dev;
1693 strcpy(dev->vdev->name, "au0828a video");
1694
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001695#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001696 /* Setup the VBI device */
1697 *dev->vbi_dev = au0828_video_template;
1698 dev->vbi_dev->vfl_type = VFL_TYPE_VBI;
1699 dev->vbi_dev->parent = &dev->usbdev->dev;
1700 strcpy(dev->vbi_dev->name, "au0828a vbi");
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001701#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001702
1703 list_add_tail(&dev->au0828list, &au0828_devlist);
1704
1705 /* Register the v4l2 device */
1706 if((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1)) != 0) {
1707 dprintk(1, "unable to register video device (error = %d).\n", retval);
1708 list_del(&dev->au0828list);
1709 video_device_release(dev->vdev);
1710 return -ENODEV;
1711 }
1712
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001713#ifdef VBI_NOT_YET_WORKING
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001714 /* Register the vbi device */
1715 if((retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1)) != 0) {
1716 dprintk(1, "unable to register vbi device (error = %d).\n", retval);
1717 list_del(&dev->au0828list);
1718 video_device_release(dev->vbi_dev);
1719 video_device_release(dev->vdev);
1720 return -ENODEV;
1721 }
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001722#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001723
1724 dprintk(1, "%s completed!\n", __FUNCTION__);
1725
1726 return 0;
1727}
1728