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.
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
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.
28 static const char version[] = "0.24";
30 #include <linux/config.h>
31 #include <linux/module.h>
32 #include <linux/init.h>
33 #include <linux/vmalloc.h>
34 #include <linux/slab.h>
35 #include <linux/pagemap.h>
36 #include <linux/usb.h>
39 static int flickerless=0;
40 static int video_nr = -1;
42 static struct usb_device_id device_table [] = {
43 { USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */
44 { USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */
45 { USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */
46 { USB_DEVICE(0x047d, 0x5002) },/* Kensington 6701(5/7) */
47 { USB_DEVICE(0x047d, 0x5003) },/* Kensington 67016 */
51 MODULE_DEVICE_TABLE(usb, device_table);
53 MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>");
54 MODULE_DESCRIPTION("SE401 USB Camera Driver");
55 MODULE_LICENSE("GPL");
56 module_param(flickerless, int, 0);
57 MODULE_PARM_DESC(flickerless, "Net frequency to adjust exposure time to (0/50/60)");
58 module_param(video_nr, int, 0);
60 static struct usb_driver se401_driver;
63 /**********************************************************************
67 **********************************************************************/
68 static void *rvmalloc(unsigned long size)
73 size = PAGE_ALIGN(size);
74 mem = vmalloc_32(size);
78 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
79 adr = (unsigned long) mem;
81 SetPageReserved(vmalloc_to_page((void *)adr));
89 static void rvfree(void *mem, unsigned long size)
96 adr = (unsigned long) mem;
97 while ((long) size > 0) {
98 ClearPageReserved(vmalloc_to_page((void *)adr));
107 /****************************************************************************
109 * se401 register read/write functions
111 ***************************************************************************/
113 static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req,
114 unsigned short value, unsigned char *cp, int size)
116 return usb_control_msg (
118 set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0),
120 (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
129 static int se401_set_feature(struct usb_se401 *se401, unsigned short selector,
130 unsigned short param)
132 /* specs say that the selector (address) should go in the value field
133 and the param in index, but in the logs of the windows driver they do
134 this the other way around...
136 return usb_control_msg (
138 usb_sndctrlpipe(se401->dev, 0),
139 SE401_REQ_SET_EXT_FEATURE,
140 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
149 static unsigned short se401_get_feature(struct usb_se401 *se401,
150 unsigned short selector)
152 /* For 'set' the selecetor should be in index, not sure if the spec is
158 usb_rcvctrlpipe(se401->dev, 0),
159 SE401_REQ_GET_EXT_FEATURE,
160 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
167 return cp[0]+cp[1]*256;
170 /****************************************************************************
174 ***************************************************************************/
177 static int se401_send_pict(struct usb_se401 *se401)
179 se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l);/* integration time low */
180 se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m);/* integration time mid */
181 se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h);/* integration time mid */
182 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);/* reset level value */
183 se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);/* red color gain */
184 se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);/* green color gain */
185 se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);/* blue color gain */
190 static void se401_set_exposure(struct usb_se401 *se401, int brightness)
192 int integration=brightness<<5;
194 if (flickerless==50) {
195 integration=integration-integration%106667;
197 if (flickerless==60) {
198 integration=integration-integration%88889;
200 se401->brightness=integration>>5;
201 se401->expose_h=(integration>>16)&0xff;
202 se401->expose_m=(integration>>8)&0xff;
203 se401->expose_l=integration&0xff;
206 static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p)
208 p->brightness=se401->brightness;
209 if (se401->enhance) {
216 p->hue=se401->rgain<<10;
217 p->palette=se401->palette;
218 p->depth=3; /* rgb24 */
223 static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p)
225 if (p->palette != VIDEO_PALETTE_RGB24)
227 se401->palette=p->palette;
228 if (p->hue!=se401->hue) {
229 se401->rgain= p->hue>>10;
230 se401->bgain= 0x40-(p->hue>>10);
233 if (p->brightness!=se401->brightness) {
234 se401_set_exposure(se401, p->brightness);
236 if (p->whiteness>=32768) {
241 se401_send_pict(se401);
242 se401_send_pict(se401);
247 Hyundai have some really nice docs about this and other sensor related
248 stuff on their homepage: www.hei.co.kr
250 static void se401_auto_resetlevel(struct usb_se401 *se401)
252 unsigned int ahrc, alrc;
253 int oldreset=se401->resetlevel;
255 /* For some reason this normally read-only register doesn't get reset
256 to zero after reading them just once...
258 se401_get_feature(se401, HV7131_REG_HIREFNOH);
259 se401_get_feature(se401, HV7131_REG_HIREFNOL);
260 se401_get_feature(se401, HV7131_REG_LOREFNOH);
261 se401_get_feature(se401, HV7131_REG_LOREFNOL);
262 ahrc=256*se401_get_feature(se401, HV7131_REG_HIREFNOH) +
263 se401_get_feature(se401, HV7131_REG_HIREFNOL);
264 alrc=256*se401_get_feature(se401, HV7131_REG_LOREFNOH) +
265 se401_get_feature(se401, HV7131_REG_LOREFNOL);
267 /* Not an exact science, but it seems to work pretty well... */
269 while (alrc>=10 && se401->resetlevel < 63) {
273 } else if (ahrc > 20) {
274 while (ahrc>=20 && se401->resetlevel > 0) {
279 if (se401->resetlevel!=oldreset)
280 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
285 /* irq handler for snapshot button */
286 static void se401_button_irq(struct urb *urb, struct pt_regs *regs)
288 struct usb_se401 *se401 = urb->context;
292 info("ohoh: device vapourished");
296 switch (urb->status) {
303 /* this urb is terminated, clean up */
304 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
307 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
311 if (urb->actual_length >=2) {
313 se401->buttonpressed=1;
316 status = usb_submit_urb (urb, GFP_ATOMIC);
318 err ("%s - usb_submit_urb failed with result %d",
319 __FUNCTION__, status);
322 static void se401_video_irq(struct urb *urb, struct pt_regs *regs)
324 struct usb_se401 *se401 = urb->context;
325 int length = urb->actual_length;
328 if (!se401->streaming)
332 info ("ohoh: device vapourished");
336 /* 0 sized packets happen if we are to fast, but sometimes the camera
337 keeps sending them forever...
339 if (length && !urb->status) {
340 se401->nullpackets=0;
341 switch(se401->scratch[se401->scratch_next].state) {
347 case BUFFER_UNUSED: {
348 memcpy(se401->scratch[se401->scratch_next].data, (unsigned char *)urb->transfer_buffer, length);
349 se401->scratch[se401->scratch_next].state=BUFFER_READY;
350 se401->scratch[se401->scratch_next].offset=se401->bayeroffset;
351 se401->scratch[se401->scratch_next].length=length;
352 if (waitqueue_active(&se401->wq)) {
353 wake_up_interruptible(&se401->wq);
355 se401->scratch_overflow=0;
356 se401->scratch_next++;
357 if (se401->scratch_next>=SE401_NUMSCRATCH)
358 se401->scratch_next=0;
362 se401->bayeroffset+=length;
363 if (se401->bayeroffset>=se401->cheight*se401->cwidth) {
364 se401->bayeroffset=0;
367 se401->nullpackets++;
368 if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
369 if (waitqueue_active(&se401->wq)) {
370 wake_up_interruptible(&se401->wq);
375 /* Resubmit urb for new data */
378 if(usb_submit_urb(urb, GFP_KERNEL))
379 info("urb burned down");
383 static void se401_send_size(struct usb_se401 *se401, int width, int height)
386 int mode=0x03; /* No compression */
387 int sendheight=height;
390 /* JangGu compression can only be used with the camera supported sizes,
391 but bayer seems to work with any size that fits on the sensor.
392 We check if we can use compression with the current size with either
393 4 or 16 times subcapturing, if not we use uncompressed bayer data
394 but this will result in cutouts of the maximum size....
396 while (i<se401->sizes && !(se401->width[i]==width && se401->height[i]==height))
398 while (i<se401->sizes) {
399 if (se401->width[i]==width*2 && se401->height[i]==height*2) {
400 sendheight=se401->height[i];
401 sendwidth=se401->width[i];
404 if (se401->width[i]==width*4 && se401->height[i]==height*4) {
405 sendheight=se401->height[i];
406 sendwidth=se401->width[i];
412 se401_sndctrl(1, se401, SE401_REQ_SET_WIDTH, sendwidth, NULL, 0);
413 se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0);
414 se401_set_feature(se401, SE401_OPERATINGMODE, mode);
417 se401->format=FMT_BAYER;
419 se401->format=FMT_JANGGU;
426 In this function se401_send_pict is called several times,
427 for some reason (depending on the state of the sensor and the phase of
428 the moon :) doing this only in either place doesn't always work...
430 static int se401_start_stream(struct usb_se401 *se401)
436 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
437 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
439 /* Set picture settings */
440 se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);/*windowed + pix intg */
441 se401_send_pict(se401);
443 se401_send_size(se401, se401->cwidth, se401->cheight);
445 se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE, 0, NULL, 0);
447 /* Do some memory allocation */
448 for (i=0; i<SE401_NUMFRAMES; i++) {
449 se401->frame[i].data=se401->fbuf + i * se401->maxframesize;
450 se401->frame[i].curpix=0;
452 for (i=0; i<SE401_NUMSBUF; i++) {
453 se401->sbuf[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
456 se401->bayeroffset=0;
457 se401->scratch_next=0;
458 se401->scratch_use=0;
459 se401->scratch_overflow=0;
460 for (i=0; i<SE401_NUMSCRATCH; i++) {
461 se401->scratch[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
462 se401->scratch[i].state=BUFFER_UNUSED;
465 for (i=0; i<SE401_NUMSBUF; i++) {
466 urb=usb_alloc_urb(0, GFP_KERNEL);
470 usb_fill_bulk_urb(urb, se401->dev,
471 usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT),
472 se401->sbuf[i].data, SE401_PACKETSIZE,
478 err=usb_submit_urb(se401->urb[i], GFP_KERNEL);
480 err("urb burned down");
488 static int se401_stop_stream(struct usb_se401 *se401)
492 if (!se401->streaming || !se401->dev)
497 se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0);
499 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
500 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
502 for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
503 usb_kill_urb(se401->urb[i]);
504 usb_free_urb(se401->urb[i]);
506 kfree(se401->sbuf[i].data);
508 for (i=0; i<SE401_NUMSCRATCH; i++) {
509 kfree(se401->scratch[i].data);
510 se401->scratch[i].data=NULL;
516 static int se401_set_size(struct usb_se401 *se401, int width, int height)
518 int wasstreaming=se401->streaming;
519 /* Check to see if we need to change */
520 if (se401->cwidth==width && se401->cheight==height)
523 /* Check for a valid mode */
524 if (!width || !height)
526 if ((width & 1) || (height & 1))
528 if (width>se401->width[se401->sizes-1])
530 if (height>se401->height[se401->sizes-1])
533 /* Stop a current stream and start it again at the new size */
535 se401_stop_stream(se401);
537 se401->cheight=height;
539 se401_start_stream(se401);
544 /****************************************************************************
548 ***************************************************************************/
551 This shouldn't really be done in a v4l driver....
552 But it does make the image look a lot more usable.
553 Basically it lifts the dark pixels more than the light pixels.
555 static inline void enhance_picture(unsigned char *frame, int len)
558 *frame=(((*frame^255)*(*frame^255))/255)^255;
563 static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data)
565 struct se401_frame *frame=&se401->frame[se401->curframe];
566 int linelength=se401->cwidth*3;
568 if (frame->curlinepix >= linelength) {
570 frame->curline+=linelength;
573 /* First three are absolute, all others relative.
574 * Format is rgb from right to left (mirrorred image),
575 * we flip it to get bgr from left to right. */
576 if (frame->curlinepix < 3) {
577 *(frame->curline-frame->curlinepix)=1+data*4;
579 *(frame->curline-frame->curlinepix)=
580 *(frame->curline-frame->curlinepix+3)+data*4;
585 static inline void decode_JangGu_vlc (struct usb_se401 *se401, unsigned char *data, int bit_exp, int packetlength)
594 while (pos < packetlength) {
596 while (bit_cur && bit_exp) {
597 bit=((*data)>>(bit_cur-1))&1;
603 decode_JangGu_integrate(se401, 0);
612 vlc_data = -(1<<vlc_size) + 1;
616 vlc_data+=bit<<vlc_size;
618 decode_JangGu_integrate(se401, vlc_data);
630 static inline void decode_JangGu (struct usb_se401 *se401, struct se401_scratch *buffer)
632 unsigned char *data=buffer->data;
633 int len=buffer->length;
634 int bit_exp=0, pix_exp=0, frameinfo=0, packetlength=0, size;
638 if (!se401->frame[se401->curframe].curpix) {
639 se401->frame[se401->curframe].curlinepix=0;
640 se401->frame[se401->curframe].curline=
641 se401->frame[se401->curframe].data+
643 if (se401->frame[se401->curframe].grabstate==FRAME_READY)
644 se401->frame[se401->curframe].grabstate=FRAME_GRABBING;
647 while (datapos < len) {
648 size=1024-se401->vlcdatapos;
649 if (size+datapos > len)
651 memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size);
652 se401->vlcdatapos+=size;
654 if (se401->vlcdatapos >= 4) {
655 bit_exp=se401->vlcdata[3]+(se401->vlcdata[2]<<8);
656 pix_exp=se401->vlcdata[1]+((se401->vlcdata[0]&0x3f)<<8);
657 frameinfo=se401->vlcdata[0]&0xc0;
658 packetlength=((bit_exp+47)>>4)<<1;
659 if (packetlength > 1024) {
664 se401->frame[se401->curframe].curpix=0;
667 if (packetlength && se401->vlcdatapos >= packetlength) {
668 decode_JangGu_vlc(se401, se401->vlcdata, bit_exp, packetlength);
669 se401->frame[se401->curframe].curpix+=pix_exp*3;
670 datapos+=size-(se401->vlcdatapos-packetlength);
672 if (se401->frame[se401->curframe].curpix>=se401->cwidth*se401->cheight*3) {
673 if (se401->frame[se401->curframe].curpix==se401->cwidth*se401->cheight*3) {
674 if (se401->frame[se401->curframe].grabstate==FRAME_GRABBING) {
675 se401->frame[se401->curframe].grabstate=FRAME_DONE;
679 if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
680 se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
685 se401->frame[se401->curframe].curpix=0;
694 static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch *buffer)
696 unsigned char *data=buffer->data;
697 int len=buffer->length;
698 int offset=buffer->offset;
699 int datasize=se401->cwidth*se401->cheight;
700 struct se401_frame *frame=&se401->frame[se401->curframe];
702 unsigned char *framedata=frame->data, *curline, *nextline;
703 int width=se401->cwidth;
704 int blineoffset=0, bline;
705 int linelength=width*3, i;
708 if (frame->curpix==0) {
709 if (frame->grabstate==FRAME_READY) {
710 frame->grabstate=FRAME_GRABBING;
712 frame->curline=framedata+linelength;
716 if (offset!=frame->curpix) {
717 /* Regard frame as lost :( */
723 /* Check if we have to much data */
724 if (frame->curpix+len > datasize) {
725 len=datasize-frame->curpix;
727 if (se401->cheight%4)
729 bline=frame->curpix/se401->cwidth+blineoffset;
731 curline=frame->curline;
732 nextline=curline+linelength;
733 if (nextline >= framedata+datasize*3)
736 if (frame->curlinepix>=width) {
737 frame->curlinepix-=width;
738 bline=frame->curpix/width+blineoffset;
739 curline+=linelength*2;
740 nextline+=linelength*2;
741 if (curline >= framedata+datasize*3) {
749 if (nextline >= framedata+datasize*3)
753 if ((frame->curlinepix&1)) {
760 (*(curline+1)+*data)/2;
762 (*(curline-2)+*data)/2;
767 if ((frame->curlinepix&1)) {
769 (*(curline+1)+*data)/2;
771 (*(curline-2)+*data)/2;
788 frame->curline=curline;
790 if (frame->curpix>=datasize) {
791 /* Fix the top line */
792 framedata+=linelength;
793 for (i=0; i<linelength; i++) {
795 *framedata=*(framedata+linelength);
797 /* Fix the left side (green is already present) */
798 for (i=0; i<se401->cheight; i++) {
799 *framedata=*(framedata+3);
800 *(framedata+1)=*(framedata+4);
801 *(framedata+2)=*(framedata+5);
802 framedata+=linelength;
805 frame->grabstate=FRAME_DONE;
808 if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
809 se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
814 static int se401_newframe(struct usb_se401 *se401, int framenr)
816 DECLARE_WAITQUEUE(wait, current);
819 while (se401->streaming &&
820 (se401->frame[framenr].grabstate==FRAME_READY ||
821 se401->frame[framenr].grabstate==FRAME_GRABBING) ) {
822 if(!se401->frame[framenr].curpix) {
826 se401->scratch[se401->scratch_use].state!=BUFFER_READY,
830 if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
831 se401->nullpackets=0;
832 info("to many null length packets, restarting capture");
833 se401_stop_stream(se401);
834 se401_start_stream(se401);
836 if (se401->scratch[se401->scratch_use].state!=BUFFER_READY) {
837 se401->frame[framenr].grabstate=FRAME_ERROR;
840 se401->scratch[se401->scratch_use].state=BUFFER_BUSY;
841 if (se401->format==FMT_JANGGU) {
842 decode_JangGu(se401, &se401->scratch[se401->scratch_use]);
844 decode_bayer(se401, &se401->scratch[se401->scratch_use]);
846 se401->scratch[se401->scratch_use].state=BUFFER_UNUSED;
847 se401->scratch_use++;
848 if (se401->scratch_use>=SE401_NUMSCRATCH)
849 se401->scratch_use=0;
850 if (errors > SE401_MAX_ERRORS) {
852 info("to much errors, restarting capture");
853 se401_stop_stream(se401);
854 se401_start_stream(se401);
859 if (se401->frame[framenr].grabstate==FRAME_DONE)
861 enhance_picture(se401->frame[framenr].data, se401->cheight*se401->cwidth*3);
865 static void usb_se401_remove_disconnected (struct usb_se401 *se401)
871 for (i=0; i<SE401_NUMSBUF; i++)
873 usb_kill_urb(se401->urb[i]);
874 usb_free_urb(se401->urb[i]);
875 se401->urb[i] = NULL;
876 kfree(se401->sbuf[i].data);
878 for (i=0; i<SE401_NUMSCRATCH; i++) {
879 kfree(se401->scratch[i].data);
882 usb_kill_urb(se401->inturb);
883 usb_free_urb(se401->inturb);
885 info("%s disconnected", se401->camera_name);
887 /* Free the memory */
889 kfree(se401->height);
895 /****************************************************************************
899 ***************************************************************************/
902 static int se401_open(struct inode *inode, struct file *file)
904 struct video_device *dev = video_devdata(file);
905 struct usb_se401 *se401 = (struct usb_se401 *)dev;
910 se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES);
912 file->private_data = dev;
920 static int se401_close(struct inode *inode, struct file *file)
922 struct video_device *dev = file->private_data;
923 struct usb_se401 *se401 = (struct usb_se401 *)dev;
926 rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES);
927 if (se401->removed) {
928 usb_se401_remove_disconnected(se401);
929 info("device unregistered");
931 for (i=0; i<SE401_NUMFRAMES; i++)
932 se401->frame[i].grabstate=FRAME_UNUSED;
933 if (se401->streaming)
934 se401_stop_stream(se401);
937 file->private_data = NULL;
941 static int se401_do_ioctl(struct inode *inode, struct file *file,
942 unsigned int cmd, void *arg)
944 struct video_device *vdev = file->private_data;
945 struct usb_se401 *se401 = (struct usb_se401 *)vdev;
953 struct video_capability *b = arg;
954 strcpy(b->name, se401->camera_name);
955 b->type = VID_TYPE_CAPTURE;
958 b->maxwidth = se401->width[se401->sizes-1];
959 b->maxheight = se401->height[se401->sizes-1];
960 b->minwidth = se401->width[0];
961 b->minheight = se401->height[0];
966 struct video_channel *v = arg;
972 v->type = VIDEO_TYPE_CAMERA;
973 strcpy(v->name, "Camera");
978 struct video_channel *v = arg;
986 struct video_picture *p = arg;
988 se401_get_pict(se401, p);
993 struct video_picture *p = arg;
995 if (se401_set_pict(se401, p))
1001 struct video_window *vw = arg;
1007 if (se401_set_size(se401, vw->width, vw->height))
1013 struct video_window *vw = arg;
1015 vw->x = 0; /* FIXME */
1020 vw->width = se401->cwidth;
1021 vw->height = se401->cheight;
1026 struct video_mbuf *vm = arg;
1029 memset(vm, 0, sizeof(*vm));
1030 vm->size = SE401_NUMFRAMES * se401->maxframesize;
1031 vm->frames = SE401_NUMFRAMES;
1032 for (i=0; i<SE401_NUMFRAMES; i++)
1033 vm->offsets[i] = se401->maxframesize * i;
1036 case VIDIOCMCAPTURE:
1038 struct video_mmap *vm = arg;
1040 if (vm->format != VIDEO_PALETTE_RGB24)
1042 if (vm->frame >= SE401_NUMFRAMES)
1044 if (se401->frame[vm->frame].grabstate != FRAME_UNUSED)
1047 /* Is this according to the v4l spec??? */
1048 if (se401_set_size(se401, vm->width, vm->height))
1050 se401->frame[vm->frame].grabstate=FRAME_READY;
1052 if (!se401->streaming)
1053 se401_start_stream(se401);
1055 /* Set the picture properties */
1056 if (se401->framecount==0)
1057 se401_send_pict(se401);
1058 /* Calibrate the reset level after a few frames. */
1059 if (se401->framecount%20==1)
1060 se401_auto_resetlevel(se401);
1069 if(*frame <0 || *frame >= SE401_NUMFRAMES)
1072 ret=se401_newframe(se401, *frame);
1073 se401->frame[*frame].grabstate=FRAME_UNUSED;
1078 struct video_buffer *vb = arg;
1080 memset(vb, 0, sizeof(*vb));
1099 return -ENOIOCTLCMD;
1105 static int se401_ioctl(struct inode *inode, struct file *file,
1106 unsigned int cmd, unsigned long arg)
1108 return video_usercopy(inode, file, cmd, arg, se401_do_ioctl);
1111 static ssize_t se401_read(struct file *file, char __user *buf,
1112 size_t count, loff_t *ppos)
1114 int realcount=count, ret=0;
1115 struct video_device *dev = file->private_data;
1116 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1119 if (se401->dev == NULL)
1121 if (realcount > se401->cwidth*se401->cheight*3)
1122 realcount=se401->cwidth*se401->cheight*3;
1124 /* Shouldn't happen: */
1125 if (se401->frame[0].grabstate==FRAME_GRABBING)
1127 se401->frame[0].grabstate=FRAME_READY;
1128 se401->frame[1].grabstate=FRAME_UNUSED;
1131 if (!se401->streaming)
1132 se401_start_stream(se401);
1134 /* Set the picture properties */
1135 if (se401->framecount==0)
1136 se401_send_pict(se401);
1137 /* Calibrate the reset level after a few frames. */
1138 if (se401->framecount%20==1)
1139 se401_auto_resetlevel(se401);
1141 ret=se401_newframe(se401, 0);
1143 se401->frame[0].grabstate=FRAME_UNUSED;
1146 if (copy_to_user(buf, se401->frame[0].data, realcount))
1152 static int se401_mmap(struct file *file, struct vm_area_struct *vma)
1154 struct video_device *dev = file->private_data;
1155 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1156 unsigned long start = vma->vm_start;
1157 unsigned long size = vma->vm_end-vma->vm_start;
1158 unsigned long page, pos;
1162 if (se401->dev == NULL) {
1166 if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) {
1170 pos = (unsigned long)se401->fbuf;
1172 page = vmalloc_to_pfn((void *)pos);
1173 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
1179 if (size > PAGE_SIZE)
1189 static struct file_operations se401_fops = {
1190 .owner = THIS_MODULE,
1192 .release = se401_close,
1195 .ioctl = se401_ioctl,
1196 .compat_ioctl = v4l_compat_ioctl32,
1197 .llseek = no_llseek,
1199 static struct video_device se401_template = {
1200 .owner = THIS_MODULE,
1201 .name = "se401 USB camera",
1202 .type = VID_TYPE_CAPTURE,
1203 .hardware = VID_HARDWARE_SE401,
1204 .fops = &se401_fops,
1209 /***************************/
1210 static int se401_init(struct usb_se401 *se401, int button)
1213 unsigned char cp[0x40];
1217 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1219 /* get camera descriptor */
1220 rc=se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, cp, sizeof(cp));
1222 err("Wrong descriptor type");
1225 sprintf (temp, "ExtraFeatures: %d", cp[3]);
1227 se401->sizes=cp[4]+cp[5]*256;
1228 se401->width=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1231 se401->height=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1232 if (!se401->height) {
1233 kfree(se401->width);
1236 for (i=0; i<se401->sizes; i++) {
1237 se401->width[i]=cp[6+i*4+0]+cp[6+i*4+1]*256;
1238 se401->height[i]=cp[6+i*4+2]+cp[6+i*4+3]*256;
1240 sprintf (temp, "%s Sizes:", temp);
1241 for (i=0; i<se401->sizes; i++) {
1242 sprintf(temp, "%s %dx%d", temp, se401->width[i], se401->height[i]);
1245 se401->maxframesize=se401->width[se401->sizes-1]*se401->height[se401->sizes-1]*3;
1247 rc=se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp));
1248 se401->cwidth=cp[0]+cp[1]*256;
1249 rc=se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp));
1250 se401->cheight=cp[0]+cp[1]*256;
1252 if (!cp[2] && SE401_FORMAT_BAYER) {
1253 err("Bayer format not supported!");
1256 /* set output mode (BAYER) */
1257 se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, SE401_FORMAT_BAYER, NULL, 0);
1259 rc=se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp));
1260 se401->brightness=cp[0]+cp[1]*256;
1261 /* some default values */
1262 se401->resetlevel=0x2d;
1266 se401_set_exposure(se401, 20000);
1267 se401->palette=VIDEO_PALETTE_RGB24;
1271 se401->framecount=0;
1274 /* Start interrupt transfers for snapshot button */
1276 se401->inturb=usb_alloc_urb(0, GFP_KERNEL);
1277 if (!se401->inturb) {
1278 info("Allocation of inturb failed");
1281 usb_fill_int_urb(se401->inturb, se401->dev,
1282 usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT),
1283 &se401->button, sizeof(se401->button),
1288 if (usb_submit_urb(se401->inturb, GFP_KERNEL)) {
1289 info("int urb burned down");
1296 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
1297 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1298 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
1299 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
1304 static int se401_probe(struct usb_interface *intf,
1305 const struct usb_device_id *id)
1307 struct usb_device *dev = interface_to_usbdev(intf);
1308 struct usb_interface_descriptor *interface;
1309 struct usb_se401 *se401;
1310 char *camera_name=NULL;
1313 /* We don't handle multi-config cameras */
1314 if (dev->descriptor.bNumConfigurations != 1)
1317 interface = &intf->cur_altsetting->desc;
1319 /* Is it an se401? */
1320 if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 &&
1321 le16_to_cpu(dev->descriptor.idProduct) == 0x0004) {
1322 camera_name="Endpoints/Aox SE401";
1323 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 &&
1324 le16_to_cpu(dev->descriptor.idProduct) == 0x030b) {
1325 camera_name="Philips PCVC665K";
1326 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1327 le16_to_cpu(dev->descriptor.idProduct) == 0x5001) {
1328 camera_name="Kensington VideoCAM 67014";
1329 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1330 le16_to_cpu(dev->descriptor.idProduct) == 0x5002) {
1331 camera_name="Kensington VideoCAM 6701(5/7)";
1332 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1333 le16_to_cpu(dev->descriptor.idProduct) == 0x5003) {
1334 camera_name="Kensington VideoCAM 67016";
1339 /* Checking vendor/product should be enough, but what the hell */
1340 if (interface->bInterfaceClass != 0x00)
1342 if (interface->bInterfaceSubClass != 0x00)
1346 info("SE401 camera found: %s", camera_name);
1348 if ((se401 = kmalloc(sizeof(*se401), GFP_KERNEL)) == NULL) {
1349 err("couldn't kmalloc se401 struct");
1353 memset(se401, 0, sizeof(*se401));
1356 se401->iface = interface->bInterfaceNumber;
1357 se401->camera_name = camera_name;
1359 info("firmware version: %02x", le16_to_cpu(dev->descriptor.bcdDevice) & 255);
1361 if (se401_init(se401, button)) {
1366 memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
1367 memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name));
1368 init_waitqueue_head(&se401->wq);
1369 init_MUTEX(&se401->lock);
1372 if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
1374 err("video_register_device failed");
1377 info("registered new video device: video%d", se401->vdev.minor);
1379 usb_set_intfdata (intf, se401);
1383 static void se401_disconnect(struct usb_interface *intf)
1385 struct usb_se401 *se401 = usb_get_intfdata (intf);
1387 usb_set_intfdata (intf, NULL);
1389 video_unregister_device(&se401->vdev);
1391 usb_se401_remove_disconnected(se401);
1393 se401->frame[0].grabstate = FRAME_ERROR;
1394 se401->frame[0].grabstate = FRAME_ERROR;
1396 se401->streaming = 0;
1398 wake_up_interruptible(&se401->wq);
1404 static struct usb_driver se401_driver = {
1406 .id_table = device_table,
1407 .probe = se401_probe,
1408 .disconnect = se401_disconnect,
1413 /****************************************************************************
1417 ***************************************************************************/
1419 static int __init usb_se401_init(void)
1421 info("SE401 usb camera driver version %s registering", version);
1423 if (flickerless!=50 && flickerless!=60) {
1424 info("Invallid flickerless value, use 0, 50 or 60.");
1427 return usb_register(&se401_driver);
1430 static void __exit usb_se401_exit(void)
1432 usb_deregister(&se401_driver);
1433 info("SE401 driver deregistered");
1436 module_init(usb_se401_init);
1437 module_exit(usb_se401_exit);