diff options
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-video.c')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 290 |
1 files changed, 266 insertions, 24 deletions
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 = { |