aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/bttv-driver.c18
-rw-r--r--drivers/media/video/bttv-vbi.c57
-rw-r--r--drivers/media/video/bttvp.h5
-rw-r--r--drivers/media/video/v4l1-compat.c11
4 files changed, 51 insertions, 40 deletions
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index 8bee7d5796dd..4e25c92ac8c4 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -210,6 +210,9 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
210 .vdelay = 0x20, 210 .vdelay = 0x20,
211 .vbipack = 255, 211 .vbipack = 255,
212 .sram = 0, 212 .sram = 0,
213 /* ITU-R frame line number of the first VBI line
214 we can capture, of the first and second field. */
215 .vbistart = { 7,320 },
213 },{ 216 },{
214 .v4l2_id = V4L2_STD_NTSC_M, 217 .v4l2_id = V4L2_STD_NTSC_M,
215 .name = "NTSC", 218 .name = "NTSC",
@@ -226,6 +229,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
226 .vdelay = 0x1a, 229 .vdelay = 0x1a,
227 .vbipack = 144, 230 .vbipack = 144,
228 .sram = 1, 231 .sram = 1,
232 .vbistart = { 10, 273 },
229 },{ 233 },{
230 .v4l2_id = V4L2_STD_SECAM, 234 .v4l2_id = V4L2_STD_SECAM,
231 .name = "SECAM", 235 .name = "SECAM",
@@ -242,6 +246,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
242 .vdelay = 0x20, 246 .vdelay = 0x20,
243 .vbipack = 255, 247 .vbipack = 255,
244 .sram = 0, /* like PAL, correct? */ 248 .sram = 0, /* like PAL, correct? */
249 .vbistart = { 7, 320 },
245 },{ 250 },{
246 .v4l2_id = V4L2_STD_PAL_Nc, 251 .v4l2_id = V4L2_STD_PAL_Nc,
247 .name = "PAL-Nc", 252 .name = "PAL-Nc",
@@ -258,6 +263,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
258 .vdelay = 0x1a, 263 .vdelay = 0x1a,
259 .vbipack = 144, 264 .vbipack = 144,
260 .sram = -1, 265 .sram = -1,
266 .vbistart = { 7, 320 },
261 },{ 267 },{
262 .v4l2_id = V4L2_STD_PAL_M, 268 .v4l2_id = V4L2_STD_PAL_M,
263 .name = "PAL-M", 269 .name = "PAL-M",
@@ -274,6 +280,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
274 .vdelay = 0x1a, 280 .vdelay = 0x1a,
275 .vbipack = 144, 281 .vbipack = 144,
276 .sram = -1, 282 .sram = -1,
283 .vbistart = { 10, 273 },
277 },{ 284 },{
278 .v4l2_id = V4L2_STD_PAL_N, 285 .v4l2_id = V4L2_STD_PAL_N,
279 .name = "PAL-N", 286 .name = "PAL-N",
@@ -290,6 +297,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
290 .vdelay = 0x20, 297 .vdelay = 0x20,
291 .vbipack = 144, 298 .vbipack = 144,
292 .sram = -1, 299 .sram = -1,
300 .vbistart = { 7, 320},
293 },{ 301 },{
294 .v4l2_id = V4L2_STD_NTSC_M_JP, 302 .v4l2_id = V4L2_STD_NTSC_M_JP,
295 .name = "NTSC-JP", 303 .name = "NTSC-JP",
@@ -306,6 +314,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
306 .vdelay = 0x16, 314 .vdelay = 0x16,
307 .vbipack = 144, 315 .vbipack = 144,
308 .sram = -1, 316 .sram = -1,
317 .vbistart = {10, 273},
309 },{ 318 },{
310 /* that one hopefully works with the strange timing 319 /* that one hopefully works with the strange timing
311 * which video recorders produce when playing a NTSC 320 * which video recorders produce when playing a NTSC
@@ -326,6 +335,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
326 .vbipack = 255, 335 .vbipack = 255,
327 .vtotal = 524, 336 .vtotal = 524,
328 .sram = -1, 337 .sram = -1,
338 .vbistart = { 10, 273 },
329 } 339 }
330}; 340};
331static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms); 341static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms);
@@ -2570,10 +2580,10 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2570 fmt->count[0] = fmt2.fmt.vbi.count[0]; 2580 fmt->count[0] = fmt2.fmt.vbi.count[0];
2571 fmt->start[1] = fmt2.fmt.vbi.start[1]; 2581 fmt->start[1] = fmt2.fmt.vbi.start[1];
2572 fmt->count[1] = fmt2.fmt.vbi.count[1]; 2582 fmt->count[1] = fmt2.fmt.vbi.count[1];
2573 if (fmt2.fmt.vbi.flags & VBI_UNSYNC) 2583 if (fmt2.fmt.vbi.flags & V4L2_VBI_UNSYNC)
2574 fmt->flags |= V4L2_VBI_UNSYNC; 2584 fmt->flags |= VBI_UNSYNC;
2575 if (fmt2.fmt.vbi.flags & VBI_INTERLACED) 2585 if (fmt2.fmt.vbi.flags & V4L2_VBI_INTERLACED)
2576 fmt->flags |= V4L2_VBI_INTERLACED; 2586 fmt->flags |= VBI_INTERLACED;
2577 return 0; 2587 return 0;
2578 } 2588 }
2579 case VIDIOCSVBIFMT: 2589 case VIDIOCSVBIFMT:
diff --git a/drivers/media/video/bttv-vbi.c b/drivers/media/video/bttv-vbi.c
index f4f58c60f152..72afdd64b882 100644
--- a/drivers/media/video/bttv-vbi.c
+++ b/drivers/media/video/bttv-vbi.c
@@ -31,6 +31,12 @@
31#include <asm/io.h> 31#include <asm/io.h>
32#include "bttvp.h" 32#include "bttvp.h"
33 33
34/* Offset from line sync pulse leading edge (0H) in 1 / sampling_rate:
35 bt8x8 /HRESET pulse starts at 0H and has length 64 / fCLKx1 (E|O_VTC
36 HSFMT = 0). VBI_HDELAY (always 0) is an offset from the trailing edge
37 of /HRESET in 1 / fCLKx1, and the sampling_rate tvnorm->Fsc is fCLKx2. */
38#define VBI_OFFSET ((64 + 0) * 2)
39
34#define VBI_DEFLINES 16 40#define VBI_DEFLINES 16
35#define VBI_MAXLINES 32 41#define VBI_MAXLINES 32
36 42
@@ -163,40 +169,30 @@ void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines)
163void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f) 169void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f)
164{ 170{
165 const struct bttv_tvnorm *tvnorm; 171 const struct bttv_tvnorm *tvnorm;
166 u32 start0,start1; 172 s64 count0,count1,count;
167 s32 count0,count1,count;
168 173
169 tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; 174 tvnorm = &bttv_tvnorms[fh->btv->tvnorm];
170 f->type = V4L2_BUF_TYPE_VBI_CAPTURE; 175 f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
171 f->fmt.vbi.sampling_rate = tvnorm->Fsc; 176 f->fmt.vbi.sampling_rate = tvnorm->Fsc;
172 f->fmt.vbi.samples_per_line = 2048; 177 f->fmt.vbi.samples_per_line = 2048;
173 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; 178 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
174 f->fmt.vbi.offset = 244; 179 f->fmt.vbi.offset = VBI_OFFSET;
175 f->fmt.vbi.flags = 0; 180 f->fmt.vbi.flags = 0;
176 switch (fh->btv->tvnorm) {
177 case 1: /* NTSC */
178 start0 = 10;
179 start1 = 273;
180 break;
181 case 0: /* PAL */
182 case 2: /* SECAM */
183 default:
184 start0 = 7;
185 start1 = 320;
186 }
187 181
188 count0 = (f->fmt.vbi.start[0] + f->fmt.vbi.count[0]) - start0; 182 /* s64 to prevent overflow. */
189 count1 = (f->fmt.vbi.start[1] + f->fmt.vbi.count[1]) - start1; 183 count0 = (s64) f->fmt.vbi.start[0] + f->fmt.vbi.count[0]
190 count = max(count0,count1); 184 - tvnorm->vbistart[0];
191 if (count > VBI_MAXLINES) 185 count1 = (s64) f->fmt.vbi.start[1] + f->fmt.vbi.count[1]
192 count = VBI_MAXLINES; 186 - tvnorm->vbistart[1];
193 if (count < 1) 187 count = clamp (max (count0, count1), 1LL, (s64) VBI_MAXLINES);
194 count = 1;
195 188
196 f->fmt.vbi.start[0] = start0; 189 f->fmt.vbi.start[0] = tvnorm->vbistart[0];
197 f->fmt.vbi.start[1] = start1; 190 f->fmt.vbi.start[1] = tvnorm->vbistart[1];
198 f->fmt.vbi.count[0] = count; 191 f->fmt.vbi.count[0] = count;
199 f->fmt.vbi.count[1] = count; 192 f->fmt.vbi.count[1] = count;
193
194 f->fmt.vbi.reserved[0] = 0;
195 f->fmt.vbi.reserved[1] = 0;
200} 196}
201 197
202void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f) 198void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f)
@@ -209,21 +205,12 @@ void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f)
209 f->fmt.vbi.sampling_rate = tvnorm->Fsc; 205 f->fmt.vbi.sampling_rate = tvnorm->Fsc;
210 f->fmt.vbi.samples_per_line = 2048; 206 f->fmt.vbi.samples_per_line = 2048;
211 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; 207 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
212 f->fmt.vbi.offset = 244; 208 f->fmt.vbi.offset = VBI_OFFSET;
209 f->fmt.vbi.start[0] = tvnorm->vbistart[0];
210 f->fmt.vbi.start[1] = tvnorm->vbistart[1];
213 f->fmt.vbi.count[0] = fh->lines; 211 f->fmt.vbi.count[0] = fh->lines;
214 f->fmt.vbi.count[1] = fh->lines; 212 f->fmt.vbi.count[1] = fh->lines;
215 f->fmt.vbi.flags = 0; 213 f->fmt.vbi.flags = 0;
216 switch (fh->btv->tvnorm) {
217 case 1: /* NTSC */
218 f->fmt.vbi.start[0] = 10;
219 f->fmt.vbi.start[1] = 273;
220 break;
221 case 0: /* PAL */
222 case 2: /* SECAM */
223 default:
224 f->fmt.vbi.start[0] = 7;
225 f->fmt.vbi.start[1] = 319;
226 }
227} 214}
228 215
229/* ----------------------------------------------------------------------- */ 216/* ----------------------------------------------------------------------- */
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index 55759f698e02..dd00c20ab95e 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -73,6 +73,8 @@
73 73
74#define UNSET (-1U) 74#define UNSET (-1U)
75 75
76#define clamp(x, low, high) min (max (low, x), high)
77
76/* ---------------------------------------------------------- */ 78/* ---------------------------------------------------------- */
77 79
78struct bttv_tvnorm { 80struct bttv_tvnorm {
@@ -88,6 +90,9 @@ struct bttv_tvnorm {
88 u8 vbipack; 90 u8 vbipack;
89 u16 vtotal; 91 u16 vtotal;
90 int sram; 92 int sram;
93 /* ITU-R frame line number of the first VBI line we can
94 capture, of the first and second field. */
95 u16 vbistart[2];
91}; 96};
92extern const struct bttv_tvnorm bttv_tvnorms[]; 97extern const struct bttv_tvnorm bttv_tvnorms[];
93 98
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index 4134549d11a8..2ab5b4093800 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -951,6 +951,10 @@ v4l_compat_translate_ioctl(struct inode *inode,
951 dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err); 951 dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err);
952 break; 952 break;
953 } 953 }
954 if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) {
955 err = -EINVAL;
956 break;
957 }
954 memset(fmt, 0, sizeof(*fmt)); 958 memset(fmt, 0, sizeof(*fmt));
955 fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line; 959 fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line;
956 fmt->sampling_rate = fmt2->fmt.vbi.sampling_rate; 960 fmt->sampling_rate = fmt2->fmt.vbi.sampling_rate;
@@ -966,6 +970,11 @@ v4l_compat_translate_ioctl(struct inode *inode,
966 { 970 {
967 struct vbi_format *fmt = arg; 971 struct vbi_format *fmt = arg;
968 972
973 if (VIDEO_PALETTE_RAW != fmt->sample_format) {
974 err = -EINVAL;
975 break;
976 }
977
969 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL); 978 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
970 memset(fmt2, 0, sizeof(*fmt2)); 979 memset(fmt2, 0, sizeof(*fmt2));
971 980
@@ -986,7 +995,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
986 995
987 if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line || 996 if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line ||
988 fmt2->fmt.vbi.sampling_rate != fmt->sampling_rate || 997 fmt2->fmt.vbi.sampling_rate != fmt->sampling_rate ||
989 VIDEO_PALETTE_RAW != fmt->sample_format || 998 fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY ||
990 fmt2->fmt.vbi.start[0] != fmt->start[0] || 999 fmt2->fmt.vbi.start[0] != fmt->start[0] ||
991 fmt2->fmt.vbi.count[0] != fmt->count[0] || 1000 fmt2->fmt.vbi.count[0] != fmt->count[0] ||
992 fmt2->fmt.vbi.start[1] != fmt->start[1] || 1001 fmt2->fmt.vbi.start[1] != fmt->start[1] ||