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

📄 h3600_backpaq_core.c

📁 pxa270下的摄像头mtd91111的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
		}		     		if ( (status = h3600_backpaq_fpga_status()) != 0)			return status;		/* We have a valid set of data */		down(&cam->lock);		set_camera_resolution( cam, vm.format, vm.width, vm.height );		update_camera_params(cam);		retval = grab_streaming_frame(cam, vm.frame );		if ( !retval ) {			if ( cam->frame[vm.frame].state == FRAME_FULL ) {				retval = process_frame(cam, NULL, vm.frame);				if ( retval > 0 ) retval = 0;			}		}//		else {//			CAMDEBUG( " ** Camera CAPTURE returned %d\n", retval);//		}		up(&cam->lock);		break;	}		/* This SYNC doesn't do much...in the future, we may wish to	   key a bottom half to do video processing for on UNUSED frames */	case VIDIOCSYNC:	{		int frame;		int status;//		CAMDEBUG(" ** Camera SYNC : fpga status %d\n", h3600_backpaq_fpga_status());		if (copy_from_user((void *)&frame, arg, sizeof(int))) {			retval = -EFAULT;			break;		}		if (frame<0 || frame >= NUMBER_OF_FRAMES) {			retval = -EINVAL;			break;		}		if ( (status = h3600_backpaq_fpga_status()) != 0)			return status;		down(&cam->lock);		sync_frame(cam, frame);		up(&cam->lock);		break;	}	/* We don't implement overlay with this camera */	case VIDIOCCAPTURE:		retval = -EINVAL;		break;	case VIDIOCGFBUF:		retval = -EINVAL;		break;	case VIDIOCSFBUF:		retval = -EINVAL;		break;	case VIDIOCKEY:		retval = -EINVAL;		break;		/* We have no tuner interface */	case VIDIOCGTUNER:		retval = -EINVAL;		break;	case VIDIOCSTUNER:		retval = -EINVAL;		break;	case VIDIOCGFREQ:		retval = -EINVAL;		break;	case VIDIOCSFREQ:		retval = -EINVAL;		break;		/* We have no audio interface */	case VIDIOCGAUDIO:		retval = -EINVAL;		break;	case VIDIOCSAUDIO:		retval = -EINVAL;		break;	default:		retval = -ENOIOCTLCMD;		break;	}	return retval;}static int h3600_camera_mmap(struct video_device *dev, const char *adr,			     unsigned long size){	struct h3600_camera_struct *cam = (struct h3600_camera_struct *) dev;	unsigned long start = (unsigned long)adr;	unsigned long page, pos;	int retval;	int status = h3600_backpaq_fpga_status();	if ( status ) 		return status;	if (!cam)		return -ENODEV;		if (size > NUMBER_OF_FRAMES * HC_MAX_PROCESSED_FRAME_SIZE)		return -EINVAL;	/* make this _really_ smp-safe */	if (down_interruptible(&cam->lock))		return -EINTR;	if (!cam->frame_buf) {	/* we do lazy allocation */		if ((retval = allocate_frame_buf(cam))) {			up(&cam->lock);			return retval;		}	}	pos = (unsigned long)(cam->frame_buf);	while (size > 0) {		page = kvirt_to_pa(pos);		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {			up(&cam->lock);			return -EAGAIN;		}		start += PAGE_SIZE;		pos += PAGE_SIZE;		if (size > PAGE_SIZE)			size -= PAGE_SIZE;		else			size = 0;	}	up(&cam->lock);	return 0;}static int h3600_camera_open( struct video_device *dev, int flags ){	struct h3600_camera_struct *cam = (struct h3600_camera_struct *) dev;	int retval = 0;	int status = h3600_backpaq_fpga_status();	if ( status )		return status;	if ( cam->usage_count > 0 ) {		CAMDEBUG(" Camera already open\n");		return -EBUSY;	}	down(&cam->lock);	cam->usage_count++;	stop_capture(cam);	cam->state = HC_V4L_IDLE;	GPDR &= ~GPIO_H3600_OPT_IRQ;    /* GPIO line as input */	set_GPIO_IRQ_edge( GPIO_H3600_OPT_IRQ, GPIO_RISING_EDGE );  /* Rising edge */	retval = request_irq(IRQ_GPIO_H3600_OPT_IRQ,			     fpga_interrupt,			     SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,			     "Backpaq FPGA", (void *)dev);	up(&cam->lock);	MOD_INC_USE_COUNT;	return retval;}static void h3600_camera_close( struct video_device *dev ){	struct h3600_camera_struct *cam = (struct h3600_camera_struct *) dev;	down(&cam->lock);	if ( --cam->usage_count == 0 ) {		if (!h3600_backpaq_fpga_status())			stop_capture(cam);		cam->state = HC_V4L_IDLE;		free_irq(IRQ_GPIO_H3600_OPT_IRQ, (void *)dev);	}	up(&cam->lock);	MOD_DEC_USE_COUNT;}int h3600_camera_video_init(struct video_device *vdev){#ifdef CONFIG_PROC_FS	// Create proc entry here?#endif	return 0;}static struct video_device h3600_camera_template ={	owner:		THIS_MODULE,	name:		"iPAQ H3600 Mercury BackPAQ",	type:		VID_TYPE_CAPTURE,	hardware:	VID_HARDWARE_H3600_BACKPAQ,	open:		h3600_camera_open,	close:		h3600_camera_close,	read:		h3600_camera_read,	ioctl:		h3600_camera_ioctl,	mmap:		h3600_camera_mmap, 	initialize:	h3600_camera_video_init,};/****************************************************************************** * * Standard initialization * * We should add a check to see if the camera responds and if it is B/W or color * ******************************************************************************/static void free_all_buffers( struct h3600_camera_struct *cam ){	int i;	for ( i = 0 ; i < NUMBER_OF_FRAMES ; i++ ) {		if ( cam->frame[i].data != NULL ) {			vfree(cam->frame[i].local_data);			cam->frame[i].local_data = NULL;		}	}	if (cam->frame_buf) {		free_frame_buf(cam);		cam->frame_buf = NULL;	}}static int h3600_camera_startup( struct h3600_camera_struct *cam ){	int i;	memset(cam, 0, sizeof(struct h3600_camera_struct));	memcpy(&cam->vdev, &h3600_camera_template, sizeof(h3600_camera_template));	for ( i = 0 ; i < NUMBER_OF_FRAMES ; i++ ) {		cam->frame[i].local_data = vmalloc( HC_RAW_BUFFER_SIZE );		if ( !cam->frame[i].local_data ) {			CAMERROR(": Unable to allocate frame buffer\n");			free_all_buffers(cam);			return -ENOBUFS;		}	} 	init_MUTEX(&cam->lock);        init_waitqueue_head(&cam->capq);        init_waitqueue_head(&cam->i2cq);	/* Set up some plausible defaults */	set_camera_type( cam );	cam->state = HC_V4L_IDLE;	cam->i2c_status = 0;	set_default_params( cam );	return 0;}static int h3600_camera_shutdown( struct h3600_camera_struct *cam ){	/* Toss the interrupt routine if we've messed up a shutdown somewhere */	if ( cam->usage_count > 0 ) {		unsigned long flags;		save_flags_cli(flags);		free_irq(IRQ_GPIO_H3600_OPT_IRQ, (void *)cam);		restore_flags(flags);	}	/* Should we kill the wait queue? */	free_all_buffers( cam );	return 0;}/****************************************************************************** * * /proc/backpaq/camera interface * ******************************************************************************/#ifdef CONFIG_PROC_FSstatic char *palette_names[] = {	"","Grey","HI240","RGB565",	"RGB24","RGB32","RGB444","YUV422",	"YUYV","UYVY","YUV420","YUV411",	"RAW","YUV422P","YUV411P","YUV420P",	"YUV410P"};static int h3600_camera_read_proc( char *page, char **start, off_t off,				   int count, int *eof, void *data ){	struct h3600_camera_struct *cam = &hc_camera;	char *out = page;	int len;	out += sprintf(out, "%s\n", BANNER);	out += sprintf(out, "CMOS Image Size %d %d\n", HC_TRUE_WIDTH, HC_TRUE_HEIGHT);	out += sprintf(out, "CameraType   : %s\n",camera_type_names[cam->ctype]);	out += sprintf(out, "CameraModel  : %d\n",		       h3600_backpaq_eeprom_shadow.camera & BACKPAQ_EEPROM_CAMERA_TYPE_MASK);	out += sprintf(out, "Capture window\n");	out += sprintf(out, "  x          : %d\n",cam->vwin.x);	out += sprintf(out, "  y          : %d\n",cam->vwin.y);	out += sprintf(out, "  width      : %d\n",cam->vwin.width);	out += sprintf(out, "  height     : %d\n",cam->vwin.height);	out += sprintf(out, "Image settings\n");	out += sprintf(out, "  brightness : 0x%04x\n",cam->vpic.brightness);	out += sprintf(out, "  contrast   : 0x%04x\n",cam->vpic.contrast);	if ( cam->vpic.palette != VIDEO_PALETTE_GREY ) {		out += sprintf(out, "  hue        : 0x%04x\n",cam->vpic.hue);		out += sprintf(out, "  colour     : 0x%.4x\n",cam->vpic.colour);	}	else {		out += sprintf(out, "  whiteness  : 0x%04x\n",cam->vpic.whiteness);	}	out += sprintf(out, "  depth      : %d\n",cam->vpic.depth);	out += sprintf(out, "  palette    : %s\n",palette_names[cam->vpic.palette]);	out += sprintf(out, "Imager parameters\n");	switch (cam->ctype) {	case H3600_SMAL:		out += sprintf(out, "  clock divisor        : %d (%d Hz)\n", cam->clock_divisor,			       1280 / cam->clock_divisor);		out += sprintf(out, "  power setting        : %d\n", cam->power_setting);		out += sprintf(out, "  gain format          : %d\n", cam->gain_format);		out += sprintf(out, "  power management     : 0x%x\n", cam->power_mgmt);		out += sprintf(out, "  special modes        : 0x%x\n", cam->special_modes);		out += sprintf(out, "  autobright           : 0x%x\n", cam->autobright);		break;	case H3600_PHILIPS:		out += sprintf(out, "  clock divisor        : %d (%d Hz)\n", cam->clock_divisor,			       40 / cam->clock_divisor);		break;	}	out += sprintf(out, "  interrupt fifo       : %d\n", cam->interrupt_fifo);	out += sprintf(out, "  read polling mode    : %d\n", cam->read_polling_mode);	out += sprintf(out, "  flip                 : %d\n", cam->flip);	out += sprintf(out, "Internal statistics\n");	out += sprintf(out, "  fifo highwater       : %d\n",cam->capture_stats.fifo_high);	out += sprintf(out, "  fifo lowwater        : %d\n",cam->capture_stats.fifo_low);	out += sprintf(out, "  vblank interrupts    : %d\n",cam->capture_stats.vblank_count);	out += sprintf(out, "  fifo interrupts      : %d\n",cam->capture_stats.fifo_count);	out += sprintf(out, "  complete frames      : %d\n",cam->capture_stats.complete_frames);	out += sprintf(out, "  missed extra vblank  : %d\n",cam->capture_stats.ef_extra_vblank);	out += sprintf(out, "         fifo overrun  : %d\n",cam->capture_stats.ef_fifo_overrun);	out += sprintf(out, "         incomplete    : %d\n",cam->capture_stats.ef_incomplete_frames);	out += sprintf(out, "         buffer unavil : %d\n",cam->capture_stats.ef_no_capture_buffer);	out += sprintf(out, "  camera writethru wait: %d\n",cam->capture_stats.camera_writethru_wait);		    	len = out - page;	len -= off;	if (len < count) {		*eof = 1;		if (len <= 0) return 0;	} else		len = count;	*start = page + off;	return len;}#endif /* CONFIG_PROC_FS *//****************************************************************************** * * Module interface * ******************************************************************************/#ifdef MODULE#define CAMERA_PROC_DIR  "backpaq"#define CAMERA_PROC_NAME "backpaq/camera"#define FPGA_MODULE      "h3600_backpaq_fpga"static int __init h3600_camera_init( void ){	int retval = 0;	/* This module only makes sense if h3600_backpaq_fpga is loaded */	retval = request_module(FPGA_MODULE);	if ( retval ) {		printk(KERN_ALERT __FILE__ ": unable to load " FPGA_MODULE "\n");		return retval;	}	printk(KERN_INFO BANNER "\n");	retval = h3600_camera_startup( &hc_camera );	if ( retval )		return retval;	if (video_register_device(&hc_camera.vdev, 				  VFL_TYPE_GRABBER,                                   -1)) {		printk(KERN_ERR __FILE__ "Unable to register H3600 BackPAQ camera\n");		return -ENODEV;	}#ifdef CONFIG_PROC_FS	/* Set up the PROC file system entry */	if ( !(proc_backpaq_camera = create_proc_entry(CAMERA_PROC_NAME,0,NULL))) {		// Couldn't create - we need to create the "backpaq" directory		proc_mkdir(CAMERA_PROC_DIR,0);		proc_backpaq_camera = create_proc_entry(CAMERA_PROC_NAME,0,NULL);	}		if ( proc_backpaq_camera )		proc_backpaq_camera->read_proc = h3600_camera_read_proc;	else		printk(KERN_ALERT __FILE__ ": unable to create proc entry %s\n", CAMERA_PROC_NAME);#endif#ifdef CONFIG_PM	h3600_backpaq_camera_dev = h3600_backpaq_register_device( H3600_BACKPAQ_CAMERA_DEV, 0,								  h3600_backpaq_camera_callback);	printk(KERN_ALERT __FILE__ ": registered pm callback=%p\n", h3600_backpaq_camera_callback);#endif	return 0;  /* No error */}static void __exit h3600_camera_cleanup( void ){#ifdef CONFIG_PM        h3600_backpaq_unregister_device(h3600_backpaq_camera_dev);#endif#ifdef CONFIG_PROC_FS	if (proc_backpaq_camera)		remove_proc_entry(CAMERA_PROC_NAME,0);#endif	h3600_camera_shutdown( &hc_camera );	video_unregister_device(&hc_camera.vdev);}module_init(h3600_camera_init);module_exit(h3600_camera_cleanup);#endif /* MODULE */

⌨️ 快捷键说明

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