Skip to content

Commit

Permalink
V4L/DVB (13932): em28xx: add PAL support for VBI
Browse files Browse the repository at this point in the history
Make the VBI support work for PAL standards in addition to NTSC.

This work was sponsored by EyeMagnet Limited.

Thanks go out to Andy Walls for providing a CD containing test PAL/VBI captures
and to Steven Toth for providing a PVR-350 to do signal generation with.

Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Devin Heitmueller authored and Mauro Carvalho Chehab committed Feb 26, 2010
1 parent 6a20710 commit 66d9cba
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 31 deletions.
19 changes: 16 additions & 3 deletions drivers/media/video/em28xx/em28xx-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -691,9 +691,15 @@ int em28xx_set_outfmt(struct em28xx *dev)
if (em28xx_vbi_supported(dev) == 1) {
vinctrl |= EM28XX_VINCTRL_VBI_RAW;
em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00);
em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09);
em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, 0xb4);
em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, 0x0c);
em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, dev->vbi_width/4);
em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, dev->vbi_height);
if (dev->norm & V4L2_STD_525_60) {
/* NTSC */
em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09);
} else if (dev->norm & V4L2_STD_625_50) {
/* PAL */
em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x07);
}
}

return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl);
Expand Down Expand Up @@ -760,6 +766,13 @@ int em28xx_resolution_set(struct em28xx *dev)
width = norm_maxw(dev);
height = norm_maxh(dev);

/* Properly setup VBI */
dev->vbi_width = 720;
if (dev->norm & V4L2_STD_525_60)
dev->vbi_height = 12;
else
dev->vbi_height = 18;

if (!dev->progressive)
height >>= norm_maxh(dev);

Expand Down
17 changes: 10 additions & 7 deletions drivers/media/video/em28xx/em28xx-vbi.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf)
static int
vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
{
*size = 720 * 12 * 2;
struct em28xx_fh *fh = q->priv_data;
struct em28xx *dev = fh->dev;

*size = dev->vbi_width * dev->vbi_height * 2;

if (0 == *count)
*count = vbibufs;
if (*count < 2)
Expand All @@ -85,19 +89,18 @@ static int
vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
enum v4l2_field field)
{
struct em28xx_fh *fh = q->priv_data;
struct em28xx *dev = fh->dev;
struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
int rc = 0;
unsigned int size;

size = 720 * 12 * 2;

buf->vb.size = size;
buf->vb.size = dev->vbi_width * dev->vbi_height * 2;

if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
return -EINVAL;

buf->vb.width = 720;
buf->vb.height = 12;
buf->vb.width = dev->vbi_width;
buf->vb.height = dev->vbi_height;
buf->vb.field = field;

if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
Expand Down
58 changes: 38 additions & 20 deletions drivers/media/video/em28xx/em28xx-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ static void em28xx_copy_vbi(struct em28xx *dev,
{
void *startwrite, *startread;
int offset;
int bytesperline = 720;
int bytesperline = dev->vbi_width;

if (dev == NULL) {
em28xx_isocdbg("dev is null\n");
Expand Down Expand Up @@ -323,8 +323,8 @@ static void em28xx_copy_vbi(struct em28xx *dev,

/* Make sure the bottom field populates the second half of the frame */
if (buf->top_field == 0) {
startwrite += bytesperline * 0x0c;
offset += bytesperline * 0x0c;
startwrite += bytesperline * dev->vbi_height;
offset += bytesperline * dev->vbi_height;
}

memcpy(startwrite, startread, len);
Expand Down Expand Up @@ -578,8 +578,7 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
dev->cur_field = p[2];
}

/* FIXME: get rid of hard-coded value */
vbi_size = 720 * 0x0c;
vbi_size = dev->vbi_width * dev->vbi_height;

if (dev->capture_type == 0) {
if (dev->vbi_read >= vbi_size) {
Expand Down Expand Up @@ -1850,37 +1849,55 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
struct v4l2_format *format)
{
format->fmt.vbi.samples_per_line = 720;
struct em28xx_fh *fh = priv;
struct em28xx *dev = fh->dev;

format->fmt.vbi.samples_per_line = dev->vbi_width;
format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
format->fmt.vbi.offset = 0;
format->fmt.vbi.flags = 0;
format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
format->fmt.vbi.count[0] = dev->vbi_height;
format->fmt.vbi.count[1] = dev->vbi_height;

/* Varies by video standard (NTSC, PAL, etc.) */
/* FIXME: hard-coded for NTSC support */
format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */
format->fmt.vbi.count[0] = 12;
format->fmt.vbi.count[1] = 12;
format->fmt.vbi.start[0] = 10;
format->fmt.vbi.start[1] = 273;
if (dev->norm & V4L2_STD_525_60) {
/* NTSC */
format->fmt.vbi.start[0] = 10;
format->fmt.vbi.start[1] = 273;
} else if (dev->norm & V4L2_STD_625_50) {
/* PAL */
format->fmt.vbi.start[0] = 6;
format->fmt.vbi.start[1] = 318;
}

return 0;
}

static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv,
struct v4l2_format *format)
{
format->fmt.vbi.samples_per_line = 720;
struct em28xx_fh *fh = priv;
struct em28xx *dev = fh->dev;

format->fmt.vbi.samples_per_line = dev->vbi_width;
format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
format->fmt.vbi.offset = 0;
format->fmt.vbi.flags = 0;
format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
format->fmt.vbi.count[0] = dev->vbi_height;
format->fmt.vbi.count[1] = dev->vbi_height;

/* Varies by video standard (NTSC, PAL, etc.) */
/* FIXME: hard-coded for NTSC support */
format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */
format->fmt.vbi.count[0] = 12;
format->fmt.vbi.count[1] = 12;
format->fmt.vbi.start[0] = 10;
format->fmt.vbi.start[1] = 273;
if (dev->norm & V4L2_STD_525_60) {
/* NTSC */
format->fmt.vbi.start[0] = 10;
format->fmt.vbi.start[1] = 273;
} else if (dev->norm & V4L2_STD_625_50) {
/* PAL */
format->fmt.vbi.start[0] = 6;
format->fmt.vbi.start[1] = 318;
}

return 0;
}
Expand Down Expand Up @@ -1922,7 +1939,8 @@ static int vidioc_querybuf(struct file *file, void *priv,
At a minimum, it causes a crash in zvbi since it does
a memcpy based on the source buffer length */
int result = videobuf_querybuf(&fh->vb_vbiq, b);
b->length = 17280;
b->length = dev->vbi_width * dev->vbi_height * 2;

return result;
}
}
Expand Down
3 changes: 2 additions & 1 deletion drivers/media/video/em28xx/em28xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,8 @@ struct em28xx {
int capture_type;
int vbi_read;
unsigned char cur_field;

unsigned int vbi_width;
unsigned int vbi_height; /* lines per field */

struct work_struct request_module_wk;

Expand Down

0 comments on commit 66d9cba

Please sign in to comment.