/*
 * Endpoints (formerly known as AOX) se401 USB Camera Driver
 *
 * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org)
 *
 * Still somewhat based on the Linux ov511 driver.
 * 
 * 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.
 *
 *
 * Thanks to Endpoints Inc. (www.endpoints.com) for making documentation on
 * their chipset available and supporting me while writing this driver.
 * 	- Jeroen Vreeken
 */

static const char version[] = "0.24";

#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/usb.h>
#include "se401.h"

static int flickerless=0;
static int video_nr = -1;

static struct usb_device_id device_table [] = {
	{ USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */
	{ USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */
	{ USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */
	{ USB_DEVICE(0x047d, 0x5002) },/* Kensington 6701(5/7) */
	{ USB_DEVICE(0x047d, 0x5003) },/* Kensington 67016 */
	{ }
};

MODULE_DEVICE_TABLE(usb, device_table);

MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>");
MODULE_DESCRIPTION("SE401 USB Camera Driver");
MODULE_LICENSE("GPL");
module_param(flickerless, int, 0);
MODULE_PARM_DESC(flickerless, "Net frequency to adjust exposure time to (0/50/60)");
module_param(video_nr, int, 0);

static struct usb_driver se401_driver;


/**********************************************************************
 *
 * Memory management
 *
 **********************************************************************/
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);
}



/****************************************************************************
 *
 * se401 register read/write functions
 *
 ***************************************************************************/

static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req,
			 unsigned short value, unsigned char *cp, int size)
{
	return usb_control_msg (
                se401->dev,
                set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0),
                req,
                (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                value,
                0,
                cp,
                size,
                1000
        );
}

static int se401_set_feature(struct usb_se401 *se401, unsigned short selector,
			     unsigned short param)
{
	/* specs say that the selector (address) should go in the value field
	   and the param in index, but in the logs of the windows driver they do
	   this the other way around...
	 */
	return usb_control_msg (
		se401->dev,
		usb_sndctrlpipe(se401->dev, 0),
		SE401_REQ_SET_EXT_FEATURE,
		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
		param,
		selector,
                NULL,
                0,
                1000
        );
}

static unsigned short se401_get_feature(struct usb_se401 *se401, 
				        unsigned short selector)
{
	/* For 'set' the selecetor should be in index, not sure if the spec is
	   wrong here to....
	 */
	unsigned char cp[2];
        usb_control_msg (
                se401->dev,
                usb_rcvctrlpipe(se401->dev, 0),
                SE401_REQ_GET_EXT_FEATURE,
                USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
        	0,
                selector,
                cp,
                2,
                1000
        );
	return cp[0]+cp[1]*256;
}

/****************************************************************************
 *
 * Camera control
 *
 ***************************************************************************/


static int se401_send_pict(struct usb_se401 *se401)
{
	se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l);/* integration time low */
	se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m);/* integration time mid */
	se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h);/* integration time mid */
	se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);/* reset level value */
	se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);/* red color gain */
	se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);/* green color gain */
	se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);/* blue color gain */
	    	
	return 0;
}

static void se401_set_exposure(struct usb_se401 *se401, int brightness)
{
	int integration=brightness<<5;
	
	if (flickerless==50) {
		integration=integration-integration%106667;
	}
	if (flickerless==60) {
		integration=integration-integration%88889;
	}
	se401->brightness=integration>>5;
	se401->expose_h=(integration>>16)&0xff;
	se401->expose_m=(integration>>8)&0xff;
	se401->expose_l=integration&0xff;
}

static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p)
{
	p->brightness=se401->brightness;
	if (se401->enhance) {
		p->whiteness=32768;
	} else {
		p->whiteness=0;
	}
	p->colour=65535;
	p->contrast=65535;
	p->hue=se401->rgain<<10;
	p->palette=se401->palette;
	p->depth=3; /* rgb24 */
	return 0;
}


static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p)
{
	if (p->palette != VIDEO_PALETTE_RGB24)
		return 1;
	se401->palette=p->palette;
	if (p->hue!=se401->hue) {
		se401->rgain= p->hue>>10;
		se401->bgain= 0x40-(p->hue>>10);
		se401->hue=p->hue;
	}
	if (p->brightness!=se401->brightness) {
		se401_set_exposure(se401, p->brightness);
	}
	if (p->whiteness>=32768) {
		se401->enhance=1;
	} else {
		se401->enhance=0;
	}
	se401_send_pict(se401);
	se401_send_pict(se401);
	return 0;
}

/*
	Hyundai have some really nice docs about this and other sensor related
	stuff on their homepage: www.hei.co.kr
*/
static void se401_auto_resetlevel(struct usb_se401 *se401)
{
	unsigned int ahrc, alrc;
	int oldreset=se401->resetlevel;

	/* For some reason this normally read-only register doesn't get reset
	   to zero after reading them just once...
	 */
	se401_get_feature(se401, HV7131_REG_HIREFNOH); 
	se401_get_feature(se401, HV7131_REG_HIREFNOL);
	se401_get_feature(se401, HV7131_REG_LOREFNOH);
	se401_get_feature(se401, HV7131_REG_LOREFNOL);
	ahrc=256*se401_get_feature(se401, HV7131_REG_HIREFNOH) + 
	    se401_get_feature(se401, HV7131_REG_HIREFNOL);
	alrc=256*se401_get_feature(se401, HV7131_REG_LOREFNOH) +
	    se401_get_feature(se401, HV7131_REG_LOREFNOL);

	/* Not an exact science, but it seems to work pretty well... */
	if (alrc > 10) {
		while (alrc>=10 && se401->resetlevel < 63) {
			se401->resetlevel++;
			alrc /=2;
		}
	} else if (ahrc > 20) {
		while (ahrc>=20 && se401->resetlevel > 0) {
			se401->resetlevel--;
			ahrc /=2;
		}
	}
	if (se401->resetlevel!=oldreset)
		se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);

	return;
}

/* irq handler for snapshot button */
static void se401_button_irq(struct urb *urb, struct pt_regs *regs)
{
	struct usb_se401 *se401 = urb->context;
	int status;
	
	if (!se401->dev) {
		info("ohoh: device vapourished");
		return;
	}
	
	switch (urb->status) {
	case 0:
		/* success */
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		/* this urb is terminated, clean up */
		dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
		return;
	default:
		dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
		goto exit;
	}

	if (urb->actual_length >=2) {
		if (se401->button)
			se401->buttonpressed=1;
	}
exit:
	status = usb_submit_urb (urb, GFP_ATOMIC);
	if (status)
		err ("%s - usb_submit_urb failed with result %d",
		     __FUNCTION__, status);
}

static void se401_video_irq(struct urb *urb, struct pt_regs *regs)
{
	struct usb_se401 *se401 = urb->context;
	int length = urb->actual_length;

	/* ohoh... */
	if (!se401->streaming)
		return;

	if (!se401->dev) {
		info ("ohoh: device vapourished");
		return;
	}

	/* 0 sized packets happen if we are to fast, but sometimes the camera
	   keeps sending them forever...
	 */
	if (length && !urb->status) {
		se401->nullpackets=0;
		switch(se401->scratch[se401->scratch_next].state) {
			case BUFFER_READY:
			case BUFFER_BUSY: {
				se401->dropped++;
				break;
			}
			case BUFFER_UNUSED: {
				memcpy(se401->scratch[se401->scratch_next].data, (unsigned char *)urb->transfer_buffer, length);
				se401->scratch[se401->scratch_next].state=BUFFER_READY;
				se401->scratch[se401->scratch_next].offset=se401->bayeroffset;
				se401->scratch[se401->scratch_next].length=length;
				if (waitqueue_active(&se401->wq)) {
					wake_up_interruptible(&se401->wq);
				}
				se401->scratch_overflow=0;
				se401->scratch_next++;
				if (se401->scratch_next>=SE401_NUMSCRATCH)
					se401->scratch_next=0;
				break;
			}
		}
		se401->bayeroffset+=length;
		if (se401->bayeroffset>=se401->cheight*se401->cwidth) {
			se401->bayeroffset=0;
		}
	} else {
		se401->nullpackets++;
		if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
			if (waitqueue_active(&se401->wq)) {
				wake_up_interruptible(&se401->wq);
			}		
		}
	}

	/* Resubmit urb for new data */
	urb->status=0;
	urb->dev=se401->dev;
	if(usb_submit_urb(urb, GFP_KERNEL))
		info("urb burned down");
	return;
}

static void se401_send_size(struct usb_se401 *se401, int width, int height)
{
	int i=0;
	int mode=0x03; /* No compression */
	int sendheight=height;
	int sendwidth=width;

	/* JangGu compression can only be used with the camera supported sizes,
	   but bayer seems to work with any size that fits on the sensor.
	   We check if we can use compression with the current size with either
	   4 or 16 times subcapturing, if not we use uncompressed bayer data
	   but this will result in cutouts of the maximum size....
	 */
	while (i<se401->sizes && !(se401->width[i]==width && se401->height[i]==height))
		i++;
	while (i<se401->sizes) {
		if (se401->width[i]==width*2 && se401->height[i]==height*2) {
			sendheight=se401->height[i];
			sendwidth=se401->width[i];
			mode=0x40;
		}
		if (se401->width[i]==width*4 && se401->height[i]==height*4) {
			sendheight=se401->height[i];
			sendwidth=se401->width[i];
			mode=0x42;
		}
		i++;
	}

	se401_sndctrl(1, se401, SE401_REQ_SET_WIDTH, sendwidth, NULL, 0);
	se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0);
	se401_set_feature(se401, SE401_OPERATINGMODE, mode);

	if (mode==0x03) {
		se401->format=FMT_BAYER;
	} else {
		se401->format=FMT_JANGGU;
	}

	return;
}

/*
	In this function se401_send_pict is called several times,
	for some reason (depending on the state of the sensor and the phase of
	the moon :) doing this only in either place doesn't always work...
*/
static int se401_start_stream(struct usb_se401 *se401)
{
	struct urb *urb;
	int err=0, i;
	se401->streaming=1;

        se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
        se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);

	/* Set picture settings */
	se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);/*windowed + pix intg */
	se401_send_pict(se401);

	se401_send_size(se401, se401->cwidth, se401->cheight);

	se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE, 0, NULL, 0);

	/* Do some memory allocation */
	for (i=0; i<SE401_NUMFRAMES; i++) {
		se401->frame[i].data=se401->fbuf + i * se401->maxframesize;
		se401->frame[i].curpix=0;
	}
	for (i=0; i<SE401_NUMSBUF; i++) {
		se401->sbuf[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
	}

	se401->bayeroffset=0;
	se401->scratch_next=0;
	se401->scratch_use=0;
	se401->scratch_overflow=0;
	for (i=0; i<SE401_NUMSCRATCH; i++) {
		se401->scratch[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
		se401->scratch[i].state=BUFFER_UNUSED;
	}

	for (i=0; i<SE401_NUMSBUF; i++) {
		urb=usb_alloc_urb(0, GFP_KERNEL);
		if(!urb)
			return -ENOMEM;

		usb_fill_bulk_urb(urb, se401->dev,
			usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT),
			se401->sbuf[i].data, SE401_PACKETSIZE,
			se401_video_irq,
			se401);

		se401->urb[i]=urb;

		err=usb_submit_urb(se401->urb[i], GFP_KERNEL);
		if(err)
			err("urb burned down");
	}

	se401->framecount=0;

	return 0;
}

static int se401_stop_stream(struct usb_se401 *se401)
{
	int i;

	if (!se401->streaming || !se401->dev)
		return 1;

	se401->streaming=0;

	se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0);

	se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
	se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);

	for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
		usb_kill_urb(se401->urb[i]);
		usb_free_urb(se401->urb[i]);
		se401->urb[i]=NULL;
		kfree(se401->sbuf[i].data);
	}
	for (i=0; i<SE401_NUMSCRATCH; i++) {
		kfree(se401->scratch[i].data);
		se401->scratch[i].data=NULL;
	}

	return 0;
}

static int se401_set_size(struct usb_se401 *se401, int width, int height)
{
	int wasstreaming=se401->streaming;
	/* Check to see if we need to change */
	if (se401->cwidth==width && se401->cheight==height)
		return 0;

	/* Check for a valid mode */
	if (!width || !height)
		return 1;
	if ((width & 1) || (height & 1))
		return 1;
	if (width>se401->width[se401->sizes-1])
		return 1;
	if (height>se401->height[se401->sizes-1])
		return 1;

	/* Stop a current stream and start it again at the new size */
	if (wasstreaming)
		se401_stop_stream(se401);
	se401->cwidth=width;
	se401->cheight=height;
	if (wasstreaming)
		se401_start_stream(se401);
	return 0;
}


/****************************************************************************
 *
 * Video Decoding
 *
 ***************************************************************************/

/*
	This shouldn't really be done in a v4l driver....
	But it does make the image look a lot more usable.
	Basically it lifts the dark pixels more than the light pixels.
*/
static inline void enhance_picture(unsigned char *frame, int len)
{
	while (len--) {
		*frame=(((*frame^255)*(*frame^255))/255)^255;
		frame++;
	}
}

static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data)
{
	struct se401_frame *frame=&se401->frame[se401->curframe];
	int linelength=se401->cwidth*3;

	if (frame->curlinepix >= linelength) {
		frame->curlinepix=0;
		frame->curline+=linelength;
	}

	/* First three are absolute, all others relative.
	 * Format is rgb from right to left (mirrorred image), 
	 * we flip it to get bgr from left to right. */
	if (frame->curlinepix < 3) {
		*(frame->curline-frame->curlinepix)=1+data*4;
	} else {
		*(frame->curline-frame->curlinepix)=
		    *(frame->curline-frame->curlinepix+3)+data*4;
	}
	frame->curlinepix++;
}

static inline void decode_JangGu_vlc (struct usb_se401 *se401, unsigned char *data, int bit_exp, int packetlength)
{
	int pos=0;
	int vlc_cod=0;
	int vlc_size=0;
	int vlc_data=0;
	int bit_cur;
	int bit;
	data+=4;
	while (pos < packetlength) {
		bit_cur=8;
		while (bit_cur && bit_exp) {
			bit=((*data)>>(bit_cur-1))&1;
			if (!vlc_cod) {
				if (bit) {
					vlc_size++;
				} else {
					if (!vlc_size) {
						decode_JangGu_integrate(se401, 0);
					} else {
						vlc_cod=2;
						vlc_data=0;
					}
				}
			} else {
				if (vlc_cod==2) {
					if (!bit)
						vlc_data =  -(1<<vlc_size) + 1;
					vlc_cod--;
				}
				vlc_size--;
				vlc_data+=bit<<vlc_size;
				if (!vlc_size) {
					decode_JangGu_integrate(se401, vlc_data);
					vlc_cod=0;
				}
			}
			bit_cur--;
			bit_exp--;
		}
		pos++;
		data++;
	}
}

static inline void decode_JangGu (struct usb_se401 *se401, struct se401_scratch *buffer)
{
	unsigned char *data=buffer->data;
	int len=buffer->length;
	int bit_exp=0, pix_exp=0, frameinfo=0, packetlength=0, size;
	int datapos=0;

	/* New image? */
	if (!se401->frame[se401->curframe].curpix) {
		se401->frame[se401->curframe].curlinepix=0;
		se401->frame[se401->curframe].curline=
		    se401->frame[se401->curframe].data+
		    se401->cwidth*3-1;
		if (se401->frame[se401->curframe].grabstate==FRAME_READY)
			se401->frame[se401->curframe].grabstate=FRAME_GRABBING;
		se401->vlcdatapos=0;
	}
	while (datapos < len) {
		size=1024-se401->vlcdatapos;
		if (size+datapos > len)
			size=len-datapos;
		memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size);
		se401->vlcdatapos+=size;
		packetlength=0;
		if (se401->vlcdatapos >= 4) {
			bit_exp=se401->vlcdata[3]+(se401->vlcdata[2]<<8);
			pix_exp=se401->vlcdata[1]+((se401->vlcdata[0]&0x3f)<<8);
			frameinfo=se401->vlcdata[0]&0xc0;
			packetlength=((bit_exp+47)>>4)<<1;
			if (packetlength > 1024) {
				se401->vlcdatapos=0;
				datapos=len;
				packetlength=0;
				se401->error++;
				se401->frame[se401->curframe].curpix=0;
			}
		}
		if (packetlength && se401->vlcdatapos >= packetlength) {
			decode_JangGu_vlc(se401, se401->vlcdata, bit_exp, packetlength);
			se401->frame[se401->curframe].curpix+=pix_exp*3;
			datapos+=size-(se401->vlcdatapos-packetlength);
			se401->vlcdatapos=0;
			if (se401->frame[se401->curframe].curpix>=se401->cwidth*se401->cheight*3) {
				if (se401->frame[se401->curframe].curpix==se401->cwidth*se401->cheight*3) {
					if (se401->frame[se401->curframe].grabstate==FRAME_GRABBING) {
						se401->frame[se401->curframe].grabstate=FRAME_DONE;
						se401->framecount++;
						se401->readcount++;
					}
					if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
						se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
					}
				} else {
					se401->error++;
				}
				se401->frame[se401->curframe].curpix=0;
				datapos=len;
			}
		} else {
			datapos+=size;
		}
	}
}

static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch *buffer)
{
	unsigned char *data=buffer->data;
	int len=buffer->length;
	int offset=buffer->offset;
	int datasize=se401->cwidth*se401->cheight;
	struct se401_frame *frame=&se401->frame[se401->curframe];

	unsigned char *framedata=frame->data, *curline, *nextline;
	int width=se401->cwidth;
	int blineoffset=0, bline;
	int linelength=width*3, i;
	

	if (frame->curpix==0) {
		if (frame->grabstate==FRAME_READY) {
			frame->grabstate=FRAME_GRABBING;
		}
		frame->curline=framedata+linelength;
		frame->curlinepix=0;
	}

	if (offset!=frame->curpix) {
		/* Regard frame as lost :( */
		frame->curpix=0;
		se401->error++;
		return;
	}

	/* Check if we have to much data */
	if (frame->curpix+len > datasize) {
		len=datasize-frame->curpix;
	}
	if (se401->cheight%4)
		blineoffset=1;
	bline=frame->curpix/se401->cwidth+blineoffset;

	curline=frame->curline;
	nextline=curline+linelength;
	if (nextline >= framedata+datasize*3)
		nextline=curline;
	while (len) {
		if (frame->curlinepix>=width) {
			frame->curlinepix-=width;
			bline=frame->curpix/width+blineoffset;
			curline+=linelength*2;
			nextline+=linelength*2;
			if (curline >= framedata+datasize*3) {
				frame->curlinepix++;
				curline-=3;
				nextline-=3;
				len--;
				data++;
				frame->curpix++;
			}
			if (nextline >= framedata+datasize*3)
				nextline=curline;
		}
		if ((bline&1)) {
			if ((frame->curlinepix&1)) {
				*(curline+2)=*data;
				*(curline-1)=*data;
				*(nextline+2)=*data;
				*(nextline-1)=*data;
			} else {
				*(curline+1)=
					(*(curline+1)+*data)/2;
				*(curline-2)=
					(*(curline-2)+*data)/2;
				*(nextline+1)=*data;
				*(nextline-2)=*data;
			}
		} else {
			if ((frame->curlinepix&1)) {
				*(curline+1)=
					(*(curline+1)+*data)/2;
				*(curline-2)=
					(*(curline-2)+*data)/2;
				*(nextline+1)=*data;
				*(nextline-2)=*data;
			} else {
				*curline=*data;
				*(curline-3)=*data;
				*nextline=*data;
				*(nextline-3)=*data;
			}
		}
		frame->curlinepix++;
		curline-=3;
		nextline-=3;
		len--;
		data++;
		frame->curpix++;
	}
	frame->curline=curline;

	if (frame->curpix>=datasize) {
		/* Fix the top line */
		framedata+=linelength;
		for (i=0; i<linelength; i++) {
			framedata--;
			*framedata=*(framedata+linelength);
		}
		/* Fix the left side (green is already present) */
		for (i=0; i<se401->cheight; i++) {
			*framedata=*(framedata+3);
			*(framedata+1)=*(framedata+4);
			*(framedata+2)=*(framedata+5);
			framedata+=linelength;
		}
		frame->curpix=0;
		frame->grabstate=FRAME_DONE;
		se401->framecount++;
		se401->readcount++;
		if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
			se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
		}
	}
}

static int se401_newframe(struct usb_se401 *se401, int framenr)
{
	DECLARE_WAITQUEUE(wait, current);
	int errors=0;

	while (se401->streaming &&
	    (se401->frame[framenr].grabstate==FRAME_READY ||
	     se401->frame[framenr].grabstate==FRAME_GRABBING) ) {
		if(!se401->frame[framenr].curpix) {
			errors++;
		}
		wait_interruptible(
		    se401->scratch[se401->scratch_use].state!=BUFFER_READY,
		    &se401->wq,
		    &wait
		);
		if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
			se401->nullpackets=0;
			info("to many null length packets, restarting capture");
			se401_stop_stream(se401);
			se401_start_stream(se401);			
		} else {
			if (se401->scratch[se401->scratch_use].state!=BUFFER_READY) {
				se401->frame[framenr].grabstate=FRAME_ERROR;
				return -EIO;
			}
			se401->scratch[se401->scratch_use].state=BUFFER_BUSY;
			if (se401->format==FMT_JANGGU) {
				decode_JangGu(se401, &se401->scratch[se401->scratch_use]);
			} else {
				decode_bayer(se401, &se401->scratch[se401->scratch_use]);
			}
			se401->scratch[se401->scratch_use].state=BUFFER_UNUSED;
			se401->scratch_use++;
			if (se401->scratch_use>=SE401_NUMSCRATCH)
				se401->scratch_use=0;
			if (errors > SE401_MAX_ERRORS) {
				errors=0;
				info("to much errors, restarting capture");
				se401_stop_stream(se401);
				se401_start_stream(se401);
			}
		}
	}

	if (se401->frame[framenr].grabstate==FRAME_DONE)
		if (se401->enhance)
			enhance_picture(se401->frame[framenr].data, se401->cheight*se401->cwidth*3);
	return 0;
}

static void usb_se401_remove_disconnected (struct usb_se401 *se401)
{
	int i;

        se401->dev = NULL;

	for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
		usb_kill_urb(se401->urb[i]);
		usb_free_urb(se401->urb[i]);
		se401->urb[i] = NULL;
		kfree(se401->sbuf[i].data);
	}
	for (i=0; i<SE401_NUMSCRATCH; i++) if (se401->scratch[i].data) {
		kfree(se401->scratch[i].data);
	}
	if (se401->inturb) {
		usb_kill_urb(se401->inturb);
		usb_free_urb(se401->inturb);
	}
        info("%s disconnected", se401->camera_name);

        /* Free the memory */
	kfree(se401->width);
	kfree(se401->height);
	kfree(se401);
}



/****************************************************************************
 *
 * Video4Linux
 *
 ***************************************************************************/


static int se401_open(struct inode *inode, struct file *file)
{
	struct video_device *dev = video_devdata(file);
	struct usb_se401 *se401 = (struct usb_se401 *)dev;
	int err = 0;

	if (se401->user)
		return -EBUSY;
	se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES);
	if (se401->fbuf)
		file->private_data = dev;
	else 
		err = -ENOMEM;
	se401->user = !err;

	return err;
}

static int se401_close(struct inode *inode, struct file *file)
{
	struct video_device *dev = file->private_data;
        struct usb_se401 *se401 = (struct usb_se401 *)dev;
	int i;

	rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES);
        if (se401->removed) {
		usb_se401_remove_disconnected(se401);
		info("device unregistered");
	} else {
		for (i=0; i<SE401_NUMFRAMES; i++)
			se401->frame[i].grabstate=FRAME_UNUSED;
		if (se401->streaming)
			se401_stop_stream(se401);
		se401->user=0;
	}
	file->private_data = NULL;
	return 0;
}

static int se401_do_ioctl(struct inode *inode, struct file *file,
			  unsigned int cmd, void *arg)
{
	struct video_device *vdev = file->private_data;
        struct usb_se401 *se401 = (struct usb_se401 *)vdev;

        if (!se401->dev)
                return -EIO;

        switch (cmd) {
	case VIDIOCGCAP:
	{
		struct video_capability *b = arg;
		strcpy(b->name, se401->camera_name);
		b->type = VID_TYPE_CAPTURE;
		b->channels = 1;
		b->audios = 0;
		b->maxwidth = se401->width[se401->sizes-1];
		b->maxheight = se401->height[se401->sizes-1];
		b->minwidth = se401->width[0];
		b->minheight = se401->height[0];
		return 0;
	}
	case VIDIOCGCHAN:
	{
		struct video_channel *v = arg;

		if (v->channel != 0)
			return -EINVAL;
		v->flags = 0;
		v->tuners = 0;
		v->type = VIDEO_TYPE_CAMERA;
		strcpy(v->name, "Camera");
		return 0;
	}
	case VIDIOCSCHAN:
	{
		struct video_channel *v = arg;

		if (v->channel != 0)
			return -EINVAL;
		return 0;
	}
        case VIDIOCGPICT:
        {
		struct video_picture *p = arg;

		se401_get_pict(se401, p);
		return 0;
	}
	case VIDIOCSPICT:
	{
		struct video_picture *p = arg;

		if (se401_set_pict(se401, p))
			return -EINVAL;
		return 0;
	}
	case VIDIOCSWIN:
	{
		struct video_window *vw = arg;

		if (vw->flags)
			return -EINVAL;
		if (vw->clipcount)
			return -EINVAL;
		if (se401_set_size(se401, vw->width, vw->height))
			return -EINVAL;
		return 0;
        }
	case VIDIOCGWIN:
	{
		struct video_window *vw = arg;

		vw->x = 0;               /* FIXME */
		vw->y = 0;
		vw->chromakey = 0;
		vw->flags = 0;
		vw->clipcount = 0;
		vw->width = se401->cwidth;
		vw->height = se401->cheight;
		return 0;
	}
	case VIDIOCGMBUF:
	{
		struct video_mbuf *vm = arg;
		int i;

		memset(vm, 0, sizeof(*vm));
		vm->size = SE401_NUMFRAMES * se401->maxframesize;
		vm->frames = SE401_NUMFRAMES;
		for (i=0; i<SE401_NUMFRAMES; i++)
			vm->offsets[i] = se401->maxframesize * i;
		return 0;
	}
	case VIDIOCMCAPTURE:
	{
		struct video_mmap *vm = arg;

		if (vm->format != VIDEO_PALETTE_RGB24)
			return -EINVAL;
		if (vm->frame >= SE401_NUMFRAMES)
			return -EINVAL;
		if (se401->frame[vm->frame].grabstate != FRAME_UNUSED)
			return -EBUSY;

		/* Is this according to the v4l spec??? */
		if (se401_set_size(se401, vm->width, vm->height))
			return -EINVAL;
		se401->frame[vm->frame].grabstate=FRAME_READY;

		if (!se401->streaming)
			se401_start_stream(se401);

		/* Set the picture properties */
		if (se401->framecount==0)
			se401_send_pict(se401);
		/* Calibrate the reset level after a few frames. */
		if (se401->framecount%20==1)
			se401_auto_resetlevel(se401);

		return 0;
	}
	case VIDIOCSYNC:
	{
		int *frame = arg;
		int ret=0;

		if(*frame <0 || *frame >= SE401_NUMFRAMES)
			return -EINVAL;

		ret=se401_newframe(se401, *frame);
		se401->frame[*frame].grabstate=FRAME_UNUSED;
		return ret;
	}
	case VIDIOCGFBUF:
	{
		struct video_buffer *vb = arg;

		memset(vb, 0, sizeof(*vb));
		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;
        } /* end switch */

        return 0;
}

static int se401_ioctl(struct inode *inode, struct file *file,
		       unsigned int cmd, unsigned long arg)
{
	return video_usercopy(inode, file, cmd, arg, se401_do_ioctl);
}

static ssize_t se401_read(struct file *file, char __user *buf,
		     size_t count, loff_t *ppos)
{
	int realcount=count, ret=0;
	struct video_device *dev = file->private_data;
	struct usb_se401 *se401 = (struct usb_se401 *)dev;


	if (se401->dev == NULL)
		return -EIO;
	if (realcount > se401->cwidth*se401->cheight*3)
		realcount=se401->cwidth*se401->cheight*3;

	/* Shouldn't happen: */
	if (se401->frame[0].grabstate==FRAME_GRABBING)
		return -EBUSY;
	se401->frame[0].grabstate=FRAME_READY;
	se401->frame[1].grabstate=FRAME_UNUSED;
	se401->curframe=0;

	if (!se401->streaming)
		se401_start_stream(se401);

	/* Set the picture properties */
	if (se401->framecount==0)
		se401_send_pict(se401);
	/* Calibrate the reset level after a few frames. */
	if (se401->framecount%20==1)
		se401_auto_resetlevel(se401);

	ret=se401_newframe(se401, 0);

	se401->frame[0].grabstate=FRAME_UNUSED;
	if (ret)
		return ret;	
	if (copy_to_user(buf, se401->frame[0].data, realcount))
		return -EFAULT;

	return realcount;
}

static int se401_mmap(struct file *file, struct vm_area_struct *vma)
{
	struct video_device *dev = file->private_data;
	struct usb_se401 *se401 = (struct usb_se401 *)dev;
	unsigned long start = vma->vm_start;
	unsigned long size  = vma->vm_end-vma->vm_start;
	unsigned long page, pos;

	down(&se401->lock);

	if (se401->dev == NULL) {
		up(&se401->lock);
		return -EIO;
	}
	if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) {
		up(&se401->lock);
		return -EINVAL;
	}
	pos = (unsigned long)se401->fbuf;
	while (size > 0) {
		page = vmalloc_to_pfn((void *)pos);
		if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
			up(&se401->lock);
			return -EAGAIN;
		}
		start += PAGE_SIZE;
		pos += PAGE_SIZE;
		if (size > PAGE_SIZE)
			size -= PAGE_SIZE;
		else
			size = 0;
	}
	up(&se401->lock);

        return 0;
}

static struct file_operations se401_fops = {
	.owner =	THIS_MODULE,
        .open =         se401_open,
        .release =      se401_close,
        .read =         se401_read,
        .mmap =         se401_mmap,
	.ioctl =        se401_ioctl,
	.llseek =       no_llseek,
};
static struct video_device se401_template = {
	.owner =	THIS_MODULE,
        .name =         "se401 USB camera",
        .type =         VID_TYPE_CAPTURE,
        .hardware =     VID_HARDWARE_SE401,
	.fops =         &se401_fops,
};



/***************************/
static int se401_init(struct usb_se401 *se401, int button)
{
        int i=0, rc;
        unsigned char cp[0x40];
	char temp[200];

	/* led on */
        se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);

	/* get camera descriptor */
	rc=se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, cp, sizeof(cp));
	if (cp[1]!=0x41) {
		err("Wrong descriptor type");
		return 1;
	}
	sprintf (temp, "ExtraFeatures: %d", cp[3]);

	se401->sizes=cp[4]+cp[5]*256;
	se401->width=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
	if (!se401->width)
		return 1;
	se401->height=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
	if (!se401->height) {
		kfree(se401->width);
		return 1;
	}
	for (i=0; i<se401->sizes; i++) {
		    se401->width[i]=cp[6+i*4+0]+cp[6+i*4+1]*256;
		    se401->height[i]=cp[6+i*4+2]+cp[6+i*4+3]*256;
	}
	sprintf (temp, "%s Sizes:", temp);
	for (i=0; i<se401->sizes; i++) {
		sprintf(temp, "%s %dx%d", temp, se401->width[i], se401->height[i]);
	}
	info("%s", temp);
	se401->maxframesize=se401->width[se401->sizes-1]*se401->height[se401->sizes-1]*3;

	rc=se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp));
	se401->cwidth=cp[0]+cp[1]*256;
	rc=se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp));
	se401->cheight=cp[0]+cp[1]*256;

	if (!cp[2] && SE401_FORMAT_BAYER) {
		err("Bayer format not supported!");
		return 1;
	}
	/* set output mode (BAYER) */
        se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, SE401_FORMAT_BAYER, NULL, 0);

	rc=se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp));
	se401->brightness=cp[0]+cp[1]*256;
	/* some default values */
	se401->resetlevel=0x2d;
	se401->rgain=0x20;
	se401->ggain=0x20;
	se401->bgain=0x20;
	se401_set_exposure(se401, 20000);
	se401->palette=VIDEO_PALETTE_RGB24;
	se401->enhance=1;
	se401->dropped=0;
	se401->error=0;
	se401->framecount=0;
	se401->readcount=0;

	/* Start interrupt transfers for snapshot button */
	if (button) {
		se401->inturb=usb_alloc_urb(0, GFP_KERNEL);
		if (!se401->inturb) {
			info("Allocation of inturb failed");
			return 1;
		}
		usb_fill_int_urb(se401->inturb, se401->dev,
		    usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT),
		    &se401->button, sizeof(se401->button),
		    se401_button_irq,
		    se401,
		    8
		);
		if (usb_submit_urb(se401->inturb, GFP_KERNEL)) {
			info("int urb burned down");
			return 1;
		}
	} else
		se401->inturb=NULL;

        /* Flash the led */
        se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
        se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
        se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
	se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);

        return 0;
}

static int se401_probe(struct usb_interface *intf,
	const struct usb_device_id *id)
{
	struct usb_device *dev = interface_to_usbdev(intf);
        struct usb_interface_descriptor *interface;
        struct usb_se401 *se401;
        char *camera_name=NULL;
	int button=1;

        /* We don't handle multi-config cameras */
        if (dev->descriptor.bNumConfigurations != 1)
                return -ENODEV;

        interface = &intf->cur_altsetting->desc;

        /* Is it an se401? */
        if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 &&
            le16_to_cpu(dev->descriptor.idProduct) == 0x0004) {
                camera_name="Endpoints/Aox SE401";
        } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 &&
            le16_to_cpu(dev->descriptor.idProduct) == 0x030b) {
                camera_name="Philips PCVC665K";
        } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
	    le16_to_cpu(dev->descriptor.idProduct) == 0x5001) {
		camera_name="Kensington VideoCAM 67014";
        } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
	    le16_to_cpu(dev->descriptor.idProduct) == 0x5002) {
		camera_name="Kensington VideoCAM 6701(5/7)";
        } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
	    le16_to_cpu(dev->descriptor.idProduct) == 0x5003) {
		camera_name="Kensington VideoCAM 67016";
		button=0;
	} else
		return -ENODEV;

        /* Checking vendor/product should be enough, but what the hell */
        if (interface->bInterfaceClass != 0x00)
		return -ENODEV;
        if (interface->bInterfaceSubClass != 0x00)
		return -ENODEV;

        /* We found one */
        info("SE401 camera found: %s", camera_name);

        if ((se401 = kmalloc(sizeof(*se401), GFP_KERNEL)) == NULL) {
                err("couldn't kmalloc se401 struct");
		return -ENOMEM;
        }

        memset(se401, 0, sizeof(*se401));

        se401->dev = dev;
        se401->iface = interface->bInterfaceNumber;
        se401->camera_name = camera_name;

	info("firmware version: %02x", le16_to_cpu(dev->descriptor.bcdDevice) & 255);

        if (se401_init(se401, button)) {
		kfree(se401);
		return -EIO;
	}

	memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
	memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name));
	init_waitqueue_head(&se401->wq);
	init_MUTEX(&se401->lock);
	wmb();

	if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
		kfree(se401);
		err("video_register_device failed");
		return -EIO;
	}
	info("registered new video device: video%d", se401->vdev.minor);

	usb_set_intfdata (intf, se401);
        return 0;
}

static void se401_disconnect(struct usb_interface *intf)
{
	struct usb_se401 *se401 = usb_get_intfdata (intf);

	usb_set_intfdata (intf, NULL);
	if (se401) {
		video_unregister_device(&se401->vdev);
		if (!se401->user){
			usb_se401_remove_disconnected(se401);
		} else {
			se401->frame[0].grabstate = FRAME_ERROR;
			se401->frame[0].grabstate = FRAME_ERROR;

			se401->streaming = 0;

			wake_up_interruptible(&se401->wq);
			se401->removed = 1;
		}
	}
}

static struct usb_driver se401_driver = {
	.owner		= THIS_MODULE,
        .name		= "se401",
        .id_table	= device_table,
	.probe		= se401_probe,
        .disconnect	= se401_disconnect,
};



/****************************************************************************
 *
 *  Module routines
 *
 ***************************************************************************/

static int __init usb_se401_init(void)
{
	info("SE401 usb camera driver version %s registering", version);
	if (flickerless)
		if (flickerless!=50 && flickerless!=60) {
			info("Invallid flickerless value, use 0, 50 or 60.");
			return -1;
	}
	return usb_register(&se401_driver);
}

static void __exit usb_se401_exit(void)
{
	usb_deregister(&se401_driver);
	info("SE401 driver deregistered");
}

module_init(usb_se401_init);
module_exit(usb_se401_exit);
