1
2
3
4
5
6
7
8
9
10
11
12
13
14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15
16#include <linux/module.h>
17#include <linux/errno.h>
18#include <linux/fs.h>
19#include <linux/kernel.h>
20#include <linux/interrupt.h>
21#include <linux/kdev_t.h>
22#include <media/v4l2-ioctl.h>
23#include <asm/io.h>
24#include "bttvp.h"
25
26
27
28
29
30
31
32
33
34
35#define VBI_OFFSET 244
36
37
38
39
40
41
42#define VBI_BPL 2048
43
44
45#define VBI_DEFLINES 16
46
47static unsigned int vbibufs = 4;
48static unsigned int vbi_debug;
49
50module_param(vbibufs, int, 0444);
51module_param(vbi_debug, int, 0644);
52MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32, default 4");
53MODULE_PARM_DESC(vbi_debug,"vbi code debug messages, default is 0 (no)");
54
55#ifdef dprintk
56# undef dprintk
57#endif
58#define dprintk(fmt, ...) \
59do { \
60 if (vbi_debug) \
61 pr_debug("%d: " fmt, btv->c.nr, ##__VA_ARGS__); \
62} while (0)
63
64#define IMAGE_SIZE(fmt) \
65 (((fmt)->count[0] + (fmt)->count[1]) * (fmt)->samples_per_line)
66
67
68
69
70static int vbi_buffer_setup(struct videobuf_queue *q,
71 unsigned int *count, unsigned int *size)
72{
73 struct bttv_fh *fh = q->priv_data;
74 struct bttv *btv = fh->btv;
75
76 if (0 == *count)
77 *count = vbibufs;
78
79 *size = IMAGE_SIZE(&fh->vbi_fmt.fmt);
80
81 dprintk("setup: samples=%u start=%d,%d count=%u,%u\n",
82 fh->vbi_fmt.fmt.samples_per_line,
83 fh->vbi_fmt.fmt.start[0],
84 fh->vbi_fmt.fmt.start[1],
85 fh->vbi_fmt.fmt.count[0],
86 fh->vbi_fmt.fmt.count[1]);
87
88 return 0;
89}
90
91static int vbi_buffer_prepare(struct videobuf_queue *q,
92 struct videobuf_buffer *vb,
93 enum v4l2_field field)
94{
95 struct bttv_fh *fh = q->priv_data;
96 struct bttv *btv = fh->btv;
97 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
98 const struct bttv_tvnorm *tvnorm;
99 unsigned int skip_lines0, skip_lines1, min_vdelay;
100 int redo_dma_risc;
101 int rc;
102
103 buf->vb.size = IMAGE_SIZE(&fh->vbi_fmt.fmt);
104 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
105 return -EINVAL;
106
107 tvnorm = fh->vbi_fmt.tvnorm;
108
109
110
111
112
113
114
115
116 skip_lines0 = 0;
117 skip_lines1 = 0;
118
119 if (fh->vbi_fmt.fmt.count[0] > 0)
120 skip_lines0 = max(0, (fh->vbi_fmt.fmt.start[0]
121 - tvnorm->vbistart[0]));
122 if (fh->vbi_fmt.fmt.count[1] > 0)
123 skip_lines1 = max(0, (fh->vbi_fmt.fmt.start[1]
124 - tvnorm->vbistart[1]));
125
126 redo_dma_risc = 0;
127
128 if (buf->vbi_skip[0] != skip_lines0 ||
129 buf->vbi_skip[1] != skip_lines1 ||
130 buf->vbi_count[0] != fh->vbi_fmt.fmt.count[0] ||
131 buf->vbi_count[1] != fh->vbi_fmt.fmt.count[1]) {
132 buf->vbi_skip[0] = skip_lines0;
133 buf->vbi_skip[1] = skip_lines1;
134 buf->vbi_count[0] = fh->vbi_fmt.fmt.count[0];
135 buf->vbi_count[1] = fh->vbi_fmt.fmt.count[1];
136 redo_dma_risc = 1;
137 }
138
139 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
140 redo_dma_risc = 1;
141 if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL)))
142 goto fail;
143 }
144
145 if (redo_dma_risc) {
146 unsigned int bpl, padding, offset;
147 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
148
149 bpl = 2044;
150 padding = VBI_BPL - bpl;
151
152 if (fh->vbi_fmt.fmt.count[0] > 0) {
153 rc = bttv_risc_packed(btv, &buf->top,
154 dma->sglist,
155 0, bpl,
156 padding, skip_lines0,
157 fh->vbi_fmt.fmt.count[0]);
158 if (0 != rc)
159 goto fail;
160 }
161
162 if (fh->vbi_fmt.fmt.count[1] > 0) {
163 offset = fh->vbi_fmt.fmt.count[0] * VBI_BPL;
164
165 rc = bttv_risc_packed(btv, &buf->bottom,
166 dma->sglist,
167 offset, bpl,
168 padding, skip_lines1,
169 fh->vbi_fmt.fmt.count[1]);
170 if (0 != rc)
171 goto fail;
172 }
173 }
174
175
176
177
178
179 min_vdelay = MIN_VDELAY;
180 if (fh->vbi_fmt.end >= tvnorm->cropcap.bounds.top)
181 min_vdelay += fh->vbi_fmt.end - tvnorm->cropcap.bounds.top;
182
183
184 buf->geo.vdelay = min_vdelay;
185
186 buf->vb.state = VIDEOBUF_PREPARED;
187 buf->vb.field = field;
188 dprintk("buf prepare %p: top=%p bottom=%p field=%s\n",
189 vb, &buf->top, &buf->bottom,
190 v4l2_field_names[buf->vb.field]);
191 return 0;
192
193 fail:
194 bttv_dma_free(q,btv,buf);
195 return rc;
196}
197
198static void
199vbi_buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
200{
201 struct bttv_fh *fh = q->priv_data;
202 struct bttv *btv = fh->btv;
203 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
204
205 dprintk("queue %p\n",vb);
206 buf->vb.state = VIDEOBUF_QUEUED;
207 list_add_tail(&buf->vb.queue,&btv->vcapture);
208 if (NULL == btv->cvbi) {
209 fh->btv->loop_irq |= 4;
210 bttv_set_dma(btv,0x0c);
211 }
212}
213
214static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
215{
216 struct bttv_fh *fh = q->priv_data;
217 struct bttv *btv = fh->btv;
218 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
219
220 dprintk("free %p\n",vb);
221 bttv_dma_free(q,fh->btv,buf);
222}
223
224const struct videobuf_queue_ops bttv_vbi_qops = {
225 .buf_setup = vbi_buffer_setup,
226 .buf_prepare = vbi_buffer_prepare,
227 .buf_queue = vbi_buffer_queue,
228 .buf_release = vbi_buffer_release,
229};
230
231
232
233static int try_fmt(struct v4l2_vbi_format *f, const struct bttv_tvnorm *tvnorm,
234 __s32 crop_start)
235{
236 __s32 min_start, max_start, max_end, f2_offset;
237 unsigned int i;
238
239
240
241
242
243
244
245 min_start = tvnorm->vbistart[0];
246 max_start = (crop_start >> 1) - 1;
247 max_end = (tvnorm->cropcap.bounds.top
248 + tvnorm->cropcap.bounds.height) >> 1;
249
250 if (min_start > max_start)
251 return -EBUSY;
252
253 BUG_ON(max_start >= max_end);
254
255 f->sampling_rate = tvnorm->Fsc;
256 f->samples_per_line = VBI_BPL;
257 f->sample_format = V4L2_PIX_FMT_GREY;
258 f->offset = VBI_OFFSET;
259
260 f2_offset = tvnorm->vbistart[1] - tvnorm->vbistart[0];
261
262 for (i = 0; i < 2; ++i) {
263 if (0 == f->count[i]) {
264
265
266
267
268 } else {
269 s64 start, count;
270
271 start = clamp(f->start[i], min_start, max_start);
272
273 count = (s64) f->start[i] + f->count[i] - start;
274 f->start[i] = start;
275 f->count[i] = clamp(count, (s64) 1,
276 max_end - start);
277 }
278
279 min_start += f2_offset;
280 max_start += f2_offset;
281 max_end += f2_offset;
282 }
283
284 if (0 == (f->count[0] | f->count[1])) {
285
286 f->start[0] = tvnorm->vbistart[0];
287 f->start[1] = tvnorm->vbistart[1];
288 f->count[0] = 1;
289 f->count[1] = 1;
290 }
291
292 f->flags = 0;
293
294 f->reserved[0] = 0;
295 f->reserved[1] = 0;
296
297 return 0;
298}
299
300int bttv_try_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
301{
302 struct bttv_fh *fh = f;
303 struct bttv *btv = fh->btv;
304 const struct bttv_tvnorm *tvnorm;
305 __s32 crop_start;
306
307 mutex_lock(&btv->lock);
308
309 tvnorm = &bttv_tvnorms[btv->tvnorm];
310 crop_start = btv->crop_start;
311
312 mutex_unlock(&btv->lock);
313
314 return try_fmt(&frt->fmt.vbi, tvnorm, crop_start);
315}
316
317
318int bttv_s_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
319{
320 struct bttv_fh *fh = f;
321 struct bttv *btv = fh->btv;
322 const struct bttv_tvnorm *tvnorm;
323 __s32 start1, end;
324 int rc;
325
326 mutex_lock(&btv->lock);
327
328 rc = -EBUSY;
329 if (fh->resources & RESOURCE_VBI)
330 goto fail;
331
332 tvnorm = &bttv_tvnorms[btv->tvnorm];
333
334 rc = try_fmt(&frt->fmt.vbi, tvnorm, btv->crop_start);
335 if (0 != rc)
336 goto fail;
337
338 start1 = frt->fmt.vbi.start[1] - tvnorm->vbistart[1] +
339 tvnorm->vbistart[0];
340
341
342
343
344
345
346
347 end = max(frt->fmt.vbi.start[0], start1) * 2 + 2;
348
349 mutex_lock(&fh->vbi.vb_lock);
350
351 fh->vbi_fmt.fmt = frt->fmt.vbi;
352 fh->vbi_fmt.tvnorm = tvnorm;
353 fh->vbi_fmt.end = end;
354
355 mutex_unlock(&fh->vbi.vb_lock);
356
357 rc = 0;
358
359 fail:
360 mutex_unlock(&btv->lock);
361
362 return rc;
363}
364
365
366int bttv_g_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
367{
368 struct bttv_fh *fh = f;
369 const struct bttv_tvnorm *tvnorm;
370
371 frt->fmt.vbi = fh->vbi_fmt.fmt;
372
373 tvnorm = &bttv_tvnorms[fh->btv->tvnorm];
374
375 if (tvnorm != fh->vbi_fmt.tvnorm) {
376 __s32 max_end;
377 unsigned int i;
378
379
380
381
382
383 max_end = (tvnorm->cropcap.bounds.top
384 + tvnorm->cropcap.bounds.height) >> 1;
385
386 frt->fmt.vbi.sampling_rate = tvnorm->Fsc;
387
388 for (i = 0; i < 2; ++i) {
389 __s32 new_start;
390
391 new_start = frt->fmt.vbi.start[i]
392 + tvnorm->vbistart[i]
393 - fh->vbi_fmt.tvnorm->vbistart[i];
394
395 frt->fmt.vbi.start[i] = min(new_start, max_end - 1);
396 frt->fmt.vbi.count[i] =
397 min((__s32) frt->fmt.vbi.count[i],
398 max_end - frt->fmt.vbi.start[i]);
399
400 max_end += tvnorm->vbistart[1]
401 - tvnorm->vbistart[0];
402 }
403 }
404 return 0;
405}
406
407void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm)
408{
409 const struct bttv_tvnorm *tvnorm;
410 unsigned int real_samples_per_line;
411 unsigned int real_count;
412
413 tvnorm = &bttv_tvnorms[norm];
414
415 f->fmt.sampling_rate = tvnorm->Fsc;
416 f->fmt.samples_per_line = VBI_BPL;
417 f->fmt.sample_format = V4L2_PIX_FMT_GREY;
418 f->fmt.offset = VBI_OFFSET;
419 f->fmt.start[0] = tvnorm->vbistart[0];
420 f->fmt.start[1] = tvnorm->vbistart[1];
421 f->fmt.count[0] = VBI_DEFLINES;
422 f->fmt.count[1] = VBI_DEFLINES;
423 f->fmt.flags = 0;
424 f->fmt.reserved[0] = 0;
425 f->fmt.reserved[1] = 0;
426
427
428
429 real_samples_per_line = 1024 + tvnorm->vbipack * 4;
430 real_count = ((tvnorm->cropcap.defrect.top >> 1)
431 - tvnorm->vbistart[0]);
432
433 BUG_ON(real_samples_per_line > VBI_BPL);
434 BUG_ON(real_count > VBI_DEFLINES);
435
436 f->tvnorm = tvnorm;
437
438
439 f->end = tvnorm->vbistart[0] * 2 + 2;
440}
441