Path: blob/master/drivers/media/video/bt8xx/bttv-vbi.c
10785 views
/*12bttv - Bt848 frame grabber driver3vbi interface45(c) 2002 Gerd Knorr <[email protected]>67Copyright (C) 2005, 2006 Michael H. Schimek <[email protected]>8Sponsored by OPQ Systems AB910This program is free software; you can redistribute it and/or modify11it under the terms of the GNU General Public License as published by12the Free Software Foundation; either version 2 of the License, or13(at your option) any later version.1415This program is distributed in the hope that it will be useful,16but WITHOUT ANY WARRANTY; without even the implied warranty of17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the18GNU General Public License for more details.1920You should have received a copy of the GNU General Public License21along with this program; if not, write to the Free Software22Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.23*/2425#include <linux/module.h>26#include <linux/errno.h>27#include <linux/fs.h>28#include <linux/kernel.h>29#include <linux/interrupt.h>30#include <linux/kdev_t.h>31#include <media/v4l2-ioctl.h>32#include <asm/io.h>33#include "bttvp.h"3435/* Offset from line sync pulse leading edge (0H) to start of VBI capture,36in fCLKx2 pixels. According to the datasheet, VBI capture starts37VBI_HDELAY fCLKx1 pixels from the tailing edgeof /HRESET, and /HRESET38is 64 fCLKx1 pixels wide. VBI_HDELAY is set to 0, so this should be39(64 + 0) * 2 = 128 fCLKx2 pixels. But it's not! The datasheet is40Just Plain Wrong. The real value appears to be different for41different revisions of the bt8x8 chips, and to be affected by the42horizontal scaling factor. Experimentally, the value is measured43to be about 244. */44#define VBI_OFFSET 2444546/* 2048 for compatibility with earlier driver versions. The driver47really stores 1024 + tvnorm->vbipack * 4 samples per line in the48buffer. Note tvnorm->vbipack is <= 0xFF (limit of VBIPACK_LO + HI49is 0x1FF DWORDs) and VBI read()s store a frame counter in the last50four bytes of the VBI image. */51#define VBI_BPL 20485253/* Compatibility. */54#define VBI_DEFLINES 165556static unsigned int vbibufs = 4;57static unsigned int vbi_debug;5859module_param(vbibufs, int, 0444);60module_param(vbi_debug, int, 0644);61MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32, default 4");62MODULE_PARM_DESC(vbi_debug,"vbi code debug messages, default is 0 (no)");6364#ifdef dprintk65# undef dprintk66#endif67#define dprintk(fmt, arg...) if (vbi_debug) \68printk(KERN_DEBUG "bttv%d/vbi: " fmt, btv->c.nr , ## arg)6970#define IMAGE_SIZE(fmt) \71(((fmt)->count[0] + (fmt)->count[1]) * (fmt)->samples_per_line)7273/* ----------------------------------------------------------------------- */74/* vbi risc code + mm */7576static int vbi_buffer_setup(struct videobuf_queue *q,77unsigned int *count, unsigned int *size)78{79struct bttv_fh *fh = q->priv_data;80struct bttv *btv = fh->btv;8182if (0 == *count)83*count = vbibufs;8485*size = IMAGE_SIZE(&fh->vbi_fmt.fmt);8687dprintk("setup: samples=%u start=%d,%d count=%u,%u\n",88fh->vbi_fmt.fmt.samples_per_line,89fh->vbi_fmt.fmt.start[0],90fh->vbi_fmt.fmt.start[1],91fh->vbi_fmt.fmt.count[0],92fh->vbi_fmt.fmt.count[1]);9394return 0;95}9697static int vbi_buffer_prepare(struct videobuf_queue *q,98struct videobuf_buffer *vb,99enum v4l2_field field)100{101struct bttv_fh *fh = q->priv_data;102struct bttv *btv = fh->btv;103struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);104const struct bttv_tvnorm *tvnorm;105unsigned int skip_lines0, skip_lines1, min_vdelay;106int redo_dma_risc;107int rc;108109buf->vb.size = IMAGE_SIZE(&fh->vbi_fmt.fmt);110if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)111return -EINVAL;112113tvnorm = fh->vbi_fmt.tvnorm;114115/* There's no VBI_VDELAY register, RISC must skip the lines116we don't want. With default parameters we skip zero lines117as earlier driver versions did. The driver permits video118standard changes while capturing, so we use vbi_fmt.tvnorm119instead of btv->tvnorm to skip zero lines after video120standard changes as well. */121122skip_lines0 = 0;123skip_lines1 = 0;124125if (fh->vbi_fmt.fmt.count[0] > 0)126skip_lines0 = max(0, (fh->vbi_fmt.fmt.start[0]127- tvnorm->vbistart[0]));128if (fh->vbi_fmt.fmt.count[1] > 0)129skip_lines1 = max(0, (fh->vbi_fmt.fmt.start[1]130- tvnorm->vbistart[1]));131132redo_dma_risc = 0;133134if (buf->vbi_skip[0] != skip_lines0 ||135buf->vbi_skip[1] != skip_lines1 ||136buf->vbi_count[0] != fh->vbi_fmt.fmt.count[0] ||137buf->vbi_count[1] != fh->vbi_fmt.fmt.count[1]) {138buf->vbi_skip[0] = skip_lines0;139buf->vbi_skip[1] = skip_lines1;140buf->vbi_count[0] = fh->vbi_fmt.fmt.count[0];141buf->vbi_count[1] = fh->vbi_fmt.fmt.count[1];142redo_dma_risc = 1;143}144145if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {146redo_dma_risc = 1;147if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL)))148goto fail;149}150151if (redo_dma_risc) {152unsigned int bpl, padding, offset;153struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);154155bpl = 2044; /* max. vbipack */156padding = VBI_BPL - bpl;157158if (fh->vbi_fmt.fmt.count[0] > 0) {159rc = bttv_risc_packed(btv, &buf->top,160dma->sglist,161/* offset */ 0, bpl,162padding, skip_lines0,163fh->vbi_fmt.fmt.count[0]);164if (0 != rc)165goto fail;166}167168if (fh->vbi_fmt.fmt.count[1] > 0) {169offset = fh->vbi_fmt.fmt.count[0] * VBI_BPL;170171rc = bttv_risc_packed(btv, &buf->bottom,172dma->sglist,173offset, bpl,174padding, skip_lines1,175fh->vbi_fmt.fmt.count[1]);176if (0 != rc)177goto fail;178}179}180181/* VBI capturing ends at VDELAY, start of video capturing,182no matter where the RISC program ends. VDELAY minimum is 2,183bounds.top is the corresponding first field line number184times two. VDELAY counts half field lines. */185min_vdelay = MIN_VDELAY;186if (fh->vbi_fmt.end >= tvnorm->cropcap.bounds.top)187min_vdelay += fh->vbi_fmt.end - tvnorm->cropcap.bounds.top;188189/* For bttv_buffer_activate_vbi(). */190buf->geo.vdelay = min_vdelay;191192buf->vb.state = VIDEOBUF_PREPARED;193buf->vb.field = field;194dprintk("buf prepare %p: top=%p bottom=%p field=%s\n",195vb, &buf->top, &buf->bottom,196v4l2_field_names[buf->vb.field]);197return 0;198199fail:200bttv_dma_free(q,btv,buf);201return rc;202}203204static void205vbi_buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)206{207struct bttv_fh *fh = q->priv_data;208struct bttv *btv = fh->btv;209struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);210211dprintk("queue %p\n",vb);212buf->vb.state = VIDEOBUF_QUEUED;213list_add_tail(&buf->vb.queue,&btv->vcapture);214if (NULL == btv->cvbi) {215fh->btv->loop_irq |= 4;216bttv_set_dma(btv,0x0c);217}218}219220static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)221{222struct bttv_fh *fh = q->priv_data;223struct bttv *btv = fh->btv;224struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);225226dprintk("free %p\n",vb);227bttv_dma_free(q,fh->btv,buf);228}229230struct videobuf_queue_ops bttv_vbi_qops = {231.buf_setup = vbi_buffer_setup,232.buf_prepare = vbi_buffer_prepare,233.buf_queue = vbi_buffer_queue,234.buf_release = vbi_buffer_release,235};236237/* ----------------------------------------------------------------------- */238239static int try_fmt(struct v4l2_vbi_format *f, const struct bttv_tvnorm *tvnorm,240__s32 crop_start)241{242__s32 min_start, max_start, max_end, f2_offset;243unsigned int i;244245/* For compatibility with earlier driver versions we must pretend246the VBI and video capture window may overlap. In reality RISC247magic aborts VBI capturing at the first line of video capturing,248leaving the rest of the buffer unchanged, usually all zero.249VBI capturing must always start before video capturing. >> 1250because cropping counts field lines times two. */251min_start = tvnorm->vbistart[0];252max_start = (crop_start >> 1) - 1;253max_end = (tvnorm->cropcap.bounds.top254+ tvnorm->cropcap.bounds.height) >> 1;255256if (min_start > max_start)257return -EBUSY;258259BUG_ON(max_start >= max_end);260261f->sampling_rate = tvnorm->Fsc;262f->samples_per_line = VBI_BPL;263f->sample_format = V4L2_PIX_FMT_GREY;264f->offset = VBI_OFFSET;265266f2_offset = tvnorm->vbistart[1] - tvnorm->vbistart[0];267268for (i = 0; i < 2; ++i) {269if (0 == f->count[i]) {270/* No data from this field. We leave f->start[i]271alone because VIDIOCSVBIFMT is w/o and EINVALs272when a driver does not support exactly the273requested parameters. */274} else {275s64 start, count;276277start = clamp(f->start[i], min_start, max_start);278/* s64 to prevent overflow. */279count = (s64) f->start[i] + f->count[i] - start;280f->start[i] = start;281f->count[i] = clamp(count, (s64) 1,282max_end - start);283}284285min_start += f2_offset;286max_start += f2_offset;287max_end += f2_offset;288}289290if (0 == (f->count[0] | f->count[1])) {291/* As in earlier driver versions. */292f->start[0] = tvnorm->vbistart[0];293f->start[1] = tvnorm->vbistart[1];294f->count[0] = 1;295f->count[1] = 1;296}297298f->flags = 0;299300f->reserved[0] = 0;301f->reserved[1] = 0;302303return 0;304}305306int bttv_try_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)307{308struct bttv_fh *fh = f;309struct bttv *btv = fh->btv;310const struct bttv_tvnorm *tvnorm;311__s32 crop_start;312313mutex_lock(&btv->lock);314315tvnorm = &bttv_tvnorms[btv->tvnorm];316crop_start = btv->crop_start;317318mutex_unlock(&btv->lock);319320return try_fmt(&frt->fmt.vbi, tvnorm, crop_start);321}322323324int bttv_s_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)325{326struct bttv_fh *fh = f;327struct bttv *btv = fh->btv;328const struct bttv_tvnorm *tvnorm;329__s32 start1, end;330int rc;331332mutex_lock(&btv->lock);333334rc = -EBUSY;335if (fh->resources & RESOURCE_VBI)336goto fail;337338tvnorm = &bttv_tvnorms[btv->tvnorm];339340rc = try_fmt(&frt->fmt.vbi, tvnorm, btv->crop_start);341if (0 != rc)342goto fail;343344start1 = frt->fmt.vbi.start[1] - tvnorm->vbistart[1] +345tvnorm->vbistart[0];346347/* First possible line of video capturing. Should be348max(f->start[0] + f->count[0], start1 + f->count[1]) * 2349when capturing both fields. But for compatibility we must350pretend the VBI and video capture window may overlap,351so end = start + 1, the lowest possible value, times two352because vbi_fmt.end counts field lines times two. */353end = max(frt->fmt.vbi.start[0], start1) * 2 + 2;354355mutex_lock(&fh->vbi.vb_lock);356357fh->vbi_fmt.fmt = frt->fmt.vbi;358fh->vbi_fmt.tvnorm = tvnorm;359fh->vbi_fmt.end = end;360361mutex_unlock(&fh->vbi.vb_lock);362363rc = 0;364365fail:366mutex_unlock(&btv->lock);367368return rc;369}370371372int bttv_g_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)373{374struct bttv_fh *fh = f;375const struct bttv_tvnorm *tvnorm;376377frt->fmt.vbi = fh->vbi_fmt.fmt;378379tvnorm = &bttv_tvnorms[fh->btv->tvnorm];380381if (tvnorm != fh->vbi_fmt.tvnorm) {382__s32 max_end;383unsigned int i;384385/* As in vbi_buffer_prepare() this imitates the386behaviour of earlier driver versions after video387standard changes, with default parameters anyway. */388389max_end = (tvnorm->cropcap.bounds.top390+ tvnorm->cropcap.bounds.height) >> 1;391392frt->fmt.vbi.sampling_rate = tvnorm->Fsc;393394for (i = 0; i < 2; ++i) {395__s32 new_start;396397new_start = frt->fmt.vbi.start[i]398+ tvnorm->vbistart[i]399- fh->vbi_fmt.tvnorm->vbistart[i];400401frt->fmt.vbi.start[i] = min(new_start, max_end - 1);402frt->fmt.vbi.count[i] =403min((__s32) frt->fmt.vbi.count[i],404max_end - frt->fmt.vbi.start[i]);405406max_end += tvnorm->vbistart[1]407- tvnorm->vbistart[0];408}409}410return 0;411}412413void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm)414{415const struct bttv_tvnorm *tvnorm;416unsigned int real_samples_per_line;417unsigned int real_count;418419tvnorm = &bttv_tvnorms[norm];420421f->fmt.sampling_rate = tvnorm->Fsc;422f->fmt.samples_per_line = VBI_BPL;423f->fmt.sample_format = V4L2_PIX_FMT_GREY;424f->fmt.offset = VBI_OFFSET;425f->fmt.start[0] = tvnorm->vbistart[0];426f->fmt.start[1] = tvnorm->vbistart[1];427f->fmt.count[0] = VBI_DEFLINES;428f->fmt.count[1] = VBI_DEFLINES;429f->fmt.flags = 0;430f->fmt.reserved[0] = 0;431f->fmt.reserved[1] = 0;432433/* For compatibility the buffer size must be 2 * VBI_DEFLINES *434VBI_BPL regardless of the current video standard. */435real_samples_per_line = 1024 + tvnorm->vbipack * 4;436real_count = ((tvnorm->cropcap.defrect.top >> 1)437- tvnorm->vbistart[0]);438439BUG_ON(real_samples_per_line > VBI_BPL);440BUG_ON(real_count > VBI_DEFLINES);441442f->tvnorm = tvnorm;443444/* See bttv_vbi_fmt_set(). */445f->end = tvnorm->vbistart[0] * 2 + 2;446}447448/* ----------------------------------------------------------------------- */449/*450* Local variables:451* c-basic-offset: 8452* End:453*/454455456