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

📄 h3600_backpaq_core.c

📁 pxa270下的摄像头mtd91111的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
		return -ENOBUFS;	for (i = 0; i < NUMBER_OF_FRAMES; i++)		cam->frame[i].shared_data = cam->frame_buf + i * HC_MAX_PROCESSED_FRAME_SIZE;	return 0;}static int free_frame_buf(struct h3600_camera_struct *cam){	int i;		rvfree(cam->frame_buf, NUMBER_OF_FRAMES * HC_MAX_PROCESSED_FRAME_SIZE);	cam->frame_buf = 0;	for (i=0; i < NUMBER_OF_FRAMES; i++)		cam->frame[i].data = NULL;	return 0;}/* Write the state out into a buffer *//* We've already checked that the buffer is of the required size and has been verified *//* There are a couple of possible states:   1. The frame has already written into shared memory and no processing is required   2. The frame needs to be written to shared memory (buf == NULL)   3. The frame needs to be copied into buf.*/static long process_frame( struct h3600_camera_struct *cam, unsigned char *dest, int index ){	struct frame *frame = &(cam->frame[index]);	unsigned long result = 0;	int           streaming;	unsigned char *buf;	if ( frame->state == FRAME_DONE ) {		CAMERROR("Trying to process DONE frame\n");		return -EINVAL;	}	if ( dest ) {		buf = dest;		streaming = 0;	} else {		buf = cam->frame[index].shared_data;		streaming = 1;	}	switch (cam->mode) {	case HC_MODE_RAW:		if ( !streaming )			__copy_to_user( buf, frame->data, HC_RAW_BUFFER_SIZE );		result = HC_RAW_BUFFER_SIZE; 		break;	case HC_MODE_RAW_DECIMATED:		if ( !streaming )			__copy_to_user( buf, frame->data, HC_DECIMATED_BUFFER_SIZE );		result = HC_DECIMATED_BUFFER_SIZE; 		break;	case HC_MODE_DECIMATION_1:		result = write_vga(frame,buf,streaming,cam->flip,cam->vpic.palette);		break;	case HC_MODE_DECIMATION_4:		decimate( frame );		/* Intentional fall through */	case HC_MODE_DECIMATION_2:		if ( !decimate_mode ) decimate( frame );		result = write_qvga(frame,buf,streaming,cam->flip,cam->vpic.palette);		break;	case HC_MODE_CIF:		result = write_cif(frame,buf,streaming,cam->flip,cam->vpic.palette);		break;	case HC_MODE_QCIF:		if ( !decimate_mode ) decimate(frame);		result = write_qcif(frame,buf,streaming,cam->flip,cam->vpic.palette);		break;	}	frame->state = FRAME_DONE;	return result;}/****************************************************************************** * * Read data from the camera.  This may be run at interrupt time or  * from a polling routine.  Return "-1" if the FIFO goes over its maximum * depth.  Otherwise, return "N" where "N" is the number of bytes left to read. * ******************************************************************************/#define MAXIMUM_FIFO_DEPTH 255static int get_fpga_data( struct h3600_camera_struct *cam ){	struct frame *frame = cam->active;	unsigned int         *lbuf = (unsigned int *) (frame->data + frame->bytes_read);	unsigned short        data_avail;	int i, count;	unsigned short        fifo_info = BackpaqFPGACameraFifoInfo;	int bytes_per_unit = (fifo_info & BACKPAQ_CAMERA_FIFO_INFO_BPC) >> 8;	int fifo_width     = (fifo_info & BACKPAQ_CAMERA_FIFO_INFO_WIDTH);	unsigned short       *sbuf = (unsigned short *) lbuf;	volatile unsigned short *fifo_data = (unsigned short *) &(BackpaqFPGACameraFifoData);	while (frame->bytes_read < frame->bytes_to_read) {		data_avail = BackpaqFPGACameraFifoDataAvail;		if ( data_avail >= MAXIMUM_FIFO_DEPTH )			return -1;		if ( data_avail > cam->capture_stats.fifo_high )			cam->capture_stats.fifo_high = data_avail;		if ( data_avail < cam->capture_stats.fifo_low )			cam->capture_stats.fifo_low = data_avail;		if ( data_avail <= 0 )			return frame->bytes_to_read - frame->bytes_read;		count = data_avail * bytes_per_unit;		if ( count + frame->bytes_read > frame->bytes_to_read )			count = frame->bytes_to_read - frame->bytes_read;			if ( fifo_width == 16 ) 			for ( i = 0 ; i < count ; i+=2 )  /* We read 2 bytes at a time */				*sbuf++ = *fifo_data;		else			for ( i = 0 ; i < count ; i+=4 )				*lbuf++ = BackpaqFPGACameraFifoData;				frame->bytes_read += i;	}		return frame->bytes_to_read - frame->bytes_read;}/****************************************************************************** * * Interrupt routines * ******************************************************************************/#define ENABLE_OPT_INT(x) \		BackpaqFPGAInterruptMask &= ~(x)#define DISABLE_OPT_INT(x) \		BackpaqFPGAInterruptMask |= (x)#define READ_OPT_INT(x) \		BackpaqFPGAInterruptStatus & (x) \                & ~BackpaqFPGAInterruptMask#define ENABLE_VBLANK_INT   ENABLE_OPT_INT(BACKPAQ_FPGA_INT_VBLANK)#define DISABLE_VBLANK_INT  DISABLE_OPT_INT(BACKPAQ_FPGA_INT_VBLANK)#define ENABLE_FIFO_INT     ENABLE_OPT_INT(BACKPAQ_FPGA_INT_FIFO)#define DISABLE_FIFO_INT    DISABLE_OPT_INT(BACKPAQ_FPGA_INT_FIFO)#define ENABLE_BOTH_INT     ENABLE_OPT_INT(BACKPAQ_FPGA_INT_FIFO | BACKPAQ_FPGA_INT_VBLANK)#define DISABLE_BOTH_INT    DISABLE_OPT_INT(BACKPAQ_FPGA_INT_FIFO | BACKPAQ_FPGA_INT_VBLANK)#define ENABLE_I2C_INT      ENABLE_OPT_INT(BACKPAQ_FPGA_INT_I2C)#define DISABLE_I2C_INT     DISABLE_OPT_INT(BACKPAQ_FPGA_INT_I2C)#define READ_BACKPAQ_INT    READ_OPT_INT(BACKPAQ_FPGA_INT_FIFO | BACKPAQ_FPGA_INT_VBLANK | BACKPAQ_FPGA_INT_I2C)static void capture_buffer_complete( struct h3600_camera_struct *cam ){	cam->active->state = FRAME_FULL;	cam->active = cam->active->next;	cam->capture_stats.complete_frames++;	/* Now, branch based on our state */	switch (cam->state) {	case HC_V4L_IDLE:		CAMERROR("Capture buffer complete when in IDLE state\n");		break;	case HC_V4L_GRABBING:		wake_up_interruptible(&cam->capq); 		DISABLE_BOTH_INT;		cam->capture_state = CAPTURE_OFF;		break;	case HC_V4L_STREAMING:		wake_up_interruptible(&cam->capq);		break;	}}  static void fpga_fifo_interrupt( struct h3600_camera_struct *cam ){	int retval;	DISABLE_FIFO_INT;      /* We must re-enable FIFO for the appropriate states */	cam->capture_stats.fifo_count++;	switch (cam->capture_state) {	case CAPTURE_OFF:		CAMERROR(": FIFO interrupt when capture is off?!?!\n");		break;	case CAPTURE_WAIT_FOR_REFRESH:		CAMERROR(": FIFO interrupt when capture is waiting for VBLANK!\n");		break;	case CAPTURE_WAIT_FOR_FIFO:		ENABLE_VBLANK_INT;    /* No matter what, we're interested in VBLANK again */		if ( !cam->active ) {  /* No buffer! */			cam->capture_state = CAPTURE_WAIT_FOR_REFRESH;			cam->capture_stats.ef_no_capture_buffer++;			return;         /* The FIFO_INT is still disabled */		}		cam->capture_state = CAPTURE_ACTIVE;		cam->active->state = FRAME_ACTIVE;		/* Deliberate fall-through */	case CAPTURE_ACTIVE:		retval = get_fpga_data(cam);		if ( retval < 0 ) {			cam->active->bytes_read = 0;			cam->active->state = FRAME_PENDING;			cam->capture_state = CAPTURE_WAIT_FOR_REFRESH;			cam->capture_stats.ef_fifo_overrun++;			return;          /* The FIFO_INT is still disabled */		}		else if ( retval > 0 )			ENABLE_FIFO_INT;   /* More data still to be read */		else {			cam->capture_state = CAPTURE_WAIT_FOR_REFRESH;			capture_buffer_complete( cam );		}		break;	}}static void fpga_vblank_interrupt( struct h3600_camera_struct *cam ){	int retval;	cam->capture_stats.vblank_count++;	switch (cam->capture_state) {	case CAPTURE_WAIT_FOR_REFRESH:		ENABLE_FIFO_INT;		cam->capture_state = CAPTURE_WAIT_FOR_FIFO;		break;	case CAPTURE_WAIT_FOR_FIFO:		cam->capture_stats.ef_extra_vblank++;		break;	case CAPTURE_ACTIVE:   /* Suck in the last bit of data */		DISABLE_FIFO_INT;         /* Shut off the FIFO interrupt */		retval = get_fpga_data(cam);		if ( retval < 0 ) {			cam->active->bytes_read = 0;			cam->active->state = FRAME_PENDING;			cam->capture_state = CAPTURE_WAIT_FOR_FIFO;			cam->capture_stats.ef_fifo_overrun++;			ENABLE_FIFO_INT;		}		else if ( retval > 0 ) {			cam->active->bytes_read = 0;			cam->active->state = FRAME_PENDING;			cam->capture_state = CAPTURE_WAIT_FOR_FIFO;			cam->capture_stats.ef_incomplete_frames++;			ENABLE_FIFO_INT;		}		else {			cam->capture_state = CAPTURE_WAIT_FOR_FIFO;			ENABLE_FIFO_INT;			capture_buffer_complete( cam );		}		break;	case CAPTURE_OFF:		CAMERROR(": Received VBLANK interrupt when capture was off\n");		break;	}}static void fpga_i2c_interrupt( struct h3600_camera_struct *cam ){	cam->i2c_status	           = BackpaqFPGACameraI2C_CR1 & FPGA_I2C_STATUS_BITS_MASK;//		printk(__FUNCTION__ ": %x\n", cam->i2c_status);	BackpaqFPGACameraI2C_CR1 = 0;  /* Clear interrupt in the FPGA *///		printk(__FUNCTION__ " tried to clear the interrupt: %x\n", READ_BACKPAQ_INT );		wake_up_interruptible(&cam->i2cq);}static void fpga_interrupt(int irq, void *dev_id, struct pt_regs *regs){	struct h3600_camera_struct *cam = (struct h3600_camera_struct *) dev_id;	unsigned short irq_value = READ_BACKPAQ_INT;		if (!cam ) {		printk(KERN_ALERT __FILE__ ": interrupt %d without valid cam\n",irq);		return;	}		if ( irq != IRQ_GPIO_H3600_OPT_IRQ ) {		printk(KERN_ALERT __FILE__ ": Unknown IRQ %d\n",irq);		return;	}	/* Handle the FIFO interrupt */	if ( irq_value & BACKPAQ_FPGA_INT_FIFO )		fpga_fifo_interrupt(cam);	/* Handle the VBLANK interrupt */	if ( irq_value & BACKPAQ_FPGA_INT_VBLANK )		fpga_vblank_interrupt(cam);	/* Handle the I2C interrupt */	if ( irq_value & BACKPAQ_FPGA_INT_I2C )		fpga_i2c_interrupt(cam);			/* Do some sanity checking */	if ( cam->state == HC_V4L_GRABBING 	     && cam->capture_stats.complete_frames == 0 	     && ( cam->capture_stats.ef_extra_vblank 		  + cam->capture_stats.ef_fifo_overrun 		  + cam->capture_stats.ef_incomplete_frames 		  + cam->capture_stats.ef_no_capture_buffer ) >= 3 ) {		/* Too many errors...abort the GRAB */		wake_up_interruptible(&cam->capq); 		DISABLE_BOTH_INT;		cam->capture_state = CAPTURE_OFF;	}	GEDR = GPIO_H3600_OPT_IRQ; /* Clear the interrupt */}/****************************************************************************** * * Turn on and off capture states * ******************************************************************************//* Add this capture buffer to the "pending" list   *//* Call this with interrupts disabled              */static int queue_capture_buffer( struct h3600_camera_struct *cam, int index ){	int result = 0;	struct frame *frame = &(cam->frame[index]);	switch (frame->state) {	case FRAME_DONE:	case FRAME_FULL:		if ( cam->active ) {			struct frame *a = cam->active;			while ( a->next )				a = a->next;			a->next = frame;		}		else			cam->active = frame;		frame->next = NULL;		frame->state = FRAME_PENDING;		break;	case FRAME_ACTIVE:		frame->state = FRAME_PENDING;		cam->capture_state = CAPTURE_WAIT_FOR_REFRESH;		DISABLE_FIFO_INT;		ENABLE_VBLANK_INT;		break;	case FRAME_PENDING:		/* Do nothing */		break;	}	if ( cam->state == HC_V4L_STREAMING 	     && (cam->mode == HC_MODE_RAW || cam->mode == HC_MODE_RAW_DECIMATED ))		frame->data = frame->shared_data;	else		frame->data = frame->local_data;	frame->bytes_read = 0;	if ( decimate_mode ) {		frame->bytes_to_read = hc_raw[fpga_mode_to_decimation[cam->mode]].bytes;		frame->width         = hc_raw[fpga_mode_to_decimation[cam->mode]].width;		frame->height        = hc_raw[fpga_mode_to_decimation[cam->mode]].height;	}	else {		frame->bytes_to_read = HC_RAW_BUFFER_SIZE;		frame->width         = HC_TRUE_WIDTH;		frame->height        = HC_TRUE_HEIGHT;	}	if ( cam->active ) {		struct frame *a = cam->active;		result++;		while ( a->next ) {			a = a->next;			result++;		}	}	return result;}/* Call this with interrupts disabled                        *//* This resets each capture buffer AND all of the statistics */static void clear_capture_buffers( struct h3600_camera_struct *cam ){	int i;	memset(&cam->capture_stats,0,sizeof(cam->capture_stats));	cam->capture_stats.fifo_low = 0xffff;  /* Set it to impossibly high */	cam->active = NULL;	for ( i = 0 ; i < NUMBER_OF_FRAMES ; i++ ) {		cam->frame[i].next = NULL;		cam->frame[i].state = FRAME_DONE;	}}static void program_camera( struct h3600_camera_struct *cam, u16 writethru ){//	printk("Programming camera %x\n", writethru );	/* This is ugly and needs to be replaced with an interrupt and a wait queue */	while ( BackpaqFPGAInterruptStatus & BACKPAQ_FPGA_INT_WTBUSY )		cam->capture_stats.camera_writethru_wait++;	BackpaqFPGACameraWritethru = writethru;}static void setup_small_cam( struct h3600_camera_struct *cam ){	if ( cam->param_mask & PARAM_FPGA_INTEGRATION_TIME ) {  /* Actually == brightness */		BackpaqFPGACameraIntegrationTime = 512 - (cam->vpic.brightness / 128);	}	if ( cam->param_mask & PARAM_IMAGER_POWER_SETTING )		program_camera( cam, IMAGER_CTL_POWER_SETTING | cam->power_setting );			if ( cam->param_mask & PARAM_IMAGER_GAIN_FORMAT )		program_camera( cam, IMAGER_CTL_GAIN_FORMAT | cam->gain_format );	if ( cam->param_mask & PARAM_IMAGER_SPECIAL_MODES )		program_camera( cam, IMAGER_CTL_SPECIAL_MODES | cam->special_modes );	if ( cam->param_mask & PARAM_IMAGER_POWER_MGMT )		program_camera( cam, IMAGER_CTL_POWER_MANAGEMENT | cam->power_mgmt );}static int WriteI2C( struct h3600_camera_struct *cam, u8 address, u8 subaddress, u8 data ){

⌨️ 快捷键说明

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