Original kernel 2.4.37.5
[tomato.git] / release / src / linux / linux / drivers / usb / se401.c
blob6c4da1494e3d37f2d466cc58c0c98c3ca90a900f
1 /*
2 * Endpoints (formerly known as AOX) se401 USB Camera Driver
4 * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org)
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.
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.
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.
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
28 static const char version[] = "0.23";
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>
44 #include "se401.h"
46 static int flickerless=0;
47 static int video_nr = -1;
49 static 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 { }
58 MODULE_DEVICE_TABLE(usb, device_table);
60 MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>");
61 MODULE_DESCRIPTION("SE401 USB Camera Driver");
62 MODULE_LICENSE("GPL");
63 MODULE_PARM(flickerless, "i");
64 MODULE_PARM_DESC(flickerless, "Net frequency to adjust exposure time to (0/50/60)");
65 MODULE_PARM(video_nr, "i");
66 EXPORT_NO_SYMBOLS;
69 static struct usb_driver se401_driver;
72 /**********************************************************************
74 * Memory management
76 **********************************************************************/
78 /* Here we want the physical address of the memory.
79 * This is used when initializing the contents of the area.
81 static inline unsigned long kvirt_to_pa(unsigned long adr)
83 unsigned long kva, ret;
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;
91 static void *rvmalloc(unsigned long size)
93 void *mem;
94 unsigned long adr;
96 size = PAGE_ALIGN(size);
97 mem = vmalloc_32(size);
98 if (!mem)
99 return NULL;
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;
109 return mem;
112 static void rvfree(void *mem, unsigned long size)
114 unsigned long adr;
116 if (!mem)
117 return;
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;
125 vfree(mem);
130 /****************************************************************************
132 * /proc interface
134 ***************************************************************************/
136 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
138 static struct proc_dir_entry *se401_proc_entry = NULL;
139 extern struct proc_dir_entry *video_proc_entry;
141 #define YES_NO(x) ((x) ? "yes" : "no")
143 static int se401_read_proc(char *page, char **start, off_t off, int count,
144 int *eof, void *data)
146 char *out = page;
147 int i, len;
148 struct usb_se401 *se401 = data;
150 /* Stay under PAGE_SIZE or else bla bla bla.... */
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);
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]);
165 out+=sprintf(out, "\n");
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);
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;
180 *start = page + off;
182 return len;
185 static int se401_write_proc(struct file *file, const char *buffer,
186 unsigned long count, void *data)
188 return -EINVAL;
191 static void create_proc_se401_cam (struct usb_se401 *se401)
193 char name[7];
194 struct proc_dir_entry *ent;
196 if (!se401_proc_entry || !se401)
197 return;
199 sprintf (name, "video%d", se401->vdev.minor);
201 ent = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR,
202 se401_proc_entry);
204 if (!ent)
205 return;
207 ent->data = se401;
208 ent->read_proc = se401_read_proc;
209 ent->write_proc = se401_write_proc;
210 se401->proc_entry = ent;
213 static void destroy_proc_se401_cam (struct usb_se401 *se401)
215 /* One to much, just to be sure :) */
216 char name[9];
218 if (!se401 || !se401->proc_entry)
219 return;
221 sprintf(name, "video%d", se401->vdev.minor);
222 remove_proc_entry(name, se401_proc_entry);
223 se401->proc_entry = NULL;
226 static void proc_se401_create (void)
228 if (video_proc_entry == NULL) {
229 err("/proc/video/ doesn't exist");
230 return;
233 se401_proc_entry=create_proc_entry("se401", S_IFDIR, video_proc_entry);
235 if (se401_proc_entry)
236 se401_proc_entry->owner = THIS_MODULE;
237 else
238 err("Unable to initialize /proc/video/se401");
241 static void proc_se401_destroy(void)
243 if (se401_proc_entry == NULL)
244 return;
246 remove_proc_entry("se401", video_proc_entry);
248 #endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */
251 /****************************************************************************
253 * se401 register read/write functions
255 ***************************************************************************/
257 static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req,
258 unsigned short value, unsigned char *cp, int size)
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,
268 size,
273 static int se401_set_feature(struct usb_se401 *se401, unsigned short selector,
274 unsigned short param)
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...
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,
293 static unsigned short se401_get_feature(struct usb_se401 *se401,
294 unsigned short selector)
296 /* For 'set' the selecetor should be in index, not sure if the spec is
297 wrong here to....
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,
306 selector,
311 return cp[0]+cp[1]*256;
314 /****************************************************************************
316 * Camera control
318 ***************************************************************************/
321 static int se401_send_pict(struct usb_se401 *se401)
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 */
331 return 0;
334 static void se401_set_exposure(struct usb_se401 *se401, int brightness)
336 int integration=brightness<<5;
338 if (flickerless==50) {
339 integration=integration-integration%106667;
341 if (flickerless==60) {
342 integration=integration-integration%88889;
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;
350 static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p)
352 p->brightness=se401->brightness;
353 if (se401->enhance) {
354 p->whiteness=32768;
355 } else {
356 p->whiteness=0;
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;
367 static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p)
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;
377 if (p->brightness!=se401->brightness) {
378 se401_set_exposure(se401, p->brightness);
380 if (p->whiteness>=32768) {
381 se401->enhance=1;
382 } else {
383 se401->enhance=0;
385 se401_send_pict(se401);
386 se401_send_pict(se401);
387 return 0;
391 Hyundai have some really nice docs about this and other sensor related
392 stuff on their homepage: www.hei.co.kr
394 static void se401_auto_resetlevel(struct usb_se401 *se401)
396 unsigned int ahrc, alrc;
397 int oldreset=se401->resetlevel;
399 /* For some reason this normally read-only register doesn't get reset
400 to zero after reading them just once...
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);
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;
417 } else if (ahrc > 20) {
418 while (ahrc>=20 && se401->resetlevel > 0) {
419 se401->resetlevel--;
420 ahrc /=2;
423 if (se401->resetlevel!=oldreset)
424 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
426 return;
429 /* irq handler for snapshot button */
430 static void se401_button_irq(struct urb *urb)
432 struct usb_se401 *se401 = urb->context;
434 if (!se401->dev) {
435 info("ohoh: device vapourished");
436 return;
439 if (urb->actual_length >=2 && !urb->status) {
440 if (se401->button)
441 se401->buttonpressed=1;
445 static void se401_video_irq(struct urb *urb)
447 struct usb_se401 *se401 = urb->context;
448 int length = urb->actual_length;
450 /* ohoh... */
451 if (!se401->streaming)
452 return;
454 if (!se401->dev) {
455 info ("ohoh: device vapourished");
456 return;
459 /* 0 sized packets happen if we are to fast, but sometimes the camera
460 keeps sending them forever...
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;
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);
478 se401->scratch_overflow=0;
479 se401->scratch_next++;
480 if (se401->scratch_next>=SE401_NUMSCRATCH)
481 se401->scratch_next=0;;
482 break;
485 se401->bayeroffset+=length;
486 if (se401->bayeroffset>=se401->cheight*se401->cwidth) {
487 se401->bayeroffset=0;
489 } else {
490 se401->nullpackets++;
491 if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
492 if (waitqueue_active(&se401->wq)) {
493 wake_up_interruptible(&se401->wq);
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;
506 static void se401_send_size(struct usb_se401 *se401, int width, int height)
508 int i=0;
509 int mode=0x03; /* No compression */
510 int sendheight=height;
511 int sendwidth=width;
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....
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;
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;
532 i++;
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);
539 if (mode==0x03) {
540 se401->format=FMT_BAYER;
541 } else {
542 se401->format=FMT_JANGGU;
545 return;
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...
553 static int se401_start_stream(struct usb_se401 *se401)
555 struct urb *urb;
556 int err=0, i;
557 se401->streaming=1;
559 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
560 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
562 /* Set picture settings */
563 se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);/*windowed + pix intg */
564 se401_send_pict(se401);
566 se401_send_size(se401, se401->cwidth, se401->cheight);
568 se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE, 0, NULL, 0);
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;
575 for (i=0; i<SE401_NUMSBUF; i++) {
576 se401->sbuf[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
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;
588 for (i=0; i<SE401_NUMSBUF; i++) {
589 urb=usb_alloc_urb(0);
590 if(!urb)
591 return -ENOMEM;
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;
600 se401->urb[i]=urb;
602 err=usb_submit_urb(se401->urb[i]);
603 if(err)
604 err("urb burned down");
607 se401->framecount=0;
609 return 0;
612 static int se401_stop_stream(struct usb_se401 *se401)
614 int i;
616 if (!se401->streaming || !se401->dev)
617 return 1;
619 se401->streaming=0;
621 se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0);
623 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
624 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
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);
633 for (i=0; i<SE401_NUMSCRATCH; i++) {
634 kfree(se401->scratch[i].data);
635 se401->scratch[i].data=NULL;
638 return 0;
641 static int se401_set_size(struct usb_se401 *se401, int width, int height)
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;
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;
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;
669 /****************************************************************************
671 * Video Decoding
673 ***************************************************************************/
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.
680 static inline void enhance_picture(unsigned char *frame, int len)
682 while (len--) {
683 *frame=(((*frame^255)*(*frame^255))/255)^255;
684 frame++;
688 static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data)
690 struct se401_frame *frame=&se401->frame[se401->curframe];
691 int linelength=se401->cwidth*3;
693 if (frame->curlinepix >= linelength) {
694 frame->curlinepix=0;
695 frame->curline+=linelength;
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;
707 frame->curlinepix++;
710 static inline void decode_JangGu_vlc (struct usb_se401 *se401, unsigned char *data, int bit_exp, int packetlength)
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;
734 } else {
735 if (vlc_cod==2) {
736 if (!bit) vlc_data=-(1<<vlc_size)+1;
737 vlc_cod--;
739 vlc_size--;
740 vlc_data+=bit<<vlc_size;
741 if (!vlc_size) {
742 decode_JangGu_integrate(se401, vlc_data);
743 vlc_cod=0;
746 bit_cur--;
747 bit_exp--;
749 pos++;
750 data++;
754 static inline void decode_JangGu (struct usb_se401 *se401, struct se401_scratch *buffer)
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;
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;
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;
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++;
803 if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
804 se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
806 } else {
807 se401->error++;
809 se401->frame[se401->curframe].curpix=0;
810 datapos=len;
812 } else {
813 datapos+=size;
818 static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch *buffer)
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];
826 unsigned char *framedata=frame->data, *curline, *nextline;
827 int width=se401->cwidth;
828 int blineoffset=0, bline;
829 int linelength=width*3, i;
832 if (frame->curpix==0) {
833 if (frame->grabstate==FRAME_READY) {
834 frame->grabstate=FRAME_GRABBING;
836 frame->curline=framedata+linelength;
837 frame->curlinepix=0;
840 if (offset!=frame->curpix) {
841 /* Regard frame as lost :( */
842 frame->curpix=0;
843 se401->error++;
844 return;
847 /* Check if we have to much data */
848 if (frame->curpix+len > datasize) {
849 len=datasize-frame->curpix;
851 if (se401->cheight%4)
852 blineoffset=1;
853 bline=frame->curpix/se401->cwidth+blineoffset;
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++;
873 if (nextline >= framedata+datasize*3)
874 nextline=curline;
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;
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;
905 frame->curlinepix++;
906 curline-=3;
907 nextline-=3;
908 len--;
909 data++;
910 frame->curpix++;
912 frame->curline=curline;
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);
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;
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);
938 static int se401_newframe(struct usb_se401 *se401, int framenr)
940 DECLARE_WAITQUEUE(wait, current);
941 int errors=0;
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++;
949 wait_interruptible(
950 se401->scratch[se401->scratch_use].state!=BUFFER_READY,
951 &se401->wq,
952 &wait
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;
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]);
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);
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;
989 static inline void usb_se401_remove_disconnected (struct usb_se401 *se401)
991 int i;
993 se401->dev = NULL;
994 se401->frame[0].grabstate = FRAME_ERROR;
995 se401->frame[1].grabstate = FRAME_ERROR;
997 se401->streaming = 0;
999 wake_up_interruptible(&se401->wq);
1001 for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
1002 se401->urb[i]->next = NULL;
1003 usb_unlink_urb(se401->urb[i]);
1004 usb_free_urb(se401->urb[i]);
1005 se401->urb[i] = NULL;
1006 kfree(se401->sbuf[i].data);
1008 for (i=0; i<SE401_NUMSCRATCH; i++) if (se401->scratch[i].data) {
1009 kfree(se401->scratch[i].data);
1011 if (se401->inturb) {
1012 usb_unlink_urb(se401->inturb);
1013 usb_free_urb(se401->inturb);
1015 info("%s disconnected", se401->camera_name);
1017 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
1018 destroy_proc_se401_cam(se401);
1019 #endif
1021 /* Free the memory */
1022 kfree(se401->width);
1023 kfree(se401->height);
1024 kfree(se401);
1028 /****************************************************************************
1030 * Video4Linux
1032 ***************************************************************************/
1035 static int se401_open(struct video_device *dev, int flags)
1037 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1038 int err = 0;
1040 /* we are called with the BKL held */
1041 MOD_INC_USE_COUNT;
1043 se401->user=1;
1044 se401->fbuf=rvmalloc(se401->maxframesize * SE401_NUMFRAMES);
1045 if(!se401->fbuf) err=-ENOMEM;
1047 if (err) {
1048 MOD_DEC_USE_COUNT;
1049 se401->user = 0;
1052 return err;
1055 static void se401_close(struct video_device *dev)
1057 /* called with BKL held */
1058 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1059 int i;
1061 for (i=0; i<SE401_NUMFRAMES; i++)
1062 se401->frame[i].grabstate=FRAME_UNUSED;
1063 if (se401->streaming)
1064 se401_stop_stream(se401);
1066 rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES);
1067 se401->user=0;
1069 if (se401->removed) {
1070 video_unregister_device(&se401->vdev);
1071 kfree(se401->width);
1072 kfree(se401->height);
1073 kfree(se401);
1074 se401 = NULL;
1075 info("device unregistered");
1078 MOD_DEC_USE_COUNT;
1081 static int se401_init_done(struct video_device *dev)
1083 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
1084 create_proc_se401_cam((struct usb_se401 *)dev);
1085 #endif
1087 return 0;
1090 static long se401_write(struct video_device *dev, const char *buf, unsigned long
1091 count, int noblock)
1093 return -EINVAL;
1096 static int se401_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
1098 struct usb_se401 *se401 = (struct usb_se401 *)vdev;
1100 if (!se401->dev)
1101 return -EIO;
1103 switch (cmd) {
1104 case VIDIOCGCAP:
1106 struct video_capability b;
1107 strcpy(b.name, se401->camera_name);
1108 b.type = VID_TYPE_CAPTURE;
1109 b.channels = 1;
1110 b.audios = 0;
1111 b.maxwidth = se401->width[se401->sizes-1];
1112 b.maxheight = se401->height[se401->sizes-1];
1113 b.minwidth = se401->width[0];
1114 b.minheight = se401->height[0];
1116 if (copy_to_user(arg, &b, sizeof(b)))
1117 return -EFAULT;
1119 return 0;
1121 case VIDIOCGCHAN:
1123 struct video_channel v;
1125 if (copy_from_user(&v, arg, sizeof(v)))
1126 return -EFAULT;
1127 if (v.channel != 0)
1128 return -EINVAL;
1130 v.flags = 0;
1131 v.tuners = 0;
1132 v.type = VIDEO_TYPE_CAMERA;
1133 strcpy(v.name, "Camera");
1135 if (copy_to_user(arg, &v, sizeof(v)))
1136 return -EFAULT;
1138 return 0;
1140 case VIDIOCSCHAN:
1142 int v;
1144 if (copy_from_user(&v, arg, sizeof(v)))
1145 return -EFAULT;
1147 if (v != 0)
1148 return -EINVAL;
1150 return 0;
1152 case VIDIOCGPICT:
1154 struct video_picture p;
1156 se401_get_pict(se401, &p);
1158 if (copy_to_user(arg, &p, sizeof(p)))
1159 return -EFAULT;
1160 return 0;
1162 case VIDIOCSPICT:
1164 struct video_picture p;
1166 if (copy_from_user(&p, arg, sizeof(p)))
1167 return -EFAULT;
1169 if (se401_set_pict(se401, &p))
1170 return -EINVAL;
1171 return 0;
1173 case VIDIOCSWIN:
1175 struct video_window vw;
1177 if (copy_from_user(&vw, arg, sizeof(vw)))
1178 return -EFAULT;
1179 if (vw.flags)
1180 return -EINVAL;
1181 if (vw.clipcount)
1182 return -EINVAL;
1183 if (se401_set_size(se401, vw.width, vw.height))
1184 return -EINVAL;
1186 return 0;
1188 case VIDIOCGWIN:
1190 struct video_window vw;
1192 vw.x = 0; /* FIXME */
1193 vw.y = 0;
1194 vw.chromakey = 0;
1195 vw.flags = 0;
1196 vw.clipcount = 0;
1197 vw.width = se401->cwidth;
1198 vw.height = se401->cheight;
1200 if (copy_to_user(arg, &vw, sizeof(vw)))
1201 return -EFAULT;
1203 return 0;
1205 case VIDIOCGMBUF:
1207 struct video_mbuf vm;
1208 int i;
1210 memset(&vm, 0, sizeof(vm));
1211 vm.size = SE401_NUMFRAMES * se401->maxframesize;
1212 vm.frames = SE401_NUMFRAMES;
1213 for (i=0; i<SE401_NUMFRAMES; i++)
1214 vm.offsets[i] = se401->maxframesize * i;
1216 if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
1217 return -EFAULT;
1219 return 0;
1221 case VIDIOCMCAPTURE:
1223 struct video_mmap vm;
1225 if (copy_from_user(&vm, arg, sizeof(vm)))
1226 return -EFAULT;
1227 if (vm.format != VIDEO_PALETTE_RGB24)
1228 return -EINVAL;
1229 if (vm.frame >= SE401_NUMFRAMES)
1230 return -EINVAL;
1231 if (se401->frame[vm.frame].grabstate != FRAME_UNUSED)
1232 return -EBUSY;
1234 /* Is this according to the v4l spec??? */
1235 if (se401_set_size(se401, vm.width, vm.height))
1236 return -EINVAL;
1237 se401->frame[vm.frame].grabstate=FRAME_READY;
1239 if (!se401->streaming)
1240 se401_start_stream(se401);
1242 /* Set the picture properties */
1243 if (se401->framecount==0)
1244 se401_send_pict(se401);
1245 /* Calibrate the reset level after a few frames. */
1246 if (se401->framecount%20==1)
1247 se401_auto_resetlevel(se401);
1249 return 0;
1251 case VIDIOCSYNC:
1253 int frame, ret=0;
1255 if (copy_from_user((void *)&frame, arg, sizeof(int)))
1256 return -EFAULT;
1258 if(frame <0 || frame >= SE401_NUMFRAMES)
1259 return -EINVAL;
1261 ret=se401_newframe(se401, frame);
1262 se401->frame[frame].grabstate=FRAME_UNUSED;
1263 return ret;
1265 case VIDIOCGFBUF:
1267 struct video_buffer vb;
1269 memset(&vb, 0, sizeof(vb));
1270 vb.base = NULL; /* frame buffer not supported, not used */
1272 if (copy_to_user((void *)arg, (void *)&vb, sizeof(vb)))
1273 return -EFAULT;
1275 return 0;
1277 case VIDIOCKEY:
1278 return 0;
1279 case VIDIOCCAPTURE:
1280 return -EINVAL;
1281 case VIDIOCSFBUF:
1282 return -EINVAL;
1283 case VIDIOCGTUNER:
1284 case VIDIOCSTUNER:
1285 return -EINVAL;
1286 case VIDIOCGFREQ:
1287 case VIDIOCSFREQ:
1288 return -EINVAL;
1289 case VIDIOCGAUDIO:
1290 case VIDIOCSAUDIO:
1291 return -EINVAL;
1292 default:
1293 return -ENOIOCTLCMD;
1294 } /* end switch */
1296 return 0;
1299 static long se401_read(struct video_device *dev, char *buf, unsigned long count,
1300 int noblock)
1302 int realcount=count, ret=0;
1303 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1306 if (se401->dev == NULL)
1307 return -EIO;
1308 if (realcount > se401->cwidth*se401->cheight*3)
1309 realcount=se401->cwidth*se401->cheight*3;
1311 /* Shouldn't happen: */
1312 if (se401->frame[0].grabstate==FRAME_GRABBING)
1313 return -EBUSY;
1314 se401->frame[0].grabstate=FRAME_READY;
1315 se401->frame[1].grabstate=FRAME_UNUSED;
1316 se401->curframe=0;
1318 if (!se401->streaming)
1319 se401_start_stream(se401);
1321 /* Set the picture properties */
1322 if (se401->framecount==0)
1323 se401_send_pict(se401);
1324 /* Calibrate the reset level after a few frames. */
1325 if (se401->framecount%20==1)
1326 se401_auto_resetlevel(se401);
1328 ret=se401_newframe(se401, 0);
1330 se401->frame[0].grabstate=FRAME_UNUSED;
1331 if (ret)
1332 return ret;
1333 if (copy_to_user(buf, se401->frame[0].data, realcount))
1334 return -EFAULT;
1336 return realcount;
1339 static int se401_mmap(struct video_device *dev, const char *adr,
1340 unsigned long size)
1342 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1343 unsigned long start = (unsigned long)adr;
1344 unsigned long page, pos;
1346 down(&se401->lock);
1348 if (se401->dev == NULL) {
1349 up(&se401->lock);
1350 return -EIO;
1352 if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) {
1353 up(&se401->lock);
1354 return -EINVAL;
1356 pos = (unsigned long)se401->fbuf;
1357 while (size > 0) {
1358 page = kvirt_to_pa(pos);
1359 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
1360 up(&se401->lock);
1361 return -EAGAIN;
1363 start += PAGE_SIZE;
1364 pos += PAGE_SIZE;
1365 if (size > PAGE_SIZE)
1366 size -= PAGE_SIZE;
1367 else
1368 size = 0;
1370 up(&se401->lock);
1372 return 0;
1375 static struct video_device se401_template = {
1376 name: "se401 USB camera",
1377 type: VID_TYPE_CAPTURE,
1378 hardware: VID_HARDWARE_SE401,
1379 open: se401_open,
1380 close: se401_close,
1381 read: se401_read,
1382 write: se401_write,
1383 ioctl: se401_ioctl,
1384 mmap: se401_mmap,
1385 initialize: se401_init_done,
1390 /***************************/
1391 static int se401_init(struct usb_se401 *se401)
1393 int i=0, rc;
1394 unsigned char cp[0x40];
1395 char temp[200];
1397 /* led on */
1398 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1400 /* get camera descriptor */
1401 rc=se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, cp, sizeof(cp));
1402 if (cp[1]!=0x41) {
1403 err("Wrong descriptor type");
1404 return 1;
1406 sprintf (temp, "ExtraFeatures: %d", cp[3]);
1408 se401->sizes=cp[4]+cp[5]*256;
1409 se401->width=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1410 if (!se401->width)
1411 return 1;
1412 se401->height=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1413 if (!se401->height) {
1414 kfree(se401->width);
1415 return 1;
1417 for (i=0; i<se401->sizes; i++) {
1418 se401->width[i]=cp[6+i*4+0]+cp[6+i*4+1]*256;
1419 se401->height[i]=cp[6+i*4+2]+cp[6+i*4+3]*256;
1421 sprintf (temp, "%s Sizes:", temp);
1422 for (i=0; i<se401->sizes; i++) {
1423 sprintf(temp, "%s %dx%d", temp, se401->width[i], se401->height[i]);
1425 info("%s", temp);
1426 se401->maxframesize=se401->width[se401->sizes-1]*se401->height[se401->sizes-1]*3;
1428 rc=se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp));
1429 se401->cwidth=cp[0]+cp[1]*256;
1430 rc=se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp));
1431 se401->cheight=cp[0]+cp[1]*256;
1433 if (!cp[2] && SE401_FORMAT_BAYER) {
1434 err("Bayer format not supported!");
1435 return 1;
1437 /* set output mode (BAYER) */
1438 se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, SE401_FORMAT_BAYER, NULL, 0);
1440 rc=se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp));
1441 se401->brightness=cp[0]+cp[1]*256;
1442 /* some default values */
1443 se401->resetlevel=0x2d;
1444 se401->rgain=0x20;
1445 se401->ggain=0x20;
1446 se401->bgain=0x20;
1447 se401_set_exposure(se401, 20000);
1448 se401->palette=VIDEO_PALETTE_RGB24;
1449 se401->enhance=1;
1450 se401->dropped=0;
1451 se401->error=0;
1452 se401->framecount=0;
1453 se401->readcount=0;
1455 /* Start interrupt transfers for snapshot button */
1456 se401->inturb=usb_alloc_urb(0);
1457 if (!se401->inturb) {
1458 info("Allocation of inturb failed");
1459 return 1;
1461 FILL_INT_URB(se401->inturb, se401->dev,
1462 usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT),
1463 &se401->button, sizeof(se401->button),
1464 se401_button_irq,
1465 se401,
1466 HZ/10
1468 if (usb_submit_urb(se401->inturb)) {
1469 info("int urb burned down");
1470 return 1;
1473 /* Flash the led */
1474 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
1475 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1476 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
1477 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
1479 return 0;
1482 static void* se401_probe(struct usb_device *dev, unsigned int ifnum,
1483 const struct usb_device_id *id)
1485 struct usb_interface_descriptor *interface;
1486 struct usb_se401 *se401;
1487 char *camera_name=NULL;
1489 /* We don't handle multi-config cameras */
1490 if (dev->descriptor.bNumConfigurations != 1)
1491 return NULL;
1493 interface = &dev->actconfig->interface[ifnum].altsetting[0];
1495 /* Is it an se401? */
1496 if (dev->descriptor.idVendor == 0x03e8 &&
1497 dev->descriptor.idProduct == 0x0004) {
1498 camera_name="Endpoints/Aox SE401";
1499 } else if (dev->descriptor.idVendor == 0x0471 &&
1500 dev->descriptor.idProduct == 0x030b) {
1501 camera_name="Philips PCVC665K";
1502 } else if (dev->descriptor.idVendor == 0x047d &&
1503 dev->descriptor.idProduct == 0x5001) {
1504 camera_name="Kensington VideoCAM 67014";
1505 } else if (dev->descriptor.idVendor == 0x047d &&
1506 dev->descriptor.idProduct == 0x5002) {
1507 camera_name="Kensington VideoCAM 6701(5/7)";
1508 } else if (dev->descriptor.idVendor == 0x047d &&
1509 dev->descriptor.idProduct == 0x5003) {
1510 camera_name="Kensington VideoCAM 67016";
1511 } else
1512 return NULL;
1514 /* Checking vendor/product should be enough, but what the hell */
1515 if (interface->bInterfaceClass != 0x00)
1516 return NULL;
1517 if (interface->bInterfaceSubClass != 0x00)
1518 return NULL;
1520 /* We found one */
1521 info("SE401 camera found: %s", camera_name);
1523 if ((se401 = kmalloc(sizeof(*se401), GFP_KERNEL)) == NULL) {
1524 err("couldn't kmalloc se401 struct");
1525 return NULL;
1528 memset(se401, 0, sizeof(*se401));
1530 se401->dev = dev;
1531 se401->iface = interface->bInterfaceNumber;
1532 se401->camera_name = camera_name;
1534 info("firmware version: %02x", dev->descriptor.bcdDevice & 255);
1536 if (se401_init(se401)) {
1537 kfree(se401);
1538 return NULL;
1541 memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
1542 memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name));
1543 init_waitqueue_head(&se401->wq);
1544 init_MUTEX(&se401->lock);
1545 wmb();
1547 if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
1548 kfree(se401);
1549 err("video_register_device failed");
1550 return NULL;
1552 info("registered new video device: video%d", se401->vdev.minor);
1554 return se401;
1557 static void se401_disconnect(struct usb_device *dev, void *ptr)
1559 struct usb_se401 *se401 = (struct usb_se401 *) ptr;
1561 lock_kernel();
1562 /* We don't want people trying to open up the device */
1563 if (!se401->user){
1564 video_unregister_device(&se401->vdev);
1565 usb_se401_remove_disconnected(se401);
1566 } else {
1567 se401->removed = 1;
1569 unlock_kernel();
1572 static struct usb_driver se401_driver = {
1573 name: "se401",
1574 id_table: device_table,
1575 probe: se401_probe,
1576 disconnect: se401_disconnect
1581 /****************************************************************************
1583 * Module routines
1585 ***************************************************************************/
1587 static int __init usb_se401_init(void)
1589 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
1590 proc_se401_create();
1591 #endif
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;
1599 if (usb_register(&se401_driver) < 0)
1600 return -1;
1601 return 0;
1604 static void __exit usb_se401_exit(void)
1606 usb_deregister(&se401_driver);
1607 info("SE401 driver deregistered");
1609 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
1610 proc_se401_destroy();
1611 #endif
1614 module_init(usb_se401_init);
1615 module_exit(usb_se401_exit);