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

📄 cpia_pp.c

📁 pxa270下的摄像头mtd91111的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * cpia_pp CPiA Parallel Port driver * * Supports CPiA based parallel port Video Camera's. * * (C) Copyright 1999 Bas Huisman <bhuism@cs.utwente.nl> * (C) Copyright 1999-2000 Scott J. Bertin <sbertin@securenym.net>, * (C) Copyright 1999-2000 Peter Pregler <Peter_Pregler@email.com> * * 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/module.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/parport.h>#include <linux/interrupt.h>#include <linux/delay.h>#include <linux/smp_lock.h>#include <linux/kmod.h>/* #define _CPIA_DEBUG_		define for verbose debug output */#include "cpia.h"static int cpia_pp_open(void *privdata);static int cpia_pp_registerCallback(void *privdata, void (*cb) (void *cbdata),                                    void *cbdata);static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data);static int cpia_pp_streamStart(void *privdata);static int cpia_pp_streamStop(void *privdata);static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock);static int cpia_pp_close(void *privdata);#define ABOUT "Parallel port driver for Vision CPiA based cameras"/* IEEE 1284 Compatiblity Mode signal names 	*/#define nStrobe		PARPORT_CONTROL_STROBE	  /* inverted */#define nAutoFd		PARPORT_CONTROL_AUTOFD	  /* inverted */#define nInit		PARPORT_CONTROL_INIT#define nSelectIn	PARPORT_CONTROL_SELECT#define IntrEnable	PARPORT_CONTROL_INTEN	  /* normally zero for no IRQ */#define DirBit		PARPORT_CONTROL_DIRECTION /* 0 = Forward, 1 = Reverse	*/#define nFault		PARPORT_STATUS_ERROR#define Select		PARPORT_STATUS_SELECT#define PError		PARPORT_STATUS_PAPEROUT#define nAck		PARPORT_STATUS_ACK#define Busy		PARPORT_STATUS_BUSY	  /* inverted */	/* some more */#define HostClk		nStrobe#define HostAck		nAutoFd#define nReverseRequest	nInit#define Active_1284	nSelectIn#define nPeriphRequest	nFault#define XFlag		Select#define nAckReverse	PError#define PeriphClk	nAck#define PeriphAck	Busy/* these can be used to correct for the inversion on some bits */#define STATUS_INVERSION_MASK	(Busy)#define CONTROL_INVERSION_MASK	(nStrobe|nAutoFd|nSelectIn)#define ECR_empty	0x01#define ECR_full	0x02#define ECR_serviceIntr 0x04#define ECR_dmaEn	0x08#define ECR_nErrIntrEn	0x10#define ECR_mode_mask	0xE0#define ECR_SPP_mode	0x00#define ECR_PS2_mode	0x20#define ECR_FIFO_mode	0x40#define ECR_ECP_mode	0x60#define ECP_FIFO_SIZE	16#define DMA_BUFFER_SIZE               PAGE_SIZE	/* for 16bit DMA make sure DMA_BUFFER_SIZE is 16 bit aligned */#define PARPORT_CHUNK_SIZE	PAGE_SIZE/* >=2.3.x */				/* we read this many bytes at once */#define GetECRMasked(port,mask)	(parport_read_econtrol(port) & (mask))#define GetStatus(port)		((parport_read_status(port)^STATUS_INVERSION_MASK)&(0xf8))#define SetStatus(port,val)	parport_write_status(port,(val)^STATUS_INVERSION_MASK)#define GetControl(port)	((parport_read_control(port)^CONTROL_INVERSION_MASK)&(0x3f))#define SetControl(port,val)	parport_write_control(port,(val)^CONTROL_INVERSION_MASK)#define GetStatusMasked(port,mask)	(GetStatus(port) & (mask))#define GetControlMasked(port,mask)	(GetControl(port) & (mask))#define SetControlMasked(port,mask)	SetControl(port,GetControl(port) | (mask));#define ClearControlMasked(port,mask)	SetControl(port,GetControl(port)&~(mask));#define FrobControlBit(port,mask,value)	SetControl(port,(GetControl(port)&~(mask))|((value)&(mask)));#define PACKET_LENGTH 	8/* Magic numbers for defining port-device mappings */#define PPCPIA_PARPORT_UNSPEC -4#define PPCPIA_PARPORT_AUTO -3#define PPCPIA_PARPORT_OFF -2#define PPCPIA_PARPORT_NONE -1#ifdef MODULEstatic int parport_nr[PARPORT_MAX] = {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};static char *parport[PARPORT_MAX] = {NULL,};MODULE_AUTHOR("B. Huisman <bhuism@cs.utwente.nl> & Peter Pregler <Peter_Pregler@email.com>");MODULE_DESCRIPTION("Parallel port driver for Vision CPiA based cameras");MODULE_LICENSE("GPL");MODULE_PARM(parport, "1-" __MODULE_STRING(PARPORT_MAX) "s");MODULE_PARM_DESC(parport, "'auto' or a list of parallel port numbers. Just like lp.");#elsestatic int parport_nr[PARPORT_MAX] __initdata =	{[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};static int parport_ptr = 0;#endifstruct pp_cam_entry {	struct pardevice *pdev;	struct parport *port;	struct tq_struct cb_task;	int open_count;	wait_queue_head_t wq_stream;	/* image state flags */	int image_ready;	/* we got an interrupt */	int image_complete;	/* we have seen 4 EOI */	int streaming; /* we are in streaming mode */	int stream_irq;};static struct cpia_camera_ops cpia_pp_ops = {	cpia_pp_open,	cpia_pp_registerCallback,	cpia_pp_transferCmd,	cpia_pp_streamStart,	cpia_pp_streamStop,	cpia_pp_streamRead,	cpia_pp_close,	1};static struct cam_data *cam_list;static spinlock_t cam_list_lock_pp;#ifdef _CPIA_DEBUG_#define DEB_PORT(port) { \u8 controll = GetControl(port); \u8 statusss = GetStatus(port); \DBG("nsel %c per %c naut %c nstrob %c nak %c busy %c nfaul %c sel %c init %c dir %c\n",\((controll & nSelectIn)	? 'U' : 'D'), \((statusss & PError)	? 'U' : 'D'), \((controll & nAutoFd)	? 'U' : 'D'), \((controll & nStrobe)	? 'U' : 'D'), \((statusss & nAck)	? 'U' : 'D'), \((statusss & Busy)	? 'U' : 'D'), \((statusss & nFault)	? 'U' : 'D'), \((statusss & Select)	? 'U' : 'D'), \((controll & nInit)	? 'U' : 'D'), \((controll & DirBit)	? 'R' : 'F')  \); }#else#define DEB_PORT(port) {}#endif#define WHILE_OUT_TIMEOUT (HZ/10)#define DMA_TIMEOUT 10*HZ/* FIXME */static void cpia_parport_enable_irq( struct parport *port ) {	parport_enable_irq(port);	mdelay(10);	return;}static void cpia_parport_disable_irq( struct parport *port ) {	parport_disable_irq(port);	mdelay(10);	return;}/**************************************************************************** * *  EndTransferMode * ***************************************************************************/static void EndTransferMode(struct pp_cam_entry *cam){	parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);}/**************************************************************************** * *  ForwardSetup * ***************************************************************************/static int ForwardSetup(struct pp_cam_entry *cam){	int retry;		/* After some commands the camera needs extra time before	 * it will respond again, so we try up to 3 times */	for(retry=0; retry<3; ++retry) {		if(!parport_negotiate(cam->port, IEEE1284_MODE_ECP)) {			break;		}	}	if(retry == 3) {		DBG("Unable to negotiate ECP mode\n");		return -1;	}	return 0;}/**************************************************************************** * *  ReverseSetup * ***************************************************************************/static int ReverseSetup(struct pp_cam_entry *cam, int extensibility){	int retry;	int mode = IEEE1284_MODE_ECP;	if(extensibility) mode = 8|3|IEEE1284_EXT_LINK;	/* After some commands the camera needs extra time before	 * it will respond again, so we try up to 3 times */	for(retry=0; retry<3; ++retry) {		if(!parport_negotiate(cam->port, mode)) {			break;		}	}	if(retry == 3) {		if(extensibility)			DBG("Unable to negotiate extensibility mode\n");		else			DBG("Unable to negotiate ECP mode\n");		return -1;	}	if(extensibility) cam->port->ieee1284.mode = IEEE1284_MODE_ECP;	return 0;}/**************************************************************************** * *  WritePacket * ***************************************************************************/static int WritePacket(struct pp_cam_entry *cam, const u8 *packet, size_t size){	int retval=0;	int size_written;	if (packet == NULL) {		return -EINVAL;	}	if (ForwardSetup(cam)) {		DBG("Write failed in setup\n");		return -EIO;	}	size_written = parport_write(cam->port, packet, size);	if(size_written != size) {		DBG("Write failed, wrote %d/%d\n", size_written, size);		retval = -EIO;	}	EndTransferMode(cam);	return retval;}/**************************************************************************** * *  ReadPacket * ***************************************************************************/static int ReadPacket(struct pp_cam_entry *cam, u8 *packet, size_t size){	int retval=0;	if (packet == NULL) {		return -EINVAL;	}	if (ReverseSetup(cam, 0)) {		return -EIO;	}	if(parport_read(cam->port, packet, size) != size) {		retval = -EIO;	}	EndTransferMode(cam);	return retval;}/**************************************************************************** * *  cpia_pp_streamStart * ***************************************************************************/static int cpia_pp_streamStart(void *privdata){	struct pp_cam_entry *cam = privdata;	DBG("\n");	cam->streaming=1;	cam->image_ready=0;	//if (ReverseSetup(cam,1)) return -EIO;	if(cam->stream_irq) cpia_parport_enable_irq(cam->port);	return 0;}/**************************************************************************** * *  cpia_pp_streamStop * ***************************************************************************/static int cpia_pp_streamStop(void *privdata){	struct pp_cam_entry *cam = privdata;	DBG("\n");	cam->streaming=0;	cpia_parport_disable_irq(cam->port);	//EndTransferMode(cam);	return 0;}/**************************************************************************** * *  cpia_pp_streamRead * ***************************************************************************/static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock){	struct pp_cam_entry *cam = privdata;	int read_bytes = 0;	int i, endseen;	if(cam == NULL) {		DBG("Internal driver error: cam is NULL\n");		return -EINVAL;	}	if(buffer == NULL) {		DBG("Internal driver error: buffer is NULL\n");

⌨️ 快捷键说明

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