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

📄 h3600_backpaq_core.c

📁 pxa270下的摄像头mtd91111的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
	int retval;	if ( cam->i2c_status == I2C_BUSY )		return EBUSY;	ENABLE_I2C_INT;	BackpaqFPGACameraI2C_SlaveAddr = address;	BackpaqFPGACameraI2C_RegAddr   = subaddress;	BackpaqFPGACameraI2C_Data      = data;		BackpaqFPGACameraI2C_CR1       = START_I2C_TRANSACTION;	cam->i2c_status                  = I2C_BUSY;          PRINTDEBUG(": I2C CR1=0x%X\n", BackpaqFPGACameraI2C_CR1 );	/* Wait for I2C completion */	retval = wait_event_interruptible( cam->i2cq, !(cam->i2c_status & I2C_BUSY) );	if( !(cam->i2c_status & I2C_ACK_SLAVE_ADDRESS) )		CAMERROR(": I2C, no acknowledge on slave address\n");	if( !(cam->i2c_status & I2C_ACK_REG_ADDRESS) )		CAMERROR(": I2C, no acknowledge on register address\n");	if( !(cam->i2c_status & I2C_ACK_DATA) )		CAMERROR(": I2C, no acknowledge on data\n");	DISABLE_I2C_INT;	return retval;}// SUBROW marcos#define SUBROWMASK		( 1 << 6 )#define SET_SUBROWMODE( x )	( x |= SUBROWMASK )#define UNSET_SUBROWMODE( x )	( x &= ~SUBROWMASK )#define CHECK_SUBROWMODE( x )	( x & SUBROWMASK )static void setup_ph_upa1021_cam( struct h3600_camera_struct *cam ){	int i;	int lines_per_frame;		/* Set all I2C resisters of the UPA1021 */	if ( cam->param_mask & PARAM_IMAGER_PH_ALLREGS ) {		BackpaqFPGACameraI2C_CR2 = I2C_FAST_SPEED;		for ( i = 0 ; i < sizeof(upa1021_i2c_regs); i++ )			WriteI2C( cam, UPA1021_BASEADDRESS, i, upa1021_i2c_regs[i] );	}	/* Electronic shutter value in # of line times */	if ( cam->param_mask & PARAM_IMAGER_PH_ESHUTTER ) {		// Prevent field stretching of UPA1022		lines_per_frame = upa1021_i2c_regs[UPA1021_LINFIL] | (upa1021_i2c_regs[UPA1021_HCKLFL] & 0xF);		if( cam->electronic_shutter >  lines_per_frame )			 cam->electronic_shutter = lines_per_frame;		PRINTDEBUG( ": setting electronic shutter (row_exposure)= 0x%x\n",  cam->electronic_shutter);		/* Low byte */		upa1021_i2c_regs[UPA1021_REL] = cam->electronic_shutter & 0xFF;		WriteI2C( cam, UPA1021_BASEADDRESS, UPA1021_REL, upa1021_i2c_regs[UPA1021_REL] );		/* High byte */		upa1021_i2c_regs[UPA1021_REH] = cam->electronic_shutter >> 8;		PRINTDEBUG( ": setting REH= 0x%x\n",  upa1021_i2c_regs[UPA1021_REH]);				WriteI2C( cam, UPA1021_BASEADDRESS, UPA1021_REH, upa1021_i2c_regs[UPA1021_REH] );	}	/* Subrow electronic shutter value */	if ( cam->param_mask & PARAM_IMAGER_PH_SUBROW ) {		PRINTDEBUG( ": setting subrow = 0x%x\n", cam->subrow);		if( cam->subrow != 0 )		{			if(  !CHECK_SUBROWMODE( upa1021_i2c_regs[UPA1021_CR1]) )			{				SET_SUBROWMODE( upa1021_i2c_regs[UPA1021_CR1] );				WriteI2C( cam, UPA1021_BASEADDRESS, UPA1021_CR1, upa1021_i2c_regs[UPA1021_CR1]  );				PRINTDEBUG( ": setting subrow mode CR1=0x%X\n", upa1021_i2c_regs[UPA1021_CR1] );			}					}		else		{			if(  CHECK_SUBROWMODE( upa1021_i2c_regs[UPA1021_CR1]) )			{				UNSET_SUBROWMODE( upa1021_i2c_regs[UPA1021_CR1] );				WriteI2C( cam, UPA1021_BASEADDRESS, UPA1021_CR1, upa1021_i2c_regs[UPA1021_CR1]  );				PRINTDEBUG( ": unsetting subrow mode CR1=0x%X\n", upa1021_i2c_regs[UPA1021_CR1] );			}		}		upa1021_i2c_regs[UPA1021_SRER] = cam->subrow;		WriteI2C( cam, UPA1021_BASEADDRESS, UPA1021_SRER, upa1021_i2c_regs[UPA1021_SRER] );	}	/* programmable Gain Amp value */	if ( cam->param_mask & PARAM_IMAGER_PH_PGA ) {		PRINTDEBUG(  ": setting contrast (GOEB) = 0x%x\n", cam->vpic.contrast);		upa1021_i2c_regs[UPA1021_GOEB] = cam->vpic.contrast;		WriteI2C( cam, UPA1021_BASEADDRESS, UPA1021_GOEB, upa1021_i2c_regs[UPA1021_GOEB] );	}			}static void setup_ph_upa1022_cam( struct h3600_camera_struct *cam ){	int i;	int lines_per_frame;	PRINTDEBUG(": setup_ph_upa1022_cam\n" );	/* Set all I2C resisters of the UPA1022 */	if ( cam->param_mask & PARAM_IMAGER_PH_ALLREGS ) {		BackpaqFPGACameraI2C_CR2 = I2C_FAST_SPEED;		for ( i = 0 ; i < sizeof(upa1022_i2c_regs); i++ )			WriteI2C( cam, UPA1022_BASEADDRESS, i, upa1022_i2c_regs[i] );	}	/* Electronic shutter value in # of line times */	if ( cam->param_mask & PARAM_IMAGER_PH_ESHUTTER ) {		// Prevent field stretching of UPA1022		lines_per_frame = upa1022_i2c_regs[UPA1022_LINFIL] | (upa1022_i2c_regs[UPA1022_HCKLFL] & 0xF);		if( cam->electronic_shutter >  lines_per_frame )			 cam->electronic_shutter = lines_per_frame;		PRINTDEBUG( ": setting electronic shutter (row_exposure)= 0x%x\n",  cam->electronic_shutter);		/* Low byte */		upa1022_i2c_regs[UPA1022_REL] = cam->electronic_shutter & 0xFF;		WriteI2C( cam, UPA1022_BASEADDRESS, UPA1022_REL, upa1022_i2c_regs[UPA1022_REL] );		/* High byte */		upa1022_i2c_regs[UPA1022_REH] = cam->electronic_shutter >> 8;		PRINTDEBUG( ": setting REH= 0x%x\n",  upa1022_i2c_regs[UPA1022_REH]);				WriteI2C( cam, UPA1022_BASEADDRESS, UPA1022_REH, upa1022_i2c_regs[UPA1022_REH] );	}	/* Subrow electronic shutter value */	if ( cam->param_mask & PARAM_IMAGER_PH_SUBROW ) {		PRINTDEBUG( ": setting subrow = 0x%x\n", cam->subrow);		if( cam->subrow != 0 )		{			if(  !CHECK_SUBROWMODE( upa1022_i2c_regs[UPA1022_CR1]) )			{				SET_SUBROWMODE( upa1022_i2c_regs[UPA1022_CR1] );				WriteI2C( cam, UPA1022_BASEADDRESS, UPA1022_CR1, upa1022_i2c_regs[UPA1022_CR1]  );				PRINTDEBUG( ": setting subrow mode CR1=0x%X\n", upa1022_i2c_regs[UPA1022_CR1] );			}					}		else		{			if(  CHECK_SUBROWMODE( upa1022_i2c_regs[UPA1022_CR1]) )			{				UNSET_SUBROWMODE( upa1022_i2c_regs[UPA1022_CR1] );				WriteI2C( cam, UPA1022_BASEADDRESS, UPA1022_CR1, upa1022_i2c_regs[UPA1022_CR1]  );				PRINTDEBUG( ": unsetting subrow mode CR1=0x%X\n", upa1022_i2c_regs[UPA1022_CR1] );			}		}		upa1022_i2c_regs[UPA1022_SRER] = cam->subrow;		WriteI2C( cam, UPA1022_BASEADDRESS, UPA1022_SRER, upa1022_i2c_regs[UPA1022_SRER] );	}	/* programmable Gain Amp value */	if ( cam->param_mask & PARAM_IMAGER_PH_PGA ) {		PRINTDEBUG(  ": setting contrast (GOEB) = 0x%x\n", cam->vpic.contrast);		upa1022_i2c_regs[UPA1022_GOEB] = cam->vpic.contrast;		WriteI2C( cam, UPA1022_BASEADDRESS, UPA1022_GOEB, upa1022_i2c_regs[UPA1022_GOEB] );	}			}static void setup_camera( struct h3600_camera_struct *cam ){	if (0) PRINTDEBUG( " param_mask=0x%04x\n", cam->param_mask);	if ( cam->param_mask & PARAM_FPGA_CLOCK_DIVISOR )		BackpaqFPGACameraClockDivisor = cam->clock_divisor;		if ( cam->param_mask & PARAM_FPGA_INTERRUPT_FIFO )		BackpaqFPGACameraInterruptFifo = cam->interrupt_fifo;			if ( cam->param_mask & PARAM_FPGA_LIVE_MODE )		BackpaqFPGACameraLiveMode     = 0x01;    /* Turn on live video mode */	/* Settings specific to the type of image sensor connected */	switch ( cam->ctype ) {	case H3600_SMAL:		setup_small_cam( cam );		break;	case H3600_PHILIPS:		switch( cam->cam_sub_type ) {		case PHILIPS_UPA1021:			setup_ph_upa1021_cam( cam );			break;		case PHILIPS_UPA1022:			setup_ph_upa1022_cam( cam );			break;		}		break;	}	if ( cam->param_mask & PARAM_FPGA_DECIMATION_MODE ) {		if ( decimate_mode )			BackpaqFPGACameraDecimationMode = fpga_mode_to_decimation[cam->mode];		else			BackpaqFPGACameraDecimationMode = 0; 	}	cam->param_mask = 0; /* Clear all parameters */}static void stop_capture( struct h3600_camera_struct *cam ){	unsigned long flags;	save_flags_cli(flags);	DISABLE_BOTH_INT;   /* Shut off interrupts */	cam->capture_state = CAPTURE_OFF;	restore_flags(flags);}static void start_capture( struct h3600_camera_struct *cam ){	unsigned long flags;	save_flags_cli(flags);	cam->capture_state = CAPTURE_WAIT_FOR_REFRESH;	DISABLE_FIFO_INT;	ENABLE_VBLANK_INT;	restore_flags(flags);}/****************************************************************************** * * Capture routines *  * These routines are called by V4L interface and are "locked" (i.e., only * one can be called at a time).  It is quite likely that interrupts are running. * ******************************************************************************//* Called by ioctl routines that change camera parameters */static void update_camera_params( struct h3600_camera_struct *cam ){	unsigned long flags;	if ( cam->state == HC_V4L_STREAMING ) {		save_flags_cli(flags);		if ( cam->param_mask & PARAM_FPGA_DECIMATION_MODE ) {			cam->capture_state = CAPTURE_WAIT_FOR_REFRESH;			DISABLE_FIFO_INT;			ENABLE_VBLANK_INT;		}		setup_camera( cam ); 		restore_flags(flags);	}	else {		setup_camera( cam );	}}/* Called by "read" */static long grab_frame( struct h3600_camera_struct *cam ){	struct frame *frame;	int retval;	stop_capture(cam);             /* Turn off interrupt routines */	setup_camera(cam);             /* Fix the camera parameters */	clear_capture_buffers(cam);    /* Clear all capture buffers */	cam->state = HC_V4L_GRABBING;  /* Set our state */	queue_capture_buffer(cam,0);   /* Queue up buffer #0 */	start_capture(cam);            /* Turn on interrupt routines */	retval = wait_event_interruptible(cam->capq,					  cam->capture_state == CAPTURE_OFF );		stop_capture(cam);	cam->state = HC_V4L_IDLE;	if ( retval < 0 ) {		CAMDEBUG(": Grab value error %d\n", retval);		return retval;	}	frame = &(cam->frame[0]);	if (!frame->state == FRAME_FULL) {		CAMDEBUG(": Unable to capture a good frame\n");		return -ERESTART;	}#ifdef BACKPAQ_CAMERA_DEBUG//	printk(KERN_ALERT __FILE__ ": Read image (size %d)\n" //	       "  Number of interrupts:   FIFO=%d  VBLANK=%d\n"//	       "  On interrupt, fifo       min=%d max=%d status=%x\n",//	       frame->bytes_read,//	       cam->capture_stats.fifo_count, cam->capture_stats.vblank_count,//	       cam->capture_stats.fifo_low, cam->capture_stats.fifo_high,//	       BackpaqFPGAInterruptStatus);#endif	return frame->bytes_read;}/* Called by "read in polling mode" */static long grab_frame_polling( struct h3600_camera_struct *cam ){	int retval;	struct frame *frame;	stop_capture(cam);               /* Turn off any running interrupt routines */	setup_camera(cam);               /* Fix camera parameters                   */	clear_capture_buffers(cam);      /* Clear all capture buffers               */	cam->state = HC_V4L_IDLE;	queue_capture_buffer(cam,0);	frame = &cam->frame[0];	/* Wait until rowcount == 1 */	while ( BackpaqFPGACameraRowCount != 1 )		;		do {		retval = get_fpga_data( cam );	} while ( retval > 0 );	if ( retval < 0 ) {		CAMDEBUG(": Fifo overrun %d\n", retval);		CAMDEBUG(": Bytes read %d\n", frame->bytes_read );		CAMDEBUG(": Bytes we're supposed to read %d\n", frame->bytes_to_read);		return retval;	}#ifdef BACKPAQ_CAMERA_DEBUG//	printk(KERN_ALERT __FILE__ ": Polling read image (size %d)\n" //	       "  Fifo  min=%d  max=%d\n",//	       frame->bytes_read,//	       cam->capture_stats.fifo_low, cam->capture_stats.fifo_high ); //	printk(KERN_ALERT __FILE__ ": fifo status = %x\n", //	       BackpaqFPGAInterruptStatus);#endif	return frame->bytes_read;}/* Called by "capture" */static int grab_streaming_frame( struct h3600_camera_struct *cam, int index ){	int retval = 0;	struct frame *frame = &cam->frame[index];	/* Allocate virtual memory if we haven't already */	if (!cam->frame_buf) {	/* we do lazy allocation */		if ((retval = allocate_frame_buf(cam)))			return retval;	}	/* If we're not currently streaming, start, and queue a buffer */	if ( cam->state != HC_V4L_STREAMING ) {		stop_capture(cam);               /* Turn off any running captures */		setup_camera(cam);               /* Fix camera parameters */		clear_capture_buffers(cam);      /* Clear all capture buffers */		cam->state = HC_V4L_STREAMING;		queue_capture_buffer(cam,index);		start_capture(cam);	}	/* Wait until our capture buffer is finished */	/* This may be interrupted by suspending the iPAQ */	retval = wait_event_interruptible(cam->capq, 					  cam->capture_state == CAPTURE_OFF					  || frame->state == FRAME_DONE 					  || frame->state == FRAME_FULL );		if ( cam->capture_state == CAPTURE_OFF )		return -EINTR;	return retval;}/* Called by "sync" */static int sync_frame( struct h3600_camera_struct *cam, int index ){	int retval = 0;	if ( cam->state != HC_V4L_STREAMING ) {//		CAMDEBUG(" Not streaming, but syncing frame %d\n", index );/* 		stop_capture(cam);		setup_camera(cam);		clear_capture_buffers(cam);		queue_capture_buffer(cam,index);		cam->state = HC_V4L_STREAMING;		start_capture(cam); */	}	else {		unsigned long flags;		int depth;		save_flags_cli(flags);		depth = queue_capture_buffer(cam,index);		restore_flags(flags);	}	return retval;}/* Called at initialization and by the RESET function */static void set_camera_type( struct h3600_camera_struct *cam ){	switch (h3600_backpaq_eeprom_shadow.camera & BACKPAQ_EEPROM_CAMERA_TYPE_MASK) {	case BACKPAQ_CAMERA_SMAL_ORIGINAL_GREY:	case BACKPAQ_CAMERA_SMAL_ORIGINAL_COLOR:	case BACKPAQ_CAMERA_SMAL_RELEASE_COLOR:	case BACKPAQ_CAMERA_SMAL_AUTOBRITE_09:		cam->ctype = H3600_SMAL;		break;	case BACKPAQ_CAMERA_PHILIPS_UPA1021:		cam->ctype          = H3600_PHILIPS;		cam->cam_sub_type   = PHILIPS_UPA1021;		break;	case BACKPAQ_CAMERA_PHILIPS_UPA1022:		cam->ctype          = H3600_PHILIPS;		cam->cam_sub_type   = PHILIPS_UPA1022;		break;		break;	}}static void set_default_params( struct h3600_camera_struct *cam ){	set_camera_type( cam );	cam->vpic.brightness = 0x8000;	cam->vpic.contrast   = 0x8000;	set_camera_resolution( cam, VIDEO_PALETTE_RGB24, 10000, 10000 );   /* Will set to 640 x 480 */	cam->flip              = 0;       /* Don't flip */	cam->read_polling_mode = 0;	switch ( cam->ctype ) {	case H3600_SMAL:		cam->clock_divisor  = H3600_BACKPAQ_CAMERA_DEFAULT_CLOCK_DIVISOR;		cam->interrupt_fifo = H3600_BACKPAQ_CAMERA_DEFAULT_INTERRUPT_FIFO;		cam->power_setting  = H3600_BACKPAQ_CAMERA_DEFAULT_POWER_SETTING;		cam->gain_format    = H3600_BACKPAQ_CAMERA_DEFAULT_GAIN_FORMAT;		cam->power_mgmt     = H3600_BACKPAQ_CAMERA_DEFAULT_POWER_MGMT;		cam->special_modes  = H3600_BACKPAQ_CAMERA_DEFAULT_SPECIAL_MODES;		cam->autobright     = H3600_BACKPAQ_CAMERA_DEFAULT_AUTOBRIGHT;		break;			case H3600_PHILIPS:		cam->clock_divisor      = H3600_BACKPAQ_CAMERA_PHILIPS_CLOCK_DIVISOR;		cam->interrupt_fifo     = H3600_BACKPAQ_CAMERA_PHILIPS_INTERRUPT_FIFO;		cam->electronic_shutter = H3600_BACKPAQ_CAMERA_PHILIPS_ELECTRONIC_SHUTTER;		cam->subrow             = H3600_BACKPAQ_CAMERA_PHILIPS_SUBROW;		break;	}	cam->param_mask = 0xffff;}

⌨️ 快捷键说明

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