⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zr36067.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
#define DEBUGLEVEL 0#define MAX_KMALLOC_MEM (128*1024)/*   Miro/Pinnacle Systems Inc. DC10/DC10plus and   Linux Media Labs LML33 video capture boards driver   now with IOMega BUZ support!      Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>   Changes for BUZ by Wolfgang Scherr <scherr@net4you.net>      Based on       Miro DC10 driver    Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>       Iomega Buz driver version 1.0    Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de>    buz.0.0.3    Copyright (C) 1998 Dave Perks <dperks@ibm.net>    bttv - Bt848 frame grabber driver    Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@thp.uni-koeln.de)                           & Marcus Metzler (mocm@thp.uni-koeln.de)        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/config.h>#include <linux/version.h>#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/major.h>#include <linux/slab.h>#include <linux/mm.h>#include <linux/pci.h>#include <linux/signal.h>#include <asm/io.h>#include <asm/pgtable.h>#include <asm/page.h>#include <linux/sched.h>#include <asm/segment.h>#include <linux/types.h>#include <linux/wrapper.h>#include <linux/spinlock.h>#include <linux/vmalloc.h>#include <linux/i2c-old.h>#define     MAP_NR(x)       virt_to_page(x)#define     ZORAN_HARDWARE  VID_HARDWARE_ZR36067#include <linux/videodev.h>#include <asm/uaccess.h>#include <linux/proc_fs.h>#include "zoran.h"#include <linux/video_decoder.h>#include <linux/video_encoder.h>// RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined#if !defined(CONFIG_BIGPHYS_AREA)//#undef CONFIG_BIGPHYS_AREA#define BUZ_USE_HIMEM#endif#if defined(CONFIG_BIGPHYS_AREA)#   include <linux/bigphysarea.h>#endif#define IRQ_MASK ( ZR36057_ISR_GIRQ0 | ZR36057_ISR_GIRQ1 | /* ZR36057_ISR_CodRepIRQ | */  ZR36057_ISR_JPEGRepIRQ )	// SW//#define GPIO_MASK 0xcd//#define GPIO_MASK 0x8d/*DC10:GPIO0 = /RESET ZR 36060GPIO1 = VIDEO BUS DIRECTION (0: CAPTURE, 1: DISPLAY)GPIO2 = VIDEO BUS ENABLE    (0: ON, 1: OFF)GPIO3 = /SLEEP ZR 36060GPIO4 = ADC7175 (video out) FREQUENCY (0: LCC/SAA7110, 1: 27 MHz (quarz))GPIO5 = ZORAN FREQUENCY  (0: LCC and LCC2 from SAA7110,                          1: 27 and 13.5 MHz (quarz))GPIO6 = /FRAME ZR 36060GPIO7 = /RESET ADV7175 (video out)(I think they lost the SAA7110 reset.....)GIRQ0 signals that ZR36060's DATERR# line is asserted.GIRQ1 signals a vertical sync of the video signal (VS SAA7110)  SAA7110A:   mode 0 - Composite   mode 1 -    mode 2 -    mode 3 -    mode 4 -    mode 5 - internal Composite (from PCTV)   mode 6 -    mode 7 - S-VideoBUZ:GPIO0 = 1, take board out of resetGPIO1 = 1, take JPEG codec out of sleep modeGPIO3 = 1, deassert FRAME# to 36060GIRQ0 signals a vertical sync of the video signalGIRQ1 signals that ZR36060's DATERR# line is asserted.SAA7111A   In their infinite wisdom, the Iomega engineers decided to   use the same input line for composite and S-Video Color,   although there are two entries not connected at all!   Through this ingenious strike, it is not possible to   keep two running video sources connected at the same time   to Composite and S-VHS input!   mode 0 - N/C   mode 1 - S-Video Y   mode 2 - noise or something I don't know   mode 3 - Composite and S-Video C   mode 4 - N/C   mode 5 - S-Video (gain C independently selectable of gain Y)   mode 6 - N/C   mode 7 - S-Video (gain C adapted to gain Y)*/#define MAJOR_VERSION 0		/* driver major version */#define MINOR_VERSION 7		/* driver minor version */#define ZORAN_NAME    "zr36067"	/* name of the device */#define BUZ_ERR       KERN_ERR     ZORAN_NAME#define BUZ_DEBUG     KERN_INFO    ZORAN_NAME#define BUZ_INFO      KERN_INFO    ZORAN_NAME#define BUZ_WARNING   KERN_WARNING ZORAN_NAME#if(DEBUGLEVEL>0)#define DEBUG1(x...)    x#else#define DEBUG1(x...)#endif#if(DEBUGLEVEL>1)#define DEBUG2(x...)    x#else#define DEBUG2(x...)#endif#if(DEBUGLEVEL>2)#define DEBUG3(x...)    x#else#define DEBUG3(x...)#endif#if(DEBUGLEVEL>3)#define DEBUG4(x...)    x#else#define DEBUG4(x...)#endif/* The parameters for this driver *//*   The video mem address of the video card.   The driver has a little database for some videocards   to determine it from there. If your video card is not in there   you have either to give it to the driver as a parameter   or set in in a VIDIOCSFBUF ioctl */static unsigned long vidmem = 0;	/* Video memory base address *//* Special purposes only: */static int triton = 0;		/* 0=no, 1=yes */static int natoma = 0;		/* 0=no, 1=yes *//*   Number and size of grab buffers for Video 4 Linux   The vast majority of applications should not need more than 2,   the very popular BTTV driver actually does ONLY have 2.   Time sensitive applications might need more, the maximum   is VIDEO_MAX_FRAME (defined in <linux/videodev.h>).   The size is set so that the maximum possible request   can be satisfied. Decrease  it, if bigphys_area alloc'd   memory is low. If you don't have the bigphys_area patch,   set it to 128 KB. Will you allow only to grab small   images with V4L, but that's better than nothing.   v4l_bufsize has to be given in KB !*/static int v4l_nbufs = 2;static int v4l_bufsize = 128;	/* Everybody should be able to work with this setting *//*   Default input and video norm at startup of the driver.*/static int default_input = 0;	/* 0=Composite, 1=S-VHS */static int default_norm = 0;	/* 0=PAL, 1=NTSC 2=SECAM */static int lock_norm = 0;	/* 1=Don't change TV standard (norm) */static int pass_through = 0;	/* 1=Pass through TV signal when device is not used */				/* 0=Show color bar when device is not used (LML33: only if lml33dpath=1) */static int lml33dpath = 0;	/* 1 will use digital path in capture mode instead of analog.				   It can be used for picture adjustments using tool like xawtv				   while watching image on TV monitor connected to the output.				   However, due to absence of 75 Ohm load on Bt819 input, there				   will be some image imperfections */static int video_nr = -1;MODULE_PARM(vidmem, "i");MODULE_PARM(triton, "i");MODULE_PARM(natoma, "i");MODULE_PARM(v4l_nbufs, "i");MODULE_PARM(v4l_bufsize, "i");MODULE_PARM(default_input, "i");MODULE_PARM(default_norm, "i");MODULE_PARM(lock_norm, "i");MODULE_PARM(pass_through, "i");MODULE_PARM(lml33dpath, "i");MODULE_PARM(video_nr, "i");static struct pci_device_id zr36067_pci_tbl[] = {	{ PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, 	  PCI_ANY_ID, PCI_ANY_ID,  0, 0, 0 },	{ 0 }};MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);/* Anybody who uses more than four? */#define BUZ_MAX 4static int zoran_num;		/* number of Buzs in use */static struct zoran zoran[BUZ_MAX];/* forward references */static void v4l_fbuffer_free(struct zoran *zr);static void jpg_fbuffer_free(struct zoran *zr);static void zoran_feed_stat_com(struct zoran *zr);/* *   Allocate the V4L grab buffers * *   These have to be pysically contiguous. *   If v4l_bufsize <= MAX_KMALLOC_MEM we use kmalloc *   else we try to allocate them with bigphysarea_alloc_pages *   if the bigphysarea patch is present in the kernel, *   else we try to use high memory (if the user has bootet *   Linux with the necessary memory left over). */static int v4l_fbuffer_alloc(struct zoran *zr){	int i, off;	unsigned char *mem;	for (i = 0; i < v4l_nbufs; i++) {		if (zr->v4l_gbuf[i].fbuffer)			printk(KERN_WARNING			       "%s: v4l_fbuffer_alloc: buffer %d allready allocated ???\n",			       zr->name, i);		//udelay(20);		if (v4l_bufsize <= MAX_KMALLOC_MEM) {			/* Use kmalloc */			mem =			    (unsigned char *) kmalloc(v4l_bufsize,						      GFP_KERNEL);			if (mem == 0) {				printk(KERN_ERR				       "%s: kmalloc for V4L bufs failed\n",				       zr->name);				v4l_fbuffer_free(zr);				return -ENOBUFS;			}			zr->v4l_gbuf[i].fbuffer = mem;			zr->v4l_gbuf[i].fbuffer_phys = virt_to_phys(mem);			zr->v4l_gbuf[i].fbuffer_bus = virt_to_bus(mem);			for (off = 0; off < v4l_bufsize; off += PAGE_SIZE)				mem_map_reserve(MAP_NR(mem + off));			DEBUG1(printk			       (KERN_INFO				"%s: V4L frame %d mem 0x%lx (bus: 0x%lx)\n",				zr->name, i, (unsigned long) mem,				virt_to_bus(mem)));		} else {#if defined(CONFIG_BIGPHYS_AREA)			/* Use bigphysarea_alloc_pages */			int n = (v4l_bufsize + PAGE_SIZE - 1) / PAGE_SIZE;			mem =			    (unsigned char *) bigphysarea_alloc_pages(n, 0,								      GFP_KERNEL);			if (mem == 0) {				printk(KERN_ERR				       "%s: bigphysarea_alloc_pages for V4L bufs failed\n",				       zr->name);				v4l_fbuffer_free(zr);				return -ENOBUFS;			}			zr->v4l_gbuf[i].fbuffer = mem;			zr->v4l_gbuf[i].fbuffer_phys = virt_to_phys(mem);			zr->v4l_gbuf[i].fbuffer_bus = virt_to_bus(mem);			DEBUG1(printk			       (KERN_INFO				"%s: Bigphysarea frame %d mem 0x%x (bus: 0x%x)\n",				zr->name, i, (unsigned) mem,				(unsigned) virt_to_bus(mem)));			/* Zero out the allocated memory */			memset(zr->v4l_gbuf[i].fbuffer, 0, v4l_bufsize);#else			/* No bigphysarea present, usage of high memory disabled,			   but user wants buffers of more than MAX_KMALLOC_MEM */			printk(KERN_ERR			       "%s: No bigphysarea_patch present, usage of high memory disabled,\n",			       zr->name);			printk(KERN_ERR			       "%s: sorry, could not allocate V4L buffers of size %d KB.\n",			       zr->name, v4l_bufsize >> 10);			return -ENOBUFS;#endif		}	}	return 0;}/* free the V4L grab buffers */static void v4l_fbuffer_free(struct zoran *zr){	int i, off;	unsigned char *mem;	for (i = 0; i < v4l_nbufs; i++) {		if (!zr->v4l_gbuf[i].fbuffer)			continue;		if (v4l_bufsize <= MAX_KMALLOC_MEM) {			mem = zr->v4l_gbuf[i].fbuffer;			for (off = 0; off < v4l_bufsize; off += PAGE_SIZE)				mem_map_unreserve(MAP_NR(mem + off));			kfree((void *) zr->v4l_gbuf[i].fbuffer);		}#if defined(CONFIG_BIGPHYS_AREA)		else			bigphysarea_free_pages((void *) zr->v4l_gbuf[i].					       fbuffer);#endif		zr->v4l_gbuf[i].fbuffer = NULL;	}}/* *   Allocate the MJPEG grab buffers. * *   If the requested buffer size is smaller than MAX_KMALLOC_MEM, *   kmalloc is used to request a physically contiguous area, *   else we allocate the memory in framgents with get_free_page. * *   If a Natoma chipset is present and this is a revision 1 zr36057, *   each MJPEG buffer needs to be physically contiguous. *   (RJ: This statement is from Dave Perks' original driver, *   I could never check it because I have a zr36067) *   The driver cares about this because it reduces the buffer *   size to MAX_KMALLOC_MEM in that case (which forces contiguous allocation). * *   RJ: The contents grab buffers needs never be accessed in the driver. *       Therefore there is no need to allocate them with vmalloc in order *       to get a contiguous virtual memory space. *       I don't understand why many other drivers first allocate them with *       vmalloc (which uses internally also get_free_page, but delivers you *       virtual addresses) and then again have to make a lot of efforts *       to get the physical address. * */static int jpg_fbuffer_alloc(struct zoran *zr){	int i, j, off;		//alloc_contig;	unsigned long mem;	/* Decide if we should alloc contiguous or fragmented memory */	/* This has to be identical in jpg_fbuffer_alloc and jpg_fbuffer_free */	//alloc_contig = (zr->jpg_bufsize <= MAX_KMALLOC_MEM);	for (i = 0; i < zr->jpg_nbufs; i++) {		if (zr->jpg_gbuf[i].frag_tab)			printk(KERN_WARNING			       "%s: jpg_fbuffer_alloc: buffer %d allready allocated ???\n",			       zr->name, i);		/* Allocate fragment table for this buffer */		mem = get_free_page(GFP_KERNEL);		if (mem == 0) {			printk(KERN_ERR			       "%s: jpg_fbuffer_alloc: get_free_page (frag_tab) failed for buffer %d\n",			       zr->name, i);			jpg_fbuffer_free(zr);			return -ENOBUFS;		}		memset((void *) mem, 0, PAGE_SIZE);		zr->jpg_gbuf[i].frag_tab = (u32 *) mem;		zr->jpg_gbuf[i].frag_tab_bus = virt_to_bus((void *) mem);		//if (alloc_contig) {		if (zr->need_contiguous) {			mem = (unsigned long) kmalloc(zr->jpg_bufsize, GFP_KERNEL);			if (mem == 0) {				printk(KERN_ERR "%s: jpg_fbuffer_alloc: kmalloc failed for buffer %d\n",				       zr->name, i);				jpg_fbuffer_free(zr);				return -ENOBUFS;			}			zr->jpg_gbuf[i].frag_tab[0] = virt_to_bus((void *) mem);			zr->jpg_gbuf[i].frag_tab[1] =			    ((zr->jpg_bufsize / 4) << 1) | 1;			for (off = 0; off < zr->jpg_bufsize; off += PAGE_SIZE)				mem_map_reserve(MAP_NR(mem + off));		} else {			/* jpg_bufsize is allreay page aligned */			for (j = 0; j < zr->jpg_bufsize / PAGE_SIZE; j++) 			{				mem = get_free_page(GFP_KERNEL);				if (mem == 0) {					printk(KERN_ERR					       "%s: jpg_fbuffer_alloc: get_free_page failed for buffer %d\n",					       zr->name, i);					jpg_fbuffer_free(zr);					return -ENOBUFS;				}				zr->jpg_gbuf[i].frag_tab[2 * j] =				    virt_to_bus((void *) mem);				zr->jpg_gbuf[i].frag_tab[2 * j + 1] =				    (PAGE_SIZE / 4) << 1;				mem_map_reserve(MAP_NR(mem));			}			zr->jpg_gbuf[i].frag_tab[2 * j - 1] |= 1;		}	}	DEBUG1(printk	       ("%s: jpg_fbuffer_alloc: %ld KB allocated\n", zr->name,		(zr->jpg_nbufs * zr->jpg_bufsize) >> 10));	zr->jpg_buffers_allocated = 1;	return 0;}/* free the MJPEG grab buffers */static void jpg_fbuffer_free(struct zoran *zr){	int i, j, off;		// alloc_contig;	unsigned char *mem;	/* Decide if we should alloc contiguous or fragmented memory */	/* This has to be identical in jpg_fbuffer_alloc and jpg_fbuffer_free */	//alloc_contig = (zr->jpg_bufsize <= MAX_KMALLOC_MEM);	for (i = 0; i < zr->jpg_nbufs; i++) {		if (!zr->jpg_gbuf[i].frag_tab)			continue;		//if (alloc_contig) {		if (zr->need_contiguous) {			if (zr->jpg_gbuf[i].frag_tab[0]) {				mem =				    (unsigned char *) bus_to_virt(zr->								  jpg_gbuf								  [i].								  frag_tab								  [0]);				for (off = 0; off < zr->jpg_bufsize;				     off += PAGE_SIZE)					mem_map_unreserve(MAP_NR							  (mem + off));				kfree((void *) mem);				zr->jpg_gbuf[i].frag_tab[0] = 0;				zr->jpg_gbuf[i].frag_tab[1] = 0;			}		} else {			for (j = 0; j < zr->jpg_bufsize / PAGE_SIZE; j++) {

⌨️ 快捷键说明

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