diff options
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 19 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-vbi.c | 17 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 58 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 3 |
4 files changed, 66 insertions, 31 deletions
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index b311d4514bdf..5a37eccbd7d6 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -691,9 +691,15 @@ int em28xx_set_outfmt(struct em28xx *dev) | |||
691 | if (em28xx_vbi_supported(dev) == 1) { | 691 | if (em28xx_vbi_supported(dev) == 1) { |
692 | vinctrl |= EM28XX_VINCTRL_VBI_RAW; | 692 | vinctrl |= EM28XX_VINCTRL_VBI_RAW; |
693 | em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00); | 693 | em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00); |
694 | em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09); | 694 | em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, dev->vbi_width/4); |
695 | em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, 0xb4); | 695 | em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, dev->vbi_height); |
696 | em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, 0x0c); | 696 | if (dev->norm & V4L2_STD_525_60) { |
697 | /* NTSC */ | ||
698 | em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09); | ||
699 | } else if (dev->norm & V4L2_STD_625_50) { | ||
700 | /* PAL */ | ||
701 | em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x07); | ||
702 | } | ||
697 | } | 703 | } |
698 | 704 | ||
699 | return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl); | 705 | return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl); |
@@ -760,6 +766,13 @@ int em28xx_resolution_set(struct em28xx *dev) | |||
760 | width = norm_maxw(dev); | 766 | width = norm_maxw(dev); |
761 | height = norm_maxh(dev); | 767 | height = norm_maxh(dev); |
762 | 768 | ||
769 | /* Properly setup VBI */ | ||
770 | dev->vbi_width = 720; | ||
771 | if (dev->norm & V4L2_STD_525_60) | ||
772 | dev->vbi_height = 12; | ||
773 | else | ||
774 | dev->vbi_height = 18; | ||
775 | |||
763 | if (!dev->progressive) | 776 | if (!dev->progressive) |
764 | height >>= norm_maxh(dev); | 777 | height >>= norm_maxh(dev); |
765 | 778 | ||
diff --git a/drivers/media/video/em28xx/em28xx-vbi.c b/drivers/media/video/em28xx/em28xx-vbi.c index 94943e5a1529..c7dce39823d8 100644 --- a/drivers/media/video/em28xx/em28xx-vbi.c +++ b/drivers/media/video/em28xx/em28xx-vbi.c | |||
@@ -71,7 +71,11 @@ free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf) | |||
71 | static int | 71 | static int |
72 | vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) | 72 | vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) |
73 | { | 73 | { |
74 | *size = 720 * 12 * 2; | 74 | struct em28xx_fh *fh = q->priv_data; |
75 | struct em28xx *dev = fh->dev; | ||
76 | |||
77 | *size = dev->vbi_width * dev->vbi_height * 2; | ||
78 | |||
75 | if (0 == *count) | 79 | if (0 == *count) |
76 | *count = vbibufs; | 80 | *count = vbibufs; |
77 | if (*count < 2) | 81 | if (*count < 2) |
@@ -85,19 +89,18 @@ static int | |||
85 | vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | 89 | vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, |
86 | enum v4l2_field field) | 90 | enum v4l2_field field) |
87 | { | 91 | { |
92 | struct em28xx_fh *fh = q->priv_data; | ||
93 | struct em28xx *dev = fh->dev; | ||
88 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); | 94 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); |
89 | int rc = 0; | 95 | int rc = 0; |
90 | unsigned int size; | ||
91 | |||
92 | size = 720 * 12 * 2; | ||
93 | 96 | ||
94 | buf->vb.size = size; | 97 | buf->vb.size = dev->vbi_width * dev->vbi_height * 2; |
95 | 98 | ||
96 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | 99 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) |
97 | return -EINVAL; | 100 | return -EINVAL; |
98 | 101 | ||
99 | buf->vb.width = 720; | 102 | buf->vb.width = dev->vbi_width; |
100 | buf->vb.height = 12; | 103 | buf->vb.height = dev->vbi_height; |
101 | buf->vb.field = field; | 104 | buf->vb.field = field; |
102 | 105 | ||
103 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | 106 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 849b18c94037..ac2bd935927e 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -282,7 +282,7 @@ static void em28xx_copy_vbi(struct em28xx *dev, | |||
282 | { | 282 | { |
283 | void *startwrite, *startread; | 283 | void *startwrite, *startread; |
284 | int offset; | 284 | int offset; |
285 | int bytesperline = 720; | 285 | int bytesperline = dev->vbi_width; |
286 | 286 | ||
287 | if (dev == NULL) { | 287 | if (dev == NULL) { |
288 | em28xx_isocdbg("dev is null\n"); | 288 | em28xx_isocdbg("dev is null\n"); |
@@ -323,8 +323,8 @@ static void em28xx_copy_vbi(struct em28xx *dev, | |||
323 | 323 | ||
324 | /* Make sure the bottom field populates the second half of the frame */ | 324 | /* Make sure the bottom field populates the second half of the frame */ |
325 | if (buf->top_field == 0) { | 325 | if (buf->top_field == 0) { |
326 | startwrite += bytesperline * 0x0c; | 326 | startwrite += bytesperline * dev->vbi_height; |
327 | offset += bytesperline * 0x0c; | 327 | offset += bytesperline * dev->vbi_height; |
328 | } | 328 | } |
329 | 329 | ||
330 | memcpy(startwrite, startread, len); | 330 | memcpy(startwrite, startread, len); |
@@ -578,8 +578,7 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb) | |||
578 | dev->cur_field = p[2]; | 578 | dev->cur_field = p[2]; |
579 | } | 579 | } |
580 | 580 | ||
581 | /* FIXME: get rid of hard-coded value */ | 581 | vbi_size = dev->vbi_width * dev->vbi_height; |
582 | vbi_size = 720 * 0x0c; | ||
583 | 582 | ||
584 | if (dev->capture_type == 0) { | 583 | if (dev->capture_type == 0) { |
585 | if (dev->vbi_read >= vbi_size) { | 584 | if (dev->vbi_read >= vbi_size) { |
@@ -1850,18 +1849,27 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv, | |||
1850 | static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, | 1849 | static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, |
1851 | struct v4l2_format *format) | 1850 | struct v4l2_format *format) |
1852 | { | 1851 | { |
1853 | format->fmt.vbi.samples_per_line = 720; | 1852 | struct em28xx_fh *fh = priv; |
1853 | struct em28xx *dev = fh->dev; | ||
1854 | |||
1855 | format->fmt.vbi.samples_per_line = dev->vbi_width; | ||
1854 | format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | 1856 | format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; |
1855 | format->fmt.vbi.offset = 0; | 1857 | format->fmt.vbi.offset = 0; |
1856 | format->fmt.vbi.flags = 0; | 1858 | format->fmt.vbi.flags = 0; |
1859 | format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; | ||
1860 | format->fmt.vbi.count[0] = dev->vbi_height; | ||
1861 | format->fmt.vbi.count[1] = dev->vbi_height; | ||
1857 | 1862 | ||
1858 | /* Varies by video standard (NTSC, PAL, etc.) */ | 1863 | /* Varies by video standard (NTSC, PAL, etc.) */ |
1859 | /* FIXME: hard-coded for NTSC support */ | 1864 | if (dev->norm & V4L2_STD_525_60) { |
1860 | format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */ | 1865 | /* NTSC */ |
1861 | format->fmt.vbi.count[0] = 12; | 1866 | format->fmt.vbi.start[0] = 10; |
1862 | format->fmt.vbi.count[1] = 12; | 1867 | format->fmt.vbi.start[1] = 273; |
1863 | format->fmt.vbi.start[0] = 10; | 1868 | } else if (dev->norm & V4L2_STD_625_50) { |
1864 | format->fmt.vbi.start[1] = 273; | 1869 | /* PAL */ |
1870 | format->fmt.vbi.start[0] = 6; | ||
1871 | format->fmt.vbi.start[1] = 318; | ||
1872 | } | ||
1865 | 1873 | ||
1866 | return 0; | 1874 | return 0; |
1867 | } | 1875 | } |
@@ -1869,18 +1877,27 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, | |||
1869 | static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv, | 1877 | static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv, |
1870 | struct v4l2_format *format) | 1878 | struct v4l2_format *format) |
1871 | { | 1879 | { |
1872 | format->fmt.vbi.samples_per_line = 720; | 1880 | struct em28xx_fh *fh = priv; |
1881 | struct em28xx *dev = fh->dev; | ||
1882 | |||
1883 | format->fmt.vbi.samples_per_line = dev->vbi_width; | ||
1873 | format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | 1884 | format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; |
1874 | format->fmt.vbi.offset = 0; | 1885 | format->fmt.vbi.offset = 0; |
1875 | format->fmt.vbi.flags = 0; | 1886 | format->fmt.vbi.flags = 0; |
1887 | format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; | ||
1888 | format->fmt.vbi.count[0] = dev->vbi_height; | ||
1889 | format->fmt.vbi.count[1] = dev->vbi_height; | ||
1876 | 1890 | ||
1877 | /* Varies by video standard (NTSC, PAL, etc.) */ | 1891 | /* Varies by video standard (NTSC, PAL, etc.) */ |
1878 | /* FIXME: hard-coded for NTSC support */ | 1892 | if (dev->norm & V4L2_STD_525_60) { |
1879 | format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */ | 1893 | /* NTSC */ |
1880 | format->fmt.vbi.count[0] = 12; | 1894 | format->fmt.vbi.start[0] = 10; |
1881 | format->fmt.vbi.count[1] = 12; | 1895 | format->fmt.vbi.start[1] = 273; |
1882 | format->fmt.vbi.start[0] = 10; | 1896 | } else if (dev->norm & V4L2_STD_625_50) { |
1883 | format->fmt.vbi.start[1] = 273; | 1897 | /* PAL */ |
1898 | format->fmt.vbi.start[0] = 6; | ||
1899 | format->fmt.vbi.start[1] = 318; | ||
1900 | } | ||
1884 | 1901 | ||
1885 | return 0; | 1902 | return 0; |
1886 | } | 1903 | } |
@@ -1922,7 +1939,8 @@ static int vidioc_querybuf(struct file *file, void *priv, | |||
1922 | At a minimum, it causes a crash in zvbi since it does | 1939 | At a minimum, it causes a crash in zvbi since it does |
1923 | a memcpy based on the source buffer length */ | 1940 | a memcpy based on the source buffer length */ |
1924 | int result = videobuf_querybuf(&fh->vb_vbiq, b); | 1941 | int result = videobuf_querybuf(&fh->vb_vbiq, b); |
1925 | b->length = 17280; | 1942 | b->length = dev->vbi_width * dev->vbi_height * 2; |
1943 | |||
1926 | return result; | 1944 | return result; |
1927 | } | 1945 | } |
1928 | } | 1946 | } |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 80d9b4fa1b97..71e90dc66582 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -552,7 +552,8 @@ struct em28xx { | |||
552 | int capture_type; | 552 | int capture_type; |
553 | int vbi_read; | 553 | int vbi_read; |
554 | unsigned char cur_field; | 554 | unsigned char cur_field; |
555 | 555 | unsigned int vbi_width; | |
556 | unsigned int vbi_height; /* lines per field */ | ||
556 | 557 | ||
557 | struct work_struct request_module_wk; | 558 | struct work_struct request_module_wk; |
558 | 559 | ||