diff options
Diffstat (limited to 'drivers/media/video/bt8xx/bttv-vbi.c')
-rw-r--r-- | drivers/media/video/bt8xx/bttv-vbi.c | 366 |
1 files changed, 298 insertions, 68 deletions
diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c index 6fc6b0260056..754f66bfdf46 100644 --- a/drivers/media/video/bt8xx/bttv-vbi.c +++ b/drivers/media/video/bt8xx/bttv-vbi.c | |||
@@ -5,6 +5,9 @@ | |||
5 | 5 | ||
6 | (c) 2002 Gerd Knorr <kraxel@bytesex.org> | 6 | (c) 2002 Gerd Knorr <kraxel@bytesex.org> |
7 | 7 | ||
8 | Copyright (C) 2005, 2006 Michael H. Schimek <mschimek@gmx.at> | ||
9 | Sponsored by OPQ Systems AB | ||
10 | |||
8 | This program is free software; you can redistribute it and/or modify | 11 | This program is free software; you can redistribute it and/or modify |
9 | it under the terms of the GNU General Public License as published by | 12 | it under the terms of the GNU General Public License as published by |
10 | the Free Software Foundation; either version 2 of the License, or | 13 | the Free Software Foundation; either version 2 of the License, or |
@@ -41,8 +44,15 @@ | |||
41 | to be about 244. */ | 44 | to be about 244. */ |
42 | #define VBI_OFFSET 244 | 45 | #define VBI_OFFSET 244 |
43 | 46 | ||
47 | /* 2048 for compatibility with earlier driver versions. The driver | ||
48 | really stores 1024 + tvnorm->vbipack * 4 samples per line in the | ||
49 | buffer. Note tvnorm->vbipack is <= 0xFF (limit of VBIPACK_LO + HI | ||
50 | is 0x1FF DWORDs) and VBI read()s store a frame counter in the last | ||
51 | four bytes of the VBI image. */ | ||
52 | #define VBI_BPL 2048 | ||
53 | |||
54 | /* Compatibility. */ | ||
44 | #define VBI_DEFLINES 16 | 55 | #define VBI_DEFLINES 16 |
45 | #define VBI_MAXLINES 32 | ||
46 | 56 | ||
47 | static unsigned int vbibufs = 4; | 57 | static unsigned int vbibufs = 4; |
48 | static unsigned int vbi_debug = 0; | 58 | static unsigned int vbi_debug = 0; |
@@ -58,21 +68,12 @@ MODULE_PARM_DESC(vbi_debug,"vbi code debug messages, default is 0 (no)"); | |||
58 | #define dprintk(fmt, arg...) if (vbi_debug) \ | 68 | #define dprintk(fmt, arg...) if (vbi_debug) \ |
59 | printk(KERN_DEBUG "bttv%d/vbi: " fmt, btv->c.nr , ## arg) | 69 | printk(KERN_DEBUG "bttv%d/vbi: " fmt, btv->c.nr , ## arg) |
60 | 70 | ||
71 | #define IMAGE_SIZE(fmt) \ | ||
72 | (((fmt)->count[0] + (fmt)->count[1]) * (fmt)->samples_per_line) | ||
73 | |||
61 | /* ----------------------------------------------------------------------- */ | 74 | /* ----------------------------------------------------------------------- */ |
62 | /* vbi risc code + mm */ | 75 | /* vbi risc code + mm */ |
63 | 76 | ||
64 | static int | ||
65 | vbi_buffer_risc(struct bttv *btv, struct bttv_buffer *buf, int lines) | ||
66 | { | ||
67 | int bpl = 2048; | ||
68 | |||
69 | bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist, | ||
70 | 0, bpl-4, 4, lines); | ||
71 | bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist, | ||
72 | lines * bpl, bpl-4, 4, lines); | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static int vbi_buffer_setup(struct videobuf_queue *q, | 77 | static int vbi_buffer_setup(struct videobuf_queue *q, |
77 | unsigned int *count, unsigned int *size) | 78 | unsigned int *count, unsigned int *size) |
78 | { | 79 | { |
@@ -81,8 +82,16 @@ static int vbi_buffer_setup(struct videobuf_queue *q, | |||
81 | 82 | ||
82 | if (0 == *count) | 83 | if (0 == *count) |
83 | *count = vbibufs; | 84 | *count = vbibufs; |
84 | *size = fh->lines * 2 * 2048; | 85 | |
85 | dprintk("setup: lines=%d\n",fh->lines); | 86 | *size = IMAGE_SIZE(&fh->vbi_fmt.fmt); |
87 | |||
88 | dprintk("setup: samples=%u start=%d,%d count=%u,%u\n", | ||
89 | fh->vbi_fmt.fmt.samples_per_line, | ||
90 | fh->vbi_fmt.fmt.start[0], | ||
91 | fh->vbi_fmt.fmt.start[1], | ||
92 | fh->vbi_fmt.fmt.count[0], | ||
93 | fh->vbi_fmt.fmt.count[1]); | ||
94 | |||
86 | return 0; | 95 | return 0; |
87 | } | 96 | } |
88 | 97 | ||
@@ -93,18 +102,93 @@ static int vbi_buffer_prepare(struct videobuf_queue *q, | |||
93 | struct bttv_fh *fh = q->priv_data; | 102 | struct bttv_fh *fh = q->priv_data; |
94 | struct bttv *btv = fh->btv; | 103 | struct bttv *btv = fh->btv; |
95 | struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); | 104 | struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); |
105 | const struct bttv_tvnorm *tvnorm; | ||
106 | unsigned int skip_lines0, skip_lines1, min_vdelay; | ||
107 | int redo_dma_risc; | ||
96 | int rc; | 108 | int rc; |
97 | 109 | ||
98 | buf->vb.size = fh->lines * 2 * 2048; | 110 | buf->vb.size = IMAGE_SIZE(&fh->vbi_fmt.fmt); |
99 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | 111 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) |
100 | return -EINVAL; | 112 | return -EINVAL; |
101 | 113 | ||
114 | tvnorm = fh->vbi_fmt.tvnorm; | ||
115 | |||
116 | /* There's no VBI_VDELAY register, RISC must skip the lines | ||
117 | we don't want. With default parameters we skip zero lines | ||
118 | as earlier driver versions did. The driver permits video | ||
119 | standard changes while capturing, so we use vbi_fmt.tvnorm | ||
120 | instead of btv->tvnorm to skip zero lines after video | ||
121 | standard changes as well. */ | ||
122 | |||
123 | skip_lines0 = 0; | ||
124 | skip_lines1 = 0; | ||
125 | |||
126 | if (fh->vbi_fmt.fmt.count[0] > 0) | ||
127 | skip_lines0 = max(0, (fh->vbi_fmt.fmt.start[0] | ||
128 | - tvnorm->vbistart[0])); | ||
129 | if (fh->vbi_fmt.fmt.count[1] > 0) | ||
130 | skip_lines1 = max(0, (fh->vbi_fmt.fmt.start[1] | ||
131 | - tvnorm->vbistart[1])); | ||
132 | |||
133 | redo_dma_risc = 0; | ||
134 | |||
135 | if (buf->vbi_skip[0] != skip_lines0 || | ||
136 | buf->vbi_skip[1] != skip_lines1 || | ||
137 | buf->vbi_count[0] != fh->vbi_fmt.fmt.count[0] || | ||
138 | buf->vbi_count[1] != fh->vbi_fmt.fmt.count[1]) { | ||
139 | buf->vbi_skip[0] = skip_lines0; | ||
140 | buf->vbi_skip[1] = skip_lines1; | ||
141 | buf->vbi_count[0] = fh->vbi_fmt.fmt.count[0]; | ||
142 | buf->vbi_count[1] = fh->vbi_fmt.fmt.count[1]; | ||
143 | redo_dma_risc = 1; | ||
144 | } | ||
145 | |||
102 | if (STATE_NEEDS_INIT == buf->vb.state) { | 146 | if (STATE_NEEDS_INIT == buf->vb.state) { |
147 | redo_dma_risc = 1; | ||
103 | if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL))) | 148 | if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL))) |
104 | goto fail; | 149 | goto fail; |
105 | if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines))) | ||
106 | goto fail; | ||
107 | } | 150 | } |
151 | |||
152 | if (redo_dma_risc) { | ||
153 | unsigned int bpl, padding, offset; | ||
154 | |||
155 | bpl = 2044; /* max. vbipack */ | ||
156 | padding = VBI_BPL - bpl; | ||
157 | |||
158 | if (fh->vbi_fmt.fmt.count[0] > 0) { | ||
159 | rc = bttv_risc_packed(btv, &buf->top, | ||
160 | buf->vb.dma.sglist, | ||
161 | /* offset */ 0, bpl, | ||
162 | padding, skip_lines0, | ||
163 | fh->vbi_fmt.fmt.count[0]); | ||
164 | if (0 != rc) | ||
165 | goto fail; | ||
166 | } | ||
167 | |||
168 | if (fh->vbi_fmt.fmt.count[1] > 0) { | ||
169 | offset = fh->vbi_fmt.fmt.count[0] * VBI_BPL; | ||
170 | |||
171 | rc = bttv_risc_packed(btv, &buf->bottom, | ||
172 | buf->vb.dma.sglist, | ||
173 | offset, bpl, | ||
174 | padding, skip_lines1, | ||
175 | fh->vbi_fmt.fmt.count[1]); | ||
176 | if (0 != rc) | ||
177 | goto fail; | ||
178 | } | ||
179 | } | ||
180 | |||
181 | /* VBI capturing ends at VDELAY, start of video capturing, | ||
182 | no matter where the RISC program ends. VDELAY minimum is 2, | ||
183 | bounds.top is the corresponding first field line number | ||
184 | times two. VDELAY counts half field lines. */ | ||
185 | min_vdelay = MIN_VDELAY; | ||
186 | if (fh->vbi_fmt.end >= tvnorm->cropcap.bounds.top) | ||
187 | min_vdelay += fh->vbi_fmt.end - tvnorm->cropcap.bounds.top; | ||
188 | |||
189 | /* For bttv_buffer_activate_vbi(). */ | ||
190 | buf->geo.vdelay = min_vdelay; | ||
191 | |||
108 | buf->vb.state = STATE_PREPARED; | 192 | buf->vb.state = STATE_PREPARED; |
109 | buf->vb.field = field; | 193 | buf->vb.field = field; |
110 | dprintk("buf prepare %p: top=%p bottom=%p field=%s\n", | 194 | dprintk("buf prepare %p: top=%p bottom=%p field=%s\n", |
@@ -152,69 +236,215 @@ struct videobuf_queue_ops bttv_vbi_qops = { | |||
152 | 236 | ||
153 | /* ----------------------------------------------------------------------- */ | 237 | /* ----------------------------------------------------------------------- */ |
154 | 238 | ||
155 | void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines) | 239 | static int |
240 | try_fmt (struct v4l2_vbi_format * f, | ||
241 | const struct bttv_tvnorm * tvnorm, | ||
242 | __s32 crop_start) | ||
156 | { | 243 | { |
157 | int vdelay; | 244 | __s32 min_start, max_start, max_end, f2_offset; |
158 | 245 | unsigned int i; | |
159 | if (lines < 1) | 246 | |
160 | lines = 1; | 247 | /* For compatibility with earlier driver versions we must pretend |
161 | if (lines > VBI_MAXLINES) | 248 | the VBI and video capture window may overlap. In reality RISC |
162 | lines = VBI_MAXLINES; | 249 | magic aborts VBI capturing at the first line of video capturing, |
163 | fh->lines = lines; | 250 | leaving the rest of the buffer unchanged, usually all zero. |
164 | 251 | VBI capturing must always start before video capturing. >> 1 | |
165 | vdelay = btread(BT848_E_VDELAY_LO); | 252 | because cropping counts field lines times two. */ |
166 | if (vdelay < lines*2) { | 253 | min_start = tvnorm->vbistart[0]; |
167 | vdelay = lines*2; | 254 | max_start = (crop_start >> 1) - 1; |
168 | btwrite(vdelay,BT848_E_VDELAY_LO); | 255 | max_end = (tvnorm->cropcap.bounds.top |
169 | btwrite(vdelay,BT848_O_VDELAY_LO); | 256 | + tvnorm->cropcap.bounds.height) >> 1; |
257 | |||
258 | if (min_start > max_start) | ||
259 | return -EBUSY; | ||
260 | |||
261 | BUG_ON(max_start >= max_end); | ||
262 | |||
263 | f->sampling_rate = tvnorm->Fsc; | ||
264 | f->samples_per_line = VBI_BPL; | ||
265 | f->sample_format = V4L2_PIX_FMT_GREY; | ||
266 | f->offset = VBI_OFFSET; | ||
267 | |||
268 | f2_offset = tvnorm->vbistart[1] - tvnorm->vbistart[0]; | ||
269 | |||
270 | for (i = 0; i < 2; ++i) { | ||
271 | if (0 == f->count[i]) { | ||
272 | /* No data from this field. We leave f->start[i] | ||
273 | alone because VIDIOCSVBIFMT is w/o and EINVALs | ||
274 | when a driver does not support exactly the | ||
275 | requested parameters. */ | ||
276 | } else { | ||
277 | s64 start, count; | ||
278 | |||
279 | start = clamp(f->start[i], min_start, max_start); | ||
280 | /* s64 to prevent overflow. */ | ||
281 | count = (s64) f->start[i] + f->count[i] - start; | ||
282 | f->start[i] = start; | ||
283 | f->count[i] = clamp(count, (s64) 1, | ||
284 | max_end - start); | ||
285 | } | ||
286 | |||
287 | min_start += f2_offset; | ||
288 | max_start += f2_offset; | ||
289 | max_end += f2_offset; | ||
170 | } | 290 | } |
291 | |||
292 | if (0 == (f->count[0] | f->count[1])) { | ||
293 | /* As in earlier driver versions. */ | ||
294 | f->start[0] = tvnorm->vbistart[0]; | ||
295 | f->start[1] = tvnorm->vbistart[1]; | ||
296 | f->count[0] = 1; | ||
297 | f->count[1] = 1; | ||
298 | } | ||
299 | |||
300 | f->flags = 0; | ||
301 | |||
302 | f->reserved[0] = 0; | ||
303 | f->reserved[1] = 0; | ||
304 | |||
305 | return 0; | ||
171 | } | 306 | } |
172 | 307 | ||
173 | void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f) | 308 | int |
309 | bttv_vbi_try_fmt (struct bttv_fh * fh, | ||
310 | struct v4l2_vbi_format * f) | ||
174 | { | 311 | { |
312 | struct bttv *btv = fh->btv; | ||
175 | const struct bttv_tvnorm *tvnorm; | 313 | const struct bttv_tvnorm *tvnorm; |
176 | s64 count0,count1,count; | 314 | __s32 crop_start; |
177 | 315 | ||
178 | tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; | 316 | mutex_lock(&btv->lock); |
179 | f->type = V4L2_BUF_TYPE_VBI_CAPTURE; | 317 | |
180 | f->fmt.vbi.sampling_rate = tvnorm->Fsc; | 318 | tvnorm = &bttv_tvnorms[btv->tvnorm]; |
181 | f->fmt.vbi.samples_per_line = 2048; | 319 | crop_start = btv->crop_start; |
182 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | 320 | |
183 | f->fmt.vbi.offset = VBI_OFFSET; | 321 | mutex_unlock(&btv->lock); |
184 | f->fmt.vbi.flags = 0; | 322 | |
185 | 323 | return try_fmt(f, tvnorm, crop_start); | |
186 | /* s64 to prevent overflow. */ | ||
187 | count0 = (s64) f->fmt.vbi.start[0] + f->fmt.vbi.count[0] | ||
188 | - tvnorm->vbistart[0]; | ||
189 | count1 = (s64) f->fmt.vbi.start[1] + f->fmt.vbi.count[1] | ||
190 | - tvnorm->vbistart[1]; | ||
191 | count = clamp (max (count0, count1), (s64) 1, (s64) VBI_MAXLINES); | ||
192 | |||
193 | f->fmt.vbi.start[0] = tvnorm->vbistart[0]; | ||
194 | f->fmt.vbi.start[1] = tvnorm->vbistart[1]; | ||
195 | f->fmt.vbi.count[0] = count; | ||
196 | f->fmt.vbi.count[1] = count; | ||
197 | |||
198 | f->fmt.vbi.reserved[0] = 0; | ||
199 | f->fmt.vbi.reserved[1] = 0; | ||
200 | } | 324 | } |
201 | 325 | ||
202 | void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f) | 326 | int |
327 | bttv_vbi_set_fmt (struct bttv_fh * fh, | ||
328 | struct v4l2_vbi_format * f) | ||
203 | { | 329 | { |
330 | struct bttv *btv = fh->btv; | ||
204 | const struct bttv_tvnorm *tvnorm; | 331 | const struct bttv_tvnorm *tvnorm; |
332 | __s32 start1, end; | ||
333 | int rc; | ||
334 | |||
335 | mutex_lock(&btv->lock); | ||
336 | |||
337 | rc = -EBUSY; | ||
338 | if (fh->resources & RESOURCE_VBI) | ||
339 | goto fail; | ||
340 | |||
341 | tvnorm = &bttv_tvnorms[btv->tvnorm]; | ||
342 | |||
343 | rc = try_fmt(f, tvnorm, btv->crop_start); | ||
344 | if (0 != rc) | ||
345 | goto fail; | ||
346 | |||
347 | start1 = f->start[1] - tvnorm->vbistart[1] + tvnorm->vbistart[0]; | ||
348 | |||
349 | /* First possible line of video capturing. Should be | ||
350 | max(f->start[0] + f->count[0], start1 + f->count[1]) * 2 | ||
351 | when capturing both fields. But for compatibility we must | ||
352 | pretend the VBI and video capture window may overlap, | ||
353 | so end = start + 1, the lowest possible value, times two | ||
354 | because vbi_fmt.end counts field lines times two. */ | ||
355 | end = max(f->start[0], start1) * 2 + 2; | ||
356 | |||
357 | mutex_lock(&fh->vbi.lock); | ||
358 | |||
359 | fh->vbi_fmt.fmt = *f; | ||
360 | fh->vbi_fmt.tvnorm = tvnorm; | ||
361 | fh->vbi_fmt.end = end; | ||
362 | |||
363 | mutex_unlock(&fh->vbi.lock); | ||
364 | |||
365 | rc = 0; | ||
366 | |||
367 | fail: | ||
368 | mutex_unlock(&btv->lock); | ||
369 | |||
370 | return rc; | ||
371 | } | ||
372 | |||
373 | void | ||
374 | bttv_vbi_get_fmt (struct bttv_fh * fh, | ||
375 | struct v4l2_vbi_format * f) | ||
376 | { | ||
377 | const struct bttv_tvnorm *tvnorm; | ||
378 | |||
379 | *f = fh->vbi_fmt.fmt; | ||
205 | 380 | ||
206 | tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; | 381 | tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; |
207 | memset(f,0,sizeof(*f)); | 382 | |
208 | f->type = V4L2_BUF_TYPE_VBI_CAPTURE; | 383 | if (tvnorm != fh->vbi_fmt.tvnorm) { |
209 | f->fmt.vbi.sampling_rate = tvnorm->Fsc; | 384 | __s32 max_end; |
210 | f->fmt.vbi.samples_per_line = 2048; | 385 | unsigned int i; |
211 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | 386 | |
212 | f->fmt.vbi.offset = VBI_OFFSET; | 387 | /* As in vbi_buffer_prepare() this imitates the |
213 | f->fmt.vbi.start[0] = tvnorm->vbistart[0]; | 388 | behaviour of earlier driver versions after video |
214 | f->fmt.vbi.start[1] = tvnorm->vbistart[1]; | 389 | standard changes, with default parameters anyway. */ |
215 | f->fmt.vbi.count[0] = fh->lines; | 390 | |
216 | f->fmt.vbi.count[1] = fh->lines; | 391 | max_end = (tvnorm->cropcap.bounds.top |
217 | f->fmt.vbi.flags = 0; | 392 | + tvnorm->cropcap.bounds.height) >> 1; |
393 | |||
394 | f->sampling_rate = tvnorm->Fsc; | ||
395 | |||
396 | for (i = 0; i < 2; ++i) { | ||
397 | __s32 new_start; | ||
398 | |||
399 | new_start = f->start[i] | ||
400 | + tvnorm->vbistart[i] | ||
401 | - fh->vbi_fmt.tvnorm->vbistart[i]; | ||
402 | |||
403 | f->start[i] = min(new_start, max_end - 1); | ||
404 | f->count[i] = min((__s32) f->count[i], | ||
405 | max_end - f->start[i]); | ||
406 | |||
407 | max_end += tvnorm->vbistart[1] | ||
408 | - tvnorm->vbistart[0]; | ||
409 | } | ||
410 | } | ||
411 | } | ||
412 | |||
413 | void | ||
414 | bttv_vbi_fmt_reset (struct bttv_vbi_fmt * f, | ||
415 | int norm) | ||
416 | { | ||
417 | const struct bttv_tvnorm *tvnorm; | ||
418 | unsigned int real_samples_per_line; | ||
419 | unsigned int real_count; | ||
420 | |||
421 | tvnorm = &bttv_tvnorms[norm]; | ||
422 | |||
423 | f->fmt.sampling_rate = tvnorm->Fsc; | ||
424 | f->fmt.samples_per_line = VBI_BPL; | ||
425 | f->fmt.sample_format = V4L2_PIX_FMT_GREY; | ||
426 | f->fmt.offset = VBI_OFFSET; | ||
427 | f->fmt.start[0] = tvnorm->vbistart[0]; | ||
428 | f->fmt.start[1] = tvnorm->vbistart[1]; | ||
429 | f->fmt.count[0] = VBI_DEFLINES; | ||
430 | f->fmt.count[1] = VBI_DEFLINES; | ||
431 | f->fmt.flags = 0; | ||
432 | f->fmt.reserved[0] = 0; | ||
433 | f->fmt.reserved[1] = 0; | ||
434 | |||
435 | /* For compatibility the buffer size must be 2 * VBI_DEFLINES * | ||
436 | VBI_BPL regardless of the current video standard. */ | ||
437 | real_samples_per_line = 1024 + tvnorm->vbipack * 4; | ||
438 | real_count = ((tvnorm->cropcap.defrect.top >> 1) | ||
439 | - tvnorm->vbistart[0]); | ||
440 | |||
441 | BUG_ON(real_samples_per_line > VBI_BPL); | ||
442 | BUG_ON(real_count > VBI_DEFLINES); | ||
443 | |||
444 | f->tvnorm = tvnorm; | ||
445 | |||
446 | /* See bttv_vbi_fmt_set(). */ | ||
447 | f->end = tvnorm->vbistart[0] * 2 + 2; | ||
218 | } | 448 | } |
219 | 449 | ||
220 | /* ----------------------------------------------------------------------- */ | 450 | /* ----------------------------------------------------------------------- */ |