1/*
2 * Endpoints (formerly known as AOX) se401 USB Camera Driver
3 *
4 * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org)
5 *
6 * Still somewhat based on the Linux ov511 driver.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 * for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 *
23 * Thanks to Endpoints Inc. (www.endpoints.com) for making documentation on
24 * their chipset available and supporting me while writing this driver.
25 * 	- Jeroen Vreeken
26 */
27
28static const char version[] = "0.23";
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/version.h>
33#include <linux/init.h>
34#include <linux/fs.h>
35#include <linux/vmalloc.h>
36#include <linux/slab.h>
37#include <linux/proc_fs.h>
38#include <linux/pagemap.h>
39#include <linux/usb.h>
40#include <asm/io.h>
41#include <asm/semaphore.h>
42#include <linux/wrapper.h>
43
44#include "se401.h"
45
46static int flickerless=0;
47static int video_nr = -1;
48
49static struct usb_device_id device_table [] = {
50	{ USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */
51	{ USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */
52	{ USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */
53	{ USB_DEVICE(0x047d, 0x5002) },/* Kensington 6701(5/7) */
54	{ USB_DEVICE(0x047d, 0x5003) },/* Kensington 67016 */
55	{ }
56};
57
58MODULE_DEVICE_TABLE(usb, device_table);
59
60MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>");
61MODULE_DESCRIPTION("SE401 USB Camera Driver");
62MODULE_LICENSE("GPL");
63MODULE_PARM(flickerless, "i");
64MODULE_PARM_DESC(flickerless, "Net frequency to adjust exposure time to (0/50/60)");
65MODULE_PARM(video_nr, "i");
66EXPORT_NO_SYMBOLS;
67
68
69static struct usb_driver se401_driver;
70
71
72/**********************************************************************
73 *
74 * Memory management
75 *
76 **********************************************************************/
77
78/* Here we want the physical address of the memory.
79 * This is used when initializing the contents of the area.
80 */
81static inline unsigned long kvirt_to_pa(unsigned long adr)
82{
83	unsigned long kva, ret;
84
85	kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
86	kva |= adr & (PAGE_SIZE-1); /* restore the offset */
87	ret = __pa(kva);
88	return ret;
89}
90
91static void *rvmalloc(unsigned long size)
92{
93	void *mem;
94	unsigned long adr;
95
96	size = PAGE_ALIGN(size);
97	mem = vmalloc_32(size);
98	if (!mem)
99		return NULL;
100
101	memset(mem, 0, size); /* Clear the ram out, no junk to the user */
102	adr = (unsigned long) mem;
103	while (size > 0) {
104		mem_map_reserve(vmalloc_to_page((void *)adr));
105		adr += PAGE_SIZE;
106		size -= PAGE_SIZE;
107	}
108
109	return mem;
110}
111
112static void rvfree(void *mem, unsigned long size)
113{
114	unsigned long adr;
115
116	if (!mem)
117		return;
118
119	adr = (unsigned long) mem;
120	while ((long) size > 0) {
121		mem_map_unreserve(vmalloc_to_page((void *)adr));
122		adr += PAGE_SIZE;
123		size -= PAGE_SIZE;
124	}
125	vfree(mem);
126}
127
128
129
130/****************************************************************************
131 *
132 * /proc interface
133 *
134 ***************************************************************************/
135
136#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
137
138static struct proc_dir_entry *se401_proc_entry = NULL;
139extern struct proc_dir_entry *video_proc_entry;
140
141#define YES_NO(x) ((x) ? "yes" : "no")
142
143static int se401_read_proc(char *page, char **start, off_t off, int count,
144			   int *eof, void *data)
145{
146	char *out = page;
147	int i, len;
148	struct usb_se401 *se401 = data;
149
150	/* Stay under PAGE_SIZE or else bla bla bla.... */
151
152	out+=sprintf(out, "driver_version  : %s\n", version);
153	out+=sprintf(out, "model           : %s\n", se401->camera_name);
154	out+=sprintf(out, "in use          : %s\n", YES_NO (se401->user));
155	out+=sprintf(out, "streaming       : %s\n", YES_NO (se401->streaming));
156	out+=sprintf(out, "button state    : %s\n", YES_NO (se401->button));
157	out+=sprintf(out, "button pressed  : %s\n", YES_NO (se401->buttonpressed));
158	out+=sprintf(out, "num_frames      : %d\n", SE401_NUMFRAMES);
159
160	out+=sprintf(out, "Sizes           :");
161	for (i=0; i<se401->sizes; i++) {
162		out+=sprintf(out, " %dx%d", se401->width[i],
163		    se401->height[i]);
164	}
165	out+=sprintf(out, "\n");
166
167	out+=sprintf(out, "Frames total    : %d\n", se401->readcount);
168	out+=sprintf(out, "Frames read     : %d\n", se401->framecount);
169	out+=sprintf(out, "Packets dropped : %d\n", se401->dropped);
170	out+=sprintf(out, "Decoding Errors : %d\n", se401->error);
171
172	len = out - page;
173	len -= off;
174	if (len < count) {
175		*eof = 1;
176			if (len <= 0) return 0;
177	} else
178		len = count;
179
180	*start = page + off;
181
182	return len;
183}
184
185static int se401_write_proc(struct file *file, const char *buffer,
186			    unsigned long count, void *data)
187{
188	return -EINVAL;
189}
190
191static void create_proc_se401_cam (struct usb_se401 *se401)
192{
193	char name[7];
194	struct proc_dir_entry *ent;
195
196	if (!se401_proc_entry || !se401)
197		return;
198
199	sprintf (name, "video%d", se401->vdev.minor);
200
201	ent = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR,
202				se401_proc_entry);
203
204	if (!ent)
205		return;
206
207	ent->data = se401;
208	ent->read_proc = se401_read_proc;
209	ent->write_proc = se401_write_proc;
210	se401->proc_entry = ent;
211}
212
213static void destroy_proc_se401_cam (struct usb_se401 *se401)
214{
215	/* One to much, just to be sure :) */
216	char name[9];
217
218	if (!se401 || !se401->proc_entry)
219		return;
220
221	sprintf(name, "video%d", se401->vdev.minor);
222	remove_proc_entry(name, se401_proc_entry);
223	se401->proc_entry = NULL;
224}
225
226static void proc_se401_create (void)
227{
228	if (video_proc_entry == NULL) {
229		err("/proc/video/ doesn't exist");
230		return;
231	}
232
233	se401_proc_entry=create_proc_entry("se401", S_IFDIR, video_proc_entry);
234
235	if (se401_proc_entry)
236		se401_proc_entry->owner = THIS_MODULE;
237	else
238		err("Unable to initialize /proc/video/se401");
239}
240
241static void proc_se401_destroy(void)
242{
243	if (se401_proc_entry == NULL)
244		return;
245
246	remove_proc_entry("se401", video_proc_entry);
247}
248#endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */
249
250
251/****************************************************************************
252 *
253 * se401 register read/write functions
254 *
255 ***************************************************************************/
256
257static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req,
258			 unsigned short value, unsigned char *cp, int size)
259{
260	return usb_control_msg (
261                se401->dev,
262                set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0),
263                req,
264                (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
265                value,
266                0,
267                cp,
268                size,
269                HZ
270        );
271}
272
273static int se401_set_feature(struct usb_se401 *se401, unsigned short selector,
274			     unsigned short param)
275{
276	/* specs say that the selector (address) should go in the value field
277	   and the param in index, but in the logs of the windows driver they do
278	   this the other way around...
279	 */
280	return usb_control_msg (
281		se401->dev,
282		usb_sndctrlpipe(se401->dev, 0),
283		SE401_REQ_SET_EXT_FEATURE,
284		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
285		param,
286		selector,
287                NULL,
288                0,
289                HZ
290        );
291}
292
293static unsigned short se401_get_feature(struct usb_se401 *se401,
294				        unsigned short selector)
295{
296	/* For 'set' the selecetor should be in index, not sure if the spec is
297	   wrong here to....
298	 */
299	unsigned char cp[2];
300        usb_control_msg (
301                se401->dev,
302                usb_rcvctrlpipe(se401->dev, 0),
303                SE401_REQ_GET_EXT_FEATURE,
304                USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
305        	0,
306                selector,
307                cp,
308                2,
309                HZ
310        );
311	return cp[0]+cp[1]*256;
312}
313
314/****************************************************************************
315 *
316 * Camera control
317 *
318 ***************************************************************************/
319
320
321static int se401_send_pict(struct usb_se401 *se401)
322{
323	se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l);/* integration time low */
324	se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m);/* integration time mid */
325	se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h);/* integration time mid */
326	se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);/* reset level value */
327	se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);/* red color gain */
328	se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);/* green color gain */
329	se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);/* blue color gain */
330
331	return 0;
332}
333
334static void se401_set_exposure(struct usb_se401 *se401, int brightness)
335{
336	int integration=brightness<<5;
337
338	if (flickerless==50) {
339		integration=integration-integration%106667;
340	}
341	if (flickerless==60) {
342		integration=integration-integration%88889;
343	}
344	se401->brightness=integration>>5;
345	se401->expose_h=(integration>>16)&0xff;
346	se401->expose_m=(integration>>8)&0xff;
347	se401->expose_l=integration&0xff;
348}
349
350static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p)
351{
352	p->brightness=se401->brightness;
353	if (se401->enhance) {
354		p->whiteness=32768;
355	} else {
356		p->whiteness=0;
357	}
358	p->colour=65535;
359	p->contrast=65535;
360	p->hue=se401->rgain<<10;
361	p->palette=se401->palette;
362	p->depth=3; /* rgb24 */
363	return 0;
364}
365
366
367static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p)
368{
369	if (p->palette != VIDEO_PALETTE_RGB24)
370		return 1;
371	se401->palette=p->palette;
372	if (p->hue!=se401->hue) {
373		se401->rgain= p->hue>>10;
374		se401->bgain= 0x40-(p->hue>>10);
375		se401->hue=p->hue;
376	}
377	if (p->brightness!=se401->brightness) {
378		se401_set_exposure(se401, p->brightness);
379	}
380	if (p->whiteness>=32768) {
381		se401->enhance=1;
382	} else {
383		se401->enhance=0;
384	}
385	se401_send_pict(se401);
386	se401_send_pict(se401);
387	return 0;
388}
389
390/*
391	Hyundai have some really nice docs about this and other sensor related
392	stuff on their homepage: www.hei.co.kr
393*/
394static void se401_auto_resetlevel(struct usb_se401 *se401)
395{
396	unsigned int ahrc, alrc;
397	int oldreset=se401->resetlevel;
398
399	/* For some reason this normally read-only register doesn't get reset
400	   to zero after reading them just once...
401	 */
402	se401_get_feature(se401, HV7131_REG_HIREFNOH);
403	se401_get_feature(se401, HV7131_REG_HIREFNOL);
404	se401_get_feature(se401, HV7131_REG_LOREFNOH);
405	se401_get_feature(se401, HV7131_REG_LOREFNOL);
406	ahrc=256*se401_get_feature(se401, HV7131_REG_HIREFNOH) +
407	    se401_get_feature(se401, HV7131_REG_HIREFNOL);
408	alrc=256*se401_get_feature(se401, HV7131_REG_LOREFNOH) +
409	    se401_get_feature(se401, HV7131_REG_LOREFNOL);
410
411	/* Not an exact science, but it seems to work pretty well... */
412	if (alrc > 10) {
413		while (alrc>=10 && se401->resetlevel < 63) {
414			se401->resetlevel++;
415			alrc /=2;
416		}
417	} else if (ahrc > 20) {
418		while (ahrc>=20 && se401->resetlevel > 0) {
419			se401->resetlevel--;
420			ahrc /=2;
421		}
422	}
423	if (se401->resetlevel!=oldreset)
424		se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
425
426	return;
427}
428
429/* irq handler for snapshot button */
430static void se401_button_irq(struct urb *urb)
431{
432	struct usb_se401 *se401 = urb->context;
433
434	if (!se401->dev) {
435		info("ohoh: device vapourished");
436		return;
437	}
438
439	if (urb->actual_length >=2 && !urb->status) {
440		if (se401->button)
441			se401->buttonpressed=1;
442	}
443}
444
445static void se401_video_irq(struct urb *urb)
446{
447	struct usb_se401 *se401 = urb->context;
448	int length = urb->actual_length;
449
450	/* ohoh... */
451	if (!se401->streaming)
452		return;
453
454	if (!se401->dev) {
455		info ("ohoh: device vapourished");
456		return;
457	}
458
459	/* 0 sized packets happen if we are to fast, but sometimes the camera
460	   keeps sending them forever...
461	 */
462	if (length && !urb->status) {
463		se401->nullpackets=0;
464		switch(se401->scratch[se401->scratch_next].state) {
465			case BUFFER_READY:
466			case BUFFER_BUSY: {
467				se401->dropped++;
468				break;
469			}
470			case BUFFER_UNUSED: {
471				memcpy(se401->scratch[se401->scratch_next].data, (unsigned char *)urb->transfer_buffer, length);
472				se401->scratch[se401->scratch_next].state=BUFFER_READY;
473				se401->scratch[se401->scratch_next].offset=se401->bayeroffset;
474				se401->scratch[se401->scratch_next].length=length;
475				if (waitqueue_active(&se401->wq)) {
476					wake_up_interruptible(&se401->wq);
477				}
478				se401->scratch_overflow=0;
479				se401->scratch_next++;
480				if (se401->scratch_next>=SE401_NUMSCRATCH)
481					se401->scratch_next=0;;
482				break;
483			}
484		}
485		se401->bayeroffset+=length;
486		if (se401->bayeroffset>=se401->cheight*se401->cwidth) {
487			se401->bayeroffset=0;
488		}
489	} else {
490		se401->nullpackets++;
491		if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
492			if (waitqueue_active(&se401->wq)) {
493				wake_up_interruptible(&se401->wq);
494			}
495		}
496	}
497
498	/* Resubmit urb for new data */
499	urb->status=0;
500	urb->dev=se401->dev;
501	if(usb_submit_urb(urb))
502		info("urb burned down");
503	return;
504}
505
506static void se401_send_size(struct usb_se401 *se401, int width, int height)
507{
508	int i=0;
509	int mode=0x03; /* No compression */
510	int sendheight=height;
511	int sendwidth=width;
512
513	/* JangGu compression can only be used with the camera supported sizes,
514	   but bayer seems to work with any size that fits on the sensor.
515	   We check if we can use compression with the current size with either
516	   4 or 16 times subcapturing, if not we use uncompressed bayer data
517	   but this will result in cutouts of the maximum size....
518	 */
519	while (i<se401->sizes && !(se401->width[i]==width && se401->height[i]==height))
520		i++;
521	while (i<se401->sizes) {
522		if (se401->width[i]==width*2 && se401->height[i]==height*2) {
523			sendheight=se401->height[i];
524			sendwidth=se401->width[i];
525			mode=0x40;
526		}
527		if (se401->width[i]==width*4 && se401->height[i]==height*4) {
528			sendheight=se401->height[i];
529			sendwidth=se401->width[i];
530			mode=0x42;
531		}
532		i++;
533	}
534
535	se401_sndctrl(1, se401, SE401_REQ_SET_WIDTH, sendwidth, NULL, 0);
536	se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0);
537	se401_set_feature(se401, SE401_OPERATINGMODE, mode);
538
539	if (mode==0x03) {
540		se401->format=FMT_BAYER;
541	} else {
542		se401->format=FMT_JANGGU;
543	}
544
545	return;
546}
547
548/*
549	In this function se401_send_pict is called several times,
550	for some reason (depending on the state of the sensor and the phase of
551	the moon :) doing this only in either place doesn't always work...
552*/
553static int se401_start_stream(struct usb_se401 *se401)
554{
555	struct urb *urb;
556	int err=0, i;
557	se401->streaming=1;
558
559        se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
560        se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
561
562	/* Set picture settings */
563	se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);/*windowed + pix intg */
564	se401_send_pict(se401);
565
566	se401_send_size(se401, se401->cwidth, se401->cheight);
567
568	se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE, 0, NULL, 0);
569
570	/* Do some memory allocation */
571	for (i=0; i<SE401_NUMFRAMES; i++) {
572		se401->frame[i].data=se401->fbuf + i * se401->maxframesize;
573		se401->frame[i].curpix=0;
574	}
575	for (i=0; i<SE401_NUMSBUF; i++) {
576		se401->sbuf[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
577	}
578
579	se401->bayeroffset=0;
580	se401->scratch_next=0;
581	se401->scratch_use=0;
582	se401->scratch_overflow=0;
583	for (i=0; i<SE401_NUMSCRATCH; i++) {
584		se401->scratch[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
585		se401->scratch[i].state=BUFFER_UNUSED;
586	}
587
588	for (i=0; i<SE401_NUMSBUF; i++) {
589		urb=usb_alloc_urb(0);
590		if(!urb)
591			return -ENOMEM;
592
593		FILL_BULK_URB(urb, se401->dev,
594			usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT),
595			se401->sbuf[i].data, SE401_PACKETSIZE,
596			se401_video_irq,
597			se401);
598		urb->transfer_flags |= USB_QUEUE_BULK;
599
600		se401->urb[i]=urb;
601
602		err=usb_submit_urb(se401->urb[i]);
603		if(err)
604			err("urb burned down");
605	}
606
607	se401->framecount=0;
608
609	return 0;
610}
611
612static int se401_stop_stream(struct usb_se401 *se401)
613{
614	int i;
615
616	if (!se401->streaming || !se401->dev)
617		return 1;
618
619	se401->streaming=0;
620
621	se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0);
622
623	se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
624	se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
625
626	for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
627		se401->urb[i]->next=NULL;
628		usb_unlink_urb(se401->urb[i]);
629		usb_free_urb(se401->urb[i]);
630		se401->urb[i]=NULL;
631		kfree(se401->sbuf[i].data);
632	}
633	for (i=0; i<SE401_NUMSCRATCH; i++) {
634		kfree(se401->scratch[i].data);
635		se401->scratch[i].data=NULL;
636	}
637
638	return 0;
639}
640
641static int se401_set_size(struct usb_se401 *se401, int width, int height)
642{
643	int wasstreaming=se401->streaming;
644	/* Check to see if we need to change */
645	if (se401->cwidth==width && se401->cheight==height)
646		return 0;
647
648	/* Check for a valid mode */
649	if (width <= 0 || height <= 0)
650		return 1;
651	if ((width & 1) || (height & 1))
652		return 1;
653	if (width>se401->width[se401->sizes-1])
654		return 1;
655	if (height>se401->height[se401->sizes-1])
656		return 1;
657
658	/* Stop a current stream and start it again at the new size */
659	if (wasstreaming)
660		se401_stop_stream(se401);
661	se401->cwidth=width;
662	se401->cheight=height;
663	if (wasstreaming)
664		se401_start_stream(se401);
665	return 0;
666}
667
668
669/****************************************************************************
670 *
671 * Video Decoding
672 *
673 ***************************************************************************/
674
675/*
676	This shouldn't really be done in a v4l driver....
677	But it does make the image look a lot more usable.
678	Basicly it lifts the dark pixels more than the light pixels.
679*/
680static inline void enhance_picture(unsigned char *frame, int len)
681{
682	while (len--) {
683		*frame=(((*frame^255)*(*frame^255))/255)^255;
684		frame++;
685	}
686}
687
688static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data)
689{
690	struct se401_frame *frame=&se401->frame[se401->curframe];
691	int linelength=se401->cwidth*3;
692
693	if (frame->curlinepix >= linelength) {
694		frame->curlinepix=0;
695		frame->curline+=linelength;
696	}
697
698	/* First three are absolute, all others relative.
699	 * Format is rgb from right to left (mirrorred image),
700	 * we flip it to get bgr from left to right. */
701	if (frame->curlinepix < 3) {
702		*(frame->curline-frame->curlinepix)=1+data*4;
703	} else {
704		*(frame->curline-frame->curlinepix)=
705		    *(frame->curline-frame->curlinepix+3)+data*4;
706	}
707	frame->curlinepix++;
708}
709
710static inline void decode_JangGu_vlc (struct usb_se401 *se401, unsigned char *data, int bit_exp, int packetlength)
711{
712	int pos=0;
713	int vlc_cod=0;
714	int vlc_size=0;
715	int vlc_data=0;
716	int bit_cur;
717	int bit;
718	data+=4;
719	while (pos < packetlength) {
720		bit_cur=8;
721		while (bit_cur && bit_exp) {
722			bit=((*data)>>(bit_cur-1))&1;
723			if (!vlc_cod) {
724				if (bit) {
725					vlc_size++;
726				} else {
727					if (!vlc_size) {
728						decode_JangGu_integrate(se401, 0);
729					} else {
730						vlc_cod=2;
731						vlc_data=0;
732					}
733				}
734			} else {
735				if (vlc_cod==2) {
736					if (!bit) vlc_data=-(1<<vlc_size)+1;
737					vlc_cod--;
738				}
739				vlc_size--;
740				vlc_data+=bit<<vlc_size;
741				if (!vlc_size) {
742					decode_JangGu_integrate(se401, vlc_data);
743					vlc_cod=0;
744				}
745			}
746			bit_cur--;
747			bit_exp--;
748		}
749		pos++;
750		data++;
751	}
752}
753
754static inline void decode_JangGu (struct usb_se401 *se401, struct se401_scratch *buffer)
755{
756	unsigned char *data=buffer->data;
757	int len=buffer->length;
758	int bit_exp=0, pix_exp=0, frameinfo=0, packetlength=0, size;
759	int datapos=0;
760
761	/* New image? */
762	if (!se401->frame[se401->curframe].curpix) {
763		se401->frame[se401->curframe].curlinepix=0;
764		se401->frame[se401->curframe].curline=
765		    se401->frame[se401->curframe].data+
766		    se401->cwidth*3-1;
767		if (se401->frame[se401->curframe].grabstate==FRAME_READY)
768			se401->frame[se401->curframe].grabstate=FRAME_GRABBING;
769		se401->vlcdatapos=0;
770	}
771	while (datapos < len) {
772		size=1024-se401->vlcdatapos;
773		if (size+datapos > len)
774			size=len-datapos;
775		memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size);
776		se401->vlcdatapos+=size;
777		packetlength=0;
778		if (se401->vlcdatapos >= 4) {
779			bit_exp=se401->vlcdata[3]+(se401->vlcdata[2]<<8);
780			pix_exp=se401->vlcdata[1]+((se401->vlcdata[0]&0x3f)<<8);
781			frameinfo=se401->vlcdata[0]&0xc0;
782			packetlength=((bit_exp+47)>>4)<<1;
783			if (packetlength > 1024) {
784				se401->vlcdatapos=0;
785				datapos=len;
786				packetlength=0;
787				se401->error++;
788				se401->frame[se401->curframe].curpix=0;
789			}
790		}
791		if (packetlength && se401->vlcdatapos >= packetlength) {
792			decode_JangGu_vlc(se401, se401->vlcdata, bit_exp, packetlength);
793			se401->frame[se401->curframe].curpix+=pix_exp*3;
794			datapos+=size-(se401->vlcdatapos-packetlength);
795			se401->vlcdatapos=0;
796			if (se401->frame[se401->curframe].curpix>=se401->cwidth*se401->cheight*3) {
797				if (se401->frame[se401->curframe].curpix==se401->cwidth*se401->cheight*3) {
798					if (se401->frame[se401->curframe].grabstate==FRAME_GRABBING) {
799						se401->frame[se401->curframe].grabstate=FRAME_DONE;
800						se401->framecount++;
801						se401->readcount++;
802					}
803					if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
804						se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
805					}
806				} else {
807					se401->error++;
808				}
809				se401->frame[se401->curframe].curpix=0;
810				datapos=len;
811			}
812		} else {
813			datapos+=size;
814		}
815	}
816}
817
818static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch *buffer)
819{
820	unsigned char *data=buffer->data;
821	int len=buffer->length;
822	int offset=buffer->offset;
823	int datasize=se401->cwidth*se401->cheight;
824	struct se401_frame *frame=&se401->frame[se401->curframe];
825
826	unsigned char *framedata=frame->data, *curline, *nextline;
827	int width=se401->cwidth;
828	int blineoffset=0, bline;
829	int linelength=width*3, i;
830
831
832	if (frame->curpix==0) {
833		if (frame->grabstate==FRAME_READY) {
834			frame->grabstate=FRAME_GRABBING;
835		}
836		frame->curline=framedata+linelength;
837		frame->curlinepix=0;
838	}
839
840	if (offset!=frame->curpix) {
841		/* Regard frame as lost :( */
842		frame->curpix=0;
843		se401->error++;
844		return;
845	}
846
847	/* Check if we have to much data */
848	if (frame->curpix+len > datasize) {
849		len=datasize-frame->curpix;
850	}
851	if (se401->cheight%4)
852		blineoffset=1;
853	bline=frame->curpix/se401->cwidth+blineoffset;
854
855	curline=frame->curline;
856	nextline=curline+linelength;
857	if (nextline >= framedata+datasize*3)
858		nextline=curline;
859	while (len) {
860		if (frame->curlinepix>=width) {
861			frame->curlinepix-=width;
862			bline=frame->curpix/width+blineoffset;
863			curline+=linelength*2;
864			nextline+=linelength*2;
865			if (curline >= framedata+datasize*3) {
866				frame->curlinepix++;
867				curline-=3;
868				nextline-=3;
869				len--;
870				data++;
871				frame->curpix++;
872			}
873			if (nextline >= framedata+datasize*3)
874				nextline=curline;
875		}
876		if ((bline&1)) {
877			if ((frame->curlinepix&1)) {
878				*(curline+2)=*data;
879				*(curline-1)=*data;
880				*(nextline+2)=*data;
881				*(nextline-1)=*data;
882			} else {
883				*(curline+1)=
884					(*(curline+1)+*data)/2;
885				*(curline-2)=
886					(*(curline-2)+*data)/2;
887				*(nextline+1)=*data;
888				*(nextline-2)=*data;
889			}
890		} else {
891			if ((frame->curlinepix&1)) {
892				*(curline+1)=
893					(*(curline+1)+*data)/2;
894				*(curline-2)=
895					(*(curline-2)+*data)/2;
896				*(nextline+1)=*data;
897				*(nextline-2)=*data;
898			} else {
899				*curline=*data;
900				*(curline-3)=*data;
901				*nextline=*data;
902				*(nextline-3)=*data;
903			}
904		}
905		frame->curlinepix++;
906		curline-=3;
907		nextline-=3;
908		len--;
909		data++;
910		frame->curpix++;
911	}
912	frame->curline=curline;
913
914	if (frame->curpix>=datasize) {
915		/* Fix the top line */
916		framedata+=linelength;
917		for (i=0; i<linelength; i++) {
918			framedata--;
919			*framedata=*(framedata+linelength);
920		}
921		/* Fix the left side (green is already present) */
922		for (i=0; i<se401->cheight; i++) {
923			*framedata=*(framedata+3);
924			*(framedata+1)=*(framedata+4);
925			*(framedata+2)=*(framedata+5);
926			framedata+=linelength;
927		}
928		frame->curpix=0;
929		frame->grabstate=FRAME_DONE;
930		se401->framecount++;
931		se401->readcount++;
932		if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
933			se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
934		}
935	}
936}
937
938static int se401_newframe(struct usb_se401 *se401, int framenr)
939{
940	DECLARE_WAITQUEUE(wait, current);
941	int errors=0;
942
943	while (se401->streaming &&
944	    (se401->frame[framenr].grabstate==FRAME_READY ||
945	     se401->frame[framenr].grabstate==FRAME_GRABBING) ) {
946		if(!se401->frame[framenr].curpix) {
947			errors++;
948		}
949		wait_interruptible(
950		    se401->scratch[se401->scratch_use].state!=BUFFER_READY,
951		    &se401->wq,
952		    &wait
953		);
954		if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
955			se401->nullpackets=0;
956			info("to many null length packets, restarting capture");
957			se401_stop_stream(se401);
958			se401_start_stream(se401);
959		} else {
960			if (se401->scratch[se401->scratch_use].state!=BUFFER_READY) {
961				se401->frame[framenr].grabstate=FRAME_ERROR;
962				return -EIO;
963			}
964			se401->scratch[se401->scratch_use].state=BUFFER_BUSY;
965			if (se401->format==FMT_JANGGU) {
966				decode_JangGu(se401, &se401->scratch[se401->scratch_use]);
967			} else {
968				decode_bayer(se401, &se401->scratch[se401->scratch_use]);
969			}
970			se401->scratch[se401->scratch_use].state=BUFFER_UNUSED;
971			se401->scratch_use++;
972			if (se401->scratch_use>=SE401_NUMSCRATCH)
973				se401->scratch_use=0;
974			if (errors > SE401_MAX_ERRORS) {
975				errors=0;
976				info("to much errors, restarting capture");
977				se401_stop_stream(se401);
978				se401_start_stream(se401);
979			}
980		}
981	}
982
983	if (se401->frame[framenr].grabstate==FRAME_DONE)
984		if (se401->enhance)
985			enhance_picture(se401->frame[framenr].data, se401->cheight*se401->cwidth*3);
986	return 0;
987}
988
989
990/****************************************************************************
991 *
992 * Video4Linux
993 *
994 ***************************************************************************/
995
996
997static int se401_open(struct video_device *dev, int flags)
998{
999	struct usb_se401 *se401 = (struct usb_se401 *)dev;
1000	int err = 0;
1001
1002	/* we are called with the BKL held */
1003	MOD_INC_USE_COUNT;
1004
1005	se401->user=1;
1006	se401->fbuf=rvmalloc(se401->maxframesize * SE401_NUMFRAMES);
1007	if(!se401->fbuf) err=-ENOMEM;
1008
1009        if (err) {
1010		MOD_DEC_USE_COUNT;
1011		se401->user = 0;
1012	}
1013
1014	return err;
1015}
1016
1017static void se401_close(struct video_device *dev)
1018{
1019	/* called with BKL held */
1020        struct usb_se401 *se401 = (struct usb_se401 *)dev;
1021	int i;
1022
1023	for (i=0; i<SE401_NUMFRAMES; i++)
1024		se401->frame[i].grabstate=FRAME_UNUSED;
1025	if (se401->streaming)
1026		se401_stop_stream(se401);
1027
1028	rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES);
1029	se401->user=0;
1030
1031        if (se401->removed) {
1032                video_unregister_device(&se401->vdev);
1033		kfree(se401->width);
1034		kfree(se401->height);
1035                kfree(se401);
1036                se401 = NULL;
1037		info("device unregistered");
1038	}
1039
1040        MOD_DEC_USE_COUNT;
1041}
1042
1043static int se401_init_done(struct video_device *dev)
1044{
1045#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
1046        create_proc_se401_cam((struct usb_se401 *)dev);
1047#endif
1048
1049        return 0;
1050}
1051
1052static long se401_write(struct video_device *dev, const char *buf, unsigned long
1053 count, int noblock)
1054{
1055        return -EINVAL;
1056}
1057
1058static int se401_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
1059{
1060        struct usb_se401 *se401 = (struct usb_se401 *)vdev;
1061
1062        if (!se401->dev)
1063                return -EIO;
1064
1065        switch (cmd) {
1066	case VIDIOCGCAP:
1067	{
1068		struct video_capability b;
1069		strcpy(b.name, se401->camera_name);
1070		b.type = VID_TYPE_CAPTURE;
1071		b.channels = 1;
1072		b.audios = 0;
1073		b.maxwidth = se401->width[se401->sizes-1];
1074		b.maxheight = se401->height[se401->sizes-1];
1075		b.minwidth = se401->width[0];
1076		b.minheight = se401->height[0];
1077
1078		if (copy_to_user(arg, &b, sizeof(b)))
1079			return -EFAULT;
1080
1081		return 0;
1082	}
1083	case VIDIOCGCHAN:
1084	{
1085		struct video_channel v;
1086
1087		if (copy_from_user(&v, arg, sizeof(v)))
1088			return -EFAULT;
1089		if (v.channel != 0)
1090			return -EINVAL;
1091
1092		v.flags = 0;
1093		v.tuners = 0;
1094		v.type = VIDEO_TYPE_CAMERA;
1095		strcpy(v.name, "Camera");
1096
1097		if (copy_to_user(arg, &v, sizeof(v)))
1098			return -EFAULT;
1099
1100		return 0;
1101	}
1102	case VIDIOCSCHAN:
1103	{
1104		int v;
1105
1106		if (copy_from_user(&v, arg, sizeof(v)))
1107			return -EFAULT;
1108
1109		if (v != 0)
1110			return -EINVAL;
1111
1112		return 0;
1113	}
1114        case VIDIOCGPICT:
1115        {
1116		struct video_picture p;
1117
1118		se401_get_pict(se401, &p);
1119
1120		if (copy_to_user(arg, &p, sizeof(p)))
1121			return -EFAULT;
1122		return 0;
1123	}
1124	case VIDIOCSPICT:
1125	{
1126		struct video_picture p;
1127
1128		if (copy_from_user(&p, arg, sizeof(p)))
1129			return -EFAULT;
1130
1131		if (se401_set_pict(se401, &p))
1132			return -EINVAL;
1133		return 0;
1134	}
1135	case VIDIOCSWIN:
1136	{
1137		struct video_window vw;
1138
1139		if (copy_from_user(&vw, arg, sizeof(vw)))
1140			return -EFAULT;
1141		if (vw.flags)
1142			return -EINVAL;
1143		if (vw.clipcount)
1144			return -EINVAL;
1145		if (se401_set_size(se401, vw.width, vw.height))
1146			return -EINVAL;
1147
1148		return 0;
1149        }
1150	case VIDIOCGWIN:
1151	{
1152		struct video_window vw;
1153
1154		vw.x = 0;               /* FIXME */
1155		vw.y = 0;
1156		vw.chromakey = 0;
1157		vw.flags = 0;
1158		vw.clipcount = 0;
1159		vw.width = se401->cwidth;
1160		vw.height = se401->cheight;
1161
1162		if (copy_to_user(arg, &vw, sizeof(vw)))
1163			return -EFAULT;
1164
1165		return 0;
1166	}
1167	case VIDIOCGMBUF:
1168	{
1169		struct video_mbuf vm;
1170		int i;
1171
1172		memset(&vm, 0, sizeof(vm));
1173		vm.size = SE401_NUMFRAMES * se401->maxframesize;
1174		vm.frames = SE401_NUMFRAMES;
1175		for (i=0; i<SE401_NUMFRAMES; i++)
1176			vm.offsets[i] = se401->maxframesize * i;
1177
1178		if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
1179		return -EFAULT;
1180
1181		return 0;
1182	}
1183	case VIDIOCMCAPTURE:
1184	{
1185		struct video_mmap vm;
1186
1187		if (copy_from_user(&vm, arg, sizeof(vm)))
1188		return -EFAULT;
1189		if (vm.format != VIDEO_PALETTE_RGB24)
1190			return -EINVAL;
1191		if (vm.frame >= SE401_NUMFRAMES)
1192			return -EINVAL;
1193		if (se401->frame[vm.frame].grabstate != FRAME_UNUSED)
1194			return -EBUSY;
1195
1196		/* Is this according to the v4l spec??? */
1197		if (se401_set_size(se401, vm.width, vm.height))
1198			return -EINVAL;
1199		se401->frame[vm.frame].grabstate=FRAME_READY;
1200
1201		if (!se401->streaming)
1202			se401_start_stream(se401);
1203
1204		/* Set the picture properties */
1205		if (se401->framecount==0)
1206			se401_send_pict(se401);
1207		/* Calibrate the reset level after a few frames. */
1208		if (se401->framecount%20==1)
1209			se401_auto_resetlevel(se401);
1210
1211		return 0;
1212	}
1213	case VIDIOCSYNC:
1214	{
1215		int frame, ret=0;
1216
1217		if (copy_from_user((void *)&frame, arg, sizeof(int)))
1218			return -EFAULT;
1219
1220		if(frame <0 || frame >= SE401_NUMFRAMES)
1221			return -EINVAL;
1222
1223		ret=se401_newframe(se401, frame);
1224		se401->frame[frame].grabstate=FRAME_UNUSED;
1225		return ret;
1226	}
1227	case VIDIOCGFBUF:
1228	{
1229		struct video_buffer vb;
1230
1231		memset(&vb, 0, sizeof(vb));
1232		vb.base = NULL; /* frame buffer not supported, not used */
1233
1234		if (copy_to_user((void *)arg, (void *)&vb, sizeof(vb)))
1235			return -EFAULT;
1236
1237		return 0;
1238	}
1239	case VIDIOCKEY:
1240		return 0;
1241	case VIDIOCCAPTURE:
1242		return -EINVAL;
1243	case VIDIOCSFBUF:
1244		return -EINVAL;
1245	case VIDIOCGTUNER:
1246	case VIDIOCSTUNER:
1247		return -EINVAL;
1248	case VIDIOCGFREQ:
1249	case VIDIOCSFREQ:
1250		return -EINVAL;
1251	case VIDIOCGAUDIO:
1252	case VIDIOCSAUDIO:
1253		return -EINVAL;
1254        default:
1255                return -ENOIOCTLCMD;
1256        } /* end switch */
1257
1258        return 0;
1259}
1260
1261static long se401_read(struct video_device *dev, char *buf, unsigned long count,
1262 int noblock)
1263{
1264	int realcount=count, ret=0;
1265	struct usb_se401 *se401 = (struct usb_se401 *)dev;
1266
1267
1268	if (se401->dev == NULL)
1269		return -EIO;
1270	if (realcount > se401->cwidth*se401->cheight*3)
1271		realcount=se401->cwidth*se401->cheight*3;
1272
1273	/* Shouldn't happen: */
1274	if (se401->frame[0].grabstate==FRAME_GRABBING)
1275		return -EBUSY;
1276	se401->frame[0].grabstate=FRAME_READY;
1277	se401->frame[1].grabstate=FRAME_UNUSED;
1278	se401->curframe=0;
1279
1280	if (!se401->streaming)
1281		se401_start_stream(se401);
1282
1283	/* Set the picture properties */
1284	if (se401->framecount==0)
1285		se401_send_pict(se401);
1286	/* Calibrate the reset level after a few frames. */
1287	if (se401->framecount%20==1)
1288		se401_auto_resetlevel(se401);
1289
1290	ret=se401_newframe(se401, 0);
1291
1292	se401->frame[0].grabstate=FRAME_UNUSED;
1293	if (ret)
1294		return ret;
1295	if (copy_to_user(buf, se401->frame[0].data, realcount))
1296		return -EFAULT;
1297
1298	return realcount;
1299}
1300
1301static int se401_mmap(struct video_device *dev, const char *adr,
1302        unsigned long size)
1303{
1304	struct usb_se401 *se401 = (struct usb_se401 *)dev;
1305	unsigned long start = (unsigned long)adr;
1306	unsigned long page, pos;
1307
1308	down(&se401->lock);
1309
1310	if (se401->dev == NULL) {
1311		up(&se401->lock);
1312		return -EIO;
1313	}
1314	if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) {
1315		up(&se401->lock);
1316		return -EINVAL;
1317	}
1318	pos = (unsigned long)se401->fbuf;
1319	while (size > 0) {
1320		page = kvirt_to_pa(pos);
1321		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
1322			up(&se401->lock);
1323			return -EAGAIN;
1324		}
1325		start += PAGE_SIZE;
1326		pos += PAGE_SIZE;
1327		if (size > PAGE_SIZE)
1328			size -= PAGE_SIZE;
1329		else
1330			size = 0;
1331	}
1332	up(&se401->lock);
1333
1334        return 0;
1335}
1336
1337static struct video_device se401_template = {
1338        name:           "se401 USB camera",
1339        type:           VID_TYPE_CAPTURE,
1340        hardware:       VID_HARDWARE_SE401,
1341        open:           se401_open,
1342        close:          se401_close,
1343        read:           se401_read,
1344        write:          se401_write,
1345        ioctl:          se401_ioctl,
1346        mmap:           se401_mmap,
1347        initialize:     se401_init_done,
1348};
1349
1350
1351
1352/***************************/
1353static int se401_init(struct usb_se401 *se401)
1354{
1355        int i=0, rc;
1356        unsigned char cp[0x40];
1357	char temp[200];
1358
1359	/* led on */
1360        se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1361
1362	/* get camera descriptor */
1363	rc=se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, cp, sizeof(cp));
1364	if (cp[1]!=0x41) {
1365		err("Wrong descriptor type");
1366		return 1;
1367	}
1368	sprintf (temp, "ExtraFeatures: %d", cp[3]);
1369
1370	se401->sizes=cp[4]+cp[5]*256;
1371	se401->width=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1372	if (!se401->width)
1373		return 1;
1374	se401->height=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1375	if (!se401->height) {
1376		kfree(se401->width);
1377		return 1;
1378	}
1379	for (i=0; i<se401->sizes; i++) {
1380		    se401->width[i]=cp[6+i*4+0]+cp[6+i*4+1]*256;
1381		    se401->height[i]=cp[6+i*4+2]+cp[6+i*4+3]*256;
1382	}
1383	sprintf (temp, "%s Sizes:", temp);
1384	for (i=0; i<se401->sizes; i++) {
1385		sprintf(temp, "%s %dx%d", temp, se401->width[i], se401->height[i]);
1386	}
1387	info("%s", temp);
1388	se401->maxframesize=se401->width[se401->sizes-1]*se401->height[se401->sizes-1]*3;
1389
1390	rc=se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp));
1391	se401->cwidth=cp[0]+cp[1]*256;
1392	rc=se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp));
1393	se401->cheight=cp[0]+cp[1]*256;
1394
1395	if (!cp[2] && SE401_FORMAT_BAYER) {
1396		err("Bayer format not supported!");
1397		return 1;
1398	}
1399	/* set output mode (BAYER) */
1400        se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, SE401_FORMAT_BAYER, NULL, 0);
1401
1402	rc=se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp));
1403	se401->brightness=cp[0]+cp[1]*256;
1404	/* some default values */
1405	se401->resetlevel=0x2d;
1406	se401->rgain=0x20;
1407	se401->ggain=0x20;
1408	se401->bgain=0x20;
1409	se401_set_exposure(se401, 20000);
1410	se401->palette=VIDEO_PALETTE_RGB24;
1411	se401->enhance=1;
1412	se401->dropped=0;
1413	se401->error=0;
1414	se401->framecount=0;
1415	se401->readcount=0;
1416
1417	/* Start interrupt transfers for snapshot button */
1418	se401->inturb=usb_alloc_urb(0);
1419	if (!se401->inturb) {
1420		info("Allocation of inturb failed");
1421		return 1;
1422	}
1423	FILL_INT_URB(se401->inturb, se401->dev,
1424	    usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT),
1425	    &se401->button, sizeof(se401->button),
1426	    se401_button_irq,
1427	    se401,
1428	    HZ/10
1429	);
1430	if (usb_submit_urb(se401->inturb)) {
1431		info("int urb burned down");
1432		return 1;
1433	}
1434
1435        /* Flash the led */
1436        se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
1437        se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1438        se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
1439	se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
1440
1441        return 0;
1442}
1443
1444static void* se401_probe(struct usb_device *dev, unsigned int ifnum,
1445	const struct usb_device_id *id)
1446{
1447        struct usb_interface_descriptor *interface;
1448        struct usb_se401 *se401;
1449        char *camera_name=NULL;
1450
1451        /* We don't handle multi-config cameras */
1452        if (dev->descriptor.bNumConfigurations != 1)
1453                return NULL;
1454
1455        interface = &dev->actconfig->interface[ifnum].altsetting[0];
1456
1457        /* Is it an se401? */
1458        if (dev->descriptor.idVendor == 0x03e8 &&
1459            dev->descriptor.idProduct == 0x0004) {
1460                camera_name="Endpoints/Aox SE401";
1461        } else if (dev->descriptor.idVendor == 0x0471 &&
1462            dev->descriptor.idProduct == 0x030b) {
1463                camera_name="Philips PCVC665K";
1464        } else if (dev->descriptor.idVendor == 0x047d &&
1465	    dev->descriptor.idProduct == 0x5001) {
1466		camera_name="Kensington VideoCAM 67014";
1467        } else if (dev->descriptor.idVendor == 0x047d &&
1468	    dev->descriptor.idProduct == 0x5002) {
1469		camera_name="Kensington VideoCAM 6701(5/7)";
1470        } else if (dev->descriptor.idVendor == 0x047d &&
1471	    dev->descriptor.idProduct == 0x5003) {
1472		camera_name="Kensington VideoCAM 67016";
1473	} else
1474		return NULL;
1475
1476        /* Checking vendor/product should be enough, but what the hell */
1477        if (interface->bInterfaceClass != 0x00)
1478                return NULL;
1479        if (interface->bInterfaceSubClass != 0x00)
1480                return NULL;
1481
1482        /* We found one */
1483        info("SE401 camera found: %s", camera_name);
1484
1485        if ((se401 = kmalloc(sizeof(*se401), GFP_KERNEL)) == NULL) {
1486                err("couldn't kmalloc se401 struct");
1487                return NULL;
1488        }
1489
1490        memset(se401, 0, sizeof(*se401));
1491
1492        se401->dev = dev;
1493        se401->iface = interface->bInterfaceNumber;
1494        se401->camera_name = camera_name;
1495
1496	info("firmware version: %02x", dev->descriptor.bcdDevice & 255);
1497
1498        if (se401_init(se401)) {
1499		kfree(se401);
1500		return NULL;
1501	}
1502
1503	memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
1504	memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name));
1505	init_waitqueue_head(&se401->wq);
1506	init_MUTEX(&se401->lock);
1507	wmb();
1508
1509	if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
1510		kfree(se401);
1511		err("video_register_device failed");
1512		return NULL;
1513	}
1514	info("registered new video device: video%d", se401->vdev.minor);
1515
1516        return se401;
1517}
1518
1519static void se401_disconnect(struct usb_device *dev, void *ptr)
1520{
1521	struct usb_se401 *se401 = (struct usb_se401 *) ptr;
1522
1523	lock_kernel();
1524	/* We don't want people trying to open up the device */
1525	if (!se401->user){
1526		video_unregister_device(&se401->vdev);
1527		usb_se401_remove_disconnected(se401);
1528	} else {
1529		se401->removed = 1;
1530	}
1531	unlock_kernel();
1532}
1533
1534static inline void usb_se401_remove_disconnected (struct usb_se401 *se401)
1535{
1536	int i;
1537
1538        se401->dev = NULL;
1539        se401->frame[0].grabstate = FRAME_ERROR;
1540        se401->frame[1].grabstate = FRAME_ERROR;
1541
1542	se401->streaming = 0;
1543
1544	wake_up_interruptible(&se401->wq);
1545
1546	for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
1547		se401->urb[i]->next = NULL;
1548		usb_unlink_urb(se401->urb[i]);
1549		usb_free_urb(se401->urb[i]);
1550		se401->urb[i] = NULL;
1551		kfree(se401->sbuf[i].data);
1552	}
1553	for (i=0; i<SE401_NUMSCRATCH; i++) if (se401->scratch[i].data) {
1554		kfree(se401->scratch[i].data);
1555	}
1556	if (se401->inturb) {
1557		usb_unlink_urb(se401->inturb);
1558		usb_free_urb(se401->inturb);
1559	}
1560        info("%s disconnected", se401->camera_name);
1561
1562#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
1563	destroy_proc_se401_cam(se401);
1564#endif
1565
1566        /* Free the memory */
1567	kfree(se401->width);
1568	kfree(se401->height);
1569	kfree(se401);
1570}
1571
1572static struct usb_driver se401_driver = {
1573        name:		"se401",
1574        id_table:	device_table,
1575	probe:		se401_probe,
1576        disconnect:	se401_disconnect
1577};
1578
1579
1580
1581/****************************************************************************
1582 *
1583 *  Module routines
1584 *
1585 ***************************************************************************/
1586
1587static int __init usb_se401_init(void)
1588{
1589#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
1590	proc_se401_create();
1591#endif
1592
1593	info("SE401 usb camera driver version %s registering", version);
1594	if (flickerless)
1595		if (flickerless!=50 && flickerless!=60) {
1596			info("Invallid flickerless value, use 0, 50 or 60.");
1597			return -1;
1598	}
1599	if (usb_register(&se401_driver) < 0)
1600		return -1;
1601	return 0;
1602}
1603
1604static void __exit usb_se401_exit(void)
1605{
1606	usb_deregister(&se401_driver);
1607	info("SE401 driver deregistered");
1608
1609#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
1610	proc_se401_destroy();
1611#endif
1612}
1613
1614module_init(usb_se401_init);
1615module_exit(usb_se401_exit);
1616