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

📄 cpia.c

📁 cpia usb摄像头的驱动程序源码。需要video4linux和i2c-core支持
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * cpia CPiA driver * * Supports CPiA based Video Camera's. * * (C) Copyright 1999-2000 Peter Pregler * (C) Copyright 1999-2000 Scott J. Bertin * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com> * (C) Copyright 2000 STMicroelectronics * * 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. *//* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) *//* #define _CPIA_DEBUG_  1 */  #include <linux/config.h>#include <linux/module.h>#include <linux/version.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/vmalloc.h>#include <linux/slab.h>#include <linux/proc_fs.h>#include <linux/ctype.h>#include <linux/pagemap.h>#include <asm/io.h>#include <asm/semaphore.h>#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0))#include <linux/wrapper.h>#endif#ifdef CONFIG_KMOD#include <linux/kmod.h>#endif#include "cpia.h"#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))#define NEW_V4L_INTERFACE 1#else#undef NEW_V4L_INTERFACE#endif#ifdef CONFIG_VIDEO_CPIA_PPextern int cpia_pp_init(void);#endif#ifdef CONFIG_VIDEO_CPIA_USBextern int cpia_usb_init(void);#endif#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,5))static int video_nr = -1;#endifstatic int usb_alt = DEFAULT_USB_ALT_SETTING;#ifdef MODULEMODULE_PARM(usb_alt,"i");MODULE_PARM_DESC(usb_alt,"initial USB alt setting: 1 (min USB bandwidth use), 2, or 3 (max)");MODULE_AUTHOR("Scott J. Bertin <sbertin@securenym.net> & Peter Pregler <Peter_Pregler@email.com> & Johannes Erdfelt <johannes@erdfeld.com>");MODULE_DESCRIPTION("V4L-driver for Vision CPiA based cameras");#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,10))MODULE_LICENSE("GPL");#endifMODULE_SUPPORTED_DEVICE("video");#endif#define ABOUT "V4L-Driver for Vision CPiA based cameras"#ifndef VID_HARDWARE_CPIA#define VID_HARDWARE_CPIA 24    /* FIXME -> from linux/videodev.h */#endif#define CPIA_MODULE_CPIA			(0<<5)#define CPIA_MODULE_SYSTEM			(1<<5)#define CPIA_MODULE_VP_CTRL			(5<<5)#define CPIA_MODULE_CAPTURE			(6<<5)#define CPIA_MODULE_DEBUG			(7<<5)#define INPUT (DATA_IN << 8)#define OUTPUT (DATA_OUT << 8)#define CPIA_COMMAND_GetCPIAVersion	(INPUT | CPIA_MODULE_CPIA | 1)#define CPIA_COMMAND_GetPnPID		(INPUT | CPIA_MODULE_CPIA | 2)#define CPIA_COMMAND_GetCameraStatus	(INPUT | CPIA_MODULE_CPIA | 3)#define CPIA_COMMAND_GotoHiPower	(OUTPUT | CPIA_MODULE_CPIA | 4)#define CPIA_COMMAND_GotoLoPower	(OUTPUT | CPIA_MODULE_CPIA | 5)#define CPIA_COMMAND_GotoSuspend	(OUTPUT | CPIA_MODULE_CPIA | 7)#define CPIA_COMMAND_GotoPassThrough	(OUTPUT | CPIA_MODULE_CPIA | 8)#define CPIA_COMMAND_ModifyCameraStatus	(OUTPUT | CPIA_MODULE_CPIA | 10)#define CPIA_COMMAND_ReadVCRegs		(INPUT | CPIA_MODULE_SYSTEM | 1)#define CPIA_COMMAND_WriteVCReg		(OUTPUT | CPIA_MODULE_SYSTEM | 2)#define CPIA_COMMAND_ReadMCPorts	(INPUT | CPIA_MODULE_SYSTEM | 3)#define CPIA_COMMAND_WriteMCPort	(OUTPUT | CPIA_MODULE_SYSTEM | 4)#define CPIA_COMMAND_SetBaudRate	(OUTPUT | CPIA_MODULE_SYSTEM | 5)#define CPIA_COMMAND_SetECPTiming	(OUTPUT | CPIA_MODULE_SYSTEM | 6)#define CPIA_COMMAND_ReadIDATA		(INPUT | CPIA_MODULE_SYSTEM | 7)#define CPIA_COMMAND_WriteIDATA		(OUTPUT | CPIA_MODULE_SYSTEM | 8)#define CPIA_COMMAND_GenericCall	(OUTPUT | CPIA_MODULE_SYSTEM | 9)#define CPIA_COMMAND_I2CStart		(OUTPUT | CPIA_MODULE_SYSTEM | 10)#define CPIA_COMMAND_I2CStop		(OUTPUT | CPIA_MODULE_SYSTEM | 11)#define CPIA_COMMAND_I2CWrite		(OUTPUT | CPIA_MODULE_SYSTEM | 12)#define CPIA_COMMAND_I2CRead		(INPUT | CPIA_MODULE_SYSTEM | 13)#define CPIA_COMMAND_GetVPVersion	(INPUT | CPIA_MODULE_VP_CTRL | 1)#define CPIA_COMMAND_ResetFrameCounter	(INPUT | CPIA_MODULE_VP_CTRL | 2)#define CPIA_COMMAND_SetColourParams	(OUTPUT | CPIA_MODULE_VP_CTRL | 3)#define CPIA_COMMAND_SetExposure	(OUTPUT | CPIA_MODULE_VP_CTRL | 4)#define CPIA_COMMAND_SetColourBalance	(OUTPUT | CPIA_MODULE_VP_CTRL | 6)#define CPIA_COMMAND_SetSensorFPS	(OUTPUT | CPIA_MODULE_VP_CTRL | 7)#define CPIA_COMMAND_SetVPDefaults	(OUTPUT | CPIA_MODULE_VP_CTRL | 8)#define CPIA_COMMAND_SetApcor		(OUTPUT | CPIA_MODULE_VP_CTRL | 9)#define CPIA_COMMAND_SetFlickerCtrl	(OUTPUT | CPIA_MODULE_VP_CTRL | 10)#define CPIA_COMMAND_SetVLOffset	(OUTPUT | CPIA_MODULE_VP_CTRL | 11)#define CPIA_COMMAND_GetColourParams	(INPUT | CPIA_MODULE_VP_CTRL | 16)#define CPIA_COMMAND_GetColourBalance	(INPUT | CPIA_MODULE_VP_CTRL | 17)#define CPIA_COMMAND_GetExposure	(INPUT | CPIA_MODULE_VP_CTRL | 18)#define CPIA_COMMAND_SetSensorMatrix	(OUTPUT | CPIA_MODULE_VP_CTRL | 19)#define CPIA_COMMAND_ColourBars		(OUTPUT | CPIA_MODULE_VP_CTRL | 25)#define CPIA_COMMAND_ReadVPRegs		(INPUT | CPIA_MODULE_VP_CTRL | 30)#define CPIA_COMMAND_WriteVPReg		(OUTPUT | CPIA_MODULE_VP_CTRL | 31)#define CPIA_COMMAND_GrabFrame		(OUTPUT | CPIA_MODULE_CAPTURE | 1)#define CPIA_COMMAND_UploadFrame	(OUTPUT | CPIA_MODULE_CAPTURE | 2)#define CPIA_COMMAND_SetGrabMode	(OUTPUT | CPIA_MODULE_CAPTURE | 3)#define CPIA_COMMAND_InitStreamCap	(OUTPUT | CPIA_MODULE_CAPTURE | 4)#define CPIA_COMMAND_FiniStreamCap	(OUTPUT | CPIA_MODULE_CAPTURE | 5)#define CPIA_COMMAND_StartStreamCap	(OUTPUT | CPIA_MODULE_CAPTURE | 6)#define CPIA_COMMAND_EndStreamCap	(OUTPUT | CPIA_MODULE_CAPTURE | 7)#define CPIA_COMMAND_SetFormat		(OUTPUT | CPIA_MODULE_CAPTURE | 8)#define CPIA_COMMAND_SetROI		(OUTPUT | CPIA_MODULE_CAPTURE | 9)#define CPIA_COMMAND_SetCompression	(OUTPUT | CPIA_MODULE_CAPTURE | 10)#define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)#define CPIA_COMMAND_SetYUVThresh	(OUTPUT | CPIA_MODULE_CAPTURE | 12)#define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)#define CPIA_COMMAND_DiscardFrame	(OUTPUT | CPIA_MODULE_CAPTURE | 14)#define CPIA_COMMAND_GrabReset		(OUTPUT | CPIA_MODULE_CAPTURE | 15)#define CPIA_COMMAND_OutputRS232	(OUTPUT | CPIA_MODULE_DEBUG | 1)#define CPIA_COMMAND_AbortProcess	(OUTPUT | CPIA_MODULE_DEBUG | 4)#define CPIA_COMMAND_SetDramPage	(OUTPUT | CPIA_MODULE_DEBUG | 5)#define CPIA_COMMAND_StartDramUpload	(OUTPUT | CPIA_MODULE_DEBUG | 6)#define CPIA_COMMAND_StartDummyDtream	(OUTPUT | CPIA_MODULE_DEBUG | 8)#define CPIA_COMMAND_AbortStream	(OUTPUT | CPIA_MODULE_DEBUG | 9)#define CPIA_COMMAND_DownloadDRAM	(OUTPUT | CPIA_MODULE_DEBUG | 10)#define CPIA_COMMAND_Null		(OUTPUT | CPIA_MODULE_DEBUG | 11)enum {	FRAME_READY,		/* Ready to grab into */	FRAME_GRABBING,		/* In the process of being grabbed into */	FRAME_DONE,		/* Finished grabbing, but not been synced yet */	FRAME_UNUSED,		/* Unused (no MCAPTURE) */};#define COMMAND_NONE			0x0000#define COMMAND_SETCOMPRESSION		0x0001#define COMMAND_SETCOMPRESSIONTARGET	0x0002#define COMMAND_SETCOLOURPARAMS		0x0004#define COMMAND_SETFORMAT		0x0008#define COMMAND_PAUSE			0x0010#define COMMAND_RESUME			0x0020#define COMMAND_SETYUVTHRESH		0x0040#define COMMAND_SETECPTIMING		0x0080    /* for parport */#define COMMAND_SETUSBALT		0x0080    /* for usb     */ #define COMMAND_SETCOMPRESSIONPARAMS	0x0100#define COMMAND_SETEXPOSURE		0x0200#define COMMAND_SETCOLOURBALANCE	0x0400#define COMMAND_SETSENSORFPS		0x0800#define COMMAND_SETAPCOR		0x1000#define COMMAND_SETFLICKERCTRL		0x2000#define COMMAND_SETVLOFFSET		0x4000#define COMMAND_SETLIGHTS		0x8000#define ROUND_UP_EXP_FOR_FLICKER 15/* Constants for automatic frame rate adjustment */#define MAX_EXP       302#define MAX_EXP_102   255#define LOW_EXP       140#define VERY_LOW_EXP   70#define TC             94#define	EXP_ACC_DARK   50#define	EXP_ACC_LIGHT  90#define HIGH_COMP_102 160		#define MAX_COMP      239		#define DARK_TIME       3#define LIGHT_TIME      3/* Maximum number of 10ms loops to wait for the stream to become ready */#define READY_TIMEOUT 100/* Developer's Guide Table 5 p 3-34 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/static u8 flicker_jumps[2][2][4] ={ { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },  { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }};/* forward declaration of local function */static void reset_camera_struct(struct cam_data *cam);static int find_over_exposure(int brightness);static void set_flicker(struct cam_params *params, volatile u32 *command_flags,                        int on);/********************************************************************** * * Memory management * **********************************************************************/#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19))/********************************************************************** * This is a shameless copy from the USB-cpia driver (linux kernel * version 2.3.29 or so, I have no idea what this code actually does ;). * Actually it seems to be a copy of a shameless copy of the bttv-driver. * Or that is a copy of a shameless copy of ... (To the powers: is there * no generic kernel-function to do this sort of stuff?) * * Yes, it was a shameless copy from the bttv-driver. IIRC, Alan says * there will be one, but apparentely not yet - jerdfelt * **********************************************************************//* Given PGD from the address space's page table, return the kernel * virtual mapping of the physical memory mapped at ADR. */static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr){	unsigned long ret = 0UL;	pmd_t *pmd;	pte_t *ptep, pte;	if (!pgd_none(*pgd)) {		pmd = pmd_offset(pgd, adr);		if (!pmd_none(*pmd)) {			ptep = pte_offset(pmd, adr);			pte = *ptep;			if (pte_present(pte)) {				ret = (unsigned long) page_address(pte_page(pte));				ret |= (adr & (PAGE_SIZE-1));			}		}	}	return ret;}/* Here we want the physical address of the memory. * This is used when initializing the contents of the * area and marking the pages as reserved. */static inline unsigned long kvirt_to_pa(unsigned long adr){	unsigned long va, kva, ret;	va = VMALLOC_VMADDR(adr);	kva = uvirt_to_kva(pgd_offset_k(va), va);	ret = __pa(kva);	return ret;}static void *rvmalloc(unsigned long size){	void *mem;	unsigned long adr, page;	/* Round it off to PAGE_SIZE */	size += (PAGE_SIZE - 1);	size &= ~(PAGE_SIZE - 1);	mem = vmalloc_32(size);	if (!mem)		return NULL;	memset(mem, 0, size); /* Clear the ram out, no junk to the user */	adr = (unsigned long) mem;	while (size > 0) {		page = kvirt_to_pa(adr);		mem_map_reserve(virt_to_page(__va(page)));		adr += PAGE_SIZE;		if (size > PAGE_SIZE)			size -= PAGE_SIZE;		else			size = 0;	}	return mem;}static void rvfree(void *mem, unsigned long size){	unsigned long adr, page;	if (!mem)		return;	size += (PAGE_SIZE - 1);	size &= ~(PAGE_SIZE - 1);	adr = (unsigned long) mem;	while (size > 0) {		page = kvirt_to_pa(adr);		mem_map_unreserve(virt_to_page(__va(page)));		adr += PAGE_SIZE;		if (size > PAGE_SIZE)			size -= PAGE_SIZE;		else			size = 0;	}	vfree(mem);}#else /*(LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))*//* Here we want the physical address of the memory. * This is used when initializing the contents of the area. */static inline unsigned long kvirt_to_pa(unsigned long adr){	unsigned long kva, ret;	kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));	kva |= adr & (PAGE_SIZE-1); /* restore the offset */	ret = __pa(kva);	return ret;}static void *rvmalloc(unsigned long size){	void *mem;	unsigned long adr;	size = PAGE_ALIGN(size);	mem = vmalloc_32(size);	if (!mem)		return NULL;	memset(mem, 0, size); /* Clear the ram out, no junk to the user */	adr = (unsigned long) mem;	while (size > 0) {#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69))		mem_map_reserve(vmalloc_to_page((void *)adr));#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,69)*/		SetPageReserved(vmalloc_to_page((void *)adr));		#endif		adr += PAGE_SIZE;		size -= PAGE_SIZE;	}	return mem;}static void rvfree(void *mem, unsigned long size){	unsigned long adr;	if (!mem)		return;	adr = (unsigned long) mem;	while ((long) size > 0) {#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69))		mem_map_unreserve(vmalloc_to_page((void *)adr));#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,69)*/		ClearPageReserved(vmalloc_to_page((void *)adr));#endif		adr += PAGE_SIZE;		size -= PAGE_SIZE;	}	vfree(mem);}#endif /*(LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))*//********************************************************************** * * /proc interface * **********************************************************************/#ifdef CONFIG_PROC_FSstatic struct proc_dir_entry *cpia_proc_root=NULL;#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,75))static ssize_t cpia_read_proc(char *page, char **start, off_t off,#elsestatic int cpia_read_proc(char *page, char **start, off_t off,#endif                          int count, int *eof, void *data){	char *out = page;	int len, tmp;	struct cam_data *cam = data;	char tmpstr[29];	/* IMPORTANT: This output MUST be kept under PAGE_SIZE	 *            or we need to get more sophisticated. */	out += sprintf(out, "read-only\n-----------------------\n");	out += sprintf(out, "V4L Driver version:       %d.%d.%d\n",		       CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER);	out += sprintf(out, "CPIA Version:             %d.%02d (%d.%d)\n",	               cam->params.version.firmwareVersion,	               cam->params.version.firmwareRevision,	               cam->params.version.vcVersion,	               cam->params.version.vcRevision);	out += sprintf(out, "CPIA PnP-ID:              %04x:%04x:%04x\n",	               cam->params.pnpID.vendor, cam->params.pnpID.product,	               cam->params.pnpID.deviceRevision);	out += sprintf(out, "VP-Version:               %d.%d %04x\n",	               cam->params.vpVersion.vpVersion,	               cam->params.vpVersion.vpRevision,	               cam->params.vpVersion.cameraHeadID);		out += sprintf(out, "system_state:             %#04x\n",	               cam->params.status.systemState);	out += sprintf(out, "grab_state:               %#04x\n",	               cam->params.status.grabState);	out += sprintf(out, "stream_state:             %#04x\n",	               cam->params.status.streamState);	out += sprintf(out, "fatal_error:              %#04x\n",	               cam->params.status.fatalError);	out += sprintf(out, "cmd_error:                %#04x\n",	               cam->params.status.cmdError);	out += sprintf(out, "debug_flags:              %#04x\n",	               cam->params.status.debugFlags);	out += sprintf(out, "vp_status:                %#04x\n",	               cam->params.status.vpStatus);	out += sprintf(out, "error_code:               %#04x\n",	               cam->params.status.errorCode);	/* QX3 specific entries */	if (cam->params.qx3.qx3_detected) {		out += sprintf(out, "button:                   %4d\n",		               cam->params.qx3.button);		out += sprintf(out, "cradled:                  %4d\n",

⌨️ 快捷键说明

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