File Index
Files and directories
Sign in
FILE

bttv-vbi.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/pci/bt8xx/bttv-vbi.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3
  4    bttv - Bt848 frame grabber driver
  5    vbi interface
  6
  7    (c) 2002 Gerd Knorr <kraxel@bytesex.org>
  8
  9    Copyright (C) 2005, 2006 Michael H. Schimek <mschimek@gmx.at>
 10    Sponsored by OPQ Systems AB
 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/* Offset from line sync pulse leading edge (0H) to start of VBI capture,
 27   in fCLKx2 pixels.  According to the datasheet, VBI capture starts
 28   VBI_HDELAY fCLKx1 pixels from the tailing edgeof /HRESET, and /HRESET
 29   is 64 fCLKx1 pixels wide.  VBI_HDELAY is set to 0, so this should be
 30   (64 + 0) * 2 = 128 fCLKx2 pixels.  But it's not!  The datasheet is
 31   Just Plain Wrong.  The real value appears to be different for
 32   different revisions of the bt8x8 chips, and to be affected by the
 33   horizontal scaling factor.  Experimentally, the value is measured
 34   to be about 244.  */
 35#define VBI_OFFSET 244
 36
 37static unsigned int vbibufs = 4;
 38static unsigned int vbi_debug;
 39
 40module_param(vbibufs,   int, 0444);
 41module_param(vbi_debug, int, 0644);
 42MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32, default 4");
 43MODULE_PARM_DESC(vbi_debug,"vbi code debug messages, default is 0 (no)");
 44
 45#ifdef dprintk
 46# undef dprintk
 47#endif
 48#define dprintk(fmt, ...)						\
 49do {									\
 50	if (vbi_debug)							\
 51		pr_debug("%d: " fmt, btv->c.nr, ##__VA_ARGS__);		\
 52} while (0)
 53
 54#define IMAGE_SIZE(fmt) \
 55	(((fmt)->count[0] + (fmt)->count[1]) * (fmt)->samples_per_line)
 56
 57/* ----------------------------------------------------------------------- */
 58/* vbi risc code + mm                                                      */
 59
 60static int queue_setup_vbi(struct vb2_queue *q, unsigned int *num_buffers,
 61			   unsigned int *num_planes, unsigned int sizes[],
 62			   struct device *alloc_devs[])
 63{
 64	struct bttv *btv = vb2_get_drv_priv(q);
 65	unsigned int size = IMAGE_SIZE(&btv->vbi_fmt.fmt);
 66
 67	if (*num_planes)
 68		return sizes[0] < size ? -EINVAL : 0;
 69	*num_planes = 1;
 70	sizes[0] = size;
 71
 72	return 0;
 73}
 74
 75static void buf_queue_vbi(struct vb2_buffer *vb)
 76{
 77	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 78	struct vb2_queue *vq = vb->vb2_queue;
 79	struct bttv *btv = vb2_get_drv_priv(vq);
 80	struct bttv_buffer *buf = container_of(vbuf, struct bttv_buffer, vbuf);
 81	unsigned long flags;
 82
 83	spin_lock_irqsave(&btv->s_lock, flags);
 84	if (list_empty(&btv->vcapture)) {
 85		btv->loop_irq = BT848_RISC_VBI;
 86		if (vb2_is_streaming(&btv->capq))
 87			btv->loop_irq |= BT848_RISC_VIDEO;
 88		bttv_set_dma(btv, BT848_CAP_CTL_CAPTURE_VBI_ODD |
 89			     BT848_CAP_CTL_CAPTURE_VBI_EVEN);
 90	}
 91	list_add_tail(&buf->list, &btv->vcapture);
 92	spin_unlock_irqrestore(&btv->s_lock, flags);
 93}
 94
 95static int buf_prepare_vbi(struct vb2_buffer *vb)
 96{
 97	int ret = 0;
 98	struct vb2_queue *vq = vb->vb2_queue;
 99	struct bttv *btv = vb2_get_drv_priv(vq);
100	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
101	struct bttv_buffer *buf = container_of(vbuf, struct bttv_buffer, vbuf);
102	unsigned int size = IMAGE_SIZE(&btv->vbi_fmt.fmt);
103
104	if (vb2_plane_size(vb, 0) < size)
105		return -EINVAL;
106	vb2_set_plane_payload(vb, 0, size);
107	buf->vbuf.field = V4L2_FIELD_NONE;
108	ret = bttv_buffer_risc_vbi(btv, buf);
109
110	return ret;
111}
112
113static void buf_cleanup_vbi(struct vb2_buffer *vb)
114{
115	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
116	struct bttv_buffer *buf = container_of(vbuf, struct bttv_buffer, vbuf);
117	struct vb2_queue *vq = vb->vb2_queue;
118	struct bttv *btv = vb2_get_drv_priv(vq);
119
120	btcx_riscmem_free(btv->c.pci, &buf->top);
121	btcx_riscmem_free(btv->c.pci, &buf->bottom);
122}
123
124static int start_streaming_vbi(struct vb2_queue *q, unsigned int count)
125{
126	int seqnr = 0;
127	struct bttv_buffer *buf;
128	struct bttv *btv = vb2_get_drv_priv(q);
129
130	btv->framedrop = 0;
131	if (!check_alloc_btres_lock(btv, RESOURCE_VBI)) {
132		if (btv->field_count)
133			seqnr++;
134		while (!list_empty(&btv->vcapture)) {
135			buf = list_entry(btv->vcapture.next,
136					 struct bttv_buffer, list);
137			list_del(&buf->list);
138			buf->vbuf.sequence = (btv->field_count >> 1) + seqnr++;
139			vb2_buffer_done(&buf->vbuf.vb2_buf,
140					VB2_BUF_STATE_QUEUED);
141		}
142		return -EBUSY;
143	}
144	if (!vb2_is_streaming(&btv->capq)) {
145		init_irqreg(btv);
146		btv->field_count = 0;
147	}
148	return 0;
149}
150
151static void stop_streaming_vbi(struct vb2_queue *q)
152{
153	struct bttv *btv = vb2_get_drv_priv(q);
154	unsigned long flags;
155
156	vb2_wait_for_all_buffers(q);
157	spin_lock_irqsave(&btv->s_lock, flags);
158	free_btres_lock(btv, RESOURCE_VBI);
159	if (!vb2_is_streaming(&btv->capq)) {
160		/* stop field counter */
161		btand(~BT848_INT_VSYNC, BT848_INT_MASK);
162	}
163	spin_unlock_irqrestore(&btv->s_lock, flags);
164}
165
166const struct vb2_ops bttv_vbi_qops = {
167	.queue_setup    = queue_setup_vbi,
168	.buf_queue      = buf_queue_vbi,
169	.buf_prepare    = buf_prepare_vbi,
170	.buf_cleanup	= buf_cleanup_vbi,
171	.start_streaming = start_streaming_vbi,
172	.stop_streaming = stop_streaming_vbi,
173};
174
175/* ----------------------------------------------------------------------- */
176
177static int try_fmt(struct v4l2_vbi_format *f, const struct bttv_tvnorm *tvnorm,
178			__s32 crop_start)
179{
180	__s32 min_start, max_start, max_end, f2_offset;
181	unsigned int i;
182
183	/* For compatibility with earlier driver versions we must pretend
184	   the VBI and video capture window may overlap. In reality RISC
185	   magic aborts VBI capturing at the first line of video capturing,
186	   leaving the rest of the buffer unchanged, usually all zero.
187	   VBI capturing must always start before video capturing. >> 1
188	   because cropping counts field lines times two. */
189	min_start = tvnorm->vbistart[0];
190	max_start = (crop_start >> 1) - 1;
191	max_end = (tvnorm->cropcap.bounds.top
192		   + tvnorm->cropcap.bounds.height) >> 1;
193
194	if (min_start > max_start)
195		return -EBUSY;
196
197	WARN_ON(max_start >= max_end);
198
199	f->sampling_rate    = tvnorm->Fsc;
200	f->samples_per_line = VBI_BPL;
201	f->sample_format    = V4L2_PIX_FMT_GREY;
202	f->offset           = VBI_OFFSET;
203
204	f2_offset = tvnorm->vbistart[1] - tvnorm->vbistart[0];
205
206	for (i = 0; i < 2; ++i) {
207		if (0 == f->count[i]) {
208			/* No data from this field. We leave f->start[i]
209			   alone because VIDIOCSVBIFMT is w/o and EINVALs
210			   when a driver does not support exactly the
211			   requested parameters. */
212		} else {
213			s64 start, count;
214
215			start = clamp(f->start[i], min_start, max_start);
216			/* s64 to prevent overflow. */
217			count = (s64) f->start[i] + f->count[i] - start;
218			f->start[i] = start;
219			f->count[i] = clamp(count, (s64) 1,
220					    max_end - start);
221		}
222
223		min_start += f2_offset;
224		max_start += f2_offset;
225		max_end += f2_offset;
226	}
227
228	if (0 == (f->count[0] | f->count[1])) {
229		/* As in earlier driver versions. */
230		f->start[0] = tvnorm->vbistart[0];
231		f->start[1] = tvnorm->vbistart[1];
232		f->count[0] = 1;
233		f->count[1] = 1;
234	}
235
236	f->flags = 0;
237
238	f->reserved[0] = 0;
239	f->reserved[1] = 0;
240
241	return 0;
242}
243
244int bttv_try_fmt_vbi_cap(struct file *file, void *priv, struct v4l2_format *frt)
245{
246	struct bttv *btv = video_drvdata(file);
247	const struct bttv_tvnorm *tvnorm;
248	__s32 crop_start;
249
250	mutex_lock(&btv->lock);
251
252	tvnorm = &bttv_tvnorms[btv->tvnorm];
253	crop_start = btv->crop_start;
254
255	mutex_unlock(&btv->lock);
256
257	return try_fmt(&frt->fmt.vbi, tvnorm, crop_start);
258}
259
260
261int bttv_s_fmt_vbi_cap(struct file *file, void *priv, struct v4l2_format *frt)
262{
263	struct bttv *btv = video_drvdata(file);
264	const struct bttv_tvnorm *tvnorm;
265	__s32 start1, end;
266	int rc;
267
268	mutex_lock(&btv->lock);
269
270	rc = -EBUSY;
271	if (btv->resources & RESOURCE_VBI)
272		goto fail;
273
274	tvnorm = &bttv_tvnorms[btv->tvnorm];
275
276	rc = try_fmt(&frt->fmt.vbi, tvnorm, btv->crop_start);
277	if (0 != rc)
278		goto fail;
279
280	start1 = frt->fmt.vbi.start[1] - tvnorm->vbistart[1] +
281		tvnorm->vbistart[0];
282
283	/* First possible line of video capturing. Should be
284	   max(f->start[0] + f->count[0], start1 + f->count[1]) * 2
285	   when capturing both fields. But for compatibility we must
286	   pretend the VBI and video capture window may overlap,
287	   so end = start + 1, the lowest possible value, times two
288	   because vbi_fmt.end counts field lines times two. */
289	end = max(frt->fmt.vbi.start[0], start1) * 2 + 2;
290
291	btv->vbi_fmt.fmt = frt->fmt.vbi;
292	btv->vbi_fmt.tvnorm = tvnorm;
293	btv->vbi_fmt.end = end;
294
295	rc = 0;
296
297 fail:
298	mutex_unlock(&btv->lock);
299
300	return rc;
301}
302
303
304int bttv_g_fmt_vbi_cap(struct file *file, void *priv, struct v4l2_format *frt)
305{
306	const struct bttv_tvnorm *tvnorm;
307	struct bttv *btv = video_drvdata(file);
308
309	frt->fmt.vbi = btv->vbi_fmt.fmt;
310
311	tvnorm = &bttv_tvnorms[btv->tvnorm];
312
313	if (tvnorm != btv->vbi_fmt.tvnorm) {
314		__s32 max_end;
315		unsigned int i;
316
317		/* As in vbi_buffer_prepare() this imitates the
318		   behaviour of earlier driver versions after video
319		   standard changes, with default parameters anyway. */
320
321		max_end = (tvnorm->cropcap.bounds.top
322			   + tvnorm->cropcap.bounds.height) >> 1;
323
324		frt->fmt.vbi.sampling_rate = tvnorm->Fsc;
325
326		for (i = 0; i < 2; ++i) {
327			__s32 new_start;
328
329			new_start = frt->fmt.vbi.start[i] + tvnorm->vbistart[i]
330				- btv->vbi_fmt.tvnorm->vbistart[i];
331
332			frt->fmt.vbi.start[i] = min(new_start, max_end - 1);
333			frt->fmt.vbi.count[i] =
334				min((__s32) frt->fmt.vbi.count[i],
335					  max_end - frt->fmt.vbi.start[i]);
336
337			max_end += tvnorm->vbistart[1]
338				- tvnorm->vbistart[0];
339		}
340	}
341	return 0;
342}
343
344void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm)
345{
346	const struct bttv_tvnorm *tvnorm;
347	unsigned int real_samples_per_line;
348	unsigned int real_count;
349
350	tvnorm = &bttv_tvnorms[norm];
351
352	f->fmt.sampling_rate    = tvnorm->Fsc;
353	f->fmt.samples_per_line = VBI_BPL;
354	f->fmt.sample_format    = V4L2_PIX_FMT_GREY;
355	f->fmt.offset           = VBI_OFFSET;
356	f->fmt.start[0]		= tvnorm->vbistart[0];
357	f->fmt.start[1]		= tvnorm->vbistart[1];
358	f->fmt.count[0]		= VBI_DEFLINES;
359	f->fmt.count[1]		= VBI_DEFLINES;
360	f->fmt.flags            = 0;
361	f->fmt.reserved[0]      = 0;
362	f->fmt.reserved[1]      = 0;
363
364	/* For compatibility the buffer size must be 2 * VBI_DEFLINES *
365	   VBI_BPL regardless of the current video standard. */
366	real_samples_per_line   = 1024 + tvnorm->vbipack * 4;
367	real_count              = ((tvnorm->cropcap.defrect.top >> 1)
368				   - tvnorm->vbistart[0]);
369
370	WARN_ON(real_samples_per_line > VBI_BPL);
371	WARN_ON(real_count > VBI_DEFLINES);
372
373	f->tvnorm               = tvnorm;
374
375	/* See bttv_vbi_fmt_set(). */
376	f->end                  = tvnorm->vbistart[0] * 2 + 2;
377}
~/ Read-only file preview.