brintos

brintos / linux-shallow public Read only

0
0
Text · 10.3 KiB · e489a3a Raw
380 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 4    bttv - Bt848 frame grabber driver5    vbi interface6 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 AB11 12*/13 14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt15 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 starts28   VBI_HDELAY fCLKx1 pixels from the tailing edgeof /HRESET, and /HRESET29   is 64 fCLKx1 pixels wide.  VBI_HDELAY is set to 0, so this should be30   (64 + 0) * 2 = 128 fCLKx2 pixels.  But it's not!  The datasheet is31   Just Plain Wrong.  The real value appears to be different for32   different revisions of the bt8x8 chips, and to be affected by the33   horizontal scaling factor.  Experimentally, the value is measured34   to be about 244.  */35#define VBI_OFFSET 24436 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 dprintk46# undef dprintk47#endif48#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	.wait_prepare   = vb2_ops_wait_prepare,174	.wait_finish    = vb2_ops_wait_finish,175};176 177/* ----------------------------------------------------------------------- */178 179static int try_fmt(struct v4l2_vbi_format *f, const struct bttv_tvnorm *tvnorm,180			__s32 crop_start)181{182	__s32 min_start, max_start, max_end, f2_offset;183	unsigned int i;184 185	/* For compatibility with earlier driver versions we must pretend186	   the VBI and video capture window may overlap. In reality RISC187	   magic aborts VBI capturing at the first line of video capturing,188	   leaving the rest of the buffer unchanged, usually all zero.189	   VBI capturing must always start before video capturing. >> 1190	   because cropping counts field lines times two. */191	min_start = tvnorm->vbistart[0];192	max_start = (crop_start >> 1) - 1;193	max_end = (tvnorm->cropcap.bounds.top194		   + tvnorm->cropcap.bounds.height) >> 1;195 196	if (min_start > max_start)197		return -EBUSY;198 199	WARN_ON(max_start >= max_end);200 201	f->sampling_rate    = tvnorm->Fsc;202	f->samples_per_line = VBI_BPL;203	f->sample_format    = V4L2_PIX_FMT_GREY;204	f->offset           = VBI_OFFSET;205 206	f2_offset = tvnorm->vbistart[1] - tvnorm->vbistart[0];207 208	for (i = 0; i < 2; ++i) {209		if (0 == f->count[i]) {210			/* No data from this field. We leave f->start[i]211			   alone because VIDIOCSVBIFMT is w/o and EINVALs212			   when a driver does not support exactly the213			   requested parameters. */214		} else {215			s64 start, count;216 217			start = clamp(f->start[i], min_start, max_start);218			/* s64 to prevent overflow. */219			count = (s64) f->start[i] + f->count[i] - start;220			f->start[i] = start;221			f->count[i] = clamp(count, (s64) 1,222					    max_end - start);223		}224 225		min_start += f2_offset;226		max_start += f2_offset;227		max_end += f2_offset;228	}229 230	if (0 == (f->count[0] | f->count[1])) {231		/* As in earlier driver versions. */232		f->start[0] = tvnorm->vbistart[0];233		f->start[1] = tvnorm->vbistart[1];234		f->count[0] = 1;235		f->count[1] = 1;236	}237 238	f->flags = 0;239 240	f->reserved[0] = 0;241	f->reserved[1] = 0;242 243	return 0;244}245 246int bttv_try_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)247{248	struct bttv *btv = video_drvdata(file);249	const struct bttv_tvnorm *tvnorm;250	__s32 crop_start;251 252	mutex_lock(&btv->lock);253 254	tvnorm = &bttv_tvnorms[btv->tvnorm];255	crop_start = btv->crop_start;256 257	mutex_unlock(&btv->lock);258 259	return try_fmt(&frt->fmt.vbi, tvnorm, crop_start);260}261 262 263int bttv_s_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)264{265	struct bttv *btv = video_drvdata(file);266	const struct bttv_tvnorm *tvnorm;267	__s32 start1, end;268	int rc;269 270	mutex_lock(&btv->lock);271 272	rc = -EBUSY;273	if (btv->resources & RESOURCE_VBI)274		goto fail;275 276	tvnorm = &bttv_tvnorms[btv->tvnorm];277 278	rc = try_fmt(&frt->fmt.vbi, tvnorm, btv->crop_start);279	if (0 != rc)280		goto fail;281 282	start1 = frt->fmt.vbi.start[1] - tvnorm->vbistart[1] +283		tvnorm->vbistart[0];284 285	/* First possible line of video capturing. Should be286	   max(f->start[0] + f->count[0], start1 + f->count[1]) * 2287	   when capturing both fields. But for compatibility we must288	   pretend the VBI and video capture window may overlap,289	   so end = start + 1, the lowest possible value, times two290	   because vbi_fmt.end counts field lines times two. */291	end = max(frt->fmt.vbi.start[0], start1) * 2 + 2;292 293	btv->vbi_fmt.fmt = frt->fmt.vbi;294	btv->vbi_fmt.tvnorm = tvnorm;295	btv->vbi_fmt.end = end;296 297	rc = 0;298 299 fail:300	mutex_unlock(&btv->lock);301 302	return rc;303}304 305 306int bttv_g_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)307{308	const struct bttv_tvnorm *tvnorm;309	struct bttv *btv = video_drvdata(file);310 311	frt->fmt.vbi = btv->vbi_fmt.fmt;312 313	tvnorm = &bttv_tvnorms[btv->tvnorm];314 315	if (tvnorm != btv->vbi_fmt.tvnorm) {316		__s32 max_end;317		unsigned int i;318 319		/* As in vbi_buffer_prepare() this imitates the320		   behaviour of earlier driver versions after video321		   standard changes, with default parameters anyway. */322 323		max_end = (tvnorm->cropcap.bounds.top324			   + tvnorm->cropcap.bounds.height) >> 1;325 326		frt->fmt.vbi.sampling_rate = tvnorm->Fsc;327 328		for (i = 0; i < 2; ++i) {329			__s32 new_start;330 331			new_start = frt->fmt.vbi.start[i] + tvnorm->vbistart[i]332				- btv->vbi_fmt.tvnorm->vbistart[i];333 334			frt->fmt.vbi.start[i] = min(new_start, max_end - 1);335			frt->fmt.vbi.count[i] =336				min((__s32) frt->fmt.vbi.count[i],337					  max_end - frt->fmt.vbi.start[i]);338 339			max_end += tvnorm->vbistart[1]340				- tvnorm->vbistart[0];341		}342	}343	return 0;344}345 346void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm)347{348	const struct bttv_tvnorm *tvnorm;349	unsigned int real_samples_per_line;350	unsigned int real_count;351 352	tvnorm = &bttv_tvnorms[norm];353 354	f->fmt.sampling_rate    = tvnorm->Fsc;355	f->fmt.samples_per_line = VBI_BPL;356	f->fmt.sample_format    = V4L2_PIX_FMT_GREY;357	f->fmt.offset           = VBI_OFFSET;358	f->fmt.start[0]		= tvnorm->vbistart[0];359	f->fmt.start[1]		= tvnorm->vbistart[1];360	f->fmt.count[0]		= VBI_DEFLINES;361	f->fmt.count[1]		= VBI_DEFLINES;362	f->fmt.flags            = 0;363	f->fmt.reserved[0]      = 0;364	f->fmt.reserved[1]      = 0;365 366	/* For compatibility the buffer size must be 2 * VBI_DEFLINES *367	   VBI_BPL regardless of the current video standard. */368	real_samples_per_line   = 1024 + tvnorm->vbipack * 4;369	real_count              = ((tvnorm->cropcap.defrect.top >> 1)370				   - tvnorm->vbistart[0]);371 372	WARN_ON(real_samples_per_line > VBI_BPL);373	WARN_ON(real_count > VBI_DEFLINES);374 375	f->tvnorm               = tvnorm;376 377	/* See bttv_vbi_fmt_set(). */378	f->end                  = tvnorm->vbistart[0] * 2 + 2;379}380