diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2008-10-04 07:05:30 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-13 07:08:01 -0400 |
commit | a8b864354e060dda1000e62d1fea7c1274581caf (patch) | |
tree | 7b1e70dc49c1605a7cdad6b460ea9f602a24b161 /drivers/media | |
parent | 3c7b933bea2ee380d54b57b99dee42b1726a4eaa (diff) |
V4L/DVB (9162): ivtv: fix raw/sliced VBI mixup
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>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/cx25840/cx25840-vbi.c | 5 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.c | 2 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.h | 6 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-fileops.c | 6 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-ioctl.c | 8 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-streams.c | 2 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-vbi.c | 2 | ||||
-rw-r--r-- | drivers/media/video/saa7115.c | 8 |
8 files changed, 27 insertions, 12 deletions
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c index 69f2bbdbb929..58e6ef1c28a0 100644 --- a/drivers/media/video/cx25840/cx25840-vbi.c +++ b/drivers/media/video/cx25840/cx25840-vbi.c | |||
@@ -141,10 +141,11 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | |||
141 | u8 lcr[24]; | 141 | u8 lcr[24]; |
142 | 142 | ||
143 | fmt = arg; | 143 | fmt = arg; |
144 | if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) | 144 | if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE && |
145 | fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE) | ||
145 | return -EINVAL; | 146 | return -EINVAL; |
146 | svbi = &fmt->fmt.sliced; | 147 | svbi = &fmt->fmt.sliced; |
147 | if (svbi->service_set == 0) { | 148 | if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { |
148 | /* raw VBI */ | 149 | /* raw VBI */ |
149 | memset(svbi, 0, sizeof(*svbi)); | 150 | memset(svbi, 0, sizeof(*svbi)); |
150 | 151 | ||
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 7aa61b617496..aeaa13f6cb36 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
@@ -720,7 +720,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv) | |||
720 | itv->speed = 1000; | 720 | itv->speed = 1000; |
721 | 721 | ||
722 | /* VBI */ | 722 | /* VBI */ |
723 | itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; | 723 | itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; |
724 | itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced; | 724 | itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced; |
725 | 725 | ||
726 | /* Init the sg table for osd/yuv output */ | 726 | /* Init the sg table for osd/yuv output */ |
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index b76a12268637..be2d779dba12 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h | |||
@@ -750,6 +750,12 @@ void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv); | |||
750 | /* First-open initialization: load firmware, init cx25840, etc. */ | 750 | /* First-open initialization: load firmware, init cx25840, etc. */ |
751 | int ivtv_init_on_first_open(struct ivtv *itv); | 751 | int ivtv_init_on_first_open(struct ivtv *itv); |
752 | 752 | ||
753 | /* Test if the current VBI mode is raw (1) or sliced (0) */ | ||
754 | static inline int ivtv_raw_vbi(const struct ivtv *itv) | ||
755 | { | ||
756 | return itv->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE; | ||
757 | } | ||
758 | |||
753 | /* This is a PCI post thing, where if the pci register is not read, then | 759 | /* This is a PCI post thing, where if the pci register is not read, then |
754 | the write doesn't always take effect right away. By reading back the | 760 | the write doesn't always take effect right away. By reading back the |
755 | register any pending PCI writes will be performed (in order), and so | 761 | register any pending PCI writes will be performed (in order), and so |
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 304261efc53d..b7457fc60ba5 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -78,7 +78,7 @@ static int ivtv_claim_stream(struct ivtv_open_id *id, int type) | |||
78 | if (type == IVTV_DEC_STREAM_TYPE_MPG) { | 78 | if (type == IVTV_DEC_STREAM_TYPE_MPG) { |
79 | vbi_type = IVTV_DEC_STREAM_TYPE_VBI; | 79 | vbi_type = IVTV_DEC_STREAM_TYPE_VBI; |
80 | } else if (type == IVTV_ENC_STREAM_TYPE_MPG && | 80 | } else if (type == IVTV_ENC_STREAM_TYPE_MPG && |
81 | itv->vbi.insert_mpeg && itv->vbi.sliced_in->service_set) { | 81 | itv->vbi.insert_mpeg && !ivtv_raw_vbi(itv)) { |
82 | vbi_type = IVTV_ENC_STREAM_TYPE_VBI; | 82 | vbi_type = IVTV_ENC_STREAM_TYPE_VBI; |
83 | } else { | 83 | } else { |
84 | return 0; | 84 | return 0; |
@@ -305,7 +305,7 @@ static size_t ivtv_copy_buf_to_user(struct ivtv_stream *s, struct ivtv_buffer *b | |||
305 | 305 | ||
306 | if (len > ucount) len = ucount; | 306 | if (len > ucount) len = ucount; |
307 | if (itv->vbi.insert_mpeg && s->type == IVTV_ENC_STREAM_TYPE_MPG && | 307 | if (itv->vbi.insert_mpeg && s->type == IVTV_ENC_STREAM_TYPE_MPG && |
308 | itv->vbi.sliced_in->service_set && buf != &itv->vbi.sliced_mpeg_buf) { | 308 | !ivtv_raw_vbi(itv) && buf != &itv->vbi.sliced_mpeg_buf) { |
309 | const char *start = buf->buf + buf->readpos; | 309 | const char *start = buf->buf + buf->readpos; |
310 | const char *p = start + 1; | 310 | const char *p = start + 1; |
311 | const u8 *q; | 311 | const u8 *q; |
@@ -372,7 +372,7 @@ static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_co | |||
372 | /* Each VBI buffer is one frame, the v4l2 API says that for VBI the frames should | 372 | /* Each VBI buffer is one frame, the v4l2 API says that for VBI the frames should |
373 | arrive one-by-one, so make sure we never output more than one VBI frame at a time */ | 373 | arrive one-by-one, so make sure we never output more than one VBI frame at a time */ |
374 | if (s->type == IVTV_DEC_STREAM_TYPE_VBI || | 374 | if (s->type == IVTV_DEC_STREAM_TYPE_VBI || |
375 | (s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set)) | 375 | (s->type == IVTV_ENC_STREAM_TYPE_VBI && !ivtv_raw_vbi(itv))) |
376 | single_frame = 1; | 376 | single_frame = 1; |
377 | 377 | ||
378 | for (;;) { | 378 | for (;;) { |
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index f5b289ef4103..3d0013bdd1fd 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -575,8 +575,11 @@ static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f | |||
575 | { | 575 | { |
576 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | 576 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
577 | 577 | ||
578 | if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0) | ||
579 | return -EBUSY; | ||
578 | itv->vbi.sliced_in->service_set = 0; | 580 | itv->vbi.sliced_in->service_set = 0; |
579 | itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in); | 581 | itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; |
582 | itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); | ||
580 | return ivtv_g_fmt_vbi_cap(file, fh, fmt); | 583 | return ivtv_g_fmt_vbi_cap(file, fh, fmt); |
581 | } | 584 | } |
582 | 585 | ||
@@ -591,8 +594,9 @@ static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo | |||
591 | return ret; | 594 | return ret; |
592 | 595 | ||
593 | check_service_set(vbifmt, itv->is_50hz); | 596 | check_service_set(vbifmt, itv->is_50hz); |
594 | if (atomic_read(&itv->capturing) > 0) | 597 | if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0) |
595 | return -EBUSY; | 598 | return -EBUSY; |
599 | itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; | ||
596 | itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); | 600 | itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); |
597 | memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in)); | 601 | memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in)); |
598 | return 0; | 602 | return 0; |
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 24273fbea470..5bbf31e39304 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c | |||
@@ -334,7 +334,7 @@ void ivtv_streams_cleanup(struct ivtv *itv, int unregister) | |||
334 | 334 | ||
335 | static void ivtv_vbi_setup(struct ivtv *itv) | 335 | static void ivtv_vbi_setup(struct ivtv *itv) |
336 | { | 336 | { |
337 | int raw = itv->vbi.sliced_in->service_set == 0; | 337 | int raw = ivtv_raw_vbi(itv); |
338 | u32 data[CX2341X_MBOX_MAX_DATA]; | 338 | u32 data[CX2341X_MBOX_MAX_DATA]; |
339 | int lines; | 339 | int lines; |
340 | int i; | 340 | int i; |
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c index 1ce9deb1104f..4a37a7d2e69d 100644 --- a/drivers/media/video/ivtv/ivtv-vbi.c +++ b/drivers/media/video/ivtv/ivtv-vbi.c | |||
@@ -334,7 +334,7 @@ void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf, | |||
334 | int y; | 334 | int y; |
335 | 335 | ||
336 | /* Raw VBI data */ | 336 | /* Raw VBI data */ |
337 | if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) { | 337 | if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && ivtv_raw_vbi(itv)) { |
338 | u8 type; | 338 | u8 type; |
339 | 339 | ||
340 | ivtv_buf_swap(buf); | 340 | ivtv_buf_swap(buf); |
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index 4ed7d65dd634..c8e9cb3db30a 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c | |||
@@ -1057,7 +1057,7 @@ static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo | |||
1057 | for (i = 0; i <= 23; i++) | 1057 | for (i = 0; i <= 23; i++) |
1058 | lcr[i] = 0xff; | 1058 | lcr[i] = 0xff; |
1059 | 1059 | ||
1060 | if (fmt->service_set == 0) { | 1060 | if (fmt == NULL) { |
1061 | /* raw VBI */ | 1061 | /* raw VBI */ |
1062 | if (is_50hz) | 1062 | if (is_50hz) |
1063 | for (i = 6; i <= 23; i++) | 1063 | for (i = 6; i <= 23; i++) |
@@ -1113,7 +1113,7 @@ static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo | |||
1113 | } | 1113 | } |
1114 | 1114 | ||
1115 | /* enable/disable raw VBI capturing */ | 1115 | /* enable/disable raw VBI capturing */ |
1116 | saa711x_writeregs(client, fmt->service_set == 0 ? | 1116 | saa711x_writeregs(client, fmt == NULL ? |
1117 | saa7115_cfg_vbi_on : | 1117 | saa7115_cfg_vbi_on : |
1118 | saa7115_cfg_vbi_off); | 1118 | saa7115_cfg_vbi_off); |
1119 | } | 1119 | } |
@@ -1153,6 +1153,10 @@ static int saa711x_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt | |||
1153 | saa711x_set_lcr(client, &fmt->fmt.sliced); | 1153 | saa711x_set_lcr(client, &fmt->fmt.sliced); |
1154 | return 0; | 1154 | return 0; |
1155 | } | 1155 | } |
1156 | if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | ||
1157 | saa711x_set_lcr(client, NULL); | ||
1158 | return 0; | ||
1159 | } | ||
1156 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1160 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1157 | return -EINVAL; | 1161 | return -EINVAL; |
1158 | 1162 | ||