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