bttv-driver.c

来自「trident tm5600的linux驱动」· C语言 代码 · 共 2,443 行 · 第 1/5 页

C
2,443
字号
/*    bttv - Bt848 frame grabber driver    Copyright (C) 1996,97,98 Ralph  Metzler <rjkm@thp.uni-koeln.de>			   & Marcus Metzler <mocm@thp.uni-koeln.de>    (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org>    some v4l2 code lines are taken from Justin's bttv2 driver which is    (c) 2000 Justin Schoeman <justin@suntiger.ee.up.ac.za>    V4L1 removal from:    (c) 2005-2006 Nickolay V. Shmyrev <nshmyrev@yandex.ru>    Fixes to be fully V4L2 compliant by    (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org>    Cropping and overscan support    Copyright (C) 2005, 2006 Michael H. Schimek <mschimek@gmx.at>    Sponsored by OPQ Systems AB    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <linux/init.h>#include <linux/module.h>#include <linux/delay.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/interrupt.h>#include <linux/kdev_t.h>#include "bttvp.h"#include <media/v4l2-common.h>#include <media/v4l2-ioctl.h>#include <media/tvaudio.h>#include <media/msp3400.h>#include <linux/dma-mapping.h>#include <asm/io.h>#include <asm/byteorder.h>#include <media/rds.h>unsigned int bttv_num;			/* number of Bt848s in use */struct bttv bttvs[BTTV_MAX];unsigned int bttv_debug;unsigned int bttv_verbose = 1;unsigned int bttv_gpio;/* config variables */#ifdef __BIG_ENDIANstatic unsigned int bigendian=1;#elsestatic unsigned int bigendian;#endifstatic unsigned int radio[BTTV_MAX];static unsigned int irq_debug;static unsigned int gbuffers = 8;static unsigned int gbufsize = 0x208000;static unsigned int reset_crop = 1;static int video_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 };static int radio_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 };static int vbi_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 };static int debug_latency;static unsigned int fdsr;/* options */static unsigned int combfilter;static unsigned int lumafilter;static unsigned int automute    = 1;static unsigned int chroma_agc;static unsigned int adc_crush   = 1;static unsigned int whitecrush_upper = 0xCF;static unsigned int whitecrush_lower = 0x7F;static unsigned int vcr_hack;static unsigned int irq_iswitch;static unsigned int uv_ratio    = 50;static unsigned int full_luma_range;static unsigned int coring;/* API features (turn on/off stuff for testing) */static unsigned int v4l2        = 1;/* insmod args */module_param(bttv_verbose,      int, 0644);module_param(bttv_gpio,         int, 0644);module_param(bttv_debug,        int, 0644);module_param(irq_debug,         int, 0644);module_param(debug_latency,     int, 0644);module_param(fdsr,              int, 0444);module_param(gbuffers,          int, 0444);module_param(gbufsize,          int, 0444);module_param(reset_crop,        int, 0444);module_param(v4l2,              int, 0644);module_param(bigendian,         int, 0644);module_param(irq_iswitch,       int, 0644);module_param(combfilter,        int, 0444);module_param(lumafilter,        int, 0444);module_param(automute,          int, 0444);module_param(chroma_agc,        int, 0444);module_param(adc_crush,         int, 0444);module_param(whitecrush_upper,  int, 0444);module_param(whitecrush_lower,  int, 0444);module_param(vcr_hack,          int, 0444);module_param(uv_ratio,          int, 0444);module_param(full_luma_range,   int, 0444);module_param(coring,            int, 0444);module_param_array(radio,       int, NULL, 0444);module_param_array(video_nr,    int, NULL, 0444);module_param_array(radio_nr,    int, NULL, 0444);module_param_array(vbi_nr,      int, NULL, 0444);MODULE_PARM_DESC(radio,"The TV card supports radio, default is 0 (no)");MODULE_PARM_DESC(bigendian,"byte order of the framebuffer, default is native endian");MODULE_PARM_DESC(bttv_verbose,"verbose startup messages, default is 1 (yes)");MODULE_PARM_DESC(bttv_gpio,"log gpio changes, default is 0 (no)");MODULE_PARM_DESC(bttv_debug,"debug messages, default is 0 (no)");MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)");MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8");MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000");MODULE_PARM_DESC(reset_crop,"reset cropping parameters at open(), default "		 "is 1 (yes) for compatibility with older applications");MODULE_PARM_DESC(automute,"mute audio on bad/missing video signal, default is 1 (yes)");MODULE_PARM_DESC(chroma_agc,"enables the AGC of chroma signal, default is 0 (no)");MODULE_PARM_DESC(adc_crush,"enables the luminance ADC crush, default is 1 (yes)");MODULE_PARM_DESC(whitecrush_upper,"sets the white crush upper value, default is 207");MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127");MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)");MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler");MODULE_PARM_DESC(uv_ratio,"ratio between u and v gains, default is 50");MODULE_PARM_DESC(full_luma_range,"use the full luma range, default is 0 (no)");MODULE_PARM_DESC(coring,"set the luma coring level, default is 0 (no)");MODULE_PARM_DESC(video_nr, "video device numbers");MODULE_PARM_DESC(vbi_nr, "vbi device numbers");MODULE_PARM_DESC(radio_nr, "radio device numbers");MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards");MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");MODULE_LICENSE("GPL");/* ----------------------------------------------------------------------- *//* sysfs                                                                   */static ssize_t show_card(struct device *cd,			 struct device_attribute *attr, char *buf){	struct video_device *vfd = container_of(cd, struct video_device, dev);	struct bttv *btv = dev_get_drvdata(vfd->parent);	return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET);}static DEVICE_ATTR(card, S_IRUGO, show_card, NULL);/* ----------------------------------------------------------------------- *//* dvb auto-load setup                                                     */#if defined(CONFIG_MODULES) && defined(MODULE)#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)static void request_module_async(void *ptr)#elsestatic void request_module_async(struct work_struct *work)#endif{	request_module("dvb-bt8xx");}static void request_modules(struct bttv *dev){#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)	INIT_WORK(&dev->request_module_wk, request_module_async, (void*)dev);#else	INIT_WORK(&dev->request_module_wk, request_module_async);#endif	schedule_work(&dev->request_module_wk);}#else#define request_modules(dev)#endif /* CONFIG_MODULES *//* ----------------------------------------------------------------------- *//* static data                                                             *//* special timing tables from conexant... */static u8 SRAM_Table[][60] ={	/* PAL digital input over GPIO[7:0] */	{		45, // 45 bytes following		0x36,0x11,0x01,0x00,0x90,0x02,0x05,0x10,0x04,0x16,		0x12,0x05,0x11,0x00,0x04,0x12,0xC0,0x00,0x31,0x00,		0x06,0x51,0x08,0x03,0x89,0x08,0x07,0xC0,0x44,0x00,		0x81,0x01,0x01,0xA9,0x0D,0x02,0x02,0x50,0x03,0x37,		0x37,0x00,0xAF,0x21,0x00	},	/* NTSC digital input over GPIO[7:0] */	{		51, // 51 bytes following		0x0C,0xC0,0x00,0x00,0x90,0x02,0x03,0x10,0x03,0x06,		0x10,0x04,0x12,0x12,0x05,0x02,0x13,0x04,0x19,0x00,		0x04,0x39,0x00,0x06,0x59,0x08,0x03,0x83,0x08,0x07,		0x03,0x50,0x00,0xC0,0x40,0x00,0x86,0x01,0x01,0xA6,		0x0D,0x02,0x03,0x11,0x01,0x05,0x37,0x00,0xAC,0x21,		0x00,	},	// TGB_NTSC392 // quartzsight	// This table has been modified to be used for Fusion Rev D	{		0x2A, // size of table = 42		0x06, 0x08, 0x04, 0x0a, 0xc0, 0x00, 0x18, 0x08, 0x03, 0x24,		0x08, 0x07, 0x02, 0x90, 0x02, 0x08, 0x10, 0x04, 0x0c, 0x10,		0x05, 0x2c, 0x11, 0x04, 0x55, 0x48, 0x00, 0x05, 0x50, 0x00,		0xbf, 0x0c, 0x02, 0x2f, 0x3d, 0x00, 0x2f, 0x3f, 0x00, 0xc3,		0x20, 0x00	}};/* minhdelayx1	first video pixel we can capture on a line and   hdelayx1	start of active video, both relative to rising edge of		/HRESET pulse (0H) in 1 / fCLKx1.   swidth	width of active video and   totalwidth	total line width, both in 1 / fCLKx1.   sqwidth	total line width in square pixels.   vdelay	start of active video in 2 * field lines relative to		trailing edge of /VRESET pulse (VDELAY register).   sheight	height of active video in 2 * field lines.   videostart0	ITU-R frame line number of the line corresponding		to vdelay in the first field. */#define CROPCAP(minhdelayx1, hdelayx1, swidth, totalwidth, sqwidth,	 \		vdelay, sheight, videostart0)				 \	.cropcap.bounds.left = minhdelayx1,				 \	/* * 2 because vertically we count field lines times two, */	 \	/* e.g. 23 * 2 to 23 * 2 + 576 in PAL-BGHI defrect. */		 \	.cropcap.bounds.top = (videostart0) * 2 - (vdelay) + MIN_VDELAY, \	/* 4 is a safety margin at the end of the line. */		 \	.cropcap.bounds.width = (totalwidth) - (minhdelayx1) - 4,	 \	.cropcap.bounds.height = (sheight) + (vdelay) - MIN_VDELAY,	 \	.cropcap.defrect.left = hdelayx1,				 \	.cropcap.defrect.top = (videostart0) * 2,			 \	.cropcap.defrect.width = swidth,				 \	.cropcap.defrect.height = sheight,				 \	.cropcap.pixelaspect.numerator = totalwidth,			 \	.cropcap.pixelaspect.denominator = sqwidth,const struct bttv_tvnorm bttv_tvnorms[] = {	/* PAL-BDGHI */	/* max. active video is actually 922, but 924 is divisible by 4 and 3! */	/* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */	{		.v4l2_id        = V4L2_STD_PAL,		.name           = "PAL",		.Fsc            = 35468950,		.swidth         = 924,		.sheight        = 576,		.totalwidth     = 1135,		.adelay         = 0x7f,		.bdelay         = 0x72,		.iform          = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),		.scaledtwidth   = 1135,		.hdelayx1       = 186,		.hactivex1      = 924,		.vdelay         = 0x20,		.vbipack        = 255, /* min (2048 / 4, 0x1ff) & 0xff */		.sram           = 0,		/* ITU-R frame line number of the first VBI line		   we can capture, of the first and second field.		   The last line is determined by cropcap.bounds. */		.vbistart       = { 7, 320 },		CROPCAP(/* minhdelayx1 */ 68,			/* hdelayx1 */ 186,			/* Should be (768 * 1135 + 944 / 2) / 944.			   cropcap.defrect is used for image width			   checks, so we keep the old value 924. */			/* swidth */ 924,			/* totalwidth */ 1135,			/* sqwidth */ 944,			/* vdelay */ 0x20,			/* sheight */ 576,			/* videostart0 */ 23)		/* bt878 (and bt848?) can capture another		   line below active video. */		.cropcap.bounds.height = (576 + 2) + 0x20 - 2,	},{		.v4l2_id        = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,		.name           = "NTSC",		.Fsc            = 28636363,		.swidth         = 768,		.sheight        = 480,		.totalwidth     = 910,		.adelay         = 0x68,		.bdelay         = 0x5d,		.iform          = (BT848_IFORM_NTSC|BT848_IFORM_XT0),		.scaledtwidth   = 910,		.hdelayx1       = 128,		.hactivex1      = 910,		.vdelay         = 0x1a,		.vbipack        = 144, /* min (1600 / 4, 0x1ff) & 0xff */		.sram           = 1,		.vbistart	= { 10, 273 },		CROPCAP(/* minhdelayx1 */ 68,			/* hdelayx1 */ 128,			/* Should be (640 * 910 + 780 / 2) / 780? */			/* swidth */ 768,			/* totalwidth */ 910,			/* sqwidth */ 780,			/* vdelay */ 0x1a,			/* sheight */ 480,			/* videostart0 */ 23)	},{		.v4l2_id        = V4L2_STD_SECAM,		.name           = "SECAM",		.Fsc            = 35468950,		.swidth         = 924,		.sheight        = 576,		.totalwidth     = 1135,		.adelay         = 0x7f,		.bdelay         = 0xb0,		.iform          = (BT848_IFORM_SECAM|BT848_IFORM_XT1),		.scaledtwidth   = 1135,		.hdelayx1       = 186,		.hactivex1      = 922,		.vdelay         = 0x20,		.vbipack        = 255,		.sram           = 0, /* like PAL, correct? */		.vbistart	= { 7, 320 },		CROPCAP(/* minhdelayx1 */ 68,			/* hdelayx1 */ 186,			/* swidth */ 924,			/* totalwidth */ 1135,			/* sqwidth */ 944,			/* vdelay */ 0x20,			/* sheight */ 576,			/* videostart0 */ 23)	},{		.v4l2_id        = V4L2_STD_PAL_Nc,		.name           = "PAL-Nc",		.Fsc            = 28636363,		.swidth         = 640,		.sheight        = 576,		.totalwidth     = 910,		.adelay         = 0x68,		.bdelay         = 0x5d,		.iform          = (BT848_IFORM_PAL_NC|BT848_IFORM_XT0),		.scaledtwidth   = 780,		.hdelayx1       = 130,		.hactivex1      = 734,		.vdelay         = 0x1a,		.vbipack        = 144,		.sram           = -1,		.vbistart	= { 7, 320 },		CROPCAP(/* minhdelayx1 */ 68,			/* hdelayx1 */ 130,			/* swidth */ (640 * 910 + 780 / 2) / 780,			/* totalwidth */ 910,			/* sqwidth */ 780,			/* vdelay */ 0x1a,			/* sheight */ 576,			/* videostart0 */ 23)	},{		.v4l2_id        = V4L2_STD_PAL_M,		.name           = "PAL-M",		.Fsc            = 28636363,		.swidth         = 640,		.sheight        = 480,		.totalwidth     = 910,		.adelay         = 0x68,		.bdelay         = 0x5d,		.iform          = (BT848_IFORM_PAL_M|BT848_IFORM_XT0),		.scaledtwidth   = 780,		.hdelayx1       = 135,		.hactivex1      = 754,		.vdelay         = 0x1a,		.vbipack        = 144,		.sram           = -1,		.vbistart	= { 10, 273 },		CROPCAP(/* minhdelayx1 */ 68,			/* hdelayx1 */ 135,			/* swidth */ (640 * 910 + 780 / 2) / 780,			/* totalwidth */ 910,			/* sqwidth */ 780,			/* vdelay */ 0x1a,			/* sheight */ 480,			/* videostart0 */ 23)	},{		.v4l2_id        = V4L2_STD_PAL_N,		.name           = "PAL-N",		.Fsc            = 35468950,		.swidth         = 768,		.sheight        = 576,		.totalwidth     = 1135,		.adelay         = 0x7f,		.bdelay         = 0x72,		.iform          = (BT848_IFORM_PAL_N|BT848_IFORM_XT1),		.scaledtwidth   = 944,		.hdelayx1       = 186,		.hactivex1      = 922,		.vdelay         = 0x20,		.vbipack        = 144,		.sram           = -1,		.vbistart       = { 7, 320 },		CROPCAP(/* minhdelayx1 */ 68,			/* hdelayx1 */ 186,			/* swidth */ (768 * 1135 + 944 / 2) / 944,			/* totalwidth */ 1135,			/* sqwidth */ 944,			/* vdelay */ 0x20,			/* sheight */ 576,			/* videostart0 */ 23)	},{		.v4l2_id        = V4L2_STD_NTSC_M_JP,		.name           = "NTSC-JP",		.Fsc            = 28636363,		.swidth         = 640,		.sheight        = 480,		.totalwidth     = 910,		.adelay         = 0x68,		.bdelay         = 0x5d,		.iform          = (BT848_IFORM_NTSC_J|BT848_IFORM_XT0),		.scaledtwidth   = 780,		.hdelayx1       = 135,		.hactivex1      = 754,		.vdelay         = 0x16,		.vbipack        = 144,		.sram           = -1,		.vbistart       = { 10, 273 },		CROPCAP(/* minhdelayx1 */ 68,			/* hdelayx1 */ 135,			/* swidth */ (640 * 910 + 780 / 2) / 780,			/* totalwidth */ 910,			/* sqwidth */ 780,			/* vdelay */ 0x16,			/* sheight */ 480,			/* videostart0 */ 23)	},{		/* that one hopefully works with the strange timing		 * which video recorders produce when playing a NTSC		 * tape on a PAL TV ... */		.v4l2_id        = V4L2_STD_PAL_60,		.name           = "PAL-60",		.Fsc            = 35468950,		.swidth         = 924,		.sheight        = 480,		.totalwidth     = 1135,		.adelay         = 0x7f,		.bdelay         = 0x72,		.iform          = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),		.scaledtwidth   = 1135,		.hdelayx1       = 186,		.hactivex1      = 924,		.vdelay         = 0x1a,		.vbipack        = 255,		.vtotal         = 524,		.sram           = -1,		.vbistart	= { 10, 273 },		CROPCAP(/* minhdelayx1 */ 68,			/* hdelayx1 */ 186,			/* swidth */ 924,			/* totalwidth */ 1135,			/* sqwidth */ 944,			/* vdelay */ 0x1a,			/* sheight */ 480,			/* videostart0 */ 23)	}};static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms);/* ----------------------------------------------------------------------- *//* bttv format list   packed pixel formats must come first */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?