Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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