]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
V4L/DVB (9162): ivtv: fix raw/sliced VBI mixup
authorHans Verkuil <hverkuil@xs4all.nl>
Sat, 4 Oct 2008 11:05:30 +0000 (08:05 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 13 Oct 2008 11:08:01 +0000 (09:08 -0200)
The service_set field was used in saa7115 and cx25840 to determine
whether raw or sliced VBI was desired. This is incorrect since it is
perfectly valid to select sliced VBI with a service_set of 0.

Instead these drivers should checked on VIDIOC_S_FMT whether the type
field matches the raw or sliced VBI type.

Updated ivtv accordingly.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/cx25840/cx25840-vbi.c
drivers/media/video/ivtv/ivtv-driver.c
drivers/media/video/ivtv/ivtv-driver.h
drivers/media/video/ivtv/ivtv-fileops.c
drivers/media/video/ivtv/ivtv-ioctl.c
drivers/media/video/ivtv/ivtv-streams.c
drivers/media/video/ivtv/ivtv-vbi.c
drivers/media/video/saa7115.c

index 69f2bbdbb929b1a9c41dad93cdfa97caca0d9122..58e6ef1c28a093d849b88f7111f5120a27b9b6aa 100644 (file)
@@ -141,10 +141,11 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
                u8 lcr[24];
 
                fmt = arg;
-               if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+               if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
+                   fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
                        return -EINVAL;
                svbi = &fmt->fmt.sliced;
-               if (svbi->service_set == 0) {
+               if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
                        /* raw VBI */
                        memset(svbi, 0, sizeof(*svbi));
 
index 7aa61b617496dbc6270feb753908c7d9667243b6..aeaa13f6cb3639edda26bbc3178e4105fcdb283b 100644 (file)
@@ -720,7 +720,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
        itv->speed = 1000;
 
        /* VBI */
-       itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+       itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
        itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced;
 
        /* Init the sg table for osd/yuv output */
index b76a1226863703d1d7934fac63ccadbfe653d490..be2d779dba124cc126b7f3eb555bbb51dc0ccb8d 100644 (file)
@@ -750,6 +750,12 @@ void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv);
 /* First-open initialization: load firmware, init cx25840, etc. */
 int ivtv_init_on_first_open(struct ivtv *itv);
 
+/* Test if the current VBI mode is raw (1) or sliced (0) */
+static inline int ivtv_raw_vbi(const struct ivtv *itv)
+{
+       return itv->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE;
+}
+
 /* This is a PCI post thing, where if the pci register is not read, then
    the write doesn't always take effect right away. By reading back the
    register any pending PCI writes will be performed (in order), and so
index 304261efc53d7890f0d88df2b9a8aef03518e3fe..b7457fc60ba5964c5131cc5282c1b2f29f831411 100644 (file)
@@ -78,7 +78,7 @@ static int ivtv_claim_stream(struct ivtv_open_id *id, int type)
        if (type == IVTV_DEC_STREAM_TYPE_MPG) {
                vbi_type = IVTV_DEC_STREAM_TYPE_VBI;
        } else if (type == IVTV_ENC_STREAM_TYPE_MPG &&
-                  itv->vbi.insert_mpeg && itv->vbi.sliced_in->service_set) {
+                  itv->vbi.insert_mpeg && !ivtv_raw_vbi(itv)) {
                vbi_type = IVTV_ENC_STREAM_TYPE_VBI;
        } else {
                return 0;
@@ -305,7 +305,7 @@ static size_t ivtv_copy_buf_to_user(struct ivtv_stream *s, struct ivtv_buffer *b
 
        if (len > ucount) len = ucount;
        if (itv->vbi.insert_mpeg && s->type == IVTV_ENC_STREAM_TYPE_MPG &&
-           itv->vbi.sliced_in->service_set && buf != &itv->vbi.sliced_mpeg_buf) {
+           !ivtv_raw_vbi(itv) && buf != &itv->vbi.sliced_mpeg_buf) {
                const char *start = buf->buf + buf->readpos;
                const char *p = start + 1;
                const u8 *q;
@@ -372,7 +372,7 @@ static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_co
        /* Each VBI buffer is one frame, the v4l2 API says that for VBI the frames should
           arrive one-by-one, so make sure we never output more than one VBI frame at a time */
        if (s->type == IVTV_DEC_STREAM_TYPE_VBI ||
-                       (s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set))
+           (s->type == IVTV_ENC_STREAM_TYPE_VBI && !ivtv_raw_vbi(itv)))
                single_frame = 1;
 
        for (;;) {
index f5b289ef4103ef6cd3a68c042af314303dac435e..3d0013bdd1fd4d75f7e9aa28cdcd46ce2c05f965 100644 (file)
@@ -575,8 +575,11 @@ static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f
 {
        struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
+       if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
+               return -EBUSY;
        itv->vbi.sliced_in->service_set = 0;
-       itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in);
+       itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
+       itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
        return ivtv_g_fmt_vbi_cap(file, fh, fmt);
 }
 
@@ -591,8 +594,9 @@ static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
                return ret;
 
        check_service_set(vbifmt, itv->is_50hz);
-       if (atomic_read(&itv->capturing) > 0)
+       if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
                return -EBUSY;
+       itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
        itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
        memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
        return 0;
index 24273fbea4709e0d6902ef628d79fa6b38bdcf86..5bbf31e393048fd6b1cd6740a4c02b9ace8f051b 100644 (file)
@@ -334,7 +334,7 @@ void ivtv_streams_cleanup(struct ivtv *itv, int unregister)
 
 static void ivtv_vbi_setup(struct ivtv *itv)
 {
-       int raw = itv->vbi.sliced_in->service_set == 0;
+       int raw = ivtv_raw_vbi(itv);
        u32 data[CX2341X_MBOX_MAX_DATA];
        int lines;
        int i;
index 1ce9deb1104fc1bdc970811d65ea52a346087570..4a37a7d2e69d53332341dd2f7cda8f66e6d6bc3e 100644 (file)
@@ -334,7 +334,7 @@ void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
        int y;
 
        /* Raw VBI data */
-       if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) {
+       if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && ivtv_raw_vbi(itv)) {
                u8 type;
 
                ivtv_buf_swap(buf);
index 4ed7d65dd634d340549e52b194ddc271e4dba0a4..c8e9cb3db30a9651692e3c4d732cca6a82643c06 100644 (file)
@@ -1057,7 +1057,7 @@ static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo
        for (i = 0; i <= 23; i++)
                lcr[i] = 0xff;
 
-       if (fmt->service_set == 0) {
+       if (fmt == NULL) {
                /* raw VBI */
                if (is_50hz)
                        for (i = 6; i <= 23; i++)
@@ -1113,7 +1113,7 @@ static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo
        }
 
        /* enable/disable raw VBI capturing */
-       saa711x_writeregs(client, fmt->service_set == 0 ?
+       saa711x_writeregs(client, fmt == NULL ?
                                saa7115_cfg_vbi_on :
                                saa7115_cfg_vbi_off);
 }
@@ -1153,6 +1153,10 @@ static int saa711x_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
                saa711x_set_lcr(client, &fmt->fmt.sliced);
                return 0;
        }
+       if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+               saa711x_set_lcr(client, NULL);
+               return 0;
+       }
        if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                return -EINVAL;