1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun bttv - Bt848 frame grabber driver
5*4882a593Smuzhiyun vbi interface
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun (c) 2002 Gerd Knorr <kraxel@bytesex.org>
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun Copyright (C) 2005, 2006 Michael H. Schimek <mschimek@gmx.at>
10*4882a593Smuzhiyun Sponsored by OPQ Systems AB
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun */
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #include <linux/module.h>
17*4882a593Smuzhiyun #include <linux/errno.h>
18*4882a593Smuzhiyun #include <linux/fs.h>
19*4882a593Smuzhiyun #include <linux/kernel.h>
20*4882a593Smuzhiyun #include <linux/interrupt.h>
21*4882a593Smuzhiyun #include <linux/kdev_t.h>
22*4882a593Smuzhiyun #include <media/v4l2-ioctl.h>
23*4882a593Smuzhiyun #include <asm/io.h>
24*4882a593Smuzhiyun #include "bttvp.h"
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun /* Offset from line sync pulse leading edge (0H) to start of VBI capture,
27*4882a593Smuzhiyun in fCLKx2 pixels. According to the datasheet, VBI capture starts
28*4882a593Smuzhiyun VBI_HDELAY fCLKx1 pixels from the tailing edgeof /HRESET, and /HRESET
29*4882a593Smuzhiyun is 64 fCLKx1 pixels wide. VBI_HDELAY is set to 0, so this should be
30*4882a593Smuzhiyun (64 + 0) * 2 = 128 fCLKx2 pixels. But it's not! The datasheet is
31*4882a593Smuzhiyun Just Plain Wrong. The real value appears to be different for
32*4882a593Smuzhiyun different revisions of the bt8x8 chips, and to be affected by the
33*4882a593Smuzhiyun horizontal scaling factor. Experimentally, the value is measured
34*4882a593Smuzhiyun to be about 244. */
35*4882a593Smuzhiyun #define VBI_OFFSET 244
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun /* 2048 for compatibility with earlier driver versions. The driver
38*4882a593Smuzhiyun really stores 1024 + tvnorm->vbipack * 4 samples per line in the
39*4882a593Smuzhiyun buffer. Note tvnorm->vbipack is <= 0xFF (limit of VBIPACK_LO + HI
40*4882a593Smuzhiyun is 0x1FF DWORDs) and VBI read()s store a frame counter in the last
41*4882a593Smuzhiyun four bytes of the VBI image. */
42*4882a593Smuzhiyun #define VBI_BPL 2048
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun /* Compatibility. */
45*4882a593Smuzhiyun #define VBI_DEFLINES 16
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun static unsigned int vbibufs = 4;
48*4882a593Smuzhiyun static unsigned int vbi_debug;
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun module_param(vbibufs, int, 0444);
51*4882a593Smuzhiyun module_param(vbi_debug, int, 0644);
52*4882a593Smuzhiyun MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32, default 4");
53*4882a593Smuzhiyun MODULE_PARM_DESC(vbi_debug,"vbi code debug messages, default is 0 (no)");
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun #ifdef dprintk
56*4882a593Smuzhiyun # undef dprintk
57*4882a593Smuzhiyun #endif
58*4882a593Smuzhiyun #define dprintk(fmt, ...) \
59*4882a593Smuzhiyun do { \
60*4882a593Smuzhiyun if (vbi_debug) \
61*4882a593Smuzhiyun pr_debug("%d: " fmt, btv->c.nr, ##__VA_ARGS__); \
62*4882a593Smuzhiyun } while (0)
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun #define IMAGE_SIZE(fmt) \
65*4882a593Smuzhiyun (((fmt)->count[0] + (fmt)->count[1]) * (fmt)->samples_per_line)
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun /* ----------------------------------------------------------------------- */
68*4882a593Smuzhiyun /* vbi risc code + mm */
69*4882a593Smuzhiyun
vbi_buffer_setup(struct videobuf_queue * q,unsigned int * count,unsigned int * size)70*4882a593Smuzhiyun static int vbi_buffer_setup(struct videobuf_queue *q,
71*4882a593Smuzhiyun unsigned int *count, unsigned int *size)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun struct bttv_fh *fh = q->priv_data;
74*4882a593Smuzhiyun struct bttv *btv = fh->btv;
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun if (0 == *count)
77*4882a593Smuzhiyun *count = vbibufs;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun *size = IMAGE_SIZE(&fh->vbi_fmt.fmt);
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun dprintk("setup: samples=%u start=%d,%d count=%u,%u\n",
82*4882a593Smuzhiyun fh->vbi_fmt.fmt.samples_per_line,
83*4882a593Smuzhiyun fh->vbi_fmt.fmt.start[0],
84*4882a593Smuzhiyun fh->vbi_fmt.fmt.start[1],
85*4882a593Smuzhiyun fh->vbi_fmt.fmt.count[0],
86*4882a593Smuzhiyun fh->vbi_fmt.fmt.count[1]);
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun return 0;
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun
vbi_buffer_prepare(struct videobuf_queue * q,struct videobuf_buffer * vb,enum v4l2_field field)91*4882a593Smuzhiyun static int vbi_buffer_prepare(struct videobuf_queue *q,
92*4882a593Smuzhiyun struct videobuf_buffer *vb,
93*4882a593Smuzhiyun enum v4l2_field field)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun struct bttv_fh *fh = q->priv_data;
96*4882a593Smuzhiyun struct bttv *btv = fh->btv;
97*4882a593Smuzhiyun struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
98*4882a593Smuzhiyun const struct bttv_tvnorm *tvnorm;
99*4882a593Smuzhiyun unsigned int skip_lines0, skip_lines1, min_vdelay;
100*4882a593Smuzhiyun int redo_dma_risc;
101*4882a593Smuzhiyun int rc;
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun buf->vb.size = IMAGE_SIZE(&fh->vbi_fmt.fmt);
104*4882a593Smuzhiyun if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
105*4882a593Smuzhiyun return -EINVAL;
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun tvnorm = fh->vbi_fmt.tvnorm;
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun /* There's no VBI_VDELAY register, RISC must skip the lines
110*4882a593Smuzhiyun we don't want. With default parameters we skip zero lines
111*4882a593Smuzhiyun as earlier driver versions did. The driver permits video
112*4882a593Smuzhiyun standard changes while capturing, so we use vbi_fmt.tvnorm
113*4882a593Smuzhiyun instead of btv->tvnorm to skip zero lines after video
114*4882a593Smuzhiyun standard changes as well. */
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun skip_lines0 = 0;
117*4882a593Smuzhiyun skip_lines1 = 0;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun if (fh->vbi_fmt.fmt.count[0] > 0)
120*4882a593Smuzhiyun skip_lines0 = max(0, (fh->vbi_fmt.fmt.start[0]
121*4882a593Smuzhiyun - tvnorm->vbistart[0]));
122*4882a593Smuzhiyun if (fh->vbi_fmt.fmt.count[1] > 0)
123*4882a593Smuzhiyun skip_lines1 = max(0, (fh->vbi_fmt.fmt.start[1]
124*4882a593Smuzhiyun - tvnorm->vbistart[1]));
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun redo_dma_risc = 0;
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun if (buf->vbi_skip[0] != skip_lines0 ||
129*4882a593Smuzhiyun buf->vbi_skip[1] != skip_lines1 ||
130*4882a593Smuzhiyun buf->vbi_count[0] != fh->vbi_fmt.fmt.count[0] ||
131*4882a593Smuzhiyun buf->vbi_count[1] != fh->vbi_fmt.fmt.count[1]) {
132*4882a593Smuzhiyun buf->vbi_skip[0] = skip_lines0;
133*4882a593Smuzhiyun buf->vbi_skip[1] = skip_lines1;
134*4882a593Smuzhiyun buf->vbi_count[0] = fh->vbi_fmt.fmt.count[0];
135*4882a593Smuzhiyun buf->vbi_count[1] = fh->vbi_fmt.fmt.count[1];
136*4882a593Smuzhiyun redo_dma_risc = 1;
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
140*4882a593Smuzhiyun redo_dma_risc = 1;
141*4882a593Smuzhiyun if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL)))
142*4882a593Smuzhiyun goto fail;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun if (redo_dma_risc) {
146*4882a593Smuzhiyun unsigned int bpl, padding, offset;
147*4882a593Smuzhiyun struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun bpl = 2044; /* max. vbipack */
150*4882a593Smuzhiyun padding = VBI_BPL - bpl;
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun if (fh->vbi_fmt.fmt.count[0] > 0) {
153*4882a593Smuzhiyun rc = bttv_risc_packed(btv, &buf->top,
154*4882a593Smuzhiyun dma->sglist,
155*4882a593Smuzhiyun /* offset */ 0, bpl,
156*4882a593Smuzhiyun padding, skip_lines0,
157*4882a593Smuzhiyun fh->vbi_fmt.fmt.count[0]);
158*4882a593Smuzhiyun if (0 != rc)
159*4882a593Smuzhiyun goto fail;
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun if (fh->vbi_fmt.fmt.count[1] > 0) {
163*4882a593Smuzhiyun offset = fh->vbi_fmt.fmt.count[0] * VBI_BPL;
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun rc = bttv_risc_packed(btv, &buf->bottom,
166*4882a593Smuzhiyun dma->sglist,
167*4882a593Smuzhiyun offset, bpl,
168*4882a593Smuzhiyun padding, skip_lines1,
169*4882a593Smuzhiyun fh->vbi_fmt.fmt.count[1]);
170*4882a593Smuzhiyun if (0 != rc)
171*4882a593Smuzhiyun goto fail;
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun /* VBI capturing ends at VDELAY, start of video capturing,
176*4882a593Smuzhiyun no matter where the RISC program ends. VDELAY minimum is 2,
177*4882a593Smuzhiyun bounds.top is the corresponding first field line number
178*4882a593Smuzhiyun times two. VDELAY counts half field lines. */
179*4882a593Smuzhiyun min_vdelay = MIN_VDELAY;
180*4882a593Smuzhiyun if (fh->vbi_fmt.end >= tvnorm->cropcap.bounds.top)
181*4882a593Smuzhiyun min_vdelay += fh->vbi_fmt.end - tvnorm->cropcap.bounds.top;
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun /* For bttv_buffer_activate_vbi(). */
184*4882a593Smuzhiyun buf->geo.vdelay = min_vdelay;
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun buf->vb.state = VIDEOBUF_PREPARED;
187*4882a593Smuzhiyun buf->vb.field = field;
188*4882a593Smuzhiyun dprintk("buf prepare %p: top=%p bottom=%p field=%s\n",
189*4882a593Smuzhiyun vb, &buf->top, &buf->bottom,
190*4882a593Smuzhiyun v4l2_field_names[buf->vb.field]);
191*4882a593Smuzhiyun return 0;
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun fail:
194*4882a593Smuzhiyun bttv_dma_free(q,btv,buf);
195*4882a593Smuzhiyun return rc;
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun static void
vbi_buffer_queue(struct videobuf_queue * q,struct videobuf_buffer * vb)199*4882a593Smuzhiyun vbi_buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
200*4882a593Smuzhiyun {
201*4882a593Smuzhiyun struct bttv_fh *fh = q->priv_data;
202*4882a593Smuzhiyun struct bttv *btv = fh->btv;
203*4882a593Smuzhiyun struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun dprintk("queue %p\n",vb);
206*4882a593Smuzhiyun buf->vb.state = VIDEOBUF_QUEUED;
207*4882a593Smuzhiyun list_add_tail(&buf->vb.queue,&btv->vcapture);
208*4882a593Smuzhiyun if (NULL == btv->cvbi) {
209*4882a593Smuzhiyun fh->btv->loop_irq |= 4;
210*4882a593Smuzhiyun bttv_set_dma(btv,0x0c);
211*4882a593Smuzhiyun }
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun
vbi_buffer_release(struct videobuf_queue * q,struct videobuf_buffer * vb)214*4882a593Smuzhiyun static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
215*4882a593Smuzhiyun {
216*4882a593Smuzhiyun struct bttv_fh *fh = q->priv_data;
217*4882a593Smuzhiyun struct bttv *btv = fh->btv;
218*4882a593Smuzhiyun struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun dprintk("free %p\n",vb);
221*4882a593Smuzhiyun bttv_dma_free(q,fh->btv,buf);
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun const struct videobuf_queue_ops bttv_vbi_qops = {
225*4882a593Smuzhiyun .buf_setup = vbi_buffer_setup,
226*4882a593Smuzhiyun .buf_prepare = vbi_buffer_prepare,
227*4882a593Smuzhiyun .buf_queue = vbi_buffer_queue,
228*4882a593Smuzhiyun .buf_release = vbi_buffer_release,
229*4882a593Smuzhiyun };
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun /* ----------------------------------------------------------------------- */
232*4882a593Smuzhiyun
try_fmt(struct v4l2_vbi_format * f,const struct bttv_tvnorm * tvnorm,__s32 crop_start)233*4882a593Smuzhiyun static int try_fmt(struct v4l2_vbi_format *f, const struct bttv_tvnorm *tvnorm,
234*4882a593Smuzhiyun __s32 crop_start)
235*4882a593Smuzhiyun {
236*4882a593Smuzhiyun __s32 min_start, max_start, max_end, f2_offset;
237*4882a593Smuzhiyun unsigned int i;
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun /* For compatibility with earlier driver versions we must pretend
240*4882a593Smuzhiyun the VBI and video capture window may overlap. In reality RISC
241*4882a593Smuzhiyun magic aborts VBI capturing at the first line of video capturing,
242*4882a593Smuzhiyun leaving the rest of the buffer unchanged, usually all zero.
243*4882a593Smuzhiyun VBI capturing must always start before video capturing. >> 1
244*4882a593Smuzhiyun because cropping counts field lines times two. */
245*4882a593Smuzhiyun min_start = tvnorm->vbistart[0];
246*4882a593Smuzhiyun max_start = (crop_start >> 1) - 1;
247*4882a593Smuzhiyun max_end = (tvnorm->cropcap.bounds.top
248*4882a593Smuzhiyun + tvnorm->cropcap.bounds.height) >> 1;
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun if (min_start > max_start)
251*4882a593Smuzhiyun return -EBUSY;
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun BUG_ON(max_start >= max_end);
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun f->sampling_rate = tvnorm->Fsc;
256*4882a593Smuzhiyun f->samples_per_line = VBI_BPL;
257*4882a593Smuzhiyun f->sample_format = V4L2_PIX_FMT_GREY;
258*4882a593Smuzhiyun f->offset = VBI_OFFSET;
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun f2_offset = tvnorm->vbistart[1] - tvnorm->vbistart[0];
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun for (i = 0; i < 2; ++i) {
263*4882a593Smuzhiyun if (0 == f->count[i]) {
264*4882a593Smuzhiyun /* No data from this field. We leave f->start[i]
265*4882a593Smuzhiyun alone because VIDIOCSVBIFMT is w/o and EINVALs
266*4882a593Smuzhiyun when a driver does not support exactly the
267*4882a593Smuzhiyun requested parameters. */
268*4882a593Smuzhiyun } else {
269*4882a593Smuzhiyun s64 start, count;
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun start = clamp(f->start[i], min_start, max_start);
272*4882a593Smuzhiyun /* s64 to prevent overflow. */
273*4882a593Smuzhiyun count = (s64) f->start[i] + f->count[i] - start;
274*4882a593Smuzhiyun f->start[i] = start;
275*4882a593Smuzhiyun f->count[i] = clamp(count, (s64) 1,
276*4882a593Smuzhiyun max_end - start);
277*4882a593Smuzhiyun }
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun min_start += f2_offset;
280*4882a593Smuzhiyun max_start += f2_offset;
281*4882a593Smuzhiyun max_end += f2_offset;
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun if (0 == (f->count[0] | f->count[1])) {
285*4882a593Smuzhiyun /* As in earlier driver versions. */
286*4882a593Smuzhiyun f->start[0] = tvnorm->vbistart[0];
287*4882a593Smuzhiyun f->start[1] = tvnorm->vbistart[1];
288*4882a593Smuzhiyun f->count[0] = 1;
289*4882a593Smuzhiyun f->count[1] = 1;
290*4882a593Smuzhiyun }
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun f->flags = 0;
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun f->reserved[0] = 0;
295*4882a593Smuzhiyun f->reserved[1] = 0;
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun return 0;
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun
bttv_try_fmt_vbi_cap(struct file * file,void * f,struct v4l2_format * frt)300*4882a593Smuzhiyun int bttv_try_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun struct bttv_fh *fh = f;
303*4882a593Smuzhiyun struct bttv *btv = fh->btv;
304*4882a593Smuzhiyun const struct bttv_tvnorm *tvnorm;
305*4882a593Smuzhiyun __s32 crop_start;
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun mutex_lock(&btv->lock);
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun tvnorm = &bttv_tvnorms[btv->tvnorm];
310*4882a593Smuzhiyun crop_start = btv->crop_start;
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun mutex_unlock(&btv->lock);
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun return try_fmt(&frt->fmt.vbi, tvnorm, crop_start);
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun
bttv_s_fmt_vbi_cap(struct file * file,void * f,struct v4l2_format * frt)318*4882a593Smuzhiyun int bttv_s_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
319*4882a593Smuzhiyun {
320*4882a593Smuzhiyun struct bttv_fh *fh = f;
321*4882a593Smuzhiyun struct bttv *btv = fh->btv;
322*4882a593Smuzhiyun const struct bttv_tvnorm *tvnorm;
323*4882a593Smuzhiyun __s32 start1, end;
324*4882a593Smuzhiyun int rc;
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun mutex_lock(&btv->lock);
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun rc = -EBUSY;
329*4882a593Smuzhiyun if (fh->resources & RESOURCE_VBI)
330*4882a593Smuzhiyun goto fail;
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun tvnorm = &bttv_tvnorms[btv->tvnorm];
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun rc = try_fmt(&frt->fmt.vbi, tvnorm, btv->crop_start);
335*4882a593Smuzhiyun if (0 != rc)
336*4882a593Smuzhiyun goto fail;
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun start1 = frt->fmt.vbi.start[1] - tvnorm->vbistart[1] +
339*4882a593Smuzhiyun tvnorm->vbistart[0];
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun /* First possible line of video capturing. Should be
342*4882a593Smuzhiyun max(f->start[0] + f->count[0], start1 + f->count[1]) * 2
343*4882a593Smuzhiyun when capturing both fields. But for compatibility we must
344*4882a593Smuzhiyun pretend the VBI and video capture window may overlap,
345*4882a593Smuzhiyun so end = start + 1, the lowest possible value, times two
346*4882a593Smuzhiyun because vbi_fmt.end counts field lines times two. */
347*4882a593Smuzhiyun end = max(frt->fmt.vbi.start[0], start1) * 2 + 2;
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun mutex_lock(&fh->vbi.vb_lock);
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun fh->vbi_fmt.fmt = frt->fmt.vbi;
352*4882a593Smuzhiyun fh->vbi_fmt.tvnorm = tvnorm;
353*4882a593Smuzhiyun fh->vbi_fmt.end = end;
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun mutex_unlock(&fh->vbi.vb_lock);
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun rc = 0;
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun fail:
360*4882a593Smuzhiyun mutex_unlock(&btv->lock);
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun return rc;
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun
bttv_g_fmt_vbi_cap(struct file * file,void * f,struct v4l2_format * frt)366*4882a593Smuzhiyun int bttv_g_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
367*4882a593Smuzhiyun {
368*4882a593Smuzhiyun struct bttv_fh *fh = f;
369*4882a593Smuzhiyun const struct bttv_tvnorm *tvnorm;
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun frt->fmt.vbi = fh->vbi_fmt.fmt;
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun tvnorm = &bttv_tvnorms[fh->btv->tvnorm];
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun if (tvnorm != fh->vbi_fmt.tvnorm) {
376*4882a593Smuzhiyun __s32 max_end;
377*4882a593Smuzhiyun unsigned int i;
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun /* As in vbi_buffer_prepare() this imitates the
380*4882a593Smuzhiyun behaviour of earlier driver versions after video
381*4882a593Smuzhiyun standard changes, with default parameters anyway. */
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun max_end = (tvnorm->cropcap.bounds.top
384*4882a593Smuzhiyun + tvnorm->cropcap.bounds.height) >> 1;
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun frt->fmt.vbi.sampling_rate = tvnorm->Fsc;
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun for (i = 0; i < 2; ++i) {
389*4882a593Smuzhiyun __s32 new_start;
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun new_start = frt->fmt.vbi.start[i]
392*4882a593Smuzhiyun + tvnorm->vbistart[i]
393*4882a593Smuzhiyun - fh->vbi_fmt.tvnorm->vbistart[i];
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun frt->fmt.vbi.start[i] = min(new_start, max_end - 1);
396*4882a593Smuzhiyun frt->fmt.vbi.count[i] =
397*4882a593Smuzhiyun min((__s32) frt->fmt.vbi.count[i],
398*4882a593Smuzhiyun max_end - frt->fmt.vbi.start[i]);
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun max_end += tvnorm->vbistart[1]
401*4882a593Smuzhiyun - tvnorm->vbistart[0];
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun }
404*4882a593Smuzhiyun return 0;
405*4882a593Smuzhiyun }
406*4882a593Smuzhiyun
bttv_vbi_fmt_reset(struct bttv_vbi_fmt * f,unsigned int norm)407*4882a593Smuzhiyun void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm)
408*4882a593Smuzhiyun {
409*4882a593Smuzhiyun const struct bttv_tvnorm *tvnorm;
410*4882a593Smuzhiyun unsigned int real_samples_per_line;
411*4882a593Smuzhiyun unsigned int real_count;
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun tvnorm = &bttv_tvnorms[norm];
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun f->fmt.sampling_rate = tvnorm->Fsc;
416*4882a593Smuzhiyun f->fmt.samples_per_line = VBI_BPL;
417*4882a593Smuzhiyun f->fmt.sample_format = V4L2_PIX_FMT_GREY;
418*4882a593Smuzhiyun f->fmt.offset = VBI_OFFSET;
419*4882a593Smuzhiyun f->fmt.start[0] = tvnorm->vbistart[0];
420*4882a593Smuzhiyun f->fmt.start[1] = tvnorm->vbistart[1];
421*4882a593Smuzhiyun f->fmt.count[0] = VBI_DEFLINES;
422*4882a593Smuzhiyun f->fmt.count[1] = VBI_DEFLINES;
423*4882a593Smuzhiyun f->fmt.flags = 0;
424*4882a593Smuzhiyun f->fmt.reserved[0] = 0;
425*4882a593Smuzhiyun f->fmt.reserved[1] = 0;
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun /* For compatibility the buffer size must be 2 * VBI_DEFLINES *
428*4882a593Smuzhiyun VBI_BPL regardless of the current video standard. */
429*4882a593Smuzhiyun real_samples_per_line = 1024 + tvnorm->vbipack * 4;
430*4882a593Smuzhiyun real_count = ((tvnorm->cropcap.defrect.top >> 1)
431*4882a593Smuzhiyun - tvnorm->vbistart[0]);
432*4882a593Smuzhiyun
433*4882a593Smuzhiyun BUG_ON(real_samples_per_line > VBI_BPL);
434*4882a593Smuzhiyun BUG_ON(real_count > VBI_DEFLINES);
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun f->tvnorm = tvnorm;
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun /* See bttv_vbi_fmt_set(). */
439*4882a593Smuzhiyun f->end = tvnorm->vbistart[0] * 2 + 2;
440*4882a593Smuzhiyun }
441