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

📄 cpia.c

📁 Usb1.1驱动c语言源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		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 != 288)				return -EINVAL;			if (vw.width != 352)				return -EINVAL;			cpia->compress = 0;			return 0;		}		case VIDIOCGWIN:		{			struct video_window vw;			vw.x = 0;			vw.y = 0;			vw.width = 352;			vw.height = 288;			vw.chromakey = 0;			vw.flags = 30;		/* 30 fps */			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 (debug >= 1)				printk(KERN_DEBUG "frame: %d, size: %dx%d, format: %d\n",					vm.frame, vm.width, vm.height, vm.format);			if (vm.format != VIDEO_PALETTE_RGB24)				return -EINVAL;			if ((vm.frame != 0) && (vm.frame != 1))				return -EINVAL;			if (cpia->frame[vm.frame].grabstate == FRAME_GRABBING)				return -EBUSY;			/* Don't compress if the size changed */			if ((cpia->frame[vm.frame].width != vm.width) ||			    (cpia->frame[vm.frame].height != vm.height))				cpia->compress = 0;			cpia->frame[vm.frame].width = vm.width;			cpia->frame[vm.frame].height = vm.height;			/* Mark it as ready */			cpia->frame[vm.frame].grabstate = FRAME_READY;			return cpia_new_frame(cpia, vm.frame);		}		case VIDIOCSYNC:		{			int frame;			if (copy_from_user((void *)&frame, arg, sizeof(int)))				return -EFAULT;			if (debug >= 1)				printk(KERN_DEBUG "cpia: syncing to frame %d\n", frame);			switch (cpia->frame[frame].grabstate) {			case FRAME_UNUSED:				return -EINVAL;			case FRAME_READY:			case FRAME_GRABBING:			case FRAME_ERROR:redo:				do {#if 0					init_waitqueue_head(&cpia->frame[frame].wq);#endif					interruptible_sleep_on(&cpia->frame[frame].wq);					if (signal_pending(current))						return -EINTR;				} while (cpia->frame[frame].grabstate == FRAME_GRABBING);				if (cpia->frame[frame].grabstate == FRAME_ERROR) {					int ret;					if ((ret = cpia_new_frame(cpia, frame)) < 0)						return ret;					goto redo;				}			case FRAME_DONE:				cpia->frame[frame].grabstate = FRAME_UNUSED;				break;			}			cpia->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 cpia_read(struct video_device *dev, char *buf, unsigned long count, int noblock){	struct usb_cpia *cpia = (struct usb_cpia *)dev;	int frmx = -1;	volatile struct cpia_frame *frame;	if (debug >= 1)		printk(KERN_DEBUG "cpia_read: %ld bytes, noblock=%d\n", count, noblock);	if (!dev || !buf)		return -EFAULT;	/* See if a frame is completed, then use it. */	if (cpia->frame[0].grabstate >= FRAME_DONE)	/* _DONE or _ERROR */		frmx = 0;	else if (cpia->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 (cpia->frame[0].grabstate == FRAME_GRABBING)			frmx = 0;		else if (cpia->frame[1].grabstate == FRAME_GRABBING)			frmx = 1;	}	/* If no frame is active, start one. */	if (frmx == -1)		cpia_new_frame(cpia, frmx = 0);	frame = &cpia->frame[frmx];restart:	while (frame->grabstate == FRAME_GRABBING) {		interruptible_sleep_on(&frame->wq);		if (signal_pending(current))			return -EINTR;	}	if (frame->grabstate == FRAME_ERROR) {		frame->bytes_read = 0;printk("cpia_read: errored frame %d\n", cpia->curframe);		if (cpia_new_frame(cpia, frmx))			printk(KERN_ERR "cpia_read: cpia_new_frame error\n");		goto restart;	}	if (debug >= 1)		printk(KERN_DEBUG "cpia_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;	if (debug >= 1)		printk(KERN_DEBUG "cpia_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. */		cpia->frame[frmx].grabstate = FRAME_UNUSED;		if (cpia_new_frame(cpia, frmx ? 0 : 1))			printk(KERN_ERR "cpia_read: cpia_new_frame returned error\n");	}	return count;}static int cpia_mmap(struct video_device *dev, const char *adr, unsigned long size){	struct usb_cpia *cpia = (struct usb_cpia *)dev;	unsigned long start = (unsigned long)adr;	unsigned long page, pos;	if (size > (((2 * MAX_FRAME_SIZE) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))		return -EINVAL;	pos = (unsigned long)cpia->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;}static struct video_device cpia_template = {	"CPiA USB Camera",	VID_TYPE_CAPTURE,	VID_HARDWARE_CPIA,	cpia_open,	cpia_close,	cpia_read,	cpia_write,	NULL,	cpia_ioctl,	cpia_mmap,	cpia_init_done,	NULL,	0,	0};static int usb_cpia_configure(struct usb_cpia *cpia){	struct usb_device *dev = cpia->dev;	unsigned char version[4];	/* Set altsetting 0 */	if (usb_set_interface(dev, cpia->iface, 0) < 0) {		printk(KERN_ERR "usb_set_interface error\n");		return -EBUSY;	}	if (usb_cpia_get_version(dev, version) < 0) {		printk(KERN_ERR "cpia_get_version error\n");		return -EBUSY;	}	if (debug >= 1)		printk(KERN_DEBUG "cpia: Firmware v%d.%d, VC Hardware v%d.%d\n",			version[0], version[1], version[2], version[3]);	memcpy(&cpia->vdev, &cpia_template, sizeof(cpia_template));	init_waitqueue_head(&cpia->frame[0].wq);	init_waitqueue_head(&cpia->frame[1].wq);	if (video_register_device(&cpia->vdev, VFL_TYPE_GRABBER) == -1) {		printk(KERN_ERR "video_register_device failed\n");		return -EBUSY;	}	if (usb_cpia_goto_hi_power(dev) < 0) {		printk(KERN_ERR "cpia_goto_hi_power error\n");		goto error;	}	if (usb_cpia_get_vp_version(dev, version) < 0) {		printk(KERN_ERR "cpia_get_vp_version error\n");		goto error;	}	if (debug >= 1) {		printk(KERN_DEBUG "cpia: VP v%d rev %d\n", version[0], version[1]);		printk(KERN_DEBUG "cpia: Camera Head ID %04X\n", (version[3] << 8) + version[2]);	}	/* Turn on continuous grab */	if (usb_cpia_set_grab_mode(dev, 1) < 0) {		printk(KERN_ERR "cpia_set_grab_mode error\n");		goto error;	}	/* Set up the sensor to be 30fps */	if (usb_cpia_set_sensor_fps(dev, 1, 0) < 0) {		printk(KERN_ERR "cpia_set_sensor_fps error\n");		goto error;	}	/* Set video into CIF mode, and order into YUYV mode */	if (usb_cpia_set_format(dev, FORMAT_CIF, FORMAT_422,			FORMAT_YUYV) < 0) {		printk(KERN_ERR "cpia_set_format error\n");		goto error;	}	/* Turn off compression */	if (usb_cpia_set_compression(dev, COMP_DISABLED, DONT_DECIMATE) < 0) {		printk(KERN_ERR "cpia_set_compression error\n");		goto error;	}	cpia->compress = 0;	return 0;error:	video_unregister_device(&cpia->vdev);	usb_driver_release_interface(&cpia_driver,		&dev->actconfig->interface[0]);	kfree(cpia);	return -EBUSY;}static void * cpia_probe(struct usb_device *dev, unsigned int ifnum){	struct usb_interface_descriptor *interface;	struct usb_cpia *cpia;	/* We don't handle multi-config cameras */	if (dev->descriptor.bNumConfigurations != 1)		return NULL;	interface = &dev->actconfig->interface[ifnum].altsetting[0];	/* Is it a CPiA? */	if (dev->descriptor.idVendor != 0x0553)		return NULL;	if (dev->descriptor.idProduct != 0x0002)		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 a CPiA */	printk(KERN_INFO "USB CPiA camera found\n");	if ((cpia = kmalloc(sizeof(*cpia), GFP_KERNEL)) == NULL) {		printk(KERN_ERR "couldn't kmalloc cpia struct\n");		return NULL;	}	memset(cpia, 0, sizeof(*cpia));	cpia->dev = dev;	cpia->iface = interface->bInterfaceNumber;	if (!usb_cpia_configure(cpia)) {	    cpia->user=0; 	    init_MUTEX(&cpia->lock);	/* to 1 == available */	    return cpia;	} else return NULL;}static void cpia_disconnect(struct usb_device *dev, void *ptr){	struct usb_cpia *cpia = (struct usb_cpia *) ptr;	video_unregister_device(&cpia->vdev);	usb_driver_release_interface(&cpia_driver,		&cpia->dev->actconfig->interface[0]);	/* Free the memory */	kfree(cpia);}static struct usb_driver cpia_driver = {	"cpia",	cpia_probe,	cpia_disconnect,	{ NULL, NULL }};int usb_cpia_init(void){	return usb_register(&cpia_driver);}void usb_cpia_cleanup(void){	usb_deregister(&cpia_driver);}#ifdef MODULEint init_module(void){	return usb_cpia_init();}void cleanup_module(void){	usb_cpia_cleanup();}#endif

⌨️ 快捷键说明

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