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

📄 ov511.c

📁 Usb1.1驱动c语言源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
			p.colour = 0x8000;			p.hue = 0x8000;			p.brightness = 180 << 8;	/* XXX */			p.contrast = 192 << 8;		/* XXX */			p.whiteness = 105 << 8;		/* XXX */			p.depth = 24;			p.palette = VIDEO_PALETTE_RGB24;			if (copy_to_user(arg, &p, sizeof(p)))				return -EFAULT;			return 0;		}		case VIDIOCSPICT:		{			struct video_picture p;			if (copy_from_user(&p, arg, sizeof(p)))				return -EFAULT;			return 0;		}		case VIDIOCSWIN:		{			struct video_window vw;			if (copy_from_user(&vw, arg, sizeof(vw)))				return -EFAULT;			if (vw.flags)				return -EINVAL;			if (vw.clipcount)				return -EINVAL;			if (vw.height != DEFAULT_HEIGHT)				return -EINVAL;			if (vw.width != DEFAULT_WIDTH)				return -EINVAL;			ov511->compress = 0;			return 0;		}		case VIDIOCGWIN:		{			struct video_window vw;			vw.x = 0;			vw.y = 0;			vw.width = DEFAULT_WIDTH;			vw.height = DEFAULT_HEIGHT;			vw.chromakey = 0;			vw.flags = 30;			if (copy_to_user(arg, &vw, sizeof(vw)))				return -EFAULT;			return 0;		}		case VIDIOCGMBUF:		{			struct video_mbuf vm;			memset(&vm, 0, sizeof(vm));			vm.size = MAX_FRAME_SIZE * 2;			vm.frames = 2;			vm.offsets[0] = 0;			vm.offsets[1] = MAX_FRAME_SIZE;			if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))				return -EFAULT;			return 0;		}		case VIDIOCMCAPTURE:		{			struct video_mmap vm;			if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm)))				return -EFAULT;#if 0			PDEBUG("MCAPTURE\n");			PDEBUG("frame: %d, size: %dx%d, format: %d\n",				vm.frame, vm.width, vm.height, vm.format);#endif			if (vm.format != VIDEO_PALETTE_RGB24)				return -EINVAL;			if ((vm.frame != 0) && (vm.frame != 1))				return -EINVAL;							if (ov511->frame[vm.frame].grabstate == FRAME_GRABBING)				return -EBUSY;			/* Don't compress if the size changed */			if ((ov511->frame[vm.frame].width != vm.width) ||			    (ov511->frame[vm.frame].height != vm.height)) {				ov511->compress = 0;				ov511_mode_init_regs(ov511,						     vm.width, vm.height, 0);#if 0				PDEBUG("ov511: Setting frame %d to (%d, %d) : %d\n",				       vm.frame, vm.width, vm.height, 0);#endif			}			ov511->frame[vm.frame].width = vm.width;			ov511->frame[vm.frame].height = vm.height;			/* Mark it as ready */			ov511->frame[vm.frame].grabstate = FRAME_READY;			return ov511_new_frame(ov511, vm.frame);		}		case VIDIOCSYNC:		{			int frame;			if (copy_from_user((void *)&frame, arg, sizeof(int)))				return -EFAULT;#if 0			PDEBUG("syncing to frame %d\n", frame);#endif			switch (ov511->frame[frame].grabstate) {				case FRAME_UNUSED:					return -EINVAL;				case FRAME_READY:				case FRAME_GRABBING:				case FRAME_ERROR:redo:				do {#if 0					init_waitqueue_head(&ov511->frame[frame].wq);#endif					interruptible_sleep_on(&ov511->frame[frame].wq);					if (signal_pending(current))						return -EINTR;				} while (ov511->frame[frame].grabstate == FRAME_GRABBING);				if (ov511->frame[frame].grabstate == FRAME_ERROR) {					int ret;					if ((ret = ov511_new_frame(ov511, frame)) < 0)						return ret;					goto redo;				}								case FRAME_DONE:					ov511->frame[frame].grabstate = FRAME_UNUSED;					break;			}			ov511->frame[frame].grabstate = FRAME_UNUSED;						return 0;		}		case VIDIOCGFBUF:		{			struct video_buffer vb;			memset(&vb, 0, sizeof(vb));			vb.base = NULL;	/* frame buffer not supported, not used */			if (copy_to_user((void *)arg, (void *)&vb, sizeof(vb)))				return -EFAULT; 			return 0; 		}		case VIDIOCKEY:			return 0; 				case VIDIOCCAPTURE:			return -EINVAL;		case VIDIOCSFBUF:			return -EINVAL;		case VIDIOCGTUNER:		case VIDIOCSTUNER:			return -EINVAL;					case VIDIOCGFREQ:		case VIDIOCSFREQ:			return -EINVAL;		case VIDIOCGAUDIO:		case VIDIOCSAUDIO:			return -EINVAL;		default:			return -ENOIOCTLCMD;	}	return 0;}static long ov511_read(struct video_device *dev, char *buf, unsigned long count, int noblock){	struct usb_ov511 *ov511 = (struct usb_ov511 *)dev;	int frmx = -1;	volatile struct ov511_frame *frame;	PDEBUG("ov511_read: %ld bytes, noblock=%d\n", count, noblock);	if (!dev || !buf)		return -EFAULT;	/* See if a frame is completed, then use it. */	if (ov511->frame[0].grabstate >= FRAME_DONE)	/* _DONE or _ERROR */		frmx = 0;	else if (ov511->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */		frmx = 1;	if (noblock && (frmx == -1))		return -EAGAIN;	/* If no FRAME_DONE, look for a FRAME_GRABBING state. */	/* See if a frame is in process (grabbing), then use it. */	if (frmx == -1) {		if (ov511->frame[0].grabstate == FRAME_GRABBING)			frmx = 0;		else if (ov511->frame[1].grabstate == FRAME_GRABBING)			frmx = 1;	}	/* If no frame is active, start one. */	if (frmx == -1)		ov511_new_frame(ov511, frmx = 0);	frame = &ov511->frame[frmx];restart:	while (frame->grabstate == FRAME_GRABBING) {		interruptible_sleep_on(&ov511->frame[frmx].wq);		if (signal_pending(current))			return -EINTR;	}	if (frame->grabstate == FRAME_ERROR) {		frame->bytes_read = 0;		printk(KERN_ERR "ov511_read: errored frame %d\n", ov511->curframe);		if (ov511_new_frame(ov511, frmx))			printk(KERN_ERR "ov511_read: ov511_new_frame error\n");		goto restart;	}	PDEBUG("ov511_read: frmx=%d, bytes_read=%ld, scanlength=%ld\n", frmx,		frame->bytes_read, frame->scanlength);	/* copy bytes to user space; we allow for partials reads */	if ((count + frame->bytes_read) > frame->scanlength)		count = frame->scanlength - frame->bytes_read;	if (copy_to_user(buf, frame->data + frame->bytes_read, count))		return -EFAULT;	frame->bytes_read += count;	PDEBUG("ov511_read: {copy} count used=%ld, new bytes_read=%ld\n",		count, frame->bytes_read);	if (frame->bytes_read >= frame->scanlength) { /* All data has been read */		frame->bytes_read = 0;		/* Mark it as available to be used again. */		ov511->frame[frmx].grabstate = FRAME_UNUSED;		if (ov511_new_frame(ov511, frmx ? 0 : 1))			printk(KERN_ERR "ov511_read: ov511_new_frame returned error\n");	}	return count;}static int ov511_mmap(struct video_device *dev, const char *adr, unsigned long size){	struct usb_ov511 *ov511 = (struct usb_ov511 *)dev;	unsigned long start = (unsigned long)adr;	unsigned long page, pos;	PDEBUG("mmap: %ld (%lX) bytes\n", size, size);	if (size > (((2 * MAX_FRAME_SIZE) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))		return -EINVAL;	pos = (unsigned long)ov511->fbuf;	while (size > 0)	{		page = kvirt_to_pa(pos);		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))			return -EAGAIN;		start += PAGE_SIZE;		pos += PAGE_SIZE;		if (size > PAGE_SIZE)			size -= PAGE_SIZE;		else			size = 0;	}	return 0;}// FIXME - needs V4L ID to be assignedstatic struct video_device ov511_template = {	"OV511 USB Camera",	VID_TYPE_CAPTURE,	VID_HARDWARE_CPIA,  /* FIXME */	ov511_open,	ov511_close,	ov511_read,	ov511_write,	NULL,	ov511_ioctl,	ov511_mmap,	ov511_init_done,	NULL,	0,	0};static int ov7610_configure(struct usb_device *dev){	if(ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE,	                        OV7610_I2C_WRITE_ID) < 0)		return -1;	if(ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ,	                        OV7610_I2C_READ_ID) < 0)		return -1;		/* Reset the camera chip */	if (ov511_i2c_reset(dev) < 0)		return -1;#if 0	if(usb_ov511_reg_write(dev, OV511_REG_I2C_CLOCK_PRESCALER,	                            OV511_I2C_CLOCK_PRESCALER))		return -1;#endif		if (ov511_reset(dev, OV511_RESET_NOREGS) < 0)		return -1;		/* Dummy read to sync I2C */	if(ov511_i2c_read(dev, 0x00) < 0)		return -1;		if((ov511_i2c_read(dev, 0x1C) != 0x7F) ||	   (ov511_i2c_read(dev, 0x1D) != 0xA2)) {		printk(KERN_ERR "ov511: Failed to read OV7610 ID. You might\n");		printk(KERN_ERR "ov511: not have an OV7610, or it may be\n");		printk(KERN_ERR "ov511: not responding. Report this to\n");		printk(KERN_ERR "ov511: mmcclelland@delphi.com\n");		return -1;	}	return 0;}static int ov511_configure(struct usb_ov511 *ov511){	struct usb_device *dev = ov511->dev;	/* Set altsetting 0 */	if (usb_set_interface(dev, ov511->iface, 0) < 0) {		printk(KERN_ERR "ov511: usb_set_interface error\n");		return -EBUSY;	}	memcpy(&ov511->vdev, &ov511_template, sizeof(ov511_template));	init_waitqueue_head(&ov511->frame[0].wq);	init_waitqueue_head(&ov511->frame[1].wq);	if (video_register_device(&ov511->vdev, VFL_TYPE_GRABBER) == -1) {		printk(KERN_ERR "ov511: video_register_device failed\n");		return -EBUSY;	}	/* Reset in case driver was unloaded and reloaded without unplug */	if (ov511_reset(dev, OV511_RESET_ALL) < 0)		goto error;	/* Initialize system */	if (ov511_reg_write(dev, OV511_REG_SYSTEM_INIT, 0x01) < 0) {		printk(KERN_ERR "ov511: enable system: command failed\n");		goto error;	}	/* This seems to be necessary */	if (ov511_reset(dev, OV511_RESET_ALL) < 0)		goto error;	if(ov7610_configure(dev) < 0) {		printk(KERN_ERR "ov511: failed to configure OV7610\n"); 		goto error;		}	/* Disable compression */	if (ov511_reg_write(dev, OV511_OMNICE_ENABLE, 0x00) < 0) {		printk(KERN_ERR "ov511: disable compression: command failed\n");		goto error;	}	ov511->compress = 0;		/* Set default sizes in case IOCTL (VIDIOCMCAPTURE) is not used	 * (using read() instead). */	ov511->frame[0].width = DEFAULT_WIDTH;	ov511->frame[0].height = DEFAULT_HEIGHT;	ov511->frame[0].bytes_read = 0;	ov511->frame[1].width = DEFAULT_WIDTH;	ov511->frame[1].height = DEFAULT_HEIGHT;	ov511->frame[1].bytes_read = 0;	/* Initialize to DEFAULT_WIDTH, DEFAULT_HEIGHT, YUV4:2:0 */	ov511_mode_init_regs(ov511, DEFAULT_WIDTH, DEFAULT_HEIGHT, 0);	return 0;	error:	video_unregister_device(&ov511->vdev);	usb_driver_release_interface(&ov511_driver,		&dev->actconfig->interface[ov511->iface]);	kfree(ov511);	return -EBUSY;	}static void* ov511_probe(struct usb_device *dev, unsigned int ifnum){	struct usb_interface_descriptor *interface;	struct usb_ov511 *ov511;	int rc;	PDEBUG("probing for device...\n");	/* We don't handle multi-config cameras */	if (dev->descriptor.bNumConfigurations != 1)		return NULL;	interface = &dev->actconfig->interface[ifnum].altsetting[0];	/* Is it an OV511? */	if (dev->descriptor.idVendor != 0x05a9)		return NULL;	if (dev->descriptor.idProduct != 0x0511)		return NULL;	/* Checking vendor/product should be enough, but what the hell */	if (interface->bInterfaceClass != 0xFF) 		return NULL;	if (interface->bInterfaceSubClass != 0x00)		return NULL;	/* We found one */	printk(KERN_INFO "ov511: USB OV511-based camera found\n");	if ((ov511 = kmalloc(sizeof(*ov511), GFP_KERNEL)) == NULL) {		printk(KERN_ERR "ov511: couldn't kmalloc ov511 struct\n");		return NULL;	}	memset(ov511, 0, sizeof(*ov511));		ov511->dev = dev;	ov511->iface = interface->bInterfaceNumber;	rc = ov511_reg_read(dev, OV511_REG_SYSTEM_CUSTOM_ID);	if (rc < 0) {		printk("ov511: Unable to read camera bridge registers\n");		return NULL;	}		switch(ov511->customid = rc) {	case 0: /* This also means that no custom ID was set */		printk("ov511: Camera is probably a MediaForte MV300\n");		break;	case 3:		printk("ov511: Camera is a D-Link DSB-C300\n");		break;	case 21:		printk("ov511: Camera is a Creative Labs WebCam 3\n");		break;	case 100:		printk("ov511: Camera is a Lifeview RoboCam\n");		break;	case 102:		printk("ov511: Camera is a AverMedia InterCam Elite\n");		break;	default:		printk("ov511: Specific camera type (%d) not recognized\n", rc);		printk("ov511: Please contact mmcclelland@delphi.com to request\n");		printk("ov511: support for your camera.\n");		return NULL;	}	if (!ov511_configure(ov511)) {		ov511->user=0;		init_MUTEX(&ov511->lock);	/* to 1 == available */		return ov511;	}	else {		printk(KERN_ERR "ov511: Failed to configure camera\n");		return NULL;	}    	     	return ov511;}static void ov511_disconnect(struct usb_device *dev, void *ptr){	struct usb_ov511 *ov511 = (struct usb_ov511 *) ptr;	video_unregister_device(&ov511->vdev);	usb_driver_release_interface(&ov511_driver,		&ov511->dev->actconfig->interface[ov511->iface]);	/* Free the memory */	kfree(ov511); ov511 = NULL;}static struct usb_driver ov511_driver = {	"ov511",	ov511_probe,	ov511_disconnect,	{ NULL, NULL }};int usb_ov511_init(void){	PDEBUG("usb_ov511_init()\n");		EXPORT_NO_SYMBOLS;		return usb_register(&ov511_driver);}void usb_ov511_cleanup(void){	usb_deregister(&ov511_driver);}#ifdef MODULEint init_module(void){	return usb_ov511_init();}void cleanup_module(void){	usb_ov511_cleanup();		PDEBUG("Module unloaded\n");}#endif

⌨️ 快捷键说明

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