/*
 * USB ViCam WebCam driver
 * Copyright (c) 2002 Joe Burks (jburks@wavicle.org),
 *                    Christopher L Cheney (ccheney@cheney.cx),
 *                    Pavel Machek (pavel@ucw.cz),
 *                    John Tyner (jtyner@cs.ucr.edu),
 *                    Monroe Williams (monroe@pobox.com)
 *
 * Supports 3COM HomeConnect PC Digital WebCam
 * Supports Compro PS39U WebCam
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * This source code is based heavily on the CPiA webcam driver which was
 * written by Peter Pregler, Scott J. Bertin and Johannes Erdfelt
 *
 * Portions of this code were also copied from usbvideo.c
 *
 * Special thanks to the whole team at Sourceforge for help making
 * this driver become a reality.  Notably:
 * Andy Armstrong who reverse engineered the color encoding and
 * Pavel Machek and Chris Cheney who worked on reverse engineering the
 *    camera controls and wrote the first generation driver.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/videodev.h>
#include <linux/usb.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/firmware.h>
#include <linux/ihex.h>
#include "usbvideo.h"

// #define VICAM_DEBUG

#ifdef VICAM_DEBUG
#define ADBG(lineno,fmt,args...) printk(fmt, jiffies, __func__, lineno, ##args)
#define DBG(fmt,args...) ADBG((__LINE__),KERN_DEBUG __FILE__"(%ld):%s (%d):"fmt,##args)
#else
#define DBG(fmn,args...) do {} while(0)
#endif

#define DRIVER_AUTHOR           "Joe Burks, jburks@wavicle.org"
#define DRIVER_DESC             "ViCam WebCam Driver"

/* Define these values to match your device */
#define USB_VICAM_VENDOR_ID	0x04c1
#define USB_VICAM_PRODUCT_ID	0x009d
#define USB_COMPRO_VENDOR_ID	0x0602
#define USB_COMPRO_PRODUCT_ID	0x1001

#define VICAM_BYTES_PER_PIXEL   3
#define VICAM_MAX_READ_SIZE     (512*242+128)
#define VICAM_MAX_FRAME_SIZE    (VICAM_BYTES_PER_PIXEL*320*240)
#define VICAM_FRAMES            2

#define VICAM_HEADER_SIZE       64

/* rvmalloc / rvfree copied from usbvideo.c
 *
 * Not sure why these are not yet non-statics which I can reference through
 * usbvideo.h the same as it is in 2.4.20.  I bet this will get fixed sometime
 * in the future.
 *
*/
static void *rvmalloc(unsigned long size)
{
	void *mem;
	unsigned long adr;

	size = PAGE_ALIGN(size);
	mem = vmalloc_32(size);
	if (!mem)
		return NULL;

	memset(mem, 0, size); /* Clear the ram out, no junk to the user */
	adr = (unsigned long) mem;
	while (size > 0) {
		SetPageReserved(vmalloc_to_page((void *)adr));
		adr += PAGE_SIZE;
		size -= PAGE_SIZE;
	}

	return mem;
}

static void rvfree(void *mem, unsigned long size)
{
	unsigned long adr;

	if (!mem)
		return;

	adr = (unsigned long) mem;
	while ((long) size > 0) {
		ClearPageReserved(vmalloc_to_page((void *)adr));
		adr += PAGE_SIZE;
		size -= PAGE_SIZE;
	}
	vfree(mem);
}

struct vicam_camera {
	u16 shutter_speed;	// capture shutter speed
	u16 gain;		// capture gain

	u8 *raw_image;		// raw data captured from the camera
	u8 *framebuf;		// processed data in RGB24 format
	u8 *cntrlbuf;		// area used to send control msgs

	struct video_device vdev;	// v4l video device
	struct usb_device *udev;	// usb device

	/* guard against simultaneous accesses to the camera */
	struct mutex cam_lock;

	int is_initialized;
	u8 open_count;
	u8 bulkEndpoint;
	int needsDummyRead;
};

static int vicam_probe( struct usb_interface *intf, const struct usb_device_id *id);
static void vicam_disconnect(struct usb_interface *intf);
static void read_frame(struct vicam_camera *cam, int framenum);
static void vicam_decode_color(const u8 *, u8 *);

static int __send_control_msg(struct vicam_camera *cam,
			      u8 request,
			      u16 value,
			      u16 index,
			      unsigned char *cp,
			      u16 size)
{
	int status;

	/* cp must be memory that has been allocated by kmalloc */

	status = usb_control_msg(cam->udev,
				 usb_sndctrlpipe(cam->udev, 0),
				 request,
				 USB_DIR_OUT | USB_TYPE_VENDOR |
				 USB_RECIP_DEVICE, value, index,
				 cp, size, 1000);

	status = min(status, 0);

	if (status < 0) {
		printk(KERN_INFO "Failed sending control message, error %d.\n",
		       status);
	}

	return status;
}

static int send_control_msg(struct vicam_camera *cam,
			    u8 request,
			    u16 value,
			    u16 index,
			    unsigned char *cp,
			    u16 size)
{
	int status = -ENODEV;
	mutex_lock(&cam->cam_lock);
	if (cam->udev) {
		status = __send_control_msg(cam, request, value,
					    index, cp, size);
	}
	mutex_unlock(&cam->cam_lock);
	return status;
}
static int
initialize_camera(struct vicam_camera *cam)
{
	int err;
	const struct ihex_binrec *rec;
	const struct firmware *uninitialized_var(fw);

	err = request_ihex_firmware(&fw, "vicam/firmware.fw", &cam->udev->dev);
	if (err) {
		printk(KERN_ERR "Failed to load \"vicam/firmware.fw\": %d\n",
		       err);
		return err;
	}

	for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
		memcpy(cam->cntrlbuf, rec->data, be16_to_cpu(rec->len));

		err = send_control_msg(cam, 0xff, 0, 0,
				       cam->cntrlbuf, be16_to_cpu(rec->len));
		if (err)
			break;
	}

	release_firmware(fw);

	return err;
}

static int
set_camera_power(struct vicam_camera *cam, int state)
{
	int status;

	if ((status = send_control_msg(cam, 0x50, state, 0, NULL, 0)) < 0)
		return status;

	if (state) {
		send_control_msg(cam, 0x55, 1, 0, NULL, 0);
	}

	return 0;
}

static long
vicam_ioctl(struct file *file, unsigned int ioctlnr, unsigned long arg)
{
	void __user *user_arg = (void __user *)arg;
	struct vicam_camera *cam = file->private_data;
	long retval = 0;

	if (!cam)
		return -ENODEV;

	switch (ioctlnr) {
		/* query capabilities */
	case VIDIOCGCAP:
		{
			struct video_capability b;

			DBG("VIDIOCGCAP\n");
			memset(&b, 0, sizeof(b));
			strcpy(b.name, "ViCam-based Camera");
			b.type = VID_TYPE_CAPTURE;
			b.channels = 1;
			b.audios = 0;
			b.maxwidth = 320;	/* VIDEOSIZE_CIF */
			b.maxheight = 240;
			b.minwidth = 320;	/* VIDEOSIZE_48_48 */
			b.minheight = 240;

			if (copy_to_user(user_arg, &b, sizeof(b)))
				retval = -EFAULT;

			break;
		}
		/* get/set video source - we are a camera and nothing else */
	case VIDIOCGCHAN:
		{
			struct video_channel v;

			DBG("VIDIOCGCHAN\n");
			if (copy_from_user(&v, user_arg, sizeof(v))) {
				retval = -EFAULT;
				break;
			}
			if (v.channel != 0) {
				retval = -EINVAL;
				break;
			}

			v.channel = 0;
			strcpy(v.name, "Camera");
			v.tuners = 0;
			v.flags = 0;
			v.type = VIDEO_TYPE_CAMERA;
			v.norm = 0;

			if (copy_to_user(user_arg, &v, sizeof(v)))
				retval = -EFAULT;
			break;
		}

	case VIDIOCSCHAN:
		{
			int v;

			if (copy_from_user(&v, user_arg, sizeof(v)))
				retval = -EFAULT;
			DBG("VIDIOCSCHAN %d\n", v);

			if (retval == 0 && v != 0)
				retval = -EINVAL;

			break;
		}

		/* image properties */
	case VIDIOCGPICT:
		{
			struct video_picture vp;
			DBG("VIDIOCGPICT\n");
			memset(&vp, 0, sizeof (struct video_picture));
			vp.brightness = cam->gain << 8;
			vp.depth = 24;
			vp.palette = VIDEO_PALETTE_RGB24;
			if (copy_to_user(user_arg, &vp, sizeof (struct video_picture)))
				retval = -EFAULT;
			break;
		}

	case VIDIOCSPICT:
		{
			struct video_picture vp;

			if (copy_from_user(&vp, user_arg, sizeof(vp))) {
				retval = -EFAULT;
				break;
			}

			DBG("VIDIOCSPICT depth = %d, pal = %d\n", vp.depth,
			    vp.palette);

			cam->gain = vp.brightness >> 8;

			if (vp.depth != 24
			    || vp.palette != VIDEO_PALETTE_RGB24)
				retval = -EINVAL;

			break;
		}

		/* get/set capture window */
	case VIDIOCGWIN:
		{
			struct video_window vw;
			vw.x = 0;
			vw.y = 0;
			vw.width = 320;
			vw.height = 240;
			vw.chromakey = 0;
			vw.flags = 0;
			vw.clips = NULL;
			vw.clipcount = 0;

			DBG("VIDIOCGWIN\n");

			if (copy_to_user(user_arg, (void *)&vw, sizeof(vw)))
				retval = -EFAULT;

			// I'm not sure what the deal with a capture window is, it is very poorly described
			// in the doc.  So I won't support it now.
			break;
		}

	case VIDIOCSWIN:
		{

			struct video_window vw;

			if (copy_from_user(&vw, user_arg, sizeof(vw))) {
				retval = -EFAULT;
				break;
			}

			DBG("VIDIOCSWIN %d x %d\n", vw.width, vw.height);

			if ( vw.width != 320 || vw.height != 240 )
				retval = -EFAULT;

			break;
		}

		/* mmap interface */
	case VIDIOCGMBUF:
		{
			struct video_mbuf vm;
			int i;

			DBG("VIDIOCGMBUF\n");
			memset(&vm, 0, sizeof (vm));
			vm.size =
			    VICAM_MAX_FRAME_SIZE * VICAM_FRAMES;
			vm.frames = VICAM_FRAMES;
			for (i = 0; i < VICAM_FRAMES; i++)
				vm.offsets[i] = VICAM_MAX_FRAME_SIZE * i;

			if (copy_to_user(user_arg, (void *)&vm, sizeof(vm)))
				retval = -EFAULT;

			break;
		}

	case VIDIOCMCAPTURE:
		{
			struct video_mmap vm;
			// int video_size;

			if (copy_from_user((void *)&vm, user_arg, sizeof(vm))) {
				retval = -EFAULT;
				break;
			}

			DBG("VIDIOCMCAPTURE frame=%d, height=%d, width=%d, format=%d.\n",vm.frame,vm.width,vm.height,vm.format);

			if ( vm.frame >= VICAM_FRAMES || vm.format != VIDEO_PALETTE_RGB24 )
				retval = -EINVAL;

			// in theory right here we'd start the image capturing
			// (fill in a bulk urb and submit it asynchronously)
			//
			// Instead we're going to do a total hack job for now and
			// retrieve the frame in VIDIOCSYNC

			break;
		}

	case VIDIOCSYNC:
		{
			int frame;

			if (copy_from_user((void *)&frame, user_arg, sizeof(int))) {
				retval = -EFAULT;
				break;
			}
			DBG("VIDIOCSYNC: %d\n", frame);

			read_frame(cam, frame);
			vicam_decode_color(cam->raw_image,
					   cam->framebuf +
					   frame * VICAM_MAX_FRAME_SIZE );

			break;
		}

		/* pointless to implement overlay with this camera */
	case VIDIOCCAPTURE:
	case VIDIOCGFBUF:
	case VIDIOCSFBUF:
	case VIDIOCKEY:
		retval = -EINVAL;
		break;

		/* tuner interface - we have none */
	case VIDIOCGTUNER:
	case VIDIOCSTUNER:
	case VIDIOCGFREQ:
	case VIDIOCSFREQ:
		retval = -EINVAL;
		break;

		/* audio interface - we have none */
	case VIDIOCGAUDIO:
	case VIDIOCSAUDIO:
		retval = -EINVAL;
		break;
	default:
		retval = -ENOIOCTLCMD;
		break;
	}

	return retval;
}

static int
vicam_open(struct file *file)
{
	struct vicam_camera *cam = video_drvdata(file);

	DBG("open\n");

	if (!cam) {
		printk(KERN_ERR
		       "vicam video_device improperly initialized");
		return -EINVAL;
	}

	/* cam_lock/open_count protects us from simultaneous opens
	 * ... for now. we probably shouldn't rely on this fact forever.
	 */

	mutex_lock(&cam->cam_lock);
	if (cam->open_count > 0) {
		printk(KERN_INFO
		       "vicam_open called on already opened camera");
		mutex_unlock(&cam->cam_lock);
		return -EBUSY;
	}

	cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL);
	if (!cam->raw_image) {
		mutex_unlock(&cam->cam_lock);
		return -ENOMEM;
	}

	cam->framebuf = rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
	if (!cam->framebuf) {
		kfree(cam->raw_image);
		mutex_unlock(&cam->cam_lock);
		return -ENOMEM;
	}

	cam->cntrlbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
	if (!cam->cntrlbuf) {
		kfree(cam->raw_image);
		rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
		mutex_unlock(&cam->cam_lock);
		return -ENOMEM;
	}

	cam->needsDummyRead = 1;
	cam->open_count++;

	file->private_data = cam;
	mutex_unlock(&cam->cam_lock);


	// First upload firmware, then turn the camera on

	if (!cam->is_initialized) {
		initialize_camera(cam);

		cam->is_initialized = 1;
	}

	set_camera_power(cam, 1);

	return 0;
}

static int
vicam_close(struct file *file)
{
	struct vicam_camera *cam = file->private_data;
	int open_count;
	struct usb_device *udev;

	DBG("close\n");

	/* it's not the end of the world if
	 * we fail to turn the camera off.
	 */

	set_camera_power(cam, 0);

	kfree(cam->raw_image);
	rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
	kfree(cam->cntrlbuf);

	mutex_lock(&cam->cam_lock);

	cam->open_count--;
	open_count = cam->open_count;
	udev = cam->udev;

	mutex_unlock(&cam->cam_lock);

	if (!open_count && !udev) {
		kfree(cam);
	}

	return 0;
}

static void vicam_decode_color(const u8 *data, u8 *rgb)
{
	/* vicam_decode_color - Convert from Vicam Y-Cr-Cb to RGB
	 * Copyright (C) 2002 Monroe Williams (monroe@pobox.com)
	 */

	int i, prevY, nextY;

	prevY = 512;
	nextY = 512;

	data += VICAM_HEADER_SIZE;

	for( i = 0; i < 240; i++, data += 512 ) {
		const int y = ( i * 242 ) / 240;

		int j, prevX, nextX;
		int Y, Cr, Cb;

		if ( y == 242 - 1 ) {
			nextY = -512;
		}

		prevX = 1;
		nextX = 1;

		for ( j = 0; j < 320; j++, rgb += 3 ) {
			const int x = ( j * 512 ) / 320;
			const u8 * const src = &data[x];

			if ( x == 512 - 1 ) {
				nextX = -1;
			}

			Cr = ( src[prevX] - src[0] ) +
				( src[nextX] - src[0] );
			Cr /= 2;

			Cb = ( src[prevY] - src[prevX + prevY] ) +
				( src[prevY] - src[nextX + prevY] ) +
				( src[nextY] - src[prevX + nextY] ) +
				( src[nextY] - src[nextX + nextY] );
			Cb /= 4;

			Y = 1160 * ( src[0] + ( Cr / 2 ) - 16 );

			if ( i & 1 ) {
				int Ct = Cr;
				Cr = Cb;
				Cb = Ct;
			}

			if ( ( x ^ i ) & 1 ) {
				Cr = -Cr;
				Cb = -Cb;
			}

			rgb[0] = clamp( ( ( Y + ( 2017 * Cb ) ) +
					500 ) / 900, 0, 255 );
			rgb[1] = clamp( ( ( Y - ( 392 * Cb ) -
					  ( 813 * Cr ) ) +
					  500 ) / 1000, 0, 255 );
			rgb[2] = clamp( ( ( Y + ( 1594 * Cr ) ) +
					500 ) / 1300, 0, 255 );

			prevX = -1;
		}

		prevY = -512;
	}
}

static void
read_frame(struct vicam_camera *cam, int framenum)
{
	unsigned char *request = cam->cntrlbuf;
	int realShutter;
	int n;
	int actual_length;

	if (cam->needsDummyRead) {
		cam->needsDummyRead = 0;
		read_frame(cam, framenum);
	}

	memset(request, 0, 16);
	request[0] = cam->gain;	// 0 = 0% gain, FF = 100% gain

	request[1] = 0;	// 512x242 capture

	request[2] = 0x90;	// the function of these two bytes
	request[3] = 0x07;	// is not yet understood

	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ørndalen, 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

	mutex_lock(&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:
	mutex_unlock(&cam->cam_lock);
}

static ssize_t
vicam_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 int
vicam_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;
}

static const struct v4l2_file_operations vicam_fops = {
	.owner		= THIS_MODULE,
	.open		= vicam_open,
	.release	= vicam_close,
	.read		= vicam_read,
	.mmap		= vicam_mmap,
	.ioctl		= vicam_ioctl,
};

static struct video_device vicam_template = {
	.name 		= "ViCam-based USB Camera",
	.fops 		= &vicam_fops,
	.release 	= video_device_release_empty,
};

/* 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)},
	{USB_DEVICE(USB_COMPRO_VENDOR_ID, USB_COMPRO_PRODUCT_ID)},
	{}			/* Terminating entry */
};

MODULE_DEVICE_TABLE(usb, vicam_table);

static struct usb_driver vicam_driver = {
	.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 int
vicam_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 (usb_endpoint_is_bulk_in(endpoint)) {
		/* 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 =
	     kzalloc(sizeof (struct vicam_camera), GFP_KERNEL)) == NULL) {
		printk(KERN_WARNING
		       "could not allocate kernel memory for vicam_camera struct\n");
		return -ENOMEM;
	}


	cam->shutter_speed = 15;

	mutex_init(&cam->cam_lock);

	memcpy(&cam->vdev, &vicam_template, sizeof(vicam_template));
	video_set_drvdata(&cam->vdev, cam);

	cam->udev = dev;
	cam->bulkEndpoint = bulkEndpoint;

	if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1) < 0) {
		kfree(cam);
		printk(KERN_WARNING "video_register_device failed\n");
		return -EIO;
	}

	printk(KERN_INFO "ViCam webcam driver now controlling device %s\n",
		video_device_node_name(&cam->vdev));

	usb_set_intfdata (intf, cam);

	return 0;
}

static void
vicam_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 */

	mutex_lock(&cam->cam_lock);

	/* mark the camera as gone */

	cam->udev = NULL;

	/* 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;

	mutex_unlock(&cam->cam_lock);

	if (!open_count) {
		kfree(cam);
	}

	printk(KERN_DEBUG "ViCam-based WebCam disconnected\n");
}

/*
 */
static int __init
usb_vicam_init(void)
{
	int retval;
	DBG(KERN_INFO "ViCam-based WebCam driver startup\n");
	retval = usb_register(&vicam_driver);
	if (retval)
		printk(KERN_WARNING "usb_register failed!\n");
	return retval;
}

static void __exit
usb_vicam_exit(void)
{
	DBG(KERN_INFO
	       "ViCam-based WebCam driver shutdown\n");

	usb_deregister(&vicam_driver);
}

module_init(usb_vicam_init);
module_exit(usb_vicam_exit);

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
MODULE_FIRMWARE("vicam/firmware.fw");
