aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/au0828
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@kernellabs.com>2010-05-29 16:18:45 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-08-02 13:48:53 -0400
commit7f8eacd2162a39ca7fc1240883118a786f147ccb (patch)
tree9bf9cd8e95c6593c04da8c37a8e836c5bb8f8274 /drivers/media/video/au0828
parentfab9bfbed22f91f271a93a3dfa142179a2278935 (diff)
V4L/DVB: Add closed captioning support for the HVR-950q
Add NTSC closed captioning support for au0828 based products. Note that this also required reworking the locking to support streaming on both the video and VBI devices (the logic for which I copied from my changes made to the em28xx several months ago). This work was sponsored by GetWellNetwork Inc. Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/au0828')
-rw-r--r--drivers/media/video/au0828/Makefile2
-rw-r--r--drivers/media/video/au0828/au0828-vbi.c138
-rw-r--r--drivers/media/video/au0828/au0828-video.c441
-rw-r--r--drivers/media/video/au0828/au0828.h20
4 files changed, 481 insertions, 120 deletions
diff --git a/drivers/media/video/au0828/Makefile b/drivers/media/video/au0828/Makefile
index 4d2623158188..5c7f2f7d9805 100644
--- a/drivers/media/video/au0828/Makefile
+++ b/drivers/media/video/au0828/Makefile
@@ -1,4 +1,4 @@
1au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o au0828-video.o 1au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o au0828-video.o au0828-vbi.o
2 2
3obj-$(CONFIG_VIDEO_AU0828) += au0828.o 3obj-$(CONFIG_VIDEO_AU0828) += au0828.o
4 4
diff --git a/drivers/media/video/au0828/au0828-vbi.c b/drivers/media/video/au0828/au0828-vbi.c
new file mode 100644
index 000000000000..63f593070ee8
--- /dev/null
+++ b/drivers/media/video/au0828/au0828-vbi.c
@@ -0,0 +1,138 @@
1/*
2 au0828-vbi.c - VBI driver for au0828
3
4 Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
5
6 This work was sponsored by GetWellNetwork Inc.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA.
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/slab.h>
28
29#include "au0828.h"
30
31static unsigned int vbibufs = 5;
32module_param(vbibufs, int, 0644);
33MODULE_PARM_DESC(vbibufs, "number of vbi buffers, range 2-32");
34
35/* ------------------------------------------------------------------ */
36
37static void
38free_buffer(struct videobuf_queue *vq, struct au0828_buffer *buf)
39{
40 struct au0828_fh *fh = vq->priv_data;
41 struct au0828_dev *dev = fh->dev;
42 unsigned long flags = 0;
43 if (in_interrupt())
44 BUG();
45
46 /* We used to wait for the buffer to finish here, but this didn't work
47 because, as we were keeping the state as VIDEOBUF_QUEUED,
48 videobuf_queue_cancel marked it as finished for us.
49 (Also, it could wedge forever if the hardware was misconfigured.)
50
51 This should be safe; by the time we get here, the buffer isn't
52 queued anymore. If we ever start marking the buffers as
53 VIDEOBUF_ACTIVE, it won't be, though.
54 */
55 spin_lock_irqsave(&dev->slock, flags);
56 if (dev->isoc_ctl.vbi_buf == buf)
57 dev->isoc_ctl.vbi_buf = NULL;
58 spin_unlock_irqrestore(&dev->slock, flags);
59
60 videobuf_vmalloc_free(&buf->vb);
61 buf->vb.state = VIDEOBUF_NEEDS_INIT;
62}
63
64static int
65vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
66{
67 struct au0828_fh *fh = q->priv_data;
68 struct au0828_dev *dev = fh->dev;
69
70 *size = dev->vbi_width * dev->vbi_height * 2;
71
72 if (0 == *count)
73 *count = vbibufs;
74 if (*count < 2)
75 *count = 2;
76 if (*count > 32)
77 *count = 32;
78 return 0;
79}
80
81static int
82vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
83 enum v4l2_field field)
84{
85 struct au0828_fh *fh = q->priv_data;
86 struct au0828_dev *dev = fh->dev;
87 struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
88 int rc = 0;
89
90 buf->vb.size = dev->vbi_width * dev->vbi_height * 2;
91
92 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
93 return -EINVAL;
94
95 buf->vb.width = dev->vbi_width;
96 buf->vb.height = dev->vbi_height;
97 buf->vb.field = field;
98
99 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
100 rc = videobuf_iolock(q, &buf->vb, NULL);
101 if (rc < 0)
102 goto fail;
103 }
104
105 buf->vb.state = VIDEOBUF_PREPARED;
106 return 0;
107
108fail:
109 free_buffer(q, buf);
110 return rc;
111}
112
113static void
114vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
115{
116 struct au0828_buffer *buf = container_of(vb,
117 struct au0828_buffer,
118 vb);
119 struct au0828_fh *fh = vq->priv_data;
120 struct au0828_dev *dev = fh->dev;
121 struct au0828_dmaqueue *vbiq = &dev->vbiq;
122
123 buf->vb.state = VIDEOBUF_QUEUED;
124 list_add_tail(&buf->vb.queue, &vbiq->active);
125}
126
127static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
128{
129 struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
130 free_buffer(q, buf);
131}
132
133struct videobuf_queue_ops au0828_vbi_qops = {
134 .buf_setup = vbi_setup,
135 .buf_prepare = vbi_prepare,
136 .buf_queue = vbi_queue,
137 .buf_release = vbi_release,
138};
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 52f25aabb6dc..d97e0a28fb24 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -314,6 +314,23 @@ static inline void buffer_filled(struct au0828_dev *dev,
314 wake_up(&buf->vb.done); 314 wake_up(&buf->vb.done);
315} 315}
316 316
317static inline void vbi_buffer_filled(struct au0828_dev *dev,
318 struct au0828_dmaqueue *dma_q,
319 struct au0828_buffer *buf)
320{
321 /* Advice that buffer was filled */
322 au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
323
324 buf->vb.state = VIDEOBUF_DONE;
325 buf->vb.field_count++;
326 do_gettimeofday(&buf->vb.ts);
327
328 dev->isoc_ctl.vbi_buf = NULL;
329
330 list_del(&buf->vb.queue);
331 wake_up(&buf->vb.done);
332}
333
317/* 334/*
318 * Identify the buffer header type and properly handles 335 * Identify the buffer header type and properly handles
319 */ 336 */
@@ -327,6 +344,9 @@ static void au0828_copy_video(struct au0828_dev *dev,
327 int linesdone, currlinedone, offset, lencopy, remain; 344 int linesdone, currlinedone, offset, lencopy, remain;
328 int bytesperline = dev->width << 1; /* Assumes 16-bit depth @@@@ */ 345 int bytesperline = dev->width << 1; /* Assumes 16-bit depth @@@@ */
329 346
347 if (len == 0)
348 return;
349
330 if (dma_q->pos + len > buf->vb.size) 350 if (dma_q->pos + len > buf->vb.size)
331 len = buf->vb.size - dma_q->pos; 351 len = buf->vb.size - dma_q->pos;
332 352
@@ -414,17 +434,96 @@ static inline void get_next_buf(struct au0828_dmaqueue *dma_q,
414 return; 434 return;
415} 435}
416 436
437static void au0828_copy_vbi(struct au0828_dev *dev,
438 struct au0828_dmaqueue *dma_q,
439 struct au0828_buffer *buf,
440 unsigned char *p,
441 unsigned char *outp, unsigned long len)
442{
443 unsigned char *startwrite, *startread;
444 int bytesperline = dev->vbi_width;
445 int i, j = 0;
446
447 if (dev == NULL) {
448 au0828_isocdbg("dev is null\n");
449 return;
450 }
451
452 if (dma_q == NULL) {
453 au0828_isocdbg("dma_q is null\n");
454 return;
455 }
456 if (buf == NULL)
457 return;
458 if (p == NULL) {
459 au0828_isocdbg("p is null\n");
460 return;
461 }
462 if (outp == NULL) {
463 au0828_isocdbg("outp is null\n");
464 return;
465 }
466
467 if (dma_q->pos + len > buf->vb.size)
468 len = buf->vb.size - dma_q->pos;
469
470 startread = p;
471 startwrite = outp + (dma_q->pos / 2);
472
473 /* Make sure the bottom field populates the second half of the frame */
474 if (buf->top_field == 0)
475 startwrite += bytesperline * dev->vbi_height;
476
477 for (i = 0; i < len; i += 2)
478 startwrite[j++] = startread[i+1];
479
480 dma_q->pos += len;
481}
482
483
484/*
485 * video-buf generic routine to get the next available VBI buffer
486 */
487static inline void vbi_get_next_buf(struct au0828_dmaqueue *dma_q,
488 struct au0828_buffer **buf)
489{
490 struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vbiq);
491 char *outp;
492
493 if (list_empty(&dma_q->active)) {
494 au0828_isocdbg("No active queue to serve\n");
495 dev->isoc_ctl.vbi_buf = NULL;
496 *buf = NULL;
497 return;
498 }
499
500 /* Get the next buffer */
501 *buf = list_entry(dma_q->active.next, struct au0828_buffer, vb.queue);
502 /* Cleans up buffer - Usefull for testing for frame/URB loss */
503 outp = videobuf_to_vmalloc(&(*buf)->vb);
504 memset(outp, 0x00, (*buf)->vb.size);
505
506 dev->isoc_ctl.vbi_buf = *buf;
507
508 return;
509}
510
417/* 511/*
418 * Controls the isoc copy of each urb packet 512 * Controls the isoc copy of each urb packet
419 */ 513 */
420static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb) 514static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
421{ 515{
422 struct au0828_buffer *buf; 516 struct au0828_buffer *buf;
517 struct au0828_buffer *vbi_buf;
423 struct au0828_dmaqueue *dma_q = urb->context; 518 struct au0828_dmaqueue *dma_q = urb->context;
519 struct au0828_dmaqueue *vbi_dma_q = &dev->vbiq;
424 unsigned char *outp = NULL; 520 unsigned char *outp = NULL;
521 unsigned char *vbioutp = NULL;
425 int i, len = 0, rc = 1; 522 int i, len = 0, rc = 1;
426 unsigned char *p; 523 unsigned char *p;
427 unsigned char fbyte; 524 unsigned char fbyte;
525 unsigned int vbi_field_size;
526 unsigned int remain, lencopy;
428 527
429 if (!dev) 528 if (!dev)
430 return 0; 529 return 0;
@@ -443,6 +542,10 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
443 if (buf != NULL) 542 if (buf != NULL)
444 outp = videobuf_to_vmalloc(&buf->vb); 543 outp = videobuf_to_vmalloc(&buf->vb);
445 544
545 vbi_buf = dev->isoc_ctl.vbi_buf;
546 if (vbi_buf != NULL)
547 vbioutp = videobuf_to_vmalloc(&vbi_buf->vb);
548
446 for (i = 0; i < urb->number_of_packets; i++) { 549 for (i = 0; i < urb->number_of_packets; i++) {
447 int status = urb->iso_frame_desc[i].status; 550 int status = urb->iso_frame_desc[i].status;
448 551
@@ -472,6 +575,19 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
472 au0828_isocdbg("Video frame %s\n", 575 au0828_isocdbg("Video frame %s\n",
473 (fbyte & 0x40) ? "odd" : "even"); 576 (fbyte & 0x40) ? "odd" : "even");
474 if (!(fbyte & 0x40)) { 577 if (!(fbyte & 0x40)) {
578 /* VBI */
579 if (vbi_buf != NULL)
580 vbi_buffer_filled(dev,
581 vbi_dma_q,
582 vbi_buf);
583 vbi_get_next_buf(vbi_dma_q, &vbi_buf);
584 if (vbi_buf == NULL)
585 vbioutp = NULL;
586 else
587 vbioutp = videobuf_to_vmalloc(
588 &vbi_buf->vb);
589
590 /* Video */
475 if (buf != NULL) 591 if (buf != NULL)
476 buffer_filled(dev, dma_q, buf); 592 buffer_filled(dev, dma_q, buf);
477 get_next_buf(dma_q, &buf); 593 get_next_buf(dma_q, &buf);
@@ -488,9 +604,36 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
488 buf->top_field = 0; 604 buf->top_field = 0;
489 } 605 }
490 606
607 if (vbi_buf != NULL) {
608 if (fbyte & 0x40)
609 vbi_buf->top_field = 1;
610 else
611 vbi_buf->top_field = 0;
612 }
613
614 dev->vbi_read = 0;
615 vbi_dma_q->pos = 0;
491 dma_q->pos = 0; 616 dma_q->pos = 0;
492 } 617 }
493 if (buf != NULL) 618
619 vbi_field_size = dev->vbi_width * dev->vbi_height * 2;
620 if (dev->vbi_read < vbi_field_size) {
621 remain = vbi_field_size - dev->vbi_read;
622 if (len < remain)
623 lencopy = len;
624 else
625 lencopy = remain;
626
627 if (vbi_buf != NULL)
628 au0828_copy_vbi(dev, vbi_dma_q, vbi_buf, p,
629 vbioutp, len);
630
631 len -= lencopy;
632 p += lencopy;
633 dev->vbi_read += lencopy;
634 }
635
636 if (dev->vbi_read >= vbi_field_size && buf != NULL)
494 au0828_copy_video(dev, dma_q, buf, p, outp, len); 637 au0828_copy_video(dev, dma_q, buf, p, outp, len);
495 } 638 }
496 return rc; 639 return rc;
@@ -642,7 +785,7 @@ int au0828_analog_stream_enable(struct au0828_dev *d)
642 au0828_writereg(d, 0x114, 0xa0); 785 au0828_writereg(d, 0x114, 0xa0);
643 au0828_writereg(d, 0x115, 0x05); 786 au0828_writereg(d, 0x115, 0x05);
644 /* set y position */ 787 /* set y position */
645 au0828_writereg(d, 0x112, 0x02); 788 au0828_writereg(d, 0x112, 0x00);
646 au0828_writereg(d, 0x113, 0x00); 789 au0828_writereg(d, 0x113, 0x00);
647 au0828_writereg(d, 0x116, 0xf2); 790 au0828_writereg(d, 0x116, 0xf2);
648 au0828_writereg(d, 0x117, 0x00); 791 au0828_writereg(d, 0x117, 0x00);
@@ -703,47 +846,83 @@ void au0828_analog_unregister(struct au0828_dev *dev)
703 846
704 847
705/* Usage lock check functions */ 848/* Usage lock check functions */
706static int res_get(struct au0828_fh *fh) 849static int res_get(struct au0828_fh *fh, unsigned int bit)
707{ 850{
708 struct au0828_dev *dev = fh->dev; 851 struct au0828_dev *dev = fh->dev;
709 int rc = 0;
710 852
711 /* This instance already has stream_on */ 853 if (fh->resources & bit)
712 if (fh->stream_on) 854 /* have it already allocated */
713 return rc; 855 return 1;
714 856
715 if (dev->stream_on) 857 /* is it free? */
716 return -EBUSY; 858 mutex_lock(&dev->lock);
859 if (dev->resources & bit) {
860 /* no, someone else uses it */
861 mutex_unlock(&dev->lock);
862 return 0;
863 }
864 /* it's free, grab it */
865 fh->resources |= bit;
866 dev->resources |= bit;
867 dprintk(1, "res: get %d\n", bit);
868 mutex_unlock(&dev->lock);
869 return 1;
870}
717 871
718 dev->stream_on = 1; 872static int res_check(struct au0828_fh *fh, unsigned int bit)
719 fh->stream_on = 1; 873{
720 return rc; 874 return fh->resources & bit;
721} 875}
722 876
723static int res_check(struct au0828_fh *fh) 877static int res_locked(struct au0828_dev *dev, unsigned int bit)
724{ 878{
725 return fh->stream_on; 879 return dev->resources & bit;
726} 880}
727 881
728static void res_free(struct au0828_fh *fh) 882static void res_free(struct au0828_fh *fh, unsigned int bits)
729{ 883{
730 struct au0828_dev *dev = fh->dev; 884 struct au0828_dev *dev = fh->dev;
885
886 BUG_ON((fh->resources & bits) != bits);
731 887
732 fh->stream_on = 0; 888 mutex_lock(&dev->lock);
733 dev->stream_on = 0; 889 fh->resources &= ~bits;
890 dev->resources &= ~bits;
891 dprintk(1, "res: put %d\n", bits);
892 mutex_unlock(&dev->lock);
893}
894
895static int get_ressource(struct au0828_fh *fh)
896{
897 switch (fh->type) {
898 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
899 return AU0828_RESOURCE_VIDEO;
900 case V4L2_BUF_TYPE_VBI_CAPTURE:
901 return AU0828_RESOURCE_VBI;
902 default:
903 BUG();
904 return 0;
905 }
734} 906}
735 907
736static int au0828_v4l2_open(struct file *filp) 908static int au0828_v4l2_open(struct file *filp)
737{ 909{
738 int ret = 0; 910 int ret = 0;
911 struct video_device *vdev = video_devdata(filp);
739 struct au0828_dev *dev = video_drvdata(filp); 912 struct au0828_dev *dev = video_drvdata(filp);
740 struct au0828_fh *fh; 913 struct au0828_fh *fh;
741 int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 914 int type;
742 915
743#ifdef VBI_IS_WORKING 916 switch (vdev->vfl_type) {
744 if (video_devdata(filp)->vfl_type == VFL_TYPE_GRABBER) 917 case VFL_TYPE_GRABBER:
918 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
919 break;
920 case VFL_TYPE_VBI:
745 type = V4L2_BUF_TYPE_VBI_CAPTURE; 921 type = V4L2_BUF_TYPE_VBI_CAPTURE;
746#endif 922 break;
923 default:
924 return -EINVAL;
925 }
747 926
748 fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL); 927 fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL);
749 if (NULL == fh) { 928 if (NULL == fh) {
@@ -781,10 +960,21 @@ static int au0828_v4l2_open(struct file *filp)
781 dev->users++; 960 dev->users++;
782 961
783 videobuf_queue_vmalloc_init(&fh->vb_vidq, &au0828_video_qops, 962 videobuf_queue_vmalloc_init(&fh->vb_vidq, &au0828_video_qops,
784 NULL, &dev->slock, fh->type, 963 NULL, &dev->slock,
964 V4L2_BUF_TYPE_VIDEO_CAPTURE,
785 V4L2_FIELD_INTERLACED, 965 V4L2_FIELD_INTERLACED,
786 sizeof(struct au0828_buffer), fh); 966 sizeof(struct au0828_buffer), fh);
787 967
968 /* VBI Setup */
969 dev->vbi_width = 720;
970 dev->vbi_height = 1;
971 videobuf_queue_vmalloc_init(&fh->vb_vbiq, &au0828_vbi_qops,
972 NULL, &dev->slock,
973 V4L2_BUF_TYPE_VBI_CAPTURE,
974 V4L2_FIELD_SEQ_TB,
975 sizeof(struct au0828_buffer), fh);
976
977
788 return ret; 978 return ret;
789} 979}
790 980
@@ -794,17 +984,19 @@ static int au0828_v4l2_close(struct file *filp)
794 struct au0828_fh *fh = filp->private_data; 984 struct au0828_fh *fh = filp->private_data;
795 struct au0828_dev *dev = fh->dev; 985 struct au0828_dev *dev = fh->dev;
796 986
797 mutex_lock(&dev->lock); 987 if (res_check(fh, AU0828_RESOURCE_VIDEO)) {
798 if (res_check(fh))
799 res_free(fh);
800
801 if (dev->users == 1) {
802 videobuf_stop(&fh->vb_vidq); 988 videobuf_stop(&fh->vb_vidq);
803 videobuf_mmap_free(&fh->vb_vidq); 989 res_free(fh, AU0828_RESOURCE_VIDEO);
990 }
804 991
992 if (res_check(fh, AU0828_RESOURCE_VBI)) {
993 videobuf_stop(&fh->vb_vbiq);
994 res_free(fh, AU0828_RESOURCE_VBI);
995 }
996
997 if (dev->users == 1) {
805 if (dev->dev_state & DEV_DISCONNECTED) { 998 if (dev->dev_state & DEV_DISCONNECTED) {
806 au0828_analog_unregister(dev); 999 au0828_analog_unregister(dev);
807 mutex_unlock(&dev->lock);
808 kfree(dev); 1000 kfree(dev);
809 return 0; 1001 return 0;
810 } 1002 }
@@ -823,10 +1015,11 @@ static int au0828_v4l2_close(struct file *filp)
823 printk(KERN_INFO "Au0828 can't set alternate to 0!\n"); 1015 printk(KERN_INFO "Au0828 can't set alternate to 0!\n");
824 } 1016 }
825 1017
1018 videobuf_mmap_free(&fh->vb_vidq);
1019 videobuf_mmap_free(&fh->vb_vbiq);
826 kfree(fh); 1020 kfree(fh);
827 dev->users--; 1021 dev->users--;
828 wake_up_interruptible_nr(&dev->open, 1); 1022 wake_up_interruptible_nr(&dev->open, 1);
829 mutex_unlock(&dev->lock);
830 return 0; 1023 return 0;
831} 1024}
832 1025
@@ -842,16 +1035,21 @@ static ssize_t au0828_v4l2_read(struct file *filp, char __user *buf,
842 return rc; 1035 return rc;
843 1036
844 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1037 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
845 mutex_lock(&dev->lock); 1038 if (res_locked(dev, AU0828_RESOURCE_VIDEO))
846 rc = res_get(fh); 1039 return -EBUSY;
847 mutex_unlock(&dev->lock);
848
849 if (unlikely(rc < 0))
850 return rc;
851 1040
852 return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0, 1041 return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
853 filp->f_flags & O_NONBLOCK); 1042 filp->f_flags & O_NONBLOCK);
854 } 1043 }
1044
1045 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
1046 if (!res_get(fh, AU0828_RESOURCE_VBI))
1047 return -EBUSY;
1048
1049 return videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0,
1050 filp->f_flags & O_NONBLOCK);
1051 }
1052
855 return 0; 1053 return 0;
856} 1054}
857 1055
@@ -865,17 +1063,17 @@ static unsigned int au0828_v4l2_poll(struct file *filp, poll_table *wait)
865 if (rc < 0) 1063 if (rc < 0)
866 return rc; 1064 return rc;
867 1065
868 mutex_lock(&dev->lock); 1066 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
869 rc = res_get(fh); 1067 if (!res_get(fh, AU0828_RESOURCE_VIDEO))
870 mutex_unlock(&dev->lock); 1068 return POLLERR;
871 1069 return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
872 if (unlikely(rc < 0)) 1070 } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
873 return POLLERR; 1071 if (!res_get(fh, AU0828_RESOURCE_VBI))
874 1072 return POLLERR;
875 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) 1073 return videobuf_poll_stream(filp, &fh->vb_vbiq, wait);
1074 } else {
876 return POLLERR; 1075 return POLLERR;
877 1076 }
878 return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
879} 1077}
880 1078
881static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) 1079static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
@@ -888,14 +1086,10 @@ static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
888 if (rc < 0) 1086 if (rc < 0)
889 return rc; 1087 return rc;
890 1088
891 mutex_lock(&dev->lock); 1089 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
892 rc = res_get(fh); 1090 rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
893 mutex_unlock(&dev->lock); 1091 else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
894 1092 rc = videobuf_mmap_mapper(&fh->vb_vbiq, vma);
895 if (unlikely(rc < 0))
896 return rc;
897
898 rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
899 1093
900 return rc; 1094 return rc;
901} 1095}
@@ -911,14 +1105,6 @@ static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd,
911 maxwidth = 720; 1105 maxwidth = 720;
912 maxheight = 480; 1106 maxheight = 480;
913 1107
914#ifdef VBI_IS_WORKING
915 if (format->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
916 dprintk(1, "VBI format set: to be supported!\n");
917 return 0;
918 }
919 if (format->type == V4L2_BUF_TYPE_VBI_CAPTURE)
920 return 0;
921#endif
922 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1108 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
923 return -EINVAL; 1109 return -EINVAL;
924 1110
@@ -999,9 +1185,7 @@ static int vidioc_querycap(struct file *file, void *priv,
999 1185
1000 /*set the device capabilities */ 1186 /*set the device capabilities */
1001 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | 1187 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
1002#ifdef VBI_IS_WORKING
1003 V4L2_CAP_VBI_CAPTURE | 1188 V4L2_CAP_VBI_CAPTURE |
1004#endif
1005 V4L2_CAP_AUDIO | 1189 V4L2_CAP_AUDIO |
1006 V4L2_CAP_READWRITE | 1190 V4L2_CAP_READWRITE |
1007 V4L2_CAP_STREAMING | 1191 V4L2_CAP_STREAMING |
@@ -1056,20 +1240,21 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1056 struct au0828_dev *dev = fh->dev; 1240 struct au0828_dev *dev = fh->dev;
1057 int rc; 1241 int rc;
1058 1242
1243 rc = check_dev(dev);
1244 if (rc < 0)
1245 return rc;
1246
1247 mutex_lock(&dev->lock);
1248
1059 if (videobuf_queue_is_busy(&fh->vb_vidq)) { 1249 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
1060 printk(KERN_INFO "%s queue busy\n", __func__); 1250 printk(KERN_INFO "%s queue busy\n", __func__);
1061 rc = -EBUSY; 1251 rc = -EBUSY;
1062 goto out; 1252 goto out;
1063 } 1253 }
1064 1254
1065 if (dev->stream_on && !fh->stream_on) { 1255 rc = au0828_set_format(dev, VIDIOC_S_FMT, f);
1066 printk(KERN_INFO "%s device in use by another fh\n", __func__);
1067 rc = -EBUSY;
1068 goto out;
1069 }
1070
1071 return au0828_set_format(dev, VIDIOC_S_FMT, f);
1072out: 1256out:
1257 mutex_unlock(&dev->lock);
1073 return rc; 1258 return rc;
1074} 1259}
1075 1260
@@ -1300,6 +1485,29 @@ static int vidioc_s_frequency(struct file *file, void *priv,
1300 return 0; 1485 return 0;
1301} 1486}
1302 1487
1488
1489/* RAW VBI ioctls */
1490
1491static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
1492 struct v4l2_format *format)
1493{
1494 struct au0828_fh *fh = priv;
1495 struct au0828_dev *dev = fh->dev;
1496
1497 format->fmt.vbi.samples_per_line = dev->vbi_width;
1498 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1499 format->fmt.vbi.offset = 0;
1500 format->fmt.vbi.flags = 0;
1501 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
1502
1503 format->fmt.vbi.count[0] = dev->vbi_height;
1504 format->fmt.vbi.count[1] = dev->vbi_height;
1505 format->fmt.vbi.start[0] = 21;
1506 format->fmt.vbi.start[1] = 284;
1507
1508 return 0;
1509}
1510
1303static int vidioc_g_chip_ident(struct file *file, void *priv, 1511static int vidioc_g_chip_ident(struct file *file, void *priv,
1304 struct v4l2_dbg_chip_ident *chip) 1512 struct v4l2_dbg_chip_ident *chip)
1305{ 1513{
@@ -1345,25 +1553,32 @@ static int vidioc_cropcap(struct file *file, void *priv,
1345static int vidioc_streamon(struct file *file, void *priv, 1553static int vidioc_streamon(struct file *file, void *priv,
1346 enum v4l2_buf_type type) 1554 enum v4l2_buf_type type)
1347{ 1555{
1348 struct au0828_fh *fh = priv; 1556 struct au0828_fh *fh = priv;
1349 struct au0828_dev *dev = fh->dev; 1557 struct au0828_dev *dev = fh->dev;
1350 int rc; 1558 int rc = -EINVAL;
1351 1559
1352 rc = check_dev(dev); 1560 rc = check_dev(dev);
1353 if (rc < 0) 1561 if (rc < 0)
1354 return rc; 1562 return rc;
1355 1563
1564 if (unlikely(type != fh->type))
1565 return -EINVAL;
1566
1567 dprintk(1, "vidioc_streamon fh=%p t=%d fh->res=%d dev->res=%d\n",
1568 fh, type, fh->resources, dev->resources);
1569
1570 if (unlikely(!res_get(fh, get_ressource(fh))))
1571 return -EBUSY;
1572
1356 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1573 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1357 au0828_analog_stream_enable(dev); 1574 au0828_analog_stream_enable(dev);
1358 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1); 1575 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1);
1359 } 1576 }
1360 1577
1361 mutex_lock(&dev->lock); 1578 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1362 rc = res_get(fh);
1363
1364 if (likely(rc >= 0))
1365 rc = videobuf_streamon(&fh->vb_vidq); 1579 rc = videobuf_streamon(&fh->vb_vidq);
1366 mutex_unlock(&dev->lock); 1580 else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1581 rc = videobuf_streamon(&fh->vb_vbiq);
1367 1582
1368 return rc; 1583 return rc;
1369} 1584}
@@ -1371,38 +1586,42 @@ static int vidioc_streamon(struct file *file, void *priv,
1371static int vidioc_streamoff(struct file *file, void *priv, 1586static int vidioc_streamoff(struct file *file, void *priv,
1372 enum v4l2_buf_type type) 1587 enum v4l2_buf_type type)
1373{ 1588{
1374 struct au0828_fh *fh = priv; 1589 struct au0828_fh *fh = priv;
1375 struct au0828_dev *dev = fh->dev; 1590 struct au0828_dev *dev = fh->dev;
1376 int i; 1591 int rc;
1377 int ret; 1592 int i;
1378 int rc;
1379 1593
1380 rc = check_dev(dev); 1594 rc = check_dev(dev);
1381 if (rc < 0) 1595 if (rc < 0)
1382 return rc; 1596 return rc;
1383 1597
1384 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1598 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1599 fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)
1385 return -EINVAL; 1600 return -EINVAL;
1386 if (type != fh->type) 1601 if (type != fh->type)
1387 return -EINVAL; 1602 return -EINVAL;
1388 1603
1389 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1604 dprintk(1, "vidioc_streamoff fh=%p t=%d fh->res=%d dev->res=%d\n",
1605 fh, type, fh->resources, dev->resources);
1606
1607 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1390 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0); 1608 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
1391 ret = au0828_stream_interrupt(dev); 1609 rc = au0828_stream_interrupt(dev);
1392 if (ret != 0) 1610 if (rc != 0)
1393 return ret; 1611 return rc;
1394 }
1395 1612
1396 for (i = 0; i < AU0828_MAX_INPUT; i++) { 1613 for (i = 0; i < AU0828_MAX_INPUT; i++) {
1397 if (AUVI_INPUT(i).audio_setup == NULL) 1614 if (AUVI_INPUT(i).audio_setup == NULL)
1398 continue; 1615 continue;
1399 (AUVI_INPUT(i).audio_setup)(dev, 0); 1616 (AUVI_INPUT(i).audio_setup)(dev, 0);
1400 } 1617 }
1401 1618
1402 mutex_lock(&dev->lock); 1619 videobuf_streamoff(&fh->vb_vidq);
1403 videobuf_streamoff(&fh->vb_vidq); 1620 res_free(fh, AU0828_RESOURCE_VIDEO);
1404 res_free(fh); 1621 } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
1405 mutex_unlock(&dev->lock); 1622 videobuf_streamoff(&fh->vb_vbiq);
1623 res_free(fh, AU0828_RESOURCE_VBI);
1624 }
1406 1625
1407 return 0; 1626 return 0;
1408} 1627}
@@ -1527,19 +1746,11 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
1527 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 1746 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1528 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 1747 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1529 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 1748 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1530#ifdef VBI_IS_WORKING
1531 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, 1749 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
1532 .vidioc_try_fmt_vbi_cap = vidioc_s_fmt_vbi_cap, 1750 .vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
1533 .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
1534#endif
1535 .vidioc_g_audio = vidioc_g_audio, 1751 .vidioc_g_audio = vidioc_g_audio,
1536 .vidioc_s_audio = vidioc_s_audio, 1752 .vidioc_s_audio = vidioc_s_audio,
1537 .vidioc_cropcap = vidioc_cropcap, 1753 .vidioc_cropcap = vidioc_cropcap,
1538#ifdef VBI_IS_WORKING
1539 .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap,
1540 .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
1541 .vidioc_s_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
1542#endif
1543 .vidioc_reqbufs = vidioc_reqbufs, 1754 .vidioc_reqbufs = vidioc_reqbufs,
1544 .vidioc_querybuf = vidioc_querybuf, 1755 .vidioc_querybuf = vidioc_querybuf,
1545 .vidioc_qbuf = vidioc_qbuf, 1756 .vidioc_qbuf = vidioc_qbuf,
@@ -1621,8 +1832,11 @@ int au0828_analog_register(struct au0828_dev *dev,
1621 spin_lock_init(&dev->slock); 1832 spin_lock_init(&dev->slock);
1622 mutex_init(&dev->lock); 1833 mutex_init(&dev->lock);
1623 1834
1835 /* init video dma queues */
1624 INIT_LIST_HEAD(&dev->vidq.active); 1836 INIT_LIST_HEAD(&dev->vidq.active);
1625 INIT_LIST_HEAD(&dev->vidq.queued); 1837 INIT_LIST_HEAD(&dev->vidq.queued);
1838 INIT_LIST_HEAD(&dev->vbiq.active);
1839 INIT_LIST_HEAD(&dev->vbiq.queued);
1626 1840
1627 dev->width = NTSC_STD_W; 1841 dev->width = NTSC_STD_W;
1628 dev->height = NTSC_STD_H; 1842 dev->height = NTSC_STD_H;
@@ -1638,26 +1852,23 @@ int au0828_analog_register(struct au0828_dev *dev,
1638 return -ENOMEM; 1852 return -ENOMEM;
1639 } 1853 }
1640 1854
1641#ifdef VBI_IS_WORKING 1855 /* allocate the VBI struct */
1642 dev->vbi_dev = video_device_alloc(); 1856 dev->vbi_dev = video_device_alloc();
1643 if (NULL == dev->vbi_dev) { 1857 if (NULL == dev->vbi_dev) {
1644 dprintk(1, "Can't allocate vbi_device.\n"); 1858 dprintk(1, "Can't allocate vbi_device.\n");
1645 kfree(dev->vdev); 1859 kfree(dev->vdev);
1646 return -ENOMEM; 1860 return -ENOMEM;
1647 } 1861 }
1648#endif
1649 1862
1650 /* Fill the video capture device struct */ 1863 /* Fill the video capture device struct */
1651 *dev->vdev = au0828_video_template; 1864 *dev->vdev = au0828_video_template;
1652 dev->vdev->parent = &dev->usbdev->dev; 1865 dev->vdev->parent = &dev->usbdev->dev;
1653 strcpy(dev->vdev->name, "au0828a video"); 1866 strcpy(dev->vdev->name, "au0828a video");
1654 1867
1655#ifdef VBI_IS_WORKING
1656 /* Setup the VBI device */ 1868 /* Setup the VBI device */
1657 *dev->vbi_dev = au0828_video_template; 1869 *dev->vbi_dev = au0828_video_template;
1658 dev->vbi_dev->parent = &dev->usbdev->dev; 1870 dev->vbi_dev->parent = &dev->usbdev->dev;
1659 strcpy(dev->vbi_dev->name, "au0828a vbi"); 1871 strcpy(dev->vbi_dev->name, "au0828a vbi");
1660#endif
1661 1872
1662 /* Register the v4l2 device */ 1873 /* Register the v4l2 device */
1663 video_set_drvdata(dev->vdev, dev); 1874 video_set_drvdata(dev->vdev, dev);
@@ -1669,7 +1880,6 @@ int au0828_analog_register(struct au0828_dev *dev,
1669 return -ENODEV; 1880 return -ENODEV;
1670 } 1881 }
1671 1882
1672#ifdef VBI_IS_WORKING
1673 /* Register the vbi device */ 1883 /* Register the vbi device */
1674 video_set_drvdata(dev->vbi_dev, dev); 1884 video_set_drvdata(dev->vbi_dev, dev);
1675 retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1); 1885 retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1);
@@ -1680,7 +1890,6 @@ int au0828_analog_register(struct au0828_dev *dev,
1680 video_device_release(dev->vdev); 1890 video_device_release(dev->vdev);
1681 return -ENODEV; 1891 return -ENODEV;
1682 } 1892 }
1683#endif
1684 1893
1685 dprintk(1, "%s completed!\n", __func__); 1894 dprintk(1, "%s completed!\n", __func__);
1686 1895
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h
index 207f32dec6a6..9905bc4f5f59 100644
--- a/drivers/media/video/au0828/au0828.h
+++ b/drivers/media/video/au0828/au0828.h
@@ -60,6 +60,10 @@
60 60
61#define AU0828_MAX_INPUT 4 61#define AU0828_MAX_INPUT 4
62 62
63/* au0828 resource types (used for res_get/res_lock etc */
64#define AU0828_RESOURCE_VIDEO 0x01
65#define AU0828_RESOURCE_VBI 0x02
66
63enum au0828_itype { 67enum au0828_itype {
64 AU0828_VMUX_UNDEFINED = 0, 68 AU0828_VMUX_UNDEFINED = 0,
65 AU0828_VMUX_COMPOSITE, 69 AU0828_VMUX_COMPOSITE,
@@ -115,8 +119,10 @@ enum au0828_dev_state {
115 119
116struct au0828_fh { 120struct au0828_fh {
117 struct au0828_dev *dev; 121 struct au0828_dev *dev;
118 unsigned int stream_on:1; /* Locks streams */ 122 unsigned int resources;
123
119 struct videobuf_queue vb_vidq; 124 struct videobuf_queue vb_vidq;
125 struct videobuf_queue vb_vbiq;
120 enum v4l2_buf_type type; 126 enum v4l2_buf_type type;
121}; 127};
122 128
@@ -145,7 +151,8 @@ struct au0828_usb_isoc_ctl {
145 int tmp_buf_len; 151 int tmp_buf_len;
146 152
147 /* Stores already requested buffers */ 153 /* Stores already requested buffers */
148 struct au0828_buffer *buf; 154 struct au0828_buffer *buf;
155 struct au0828_buffer *vbi_buf;
149 156
150 /* Stores the number of received fields */ 157 /* Stores the number of received fields */
151 int nfields; 158 int nfields;
@@ -194,11 +201,14 @@ struct au0828_dev {
194 /* Analog */ 201 /* Analog */
195 struct v4l2_device v4l2_dev; 202 struct v4l2_device v4l2_dev;
196 int users; 203 int users;
197 unsigned int stream_on:1; /* Locks streams */ 204 unsigned int resources; /* resources in use */
198 struct video_device *vdev; 205 struct video_device *vdev;
199 struct video_device *vbi_dev; 206 struct video_device *vbi_dev;
200 int width; 207 int width;
201 int height; 208 int height;
209 int vbi_width;
210 int vbi_height;
211 u32 vbi_read;
202 u32 field_size; 212 u32 field_size;
203 u32 frame_size; 213 u32 frame_size;
204 u32 bytesperline; 214 u32 bytesperline;
@@ -219,6 +229,7 @@ struct au0828_dev {
219 229
220 /* Isoc control struct */ 230 /* Isoc control struct */
221 struct au0828_dmaqueue vidq; 231 struct au0828_dmaqueue vidq;
232 struct au0828_dmaqueue vbiq;
222 struct au0828_usb_isoc_ctl isoc_ctl; 233 struct au0828_usb_isoc_ctl isoc_ctl;
223 spinlock_t slock; 234 spinlock_t slock;
224 235
@@ -278,6 +289,9 @@ void au0828_analog_unregister(struct au0828_dev *dev);
278extern int au0828_dvb_register(struct au0828_dev *dev); 289extern int au0828_dvb_register(struct au0828_dev *dev);
279extern void au0828_dvb_unregister(struct au0828_dev *dev); 290extern void au0828_dvb_unregister(struct au0828_dev *dev);
280 291
292/* au0828-vbi.c */
293extern struct videobuf_queue_ops au0828_vbi_qops;
294
281#define dprintk(level, fmt, arg...)\ 295#define dprintk(level, fmt, arg...)\
282 do { if (au0828_debug & level)\ 296 do { if (au0828_debug & level)\
283 printk(KERN_DEBUG DRIVER_NAME "/0: " fmt, ## arg);\ 297 printk(KERN_DEBUG DRIVER_NAME "/0: " fmt, ## arg);\