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

📄 vicam.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (cam->shutter_speed > 60) {		// Short exposure		realShutter =		    ((-15631900 / cam->shutter_speed) + 260533) / 1000;		request[4] = realShutter & 0xFF;		request[5] = (realShutter >> 8) & 0xFF;		request[6] = 0x03;		request[7] = 0x01;	} else {		// Long exposure		realShutter = 15600 / cam->shutter_speed - 1;		request[4] = 0;		request[5] = 0;		request[6] = realShutter & 0xFF;		request[7] = realShutter >> 8;	}	// Per John Markus Bj鴕ndalen, byte at index 8 causes problems if it isn't 0	request[8] = 0;	// bytes 9-15 do not seem to affect exposure or image quality	down(&cam->cam_lock);	if (!cam->udev) {		goto done;	}	n = __send_control_msg(cam, 0x51, 0x80, 0, request, 16);	if (n < 0) {		printk(KERN_ERR		       " Problem sending frame capture control message");		goto done;	}	n = usb_bulk_msg(cam->udev,			 usb_rcvbulkpipe(cam->udev, cam->bulkEndpoint),			 cam->raw_image,			 512 * 242 + 128, &actual_length, 10000);	if (n < 0) {		printk(KERN_ERR "Problem during bulk read of frame data: %d\n",		       n);	} done:	up(&cam->cam_lock);}static ssize_tvicam_read( struct file *file, char __user *buf, size_t count, loff_t *ppos ){	struct vicam_camera *cam = file->private_data;	DBG("read %d bytes.\n", (int) count);	if (*ppos >= VICAM_MAX_FRAME_SIZE) {		*ppos = 0;		return 0;	}	if (*ppos == 0) {		read_frame(cam, 0);		vicam_decode_color(cam->raw_image,				   cam->framebuf +				   0 * VICAM_MAX_FRAME_SIZE);	}	count = min_t(size_t, count, VICAM_MAX_FRAME_SIZE - *ppos);	if (copy_to_user(buf, &cam->framebuf[*ppos], count)) {		count = -EFAULT;	} else {		*ppos += count;	}	if (count == VICAM_MAX_FRAME_SIZE) {		*ppos = 0;	}	return count;}static intvicam_mmap(struct file *file, struct vm_area_struct *vma){	// TODO: allocate the raw frame buffer if necessary	unsigned long page, pos;	unsigned long start = vma->vm_start;	unsigned long size  = vma->vm_end-vma->vm_start;	struct vicam_camera *cam = file->private_data;	if (!cam)		return -ENODEV;	DBG("vicam_mmap: %ld\n", size);	/* We let mmap allocate as much as it wants because Linux was adding 2048 bytes	 * to the size the application requested for mmap and it was screwing apps up.	 if (size > VICAM_FRAMES*VICAM_MAX_FRAME_SIZE)	 return -EINVAL;	 */	pos = (unsigned long)cam->framebuf;	while (size > 0) {		page = vmalloc_to_pfn((void *)pos);		if (remap_pfn_range(vma, 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;}#if defined(CONFIG_VIDEO_PROC_FS)static struct proc_dir_entry *vicam_proc_root = NULL;static int vicam_read_helper(char *page, char **start, off_t off,				int count, int *eof, int value){	char *out = page;	int len;	out += sprintf(out, "%d",value);	len = out - page;	len -= off;	if (len < count) {		*eof = 1;		if (len <= 0)			return 0;	} else		len = count;	*start = page + off;	return len;}static int vicam_read_proc_shutter(char *page, char **start, off_t off,				int count, int *eof, void *data){	return vicam_read_helper(page,start,off,count,eof,				((struct vicam_camera *)data)->shutter_speed);}static int vicam_read_proc_gain(char *page, char **start, off_t off,				int count, int *eof, void *data){	return vicam_read_helper(page,start,off,count,eof,				((struct vicam_camera *)data)->gain);}static intvicam_write_proc_shutter(struct file *file, const char *buffer,			 unsigned long count, void *data){	u16 stmp;	char kbuf[8];	struct vicam_camera *cam = (struct vicam_camera *) data;	if (count > 6)		return -EINVAL;	if (copy_from_user(kbuf, buffer, count))		return -EFAULT;	stmp = (u16) simple_strtoul(kbuf, NULL, 10);	if (stmp < 4 || stmp > 32000)		return -EINVAL;	cam->shutter_speed = stmp;	return count;}static intvicam_write_proc_gain(struct file *file, const char *buffer,		      unsigned long count, void *data){	u16 gtmp;	char kbuf[8];	struct vicam_camera *cam = (struct vicam_camera *) data;	if (count > 4)		return -EINVAL;	if (copy_from_user(kbuf, buffer, count))		return -EFAULT;	gtmp = (u16) simple_strtoul(kbuf, NULL, 10);	if (gtmp > 255)		return -EINVAL;	cam->gain = gtmp;	return count;}static voidvicam_create_proc_root(void){	vicam_proc_root = proc_mkdir("video/vicam", NULL);	if (vicam_proc_root)		vicam_proc_root->owner = THIS_MODULE;	else		printk(KERN_ERR		       "could not create /proc entry for vicam!");}static voidvicam_destroy_proc_root(void){	if (vicam_proc_root)		remove_proc_entry("video/vicam", 0);}static voidvicam_create_proc_entry(struct vicam_camera *cam){	char name[64];	struct proc_dir_entry *ent;	DBG(KERN_INFO "vicam: creating proc entry\n");	if (!vicam_proc_root || !cam) {		printk(KERN_INFO		       "vicam: could not create proc entry, %s pointer is null.\n",		       (!cam ? "camera" : "root"));		return;	}	sprintf(name, "video%d", cam->vdev.minor);	cam->proc_dir = proc_mkdir(name, vicam_proc_root);	if ( !cam->proc_dir )		return; // FIXME: We should probably return an error here		ent = create_proc_entry("shutter", S_IFREG | S_IRUGO | S_IWUSR,				cam->proc_dir);	if (ent) {		ent->data = cam;		ent->read_proc = vicam_read_proc_shutter;		ent->write_proc = vicam_write_proc_shutter;		ent->size = 64;	}	ent = create_proc_entry("gain", S_IFREG | S_IRUGO | S_IWUSR,				cam->proc_dir);	if (ent) {		ent->data = cam;		ent->read_proc = vicam_read_proc_gain;		ent->write_proc = vicam_write_proc_gain;		ent->size = 64;	}}static voidvicam_destroy_proc_entry(void *ptr){	struct vicam_camera *cam = (struct vicam_camera *) ptr;	char name[16];	if ( !cam->proc_dir )		return;	sprintf(name, "video%d", cam->vdev.minor);	remove_proc_entry("shutter", cam->proc_dir);	remove_proc_entry("gain", cam->proc_dir);	remove_proc_entry(name,vicam_proc_root);	cam->proc_dir = NULL;}#elsestatic inline void vicam_create_proc_root(void) { }static inline void vicam_destroy_proc_root(void) { }static inline void vicam_create_proc_entry(struct vicam_camera *cam) { }static inline void vicam_destroy_proc_entry(void *ptr) { }#endifstatic struct file_operations vicam_fops = {	.owner		= THIS_MODULE,	.open		= vicam_open,	.release	= vicam_close,	.read		= vicam_read,	.mmap		= vicam_mmap,	.ioctl		= vicam_ioctl,	.llseek		= no_llseek,};static struct video_device vicam_template = {	.owner 		= THIS_MODULE,	.name 		= "ViCam-based USB Camera",	.type 		= VID_TYPE_CAPTURE,	.hardware 	= VID_HARDWARE_VICAM,	.fops 		= &vicam_fops,	.minor 		= -1,};/* table of devices that work with this driver */static struct usb_device_id vicam_table[] = {	{USB_DEVICE(USB_VICAM_VENDOR_ID, USB_VICAM_PRODUCT_ID)},	{}			/* Terminating entry */};MODULE_DEVICE_TABLE(usb, vicam_table);static struct usb_driver vicam_driver = {	.owner		= THIS_MODULE,	.name		= "vicam",	.probe		= vicam_probe,	.disconnect	= vicam_disconnect,	.id_table	= vicam_table};/** *	vicam_probe *	@intf: the interface *	@id: the device id * *	Called by the usb core when a new device is connected that it thinks *	this driver might be interested in. */static intvicam_probe( struct usb_interface *intf, const struct usb_device_id *id){	struct usb_device *dev = interface_to_usbdev(intf);	int bulkEndpoint = 0;	const struct usb_host_interface *interface;	const struct usb_endpoint_descriptor *endpoint;	struct vicam_camera *cam;		printk(KERN_INFO "ViCam based webcam connected\n");	interface = intf->cur_altsetting;	DBG(KERN_DEBUG "Interface %d. has %u. endpoints!\n",	       interface->desc.bInterfaceNumber, (unsigned) (interface->desc.bNumEndpoints));	endpoint = &interface->endpoint[0].desc;	if ((endpoint->bEndpointAddress & 0x80) &&	    ((endpoint->bmAttributes & 3) == 0x02)) {		/* we found a bulk in endpoint */		bulkEndpoint = endpoint->bEndpointAddress;	} else {		printk(KERN_ERR		       "No bulk in endpoint was found ?! (this is bad)\n");	}	if ((cam =	     kmalloc(sizeof (struct vicam_camera), GFP_KERNEL)) == NULL) {		printk(KERN_WARNING		       "could not allocate kernel memory for vicam_camera struct\n");		return -ENOMEM;	}	memset(cam, 0, sizeof (struct vicam_camera));	cam->shutter_speed = 15;	init_MUTEX(&cam->cam_lock);	memcpy(&cam->vdev, &vicam_template,	       sizeof (vicam_template));	cam->vdev.priv = cam;	// sort of a reverse mapping for those functions that get vdev only	cam->udev = dev;	cam->bulkEndpoint = bulkEndpoint;	if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1) == -1) {		kfree(cam);		printk(KERN_WARNING "video_register_device failed\n");		return -EIO;	}	vicam_create_proc_entry(cam);	printk(KERN_INFO "ViCam webcam driver now controlling video device %d\n",cam->vdev.minor);	usb_set_intfdata (intf, cam);		return 0;}static voidvicam_disconnect(struct usb_interface *intf){	int open_count;	struct vicam_camera *cam = usb_get_intfdata (intf);	usb_set_intfdata (intf, NULL);	/* we must unregister the device before taking its	 * cam_lock. This is because the video open call	 * holds the same lock as video unregister. if we	 * unregister inside of the cam_lock and open also	 * uses the cam_lock, we get deadlock.	 */	video_unregister_device(&cam->vdev);	/* stop the camera from being used */	down(&cam->cam_lock);	/* mark the camera as gone */	cam->udev = NULL;	vicam_destroy_proc_entry(cam);	/* the only thing left to do is synchronize with	 * our close/release function on who should release	 * the camera memory. if there are any users using the	 * camera, it's their job. if there are no users,	 * it's ours.	 */	open_count = cam->open_count;	up(&cam->cam_lock);	if (!open_count) {		kfree(cam);	}	printk(KERN_DEBUG "ViCam-based WebCam disconnected\n");}/* */static int __initusb_vicam_init(void){	int retval;	DBG(KERN_INFO "ViCam-based WebCam driver startup\n");	vicam_create_proc_root();	retval = usb_register(&vicam_driver);	if (retval)		printk(KERN_WARNING "usb_register failed!\n");	return retval;}static void __exitusb_vicam_exit(void){	DBG(KERN_INFO	       "ViCam-based WebCam driver shutdown\n");	usb_deregister(&vicam_driver);	vicam_destroy_proc_root();}module_init(usb_vicam_init);module_exit(usb_vicam_exit);MODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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