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

📄 cpia_usb.c

📁 cpia usb摄像头的驱动程序源码。需要video4linux和i2c-core支持
💻 C
📖 第 1 页 / 共 2 页
字号:
	return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),			 packet[1] + (packet[0] << 8),			 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,			 packet[2] + (packet[3] << 8), 			 packet[4] + (packet[5] << 8), buf, size, HZ);}static int cpia_usb_transferCmd(void *privdata, u8 *command, u8 *data){	int err = 0;	int databytes;	struct usb_cpia *ucpia = (struct usb_cpia *)privdata;	struct usb_device *udev = ucpia->dev;	if (!udev) {		DBG("Internal driver error: udev is NULL\n");		return -EINVAL;	}	if (!command) {		DBG("Internal driver error: command is NULL\n");		return -EINVAL;	}	databytes = (((int)command[7])<<8) | command[6];	if (command[0] == DATA_IN) {		u8 buffer[8];		if (!data) {			DBG("Internal driver error: data is NULL\n");			return -EINVAL;		}		err = ReadPacket(udev, command, buffer, 8);		if (err < 0)			return err;		memcpy(data, buffer, databytes);	} else if(command[0] == DATA_OUT)		WritePacket(udev, command, data, databytes);	else {		DBG("Unexpected first byte of command: %x\n", command[0]);		err = -EINVAL;	}	return 0;}static int cpia_usb_registerCallback(void *privdata, void (*cb) (void *cbdata),	void *cbdata){	return -ENODEV;}static int cpia_usb_streamStart(void *privdata){	return -ENODEV;}static int cpia_usb_streamStop(void *privdata){	return -ENODEV;}static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock){	struct usb_cpia *ucpia = (struct usb_cpia *) privdata;	struct framebuf *mybuff;	if (!ucpia || !ucpia->present)		return -1;  	if (ucpia->curbuff->status != FRAME_READY)		interruptible_sleep_on(&ucpia->wq_stream);	else		DBG("Frame already waiting!\n");	mybuff = ucpia->curbuff;	if (!mybuff)		return -1;  	if (mybuff->status != FRAME_READY || mybuff->length < 4) {		DBG("Something went wrong!\n");		return -1;	}	memcpy(frame, mybuff->data, mybuff->length);	mybuff->status = FRAME_EMPTY;  /*   DBG("read done, %d bytes, Header: %x/%x, Footer: %x%x%x%x\n",  *//*       mybuff->length, frame[0], frame[1], *//*       frame[mybuff->length-4], frame[mybuff->length-3],  *//*       frame[mybuff->length-2], frame[mybuff->length-1]); */	return mybuff->length;}static void cpia_usb_free_resources(struct usb_cpia *ucpia, int try){	if (!ucpia->streaming)		return;	ucpia->streaming = 0;	/* Set packet size to 0 */	if (try) {		int ret;		ret = usb_set_interface(ucpia->dev, ucpia->iface, 0);		if (ret < 0) {			printk(KERN_ERR "usb_set_interface error (ret = %d)\n", ret);			return;		}		ucpia->alt = 0;	}	/* Unschedule all of the iso td's */	if (ucpia->sbuf[1].urb) {		usb_unlink_urb(ucpia->sbuf[1].urb);		usb_free_urb(ucpia->sbuf[1].urb);		ucpia->sbuf[1].urb = NULL;	}	if (ucpia->sbuf[1].data) {		kfree(ucpia->sbuf[1].data);		ucpia->sbuf[1].data = NULL;	} 	if (ucpia->sbuf[0].urb) {		usb_unlink_urb(ucpia->sbuf[0].urb);		usb_free_urb(ucpia->sbuf[0].urb);		ucpia->sbuf[0].urb = NULL;	}	if (ucpia->sbuf[0].data) {		kfree(ucpia->sbuf[0].data);		ucpia->sbuf[0].data = NULL;	}}static int cpia_usb_close(void *privdata){	struct usb_cpia *ucpia = (struct usb_cpia *) privdata;	if(!ucpia)		return -ENODEV;	ucpia->open = 0;	/* ucpia->present = 0 protects against trying to reset the	 * alt setting if camera is physically disconnected while open */	cpia_usb_free_resources(ucpia, ucpia->present);	return 0;}int cpia_usb_init(void){	/* return -ENODEV; */	return 0;}/* Probing and initializing */#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))static void *cpia_probe(struct usb_device *udev, unsigned int ifnum,			const struct usb_device_id *id){	struct usb_interface_descriptor *interface;#elsestatic int cpia_probe(struct usb_interface *intf,		      const struct usb_device_id *id){	struct usb_device *udev = interface_to_usbdev(intf);	struct usb_host_interface *interface;#endif	struct usb_cpia *ucpia;	struct cam_data *cam;	int ret;  	/* A multi-config CPiA camera? */	if (udev->descriptor.bNumConfigurations != 1)#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))		return NULL;#else		return -ENODEV;#endif#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))	interface = &udev->actconfig->interface[ifnum].altsetting[0];#else	interface = &intf->altsetting[0];#endif	printk(KERN_INFO "USB CPiA camera found\n");	ucpia = kmalloc(sizeof(*ucpia), GFP_KERNEL);	if (!ucpia) {		printk(KERN_ERR "couldn't kmalloc cpia struct\n");#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))		return NULL;#else		return -ENOMEM;#endif	}	memset(ucpia, 0, sizeof(*ucpia));	ucpia->dev = udev;#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))	ucpia->iface = interface->bInterfaceNumber;#else	ucpia->iface = interface->desc.bInterfaceNumber;#endif	init_waitqueue_head(&ucpia->wq_stream);	ucpia->buffers[0] = vmalloc(sizeof(*ucpia->buffers[0]));	if (!ucpia->buffers[0]) {		printk(KERN_ERR "couldn't vmalloc frame buffer 0\n");		goto fail_alloc_0;	}	ucpia->buffers[1] = vmalloc(sizeof(*ucpia->buffers[1]));	if (!ucpia->buffers[1]) {		printk(KERN_ERR "couldn't vmalloc frame buffer 1\n");		goto fail_alloc_1;	}	ucpia->buffers[2] = vmalloc(sizeof(*ucpia->buffers[2]));	if (!ucpia->buffers[2]) {		printk(KERN_ERR "couldn't vmalloc frame buffer 2\n");		goto fail_alloc_2;	}	ucpia->buffers[0]->next = ucpia->buffers[1];	ucpia->buffers[1]->next = ucpia->buffers[2];	ucpia->buffers[2]->next = ucpia->buffers[0];	ret = usb_set_interface(udev, ucpia->iface, 0);	if (ret < 0) {		printk(KERN_ERR "cpia_probe: usb_set_interface error (ret = %d)\n", ret);		/* goto fail_all; */	}	ucpia->alt = 0;	/* Before register_camera, important */	ucpia->present = 1;  	cam = cpia_register_camera(&cpia_usb_ops, ucpia);	if (!cam) {		LOG("failed to cpia_register_camera\n");		goto fail_all;	}	spin_lock( &cam_list_lock_usb );	list_add( &cam->cam_data_list, &cam_list );	spin_unlock( &cam_list_lock_usb );#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))	return cam;#else	usb_set_intfdata(intf, cam);	return 0;#endiffail_all:	vfree(ucpia->buffers[2]);	ucpia->buffers[2] = NULL;fail_alloc_2:	vfree(ucpia->buffers[1]);	ucpia->buffers[1] = NULL;fail_alloc_1:	vfree(ucpia->buffers[0]);	ucpia->buffers[0] = NULL;fail_alloc_0:	kfree(ucpia);#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))	return NULL;#else	return -EIO;#endif}#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))static void cpia_disconnect(struct usb_device *dev, void *ptr);#elsestatic void cpia_disconnect(struct usb_interface *intf);#endifstatic struct usb_device_id cpia_id_table [] = {	{ USB_DEVICE(0x0553, 0x0002) },	{ USB_DEVICE(0x0813, 0x0001) },	{ }					/* Terminating entry */};MODULE_DEVICE_TABLE (usb, cpia_id_table);#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,10))MODULE_LICENSE("GPL");#endifstatic struct usb_driver cpia_driver = {#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))	name:		"cpia",	probe:		cpia_probe,	disconnect:	cpia_disconnect,	id_table:	cpia_id_table,#else#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,70))	.owner          = THIS_MODULE,#endif	.name		= "cpia",	.probe		= cpia_probe,	.disconnect	= cpia_disconnect,	.id_table	= cpia_id_table,#endif};#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))static void cpia_disconnect(struct usb_device *udev, void *ptr){	struct cam_data *cam = (struct cam_data *) ptr;#elsestatic void cpia_disconnect(struct usb_interface *intf){	struct cam_data *cam = usb_get_intfdata(intf);	struct usb_device *udev;#endif	struct usb_cpia *ucpia;  #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))	usb_set_intfdata(intf, NULL);#endif	if (!cam)		return;	ucpia = (struct usb_cpia *) cam->lowlevel_data;  	spin_lock( &cam_list_lock_usb );	list_del(&cam->cam_data_list);	spin_unlock( &cam_list_lock_usb );		ucpia->present = 0;	cpia_unregister_camera(cam);	if(ucpia->open)		cpia_usb_close(cam->lowlevel_data);	ucpia->curbuff->status = FRAME_ERROR;	if (waitqueue_active(&ucpia->wq_stream))		wake_up_interruptible(&ucpia->wq_stream);#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,75))	udev = interface_to_usbdev(intf);	usb_driver_release_interface(&cpia_driver,				     udev->actconfig->interface[0]);#else	usb_driver_release_interface(&cpia_driver,				     &udev->actconfig->interface[0]);#endif	ucpia->curbuff = ucpia->workbuff = NULL;	if (ucpia->buffers[2]) {		vfree(ucpia->buffers[2]);		ucpia->buffers[2] = NULL;	}	if (ucpia->buffers[1]) {		vfree(ucpia->buffers[1]);		ucpia->buffers[1] = NULL;	}	if (ucpia->buffers[0]) {		vfree(ucpia->buffers[0]);		ucpia->buffers[0] = NULL;	}	cam->lowlevel_data = NULL;	kfree(ucpia);}static int __init usb_cpia_init(void){	printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT, 	       CPIA_USB_MAJ_VER,CPIA_USB_MIN_VER,CPIA_USB_PATCH_VER);	spin_lock_init(&cam_list_lock_usb);	return usb_register(&cpia_driver);}static void __exit usb_cpia_cleanup(void){	usb_deregister(&cpia_driver);}module_init (usb_cpia_init);module_exit (usb_cpia_cleanup);

⌨️ 快捷键说明

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