xref: /OK3568_Linux_fs/kernel/drivers/media/pci/bt8xx/bttv-vbi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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