diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/em28xx/Makefile | 2 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-cards.c | 2 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 5 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-vbi.c | 150 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 290 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 8 |
6 files changed, 430 insertions, 27 deletions
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile index 8137a8c94bfc..d0f093d1d0df 100644 --- a/drivers/media/video/em28xx/Makefile +++ b/drivers/media/video/em28xx/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \ | 1 | em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \ |
2 | em28xx-input.o | 2 | em28xx-input.o em28xx-vbi.o |
3 | 3 | ||
4 | em28xx-alsa-objs := em28xx-audio.o | 4 | em28xx-alsa-objs := em28xx-audio.o |
5 | 5 | ||
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index cc807232b820..2479c6f86411 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -2590,6 +2590,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
2590 | /* init video dma queues */ | 2590 | /* init video dma queues */ |
2591 | INIT_LIST_HEAD(&dev->vidq.active); | 2591 | INIT_LIST_HEAD(&dev->vidq.active); |
2592 | INIT_LIST_HEAD(&dev->vidq.queued); | 2592 | INIT_LIST_HEAD(&dev->vidq.queued); |
2593 | INIT_LIST_HEAD(&dev->vbiq.active); | ||
2594 | INIT_LIST_HEAD(&dev->vbiq.queued); | ||
2593 | 2595 | ||
2594 | 2596 | ||
2595 | if (dev->board.has_msp34xx) { | 2597 | if (dev->board.has_msp34xx) { |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index d4107f6933f8..3128b7fce07d 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -964,6 +964,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets, | |||
964 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb)) | 964 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb)) |
965 | { | 965 | { |
966 | struct em28xx_dmaqueue *dma_q = &dev->vidq; | 966 | struct em28xx_dmaqueue *dma_q = &dev->vidq; |
967 | struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq; | ||
967 | int i; | 968 | int i; |
968 | int sb_size, pipe; | 969 | int sb_size, pipe; |
969 | struct urb *urb; | 970 | struct urb *urb; |
@@ -993,7 +994,8 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets, | |||
993 | } | 994 | } |
994 | 995 | ||
995 | dev->isoc_ctl.max_pkt_size = max_pkt_size; | 996 | dev->isoc_ctl.max_pkt_size = max_pkt_size; |
996 | dev->isoc_ctl.buf = NULL; | 997 | dev->isoc_ctl.vid_buf = NULL; |
998 | dev->isoc_ctl.vbi_buf = NULL; | ||
997 | 999 | ||
998 | sb_size = max_packets * dev->isoc_ctl.max_pkt_size; | 1000 | sb_size = max_packets * dev->isoc_ctl.max_pkt_size; |
999 | 1001 | ||
@@ -1043,6 +1045,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets, | |||
1043 | } | 1045 | } |
1044 | 1046 | ||
1045 | init_waitqueue_head(&dma_q->wq); | 1047 | init_waitqueue_head(&dma_q->wq); |
1048 | init_waitqueue_head(&vbi_dma_q->wq); | ||
1046 | 1049 | ||
1047 | em28xx_capture_start(dev, 1); | 1050 | em28xx_capture_start(dev, 1); |
1048 | 1051 | ||
diff --git a/drivers/media/video/em28xx/em28xx-vbi.c b/drivers/media/video/em28xx/em28xx-vbi.c new file mode 100644 index 000000000000..b5802d4cb623 --- /dev/null +++ b/drivers/media/video/em28xx/em28xx-vbi.c | |||
@@ -0,0 +1,150 @@ | |||
1 | /* | ||
2 | em28xx-vbi.c - VBI driver for em28xx | ||
3 | |||
4 | Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com> | ||
5 | |||
6 | This work was sponsored by EyeMagnet Limited. | ||
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 "em28xx.h" | ||
30 | |||
31 | static unsigned int vbibufs = 5; | ||
32 | module_param(vbibufs,int,0644); | ||
33 | MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32"); | ||
34 | |||
35 | static unsigned int vbi_debug; | ||
36 | module_param(vbi_debug,int,0644); | ||
37 | MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]"); | ||
38 | |||
39 | #define dprintk(level,fmt, arg...) if (vbi_debug >= level) \ | ||
40 | printk(KERN_DEBUG "%s: " fmt, dev->core->name , ## arg) | ||
41 | |||
42 | /* ------------------------------------------------------------------ */ | ||
43 | |||
44 | static void | ||
45 | free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf) | ||
46 | { | ||
47 | struct em28xx_fh *fh = vq->priv_data; | ||
48 | struct em28xx *dev = fh->dev; | ||
49 | unsigned long flags = 0; | ||
50 | if (in_interrupt()) | ||
51 | BUG(); | ||
52 | |||
53 | /* We used to wait for the buffer to finish here, but this didn't work | ||
54 | because, as we were keeping the state as VIDEOBUF_QUEUED, | ||
55 | videobuf_queue_cancel marked it as finished for us. | ||
56 | (Also, it could wedge forever if the hardware was misconfigured.) | ||
57 | |||
58 | This should be safe; by the time we get here, the buffer isn't | ||
59 | queued anymore. If we ever start marking the buffers as | ||
60 | VIDEOBUF_ACTIVE, it won't be, though. | ||
61 | */ | ||
62 | spin_lock_irqsave(&dev->slock, flags); | ||
63 | if (dev->isoc_ctl.vbi_buf == buf) | ||
64 | dev->isoc_ctl.vbi_buf = NULL; | ||
65 | spin_unlock_irqrestore(&dev->slock, flags); | ||
66 | |||
67 | videobuf_vmalloc_free(&buf->vb); | ||
68 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | ||
69 | } | ||
70 | |||
71 | static int | ||
72 | vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) | ||
73 | { | ||
74 | *size = 720 * 12 * 2; | ||
75 | if (0 == *count) | ||
76 | *count = vbibufs; | ||
77 | if (*count < 2) | ||
78 | *count = 2; | ||
79 | if (*count > 32) | ||
80 | *count = 32; | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | static int | ||
85 | vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | ||
86 | enum v4l2_field field) | ||
87 | { | ||
88 | struct em28xx_fh *fh = q->priv_data; | ||
89 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); | ||
90 | int rc = 0; | ||
91 | unsigned int size; | ||
92 | |||
93 | size = 720 * 12 * 2; | ||
94 | |||
95 | buf->vb.size = size; | ||
96 | |||
97 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | ||
98 | return -EINVAL; | ||
99 | |||
100 | buf->vb.width = 720; | ||
101 | buf->vb.height = 12; | ||
102 | buf->vb.field = field; | ||
103 | |||
104 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | ||
105 | rc = videobuf_iolock(q, &buf->vb, NULL); | ||
106 | if (rc < 0) | ||
107 | goto fail; | ||
108 | } | ||
109 | |||
110 | buf->vb.state = VIDEOBUF_PREPARED; | ||
111 | return 0; | ||
112 | |||
113 | fail: | ||
114 | free_buffer(q, buf); | ||
115 | return rc; | ||
116 | } | ||
117 | |||
118 | static void | ||
119 | vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | ||
120 | { | ||
121 | struct em28xx_buffer *buf = container_of(vb, | ||
122 | struct em28xx_buffer, | ||
123 | vb); | ||
124 | struct em28xx_fh *fh = vq->priv_data; | ||
125 | struct em28xx *dev = fh->dev; | ||
126 | struct em28xx_dmaqueue *vbiq = &dev->vbiq; | ||
127 | |||
128 | buf->vb.state = VIDEOBUF_QUEUED; | ||
129 | list_add_tail(&buf->vb.queue, &vbiq->active); | ||
130 | } | ||
131 | |||
132 | static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | ||
133 | { | ||
134 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); | ||
135 | free_buffer(q, buf); | ||
136 | } | ||
137 | |||
138 | struct videobuf_queue_ops em28xx_vbi_qops = { | ||
139 | .buf_setup = vbi_setup, | ||
140 | .buf_prepare = vbi_prepare, | ||
141 | .buf_queue = vbi_queue, | ||
142 | .buf_release = vbi_release, | ||
143 | }; | ||
144 | |||
145 | /* ------------------------------------------------------------------ */ | ||
146 | /* | ||
147 | * Local variables: | ||
148 | * c-basic-offset: 8 | ||
149 | * End: | ||
150 | */ | ||
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 04c9ecc3c22a..7022f7ba61bb 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -163,7 +163,24 @@ static inline void buffer_filled(struct em28xx *dev, | |||
163 | buf->vb.field_count++; | 163 | buf->vb.field_count++; |
164 | do_gettimeofday(&buf->vb.ts); | 164 | do_gettimeofday(&buf->vb.ts); |
165 | 165 | ||
166 | dev->isoc_ctl.buf = NULL; | 166 | dev->isoc_ctl.vid_buf = NULL; |
167 | |||
168 | list_del(&buf->vb.queue); | ||
169 | wake_up(&buf->vb.done); | ||
170 | } | ||
171 | |||
172 | static inline void vbi_buffer_filled(struct em28xx *dev, | ||
173 | struct em28xx_dmaqueue *dma_q, | ||
174 | struct em28xx_buffer *buf) | ||
175 | { | ||
176 | /* Advice that buffer was filled */ | ||
177 | em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i); | ||
178 | |||
179 | buf->vb.state = VIDEOBUF_DONE; | ||
180 | buf->vb.field_count++; | ||
181 | do_gettimeofday(&buf->vb.ts); | ||
182 | |||
183 | dev->isoc_ctl.vbi_buf = NULL; | ||
167 | 184 | ||
168 | list_del(&buf->vb.queue); | 185 | list_del(&buf->vb.queue); |
169 | wake_up(&buf->vb.done); | 186 | wake_up(&buf->vb.done); |
@@ -256,6 +273,63 @@ static void em28xx_copy_video(struct em28xx *dev, | |||
256 | dma_q->pos += len; | 273 | dma_q->pos += len; |
257 | } | 274 | } |
258 | 275 | ||
276 | static void em28xx_copy_vbi(struct em28xx *dev, | ||
277 | struct em28xx_dmaqueue *dma_q, | ||
278 | struct em28xx_buffer *buf, | ||
279 | unsigned char *p, | ||
280 | unsigned char *outp, unsigned long len) | ||
281 | { | ||
282 | void *startwrite, *startread; | ||
283 | int offset; | ||
284 | int bytesperline = 720; | ||
285 | |||
286 | if (dev == NULL) { | ||
287 | printk("dev is null\n"); | ||
288 | return; | ||
289 | } | ||
290 | |||
291 | if (dma_q == NULL) { | ||
292 | printk("dma_q is null\n"); | ||
293 | return; | ||
294 | } | ||
295 | if (buf == NULL) { | ||
296 | return; | ||
297 | } | ||
298 | if (p == NULL) { | ||
299 | printk("p is null\n"); | ||
300 | return; | ||
301 | } | ||
302 | if (outp == NULL) { | ||
303 | printk("outp is null\n"); | ||
304 | return; | ||
305 | } | ||
306 | |||
307 | if (dma_q->pos + len > buf->vb.size) | ||
308 | len = buf->vb.size - dma_q->pos; | ||
309 | |||
310 | if ((p[0] == 0x33 && p[1] == 0x95) || | ||
311 | (p[0] == 0x88 && p[1] == 0x88)) { | ||
312 | /* Header field, advance past it */ | ||
313 | p += 4; | ||
314 | } else { | ||
315 | len += 4; | ||
316 | } | ||
317 | |||
318 | startread = p; | ||
319 | |||
320 | startwrite = outp + dma_q->pos; | ||
321 | offset = dma_q->pos; | ||
322 | |||
323 | /* Make sure the bottom field populates the second half of the frame */ | ||
324 | if (buf->top_field == 0) { | ||
325 | startwrite += bytesperline * 0x0c; | ||
326 | offset += bytesperline * 0x0c; | ||
327 | } | ||
328 | |||
329 | memcpy(startwrite, startread, len); | ||
330 | dma_q->pos += len; | ||
331 | } | ||
332 | |||
259 | static inline void print_err_status(struct em28xx *dev, | 333 | static inline void print_err_status(struct em28xx *dev, |
260 | int packet, int status) | 334 | int packet, int status) |
261 | { | 335 | { |
@@ -306,7 +380,7 @@ static inline void get_next_buf(struct em28xx_dmaqueue *dma_q, | |||
306 | 380 | ||
307 | if (list_empty(&dma_q->active)) { | 381 | if (list_empty(&dma_q->active)) { |
308 | em28xx_isocdbg("No active queue to serve\n"); | 382 | em28xx_isocdbg("No active queue to serve\n"); |
309 | dev->isoc_ctl.buf = NULL; | 383 | dev->isoc_ctl.vid_buf = NULL; |
310 | *buf = NULL; | 384 | *buf = NULL; |
311 | return; | 385 | return; |
312 | } | 386 | } |
@@ -318,7 +392,34 @@ static inline void get_next_buf(struct em28xx_dmaqueue *dma_q, | |||
318 | outp = videobuf_to_vmalloc(&(*buf)->vb); | 392 | outp = videobuf_to_vmalloc(&(*buf)->vb); |
319 | memset(outp, 0, (*buf)->vb.size); | 393 | memset(outp, 0, (*buf)->vb.size); |
320 | 394 | ||
321 | dev->isoc_ctl.buf = *buf; | 395 | dev->isoc_ctl.vid_buf = *buf; |
396 | |||
397 | return; | ||
398 | } | ||
399 | |||
400 | /* | ||
401 | * video-buf generic routine to get the next available VBI buffer | ||
402 | */ | ||
403 | static inline void vbi_get_next_buf(struct em28xx_dmaqueue *dma_q, | ||
404 | struct em28xx_buffer **buf) | ||
405 | { | ||
406 | struct em28xx *dev = container_of(dma_q, struct em28xx, vbiq); | ||
407 | char *outp; | ||
408 | |||
409 | if (list_empty(&dma_q->active)) { | ||
410 | em28xx_isocdbg("No active queue to serve\n"); | ||
411 | dev->isoc_ctl.vbi_buf = NULL; | ||
412 | *buf = NULL; | ||
413 | return; | ||
414 | } | ||
415 | |||
416 | /* Get the next buffer */ | ||
417 | *buf = list_entry(dma_q->active.next, struct em28xx_buffer, vb.queue); | ||
418 | /* Cleans up buffer - Usefull for testing for frame/URB loss */ | ||
419 | outp = videobuf_to_vmalloc(&(*buf)->vb); | ||
420 | memset(outp, 0x00, (*buf)->vb.size); | ||
421 | |||
422 | dev->isoc_ctl.vbi_buf = *buf; | ||
322 | 423 | ||
323 | return; | 424 | return; |
324 | } | 425 | } |
@@ -346,7 +447,7 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb) | |||
346 | return 0; | 447 | return 0; |
347 | } | 448 | } |
348 | 449 | ||
349 | buf = dev->isoc_ctl.buf; | 450 | buf = dev->isoc_ctl.vid_buf; |
350 | if (buf != NULL) | 451 | if (buf != NULL) |
351 | outp = videobuf_to_vmalloc(&buf->vb); | 452 | outp = videobuf_to_vmalloc(&buf->vb); |
352 | 453 | ||
@@ -416,6 +517,7 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb) | |||
416 | { | 517 | { |
417 | struct em28xx_buffer *buf, *vbi_buf; | 518 | struct em28xx_buffer *buf, *vbi_buf; |
418 | struct em28xx_dmaqueue *dma_q = &dev->vidq; | 519 | struct em28xx_dmaqueue *dma_q = &dev->vidq; |
520 | struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq; | ||
419 | unsigned char *outp = NULL; | 521 | unsigned char *outp = NULL; |
420 | unsigned char *vbioutp = NULL; | 522 | unsigned char *vbioutp = NULL; |
421 | int i, len = 0, rc = 1; | 523 | int i, len = 0, rc = 1; |
@@ -434,9 +536,14 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb) | |||
434 | return 0; | 536 | return 0; |
435 | } | 537 | } |
436 | 538 | ||
437 | buf = dev->isoc_ctl.buf; | 539 | buf = dev->isoc_ctl.vid_buf; |
438 | if (buf != NULL) | 540 | if (buf != NULL) |
439 | outp = videobuf_to_vmalloc(&buf->vb); | 541 | outp = videobuf_to_vmalloc(&buf->vb); |
542 | |||
543 | vbi_buf = dev->isoc_ctl.vbi_buf; | ||
544 | if (vbi_buf != NULL) | ||
545 | vbioutp = videobuf_to_vmalloc(&vbi_buf->vb); | ||
546 | |||
440 | for (i = 0; i < urb->number_of_packets; i++) { | 547 | for (i = 0; i < urb->number_of_packets; i++) { |
441 | int status = urb->iso_frame_desc[i].status; | 548 | int status = urb->iso_frame_desc[i].status; |
442 | 549 | ||
@@ -480,12 +587,41 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb) | |||
480 | printk("djh c should never happen\n"); | 587 | printk("djh c should never happen\n"); |
481 | } else if ((dev->vbi_read + len) < vbi_size) { | 588 | } else if ((dev->vbi_read + len) < vbi_size) { |
482 | /* This entire frame is VBI data */ | 589 | /* This entire frame is VBI data */ |
590 | if (dev->vbi_read == 0 && | ||
591 | (!(dev->cur_field & 1))) { | ||
592 | /* Brand new frame */ | ||
593 | if (vbi_buf != NULL) | ||
594 | vbi_buffer_filled(dev, | ||
595 | vbi_dma_q, | ||
596 | vbi_buf); | ||
597 | vbi_get_next_buf(vbi_dma_q, &vbi_buf); | ||
598 | if (vbi_buf == NULL) | ||
599 | vbioutp = NULL; | ||
600 | else { | ||
601 | vbioutp = videobuf_to_vmalloc(&vbi_buf->vb); | ||
602 | } | ||
603 | } | ||
604 | |||
605 | if (dev->vbi_read == 0) { | ||
606 | vbi_dma_q->pos = 0; | ||
607 | if (vbi_buf != NULL) { | ||
608 | if (dev->cur_field & 1) | ||
609 | vbi_buf->top_field = 0; | ||
610 | else | ||
611 | vbi_buf->top_field = 1; | ||
612 | } | ||
613 | } | ||
614 | |||
483 | dev->vbi_read += len; | 615 | dev->vbi_read += len; |
616 | em28xx_copy_vbi(dev, vbi_dma_q, vbi_buf, p, | ||
617 | vbioutp, len); | ||
484 | } else { | 618 | } else { |
485 | /* Some of this frame is VBI data and some is | 619 | /* Some of this frame is VBI data and some is |
486 | video data */ | 620 | video data */ |
487 | int vbi_data_len = vbi_size - dev->vbi_read; | 621 | int vbi_data_len = vbi_size - dev->vbi_read; |
488 | dev->vbi_read += vbi_data_len; | 622 | dev->vbi_read += vbi_data_len; |
623 | em28xx_copy_vbi(dev, vbi_dma_q, vbi_buf, p, | ||
624 | vbioutp, vbi_data_len); | ||
489 | dev->capture_type = 1; | 625 | dev->capture_type = 1; |
490 | p += vbi_data_len; | 626 | p += vbi_data_len; |
491 | len -= vbi_data_len; | 627 | len -= vbi_data_len; |
@@ -570,8 +706,8 @@ static void free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf) | |||
570 | VIDEOBUF_ACTIVE, it won't be, though. | 706 | VIDEOBUF_ACTIVE, it won't be, though. |
571 | */ | 707 | */ |
572 | spin_lock_irqsave(&dev->slock, flags); | 708 | spin_lock_irqsave(&dev->slock, flags); |
573 | if (dev->isoc_ctl.buf == buf) | 709 | if (dev->isoc_ctl.vid_buf == buf) |
574 | dev->isoc_ctl.buf = NULL; | 710 | dev->isoc_ctl.vid_buf = NULL; |
575 | spin_unlock_irqrestore(&dev->slock, flags); | 711 | spin_unlock_irqrestore(&dev->slock, flags); |
576 | 712 | ||
577 | videobuf_vmalloc_free(&buf->vb); | 713 | videobuf_vmalloc_free(&buf->vb); |
@@ -1542,8 +1678,12 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
1542 | mutex_lock(&dev->lock); | 1678 | mutex_lock(&dev->lock); |
1543 | rc = res_get(fh); | 1679 | rc = res_get(fh); |
1544 | 1680 | ||
1545 | if (likely(rc >= 0)) | 1681 | if (likely(rc >= 0)) { |
1546 | rc = videobuf_streamon(&fh->vb_vidq); | 1682 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1683 | rc = videobuf_streamon(&fh->vb_vidq); | ||
1684 | else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) | ||
1685 | rc = videobuf_streamon(&fh->vb_vbiq); | ||
1686 | } | ||
1547 | 1687 | ||
1548 | mutex_unlock(&dev->lock); | 1688 | mutex_unlock(&dev->lock); |
1549 | 1689 | ||
@@ -1561,14 +1701,19 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
1561 | if (rc < 0) | 1701 | if (rc < 0) |
1562 | return rc; | 1702 | return rc; |
1563 | 1703 | ||
1564 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1704 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && |
1705 | fh->type != V4L2_BUF_TYPE_VBI_CAPTURE) | ||
1565 | return -EINVAL; | 1706 | return -EINVAL; |
1566 | if (type != fh->type) | 1707 | if (type != fh->type) |
1567 | return -EINVAL; | 1708 | return -EINVAL; |
1568 | 1709 | ||
1569 | mutex_lock(&dev->lock); | 1710 | mutex_lock(&dev->lock); |
1570 | 1711 | ||
1571 | videobuf_streamoff(&fh->vb_vidq); | 1712 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1713 | videobuf_streamoff(&fh->vb_vidq); | ||
1714 | else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) | ||
1715 | videobuf_streamoff(&fh->vb_vbiq); | ||
1716 | |||
1572 | res_free(fh); | 1717 | res_free(fh); |
1573 | 1718 | ||
1574 | mutex_unlock(&dev->lock); | 1719 | mutex_unlock(&dev->lock); |
@@ -1589,6 +1734,7 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
1589 | cap->version = EM28XX_VERSION_CODE; | 1734 | cap->version = EM28XX_VERSION_CODE; |
1590 | 1735 | ||
1591 | cap->capabilities = | 1736 | cap->capabilities = |
1737 | V4L2_CAP_VBI_CAPTURE | | ||
1592 | V4L2_CAP_SLICED_VBI_CAPTURE | | 1738 | V4L2_CAP_SLICED_VBI_CAPTURE | |
1593 | V4L2_CAP_VIDEO_CAPTURE | | 1739 | V4L2_CAP_VIDEO_CAPTURE | |
1594 | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; | 1740 | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; |
@@ -1660,6 +1806,45 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv, | |||
1660 | return 0; | 1806 | return 0; |
1661 | } | 1807 | } |
1662 | 1808 | ||
1809 | /* RAW VBI ioctls */ | ||
1810 | |||
1811 | static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, | ||
1812 | struct v4l2_format *format) | ||
1813 | { | ||
1814 | format->fmt.vbi.samples_per_line = 720; | ||
1815 | format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | ||
1816 | format->fmt.vbi.offset = 0; | ||
1817 | format->fmt.vbi.flags = 0; | ||
1818 | |||
1819 | /* Varies by video standard (NTSC, PAL, etc.) */ | ||
1820 | /* FIXME: hard-coded for NTSC support */ | ||
1821 | format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */ | ||
1822 | format->fmt.vbi.count[0] = 12; | ||
1823 | format->fmt.vbi.count[1] = 12; | ||
1824 | format->fmt.vbi.start[0] = 10; | ||
1825 | format->fmt.vbi.start[1] = 273; | ||
1826 | |||
1827 | return 0; | ||
1828 | } | ||
1829 | |||
1830 | static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv, | ||
1831 | struct v4l2_format *format) | ||
1832 | { | ||
1833 | format->fmt.vbi.samples_per_line = 720; | ||
1834 | format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | ||
1835 | format->fmt.vbi.offset = 0; | ||
1836 | format->fmt.vbi.flags = 0; | ||
1837 | |||
1838 | /* Varies by video standard (NTSC, PAL, etc.) */ | ||
1839 | /* FIXME: hard-coded for NTSC support */ | ||
1840 | format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */ | ||
1841 | format->fmt.vbi.count[0] = 12; | ||
1842 | format->fmt.vbi.count[1] = 12; | ||
1843 | format->fmt.vbi.start[0] = 10; | ||
1844 | format->fmt.vbi.start[1] = 273; | ||
1845 | |||
1846 | return 0; | ||
1847 | } | ||
1663 | 1848 | ||
1664 | static int vidioc_reqbufs(struct file *file, void *priv, | 1849 | static int vidioc_reqbufs(struct file *file, void *priv, |
1665 | struct v4l2_requestbuffers *rb) | 1850 | struct v4l2_requestbuffers *rb) |
@@ -1672,7 +1857,10 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
1672 | if (rc < 0) | 1857 | if (rc < 0) |
1673 | return rc; | 1858 | return rc; |
1674 | 1859 | ||
1675 | return videobuf_reqbufs(&fh->vb_vidq, rb); | 1860 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1861 | return videobuf_reqbufs(&fh->vb_vidq, rb); | ||
1862 | else | ||
1863 | return videobuf_reqbufs(&fh->vb_vbiq, rb); | ||
1676 | } | 1864 | } |
1677 | 1865 | ||
1678 | static int vidioc_querybuf(struct file *file, void *priv, | 1866 | static int vidioc_querybuf(struct file *file, void *priv, |
@@ -1686,7 +1874,18 @@ static int vidioc_querybuf(struct file *file, void *priv, | |||
1686 | if (rc < 0) | 1874 | if (rc < 0) |
1687 | return rc; | 1875 | return rc; |
1688 | 1876 | ||
1689 | return videobuf_querybuf(&fh->vb_vidq, b); | 1877 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1878 | return videobuf_querybuf(&fh->vb_vidq, b); | ||
1879 | else { | ||
1880 | /* FIXME: I'm not sure yet whether this is a bug in zvbi or | ||
1881 | the videobuf framework, but we probably shouldn't be | ||
1882 | returning a buffer larger than that which was asked for. | ||
1883 | At a minimum, it causes a crash in zvbi since it does | ||
1884 | a memcpy based on the source buffer length */ | ||
1885 | int result = videobuf_querybuf(&fh->vb_vbiq, b); | ||
1886 | b->length = 17280; | ||
1887 | return result; | ||
1888 | } | ||
1690 | } | 1889 | } |
1691 | 1890 | ||
1692 | static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) | 1891 | static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) |
@@ -1699,7 +1898,11 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) | |||
1699 | if (rc < 0) | 1898 | if (rc < 0) |
1700 | return rc; | 1899 | return rc; |
1701 | 1900 | ||
1702 | return videobuf_qbuf(&fh->vb_vidq, b); | 1901 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1902 | return videobuf_qbuf(&fh->vb_vidq, b); | ||
1903 | else { | ||
1904 | return videobuf_qbuf(&fh->vb_vbiq, b); | ||
1905 | } | ||
1703 | } | 1906 | } |
1704 | 1907 | ||
1705 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) | 1908 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) |
@@ -1712,7 +1915,12 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) | |||
1712 | if (rc < 0) | 1915 | if (rc < 0) |
1713 | return rc; | 1916 | return rc; |
1714 | 1917 | ||
1715 | return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK); | 1918 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1919 | return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & | ||
1920 | O_NONBLOCK); | ||
1921 | else | ||
1922 | return videobuf_dqbuf(&fh->vb_vbiq, b, file->f_flags & | ||
1923 | O_NONBLOCK); | ||
1716 | } | 1924 | } |
1717 | 1925 | ||
1718 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1926 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
@@ -1720,7 +1928,10 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) | |||
1720 | { | 1928 | { |
1721 | struct em28xx_fh *fh = priv; | 1929 | struct em28xx_fh *fh = priv; |
1722 | 1930 | ||
1723 | return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); | 1931 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1932 | return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); | ||
1933 | else | ||
1934 | return videobuf_cgmbuf(&fh->vb_vbiq, mbuf, 8); | ||
1724 | } | 1935 | } |
1725 | #endif | 1936 | #endif |
1726 | 1937 | ||
@@ -1884,9 +2095,17 @@ static int em28xx_v4l2_open(struct file *filp) | |||
1884 | else | 2095 | else |
1885 | field = V4L2_FIELD_INTERLACED; | 2096 | field = V4L2_FIELD_INTERLACED; |
1886 | 2097 | ||
1887 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops, | 2098 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1888 | NULL, &dev->slock, fh->type, field, | 2099 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops, |
1889 | sizeof(struct em28xx_buffer), fh); | 2100 | NULL, &dev->slock, fh->type, field, |
2101 | sizeof(struct em28xx_buffer), fh); | ||
2102 | |||
2103 | if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) | ||
2104 | videobuf_queue_vmalloc_init(&fh->vb_vbiq, &em28xx_vbi_qops, | ||
2105 | NULL, &dev->slock, | ||
2106 | V4L2_BUF_TYPE_VBI_CAPTURE, | ||
2107 | V4L2_FIELD_SEQ_TB, | ||
2108 | sizeof(struct em28xx_buffer), fh); | ||
1890 | 2109 | ||
1891 | mutex_unlock(&dev->lock); | 2110 | mutex_unlock(&dev->lock); |
1892 | 2111 | ||
@@ -1948,7 +2167,7 @@ static int em28xx_v4l2_close(struct file *filp) | |||
1948 | if (res_check(fh)) | 2167 | if (res_check(fh)) |
1949 | res_free(fh); | 2168 | res_free(fh); |
1950 | 2169 | ||
1951 | if (dev->users == 1) { | 2170 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 1) { |
1952 | videobuf_stop(&fh->vb_vidq); | 2171 | videobuf_stop(&fh->vb_vidq); |
1953 | videobuf_mmap_free(&fh->vb_vidq); | 2172 | videobuf_mmap_free(&fh->vb_vidq); |
1954 | 2173 | ||
@@ -1977,6 +2196,12 @@ static int em28xx_v4l2_close(struct file *filp) | |||
1977 | "0 (error=%i)\n", errCode); | 2196 | "0 (error=%i)\n", errCode); |
1978 | } | 2197 | } |
1979 | } | 2198 | } |
2199 | |||
2200 | if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | ||
2201 | videobuf_stop(&fh->vb_vbiq); | ||
2202 | videobuf_mmap_free(&fh->vb_vbiq); | ||
2203 | } | ||
2204 | |||
1980 | kfree(fh); | 2205 | kfree(fh); |
1981 | dev->users--; | 2206 | dev->users--; |
1982 | wake_up_interruptible_nr(&dev->open, 1); | 2207 | wake_up_interruptible_nr(&dev->open, 1); |
@@ -2015,6 +2240,17 @@ em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count, | |||
2015 | return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0, | 2240 | return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0, |
2016 | filp->f_flags & O_NONBLOCK); | 2241 | filp->f_flags & O_NONBLOCK); |
2017 | } | 2242 | } |
2243 | |||
2244 | |||
2245 | if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | ||
2246 | mutex_lock(&dev->lock); | ||
2247 | rc = res_get(fh); | ||
2248 | mutex_unlock(&dev->lock); | ||
2249 | |||
2250 | return videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0, | ||
2251 | filp->f_flags & O_NONBLOCK); | ||
2252 | } | ||
2253 | |||
2018 | return 0; | 2254 | return 0; |
2019 | } | 2255 | } |
2020 | 2256 | ||
@@ -2039,10 +2275,12 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait) | |||
2039 | if (unlikely(rc < 0)) | 2275 | if (unlikely(rc < 0)) |
2040 | return POLLERR; | 2276 | return POLLERR; |
2041 | 2277 | ||
2042 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) | 2278 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
2279 | return videobuf_poll_stream(filp, &fh->vb_vidq, wait); | ||
2280 | else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) | ||
2281 | return videobuf_poll_stream(filp, &fh->vb_vbiq, wait); | ||
2282 | else | ||
2043 | return POLLERR; | 2283 | return POLLERR; |
2044 | |||
2045 | return videobuf_poll_stream(filp, &fh->vb_vidq, wait); | ||
2046 | } | 2284 | } |
2047 | 2285 | ||
2048 | /* | 2286 | /* |
@@ -2091,6 +2329,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
2091 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, | 2329 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, |
2092 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, | 2330 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, |
2093 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, | 2331 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, |
2332 | .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, | ||
2333 | .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap, | ||
2094 | .vidioc_g_audio = vidioc_g_audio, | 2334 | .vidioc_g_audio = vidioc_g_audio, |
2095 | .vidioc_s_audio = vidioc_s_audio, | 2335 | .vidioc_s_audio = vidioc_s_audio, |
2096 | .vidioc_cropcap = vidioc_cropcap, | 2336 | .vidioc_cropcap = vidioc_cropcap, |
@@ -2136,7 +2376,9 @@ static const struct video_device em28xx_video_template = { | |||
2136 | .minor = -1, | 2376 | .minor = -1, |
2137 | 2377 | ||
2138 | .tvnorms = V4L2_STD_ALL, | 2378 | .tvnorms = V4L2_STD_ALL, |
2139 | .current_norm = V4L2_STD_PAL, | 2379 | /* FIXME: we need this to be NTSC for VBI to work - it should |
2380 | be moved to a per-board definition */ | ||
2381 | .current_norm = V4L2_STD_NTSC, | ||
2140 | }; | 2382 | }; |
2141 | 2383 | ||
2142 | static const struct v4l2_file_operations radio_fops = { | 2384 | static const struct v4l2_file_operations radio_fops = { |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 1656d2cf34a9..8dac50b9c00b 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -214,7 +214,8 @@ struct em28xx_usb_isoc_ctl { | |||
214 | int tmp_buf_len; | 214 | int tmp_buf_len; |
215 | 215 | ||
216 | /* Stores already requested buffers */ | 216 | /* Stores already requested buffers */ |
217 | struct em28xx_buffer *buf; | 217 | struct em28xx_buffer *vid_buf; |
218 | struct em28xx_buffer *vbi_buf; | ||
218 | 219 | ||
219 | /* Stores the number of received fields */ | 220 | /* Stores the number of received fields */ |
220 | int nfields; | 221 | int nfields; |
@@ -467,6 +468,7 @@ struct em28xx_fh { | |||
467 | int radio; | 468 | int radio; |
468 | 469 | ||
469 | struct videobuf_queue vb_vidq; | 470 | struct videobuf_queue vb_vidq; |
471 | struct videobuf_queue vb_vbiq; | ||
470 | 472 | ||
471 | enum v4l2_buf_type type; | 473 | enum v4l2_buf_type type; |
472 | }; | 474 | }; |
@@ -565,6 +567,7 @@ struct em28xx { | |||
565 | 567 | ||
566 | /* Isoc control struct */ | 568 | /* Isoc control struct */ |
567 | struct em28xx_dmaqueue vidq; | 569 | struct em28xx_dmaqueue vidq; |
570 | struct em28xx_dmaqueue vbiq; | ||
568 | struct em28xx_usb_isoc_ctl isoc_ctl; | 571 | struct em28xx_usb_isoc_ctl isoc_ctl; |
569 | spinlock_t slock; | 572 | spinlock_t slock; |
570 | 573 | ||
@@ -693,6 +696,9 @@ void em28xx_deregister_snapshot_button(struct em28xx *dev); | |||
693 | int em28xx_ir_init(struct em28xx *dev); | 696 | int em28xx_ir_init(struct em28xx *dev); |
694 | int em28xx_ir_fini(struct em28xx *dev); | 697 | int em28xx_ir_fini(struct em28xx *dev); |
695 | 698 | ||
699 | /* Provided by em28xx-vbi.c */ | ||
700 | extern struct videobuf_queue_ops em28xx_vbi_qops; | ||
701 | |||
696 | /* printk macros */ | 702 | /* printk macros */ |
697 | 703 | ||
698 | #define em28xx_err(fmt, arg...) do {\ | 704 | #define em28xx_err(fmt, arg...) do {\ |